我是Docker的初学者。最近,我试图将一个简单的Java应用程序与带有Docker容器的Postgresql连接起来。
我想我的Postgresql码头工人工作得很好:
PostgreSQL dockerfile
FROM postgres
ENV POSTGRES_PASSWORD postgres
ENV POSTGRES_DB testdb
COPY init.sql /docker-entrypoint-initdb.d/
Java应用程序dockerfile:
FROM java:8-jdk-alpine
COPY . /src
WORKDIR /src
RUN javac DBCheck.java
CMD ["java", "-cp", "./postgresql-42.2.8.jar:.", "DBCheck"]
这是我的目录结构
目标是什么?
目标是创建两个Docker容器:一个用于数据库,另一个用于Java应用程序。 Java应用程序应从一个容器连接到数据库容器。
我使用以下命令构建PostgreSQL容器:
$ docker build -t postgres-db .
$ docker run -d --network="bridge" --name db -p 5555:5432 postgres-db
和Java应用容器
$ docker build --tag=java-db-app .
当我使用docker run java-db-app
运行Java应用程序时,它向我返回错误:
Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
我正在使用此URL连接到数据库String url = "jdbc:postgresql://localhost:5432/testdb";
我也尝试了不同的命令,但没有达到目标。
$ docker run --name app -p 5555:5432 --link db:db java-db-app
docker: Error response from daemon: driver failed programming external connectivity on endpoint app (c944c9542dc8633940a9cae6d8cdf7213cce43be126334c4ffff2648e339fba2): Bind for 0.0.0.0:5555 failed: port is already allocated.
ERRO[0004] error waiting for container: context canceled
尝试了其他命令:
docker run -itd --name app -p 5556:5432 java-db-app
docker run d --name app -p 5556:5432 java-db-app
我的Java代码DBCheck.java
public static void main(String[] args) {
String url = "jdbc:postgresql://localhost:5432/testdb";
String user = "postgres";
String password = "postgres";
try (Connection con = DriverManager.getConnection(url, user, password);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT VERSION()")) {
if (rs.next()) {
System.out.println(rs.getString(1));
System.out.println("ldahsfs");
}else{
System.out.println("Failed next!");
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
答案 0 :(得分:1)
因此,在docker run -d --network="bridge" --name db -p 5555:5432 postgres-db
中,您的本地端口映射错误,您已将本地端口5555与docker端口5432进行了映射。尽管Java容器尝试运行,但它在与postgres不同的网络中运行。
因此,可以使用docker network connect
命令或使用docker-compose`。
我建议使用docker compose,因为它可以很好地组织代码,并且默认情况下将图像连接到同一网络上。
我建议使用docker-compose。下面的示例:
version: "3.7"
services:
postgres-db:
image: db:latest
ports:
- 5432:5432
java-db-app:
image: java-db-app:latest
答案 1 :(得分:0)
我在本地主机上遇到了一些问题。所以我使用了docker0 ip地址。
$ ifconfig
您应该找到一个docker0接口并复制inet(172.xxx.yyy.v)
Postgres dockerfile:
FROM postgres
ENV POSTGRES_PASSWORD postgres
ENV POSTGRES_DB testdb
COPY init.sql /docker-entrypoint-initdb.d/
Java应用程序dockerfile
FROM java:8
COPY . /src
WORKDIR /src
RUN javac DBCheck.java
CMD ["java", "-cp", "./postgresql-42.2.8.jar:.", "DBCheck"]
DBCheck.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBCheck {
public static void main(String[] args) {
String user = "postgres";
String password = "postgres";
String url = "jdbc:postgresql://**docker0->ip-address**/testdb?user="+user+"&password="+password;
try (
Connection con = DriverManager.getConnection(url);
// Connection con = DriverManager.getConnection(url, user, password);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT VERSION()")) {
if (rs.next()) {
System.out.println("\nVersion: "+ rs.getString(1)+"\n");
System.out.println("Successfully selected the version!");
}else{
System.out.println("Failed next!");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
首先,运行数据库: docker build -t数据库。 docker run --name db -p 5432:5432数据库
您应该在终端database system is ready to accept connections
然后,构建您的应用程序
docker build -t java-app .
docker run --name app --link db java-app
这就是我能够使用两个Docker容器的方式。