When your database is hosted on a remote server, especially inside a private network or cloud VPC, you should never expose the database port publicly. Instead, the safest and most developer-friendly method is to create an SSH Tunnel (SSH Port Forwarding).
An SSH tunnel lets your Java or Spring Boot application connect to a remote MySQL, PostgreSQL, or MariaDB database as if it were running locally, while the actual connection happens securely through SSH.
This guide explains how to connect any Java application (JDBC, plain Java apps, CLI tools, and Spring Boot apps) to a remote database via SSH tunneling using the recommended terminal-based method.
Table of Contents
β What Is an SSH Tunnel?
SSH Tunnel (or SSH Port Forwarding) securely forwards a local port on your machine to a remote system over SSH.
Example:
Local App β SSH Tunnel β Remote Server β Database
You get:
β Encrypted communication
β No exposure of DB ports
β Works behind private networks
β Simple setup
β Perfect for Java developers
Use Cases
1. Local Java development connecting to production-like DB
Avoid exposing port 3306/5432 over the internet.
2. Run backend apps against remote staging DB
SSH tunnel provides secure access.
3. Remote cloud databases inside private subnets
Ideal for AWS EC2, Google Cloud VM, or on-premise servers.
4. Debugging issues on remote DB
View and interact with DB safely.
π Why SSH Tunnel Instead of Exposing DB Ports?
| Without SSH Tunnel | With SSH Tunnel |
|---|---|
| DB must be public | DB stays private |
| Exposed to attacks | Traffic encrypted |
| Firewall complexity | Simple forwarding |
| Risky in production | Secure & standard |
SSH tunneling is the recommended DevOps practice.
β‘ Solution: Connect Java or Spring Boot Application Using SSH Tunnel (Terminal Method)
This method does NOT require extra code.
You open a secure tunnel β your Java or Spring Boot app connects locally.
Step 1: Create SSH Tunnel Using Terminal
Go to the location where your pem file is present and open terminal from there.
For MySQL
ssh -i my-sshkey.pem -L 3307:my-mysql-host:3306 ubuntu@my-bastion-host-server-ip
For PostgreSQL
ssh -i my-sshkey.pem -L 5433:my-mysql-host:5432 ubuntu@my-bastion-host-server-ip
Meaning:
- Remote DB ports: 3306 / 5432
- Local forwarded ports: 3307 / 5433
- Java application connects locally
- SSH securely handles routing
Keep the SSH tunnel terminal open while running your app.
Step 2: Connect From Any Java Application (Plain JDBC)
Java JDBC Example β MySQL
import java.sql.Connection;
import java.sql.DriverManager;
public class TestConnection {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3307/mydatabase";
String username = "dbuser";
String password = "dbpass";
Connection conn = DriverManager.getConnection(url, username, password);
System.out.println("Connected successfully via SSH tunnel!");
}
}
Java JDBC Example β PostgreSQL
String url = "jdbc:postgresql://localhost:5433/mydatabase";
Connection conn = DriverManager.getConnection(url, "dbuser", "dbpass");
No special SSH libraries required.
Step 3: Connect From Spring Boot
Spring Boot β MySQL via SSH Tunnel
spring.datasource.url=jdbc:mysql://localhost:3307/mydatabase
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Spring Boot β PostgreSQL via SSH Tunnel
spring.datasource.url=jdbc:postgresql://localhost:5433/mydatabase
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=org.postgresql.Driver
Common Errors and Fixes
β Local port already used
Address already in use
Fix: use a different port:
-L 3308:localhost:3306
β Database access denied
Check DB user permissions and host restrictions.
β Connection refused
β DB may not be running
β Wrong remote hostname
β Firewall rules
Security Best Practices
β Always use private keys (not passwords)
β Never expose DB ports publicly
β Allow SSH access only for trusted IPs
β Rotate SSH keys regularly
β Use strong DB passwords
β Disable root login in DB
Conclusion
Connecting to a remote database through an SSH tunnel is the most secure and simplest way for Java and Spring Boot applications to access remote MySQL or PostgreSQL servers without exposing your database to the internet.
Whether you’re building:
- a Java CLI tool,
- a JDBC-based Java application, or
- a Spring Boot backend
β¦this SSH tunneling method works flawlessly and securely.
Just create the SSH tunnel, point your application to the local port, and let SSH handle the secure connection behind the scenes.