同一端口上两个docker容器(db和简单java应用程序)之间的通信

同一端口上两个docker容器(db和简单java应用程序)之间的通信,java,postgresql,docker,containers,Java,Postgresql,Docker,Containers,我是码头工人的新手。最近,我试图用带有docker容器的Postgresql连接一个简单的java应用程序 我想我的Postgresql docker工作得很好: Postgresql dockerfile FROM postgres ENV POSTGRES_PASSWORD postgres ENV POSTGRES_DB testdb COPY init.sql /docker-entrypoint-initdb.d/ FROM java:8 COPY . /src WORKDIR

我是码头工人的新手。最近,我试图用带有docker容器的Postgresql连接一个简单的java应用程序

我想我的Postgresql docker工作得很好:

Postgresql dockerfile

FROM postgres 
ENV POSTGRES_PASSWORD postgres 
ENV POSTGRES_DB testdb 
COPY init.sql /docker-entrypoint-initdb.d/
FROM java:8
COPY . /src
WORKDIR /src
RUN javac DBCheck.java
CMD ["java", "-cp", "./postgresql-42.2.8.jar:.", "DBCheck"]
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());
        }
    }
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 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



我在localhost上遇到了一些问题。所以我用了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 postgres 
ENV POSTGRES_PASSWORD postgres 
ENV POSTGRES_DB testdb 
COPY init.sql /docker-entrypoint-initdb.d/
FROM java:8
COPY . /src
WORKDIR /src
RUN javac DBCheck.java
CMD ["java", "-cp", "./postgresql-42.2.8.jar:.", "DBCheck"]
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());
        }
    }
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构建-t数据库。 docker run--名称db-p 5432:5432数据库

您应该在终端中看到此消息:
数据库系统已准备好接受连接

然后,构建您的应用程序

docker build -t java-app .
docker run --name app --link db java-app

这就是我使用两个docker容器的方式。

它给了我一个错误:错误:db的拉取访问被拒绝,存储库不存在或可能需要“docker登录”。您必须在docker hub上创建帐户并在本地配置。