无法从另一个容器中的 Web 应用程序访问 docker 中的 postgres

时间:2021-05-27 08:49:36

标签: postgresql docker docker-compose

我有一个示例应用程序,我正在使用 docker-compose 在我的机器上本地运行。 Web 应用程序位于一个容器中,而 db (postgres) 位于另一个容器中。

我遇到了无法解决的连接问题。

docker-compose

version: '3.8'


services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: 'password'
      POSTGRES_DB: 'postgres'
      POSTGRES_USER: 'postgres'
    volumes:
      - ./postgres-db:/var/lib/postgresql/data
    ports:
      - '5432:5432'
  app:
    build:
      context: .
      dockerfile: app/Dockerfile
    restart: always
    environment:
      APP_FRONTEND_PORT: '8080'
      DB_PORT: '5433'
      DB_HOST: 'db'
    ports:
      - '8080:8080'
    depends_on:
      - 'db'

volumes:
    postgres-db:

Dockerfile

FROM golang:latest
WORKDIR /scratch
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build  -o /bin/frontend ./...

FROM alpine:latest

RUN apk --no-cache add ca-certificates
WORKDIR /go/bin/
COPY --from=build /bin/frontend /go/bin/frontend
ENTRYPOINT ["/go/bin/frontend"]

两个容器都在运行,我能够登录到正在运行的 postgres 容器和 postgres 我们运行。

当我尝试从美国运行更新时,出现 500 错误,而且应用程序容器似乎无法与 db 容器通信。我不确定我错过了什么

尝试调用更新日期时出现客户端错误:

encountered err: failed to begin transaction: failed to connect to `host=db user=postgres database=postgres`: dial error (dial tcp 172.29.0.2:5433: connect: connection refused)

docker ps 收益:

$ docker ps
CONTAINER ID   IMAGE               COMMAND                  CREATED          STATUS          PORTS                                       NAMES
19eeed869434   sample_app   "/go/bin/frontend"       48 minutes ago   Up 48 minutes   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   sample_app_1
84804f00c751   postgres            "docker-entrypoint.s…"   48 minutes ago   Up 48 minutes   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp   sample_app_db_1
$ 

1 个答案:

答案 0 :(得分:0)

https://docs.docker.com/network/bridge/中所述,您需要将两个服务放入用户定义的桥接网络中,以便它们通过容器名称相互引用。以下是如何在 public class TeamActivity extends AppCompatActivity { private RequestQueue queue; private String teamName; private static Team team = new Team(); @RequiresApi(api = Build.VERSION_CODES.O) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.team_activity_layout); Intent intent = getIntent(); teamName = intent.getStringExtra("teamName"); queue = Volley.newRequestQueue(this); parseJSON(); Log.i("Team", this.team.getTeamName()); } @RequiresApi(api = Build.VERSION_CODES.O) private void parseJSON(){ String url = "http://192.168.0.174:8080/team/" + teamName; JsonObjectRequest jsonObjectRequest = new JsonObjectRequest (Request.Method.GET, url, null, response -> { try { this.team.setId(Long.parseLong(response.getString("id"))); this.team.setTeamName(response.getString("teamName")); this.team.setTotalMatches(Long.parseLong(response.getString("totalMatches"))); this.team.setTotalWins(Long.parseLong(response.getString("totalWins"))); } } catch (JSONException e) { e.printStackTrace(); } }, error -> Log.i("ERROR","Couldn't parse JSON")); queue.add(jsonObjectRequest); }} 中执行此操作:

  1. 定义自定义桥接网络:
docker-compose.yml
  1. 将这两个服务放入该网络:
networks:
  some-name:
    driver: bridge
  1. 强制使用特定的容器名称,尤其是被另一个引用的容器名称,否则 docker-compose 会将前缀和后缀添加到服务名称作为容器名称,如 services: db: image: postgres environment: POSTGRES_PASSWORD: 'password' POSTGRES_DB: 'postgres' POSTGRES_USER: 'postgres' volumes: - ./postgres-db:/var/lib/postgresql/data ports: - '5432:5432' networks: - some-name app: build: context: . dockerfile: app/Dockerfile restart: always environment: APP_FRONTEND_PORT: '8080' DB_PORT: '5433' DB_HOST: 'db' ports: - '8080:8080' depends_on: - 'db' networks: - some-name
sample_app_db_1