简体   繁体   English

从另一个容器(Docker)连接到 postgresql 容器

[英]Connect to postgresql container from another container (Docker)

I have am trying to follow this tutorial and set up a postgresql container.我正在尝试按照本教程设置一个 postgresql 容器。

I have the following script:我有以下脚本:

#!/bin/bash
# wait-for-postgres.sh

set -e

host="$1"
shift
cmd="$@"

until psql -h "$host" -U "postgres" -c '\l'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec $cmd

And the following docker-compose.yml :以及以下docker-compose.yml

version: '2'
services:
  server:
    build: .
    ports:
      - 3030:3030
    depends_on:
      - database
    command: ["./setup/wait-for-postgres.sh", "localhost:5432", "--", "node", "src"]
  database:
    image: postgres
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=postgres"
      - "POSTGRES_DB=tide_server"
    ports:
      - 5432:5432

The problem is that when I run docker-compose up I get the following error:问题是,当我运行docker-compose up ,出现以下错误:

server_1    | Postgres is unavailable - sleeping
server_1    | psql: could not translate host name "192.168.64.2:5432" to address: Name or servi
ce not known
server_1    | Postgres is unavailable - sleeping
server_1    | psql: could not translate host name "192.168.64.2:5432" to address: Name or servi
ce not known
server_1    | Postgres is unavailable - sleeping
server_1    | psql: could not translate host name "192.168.64.2:5432" to address: Name or servi
ce not known

Now I have tried setting the host as database , localhost , 0.0.0.0 , and even the containers IP but nothing works, I have no idea what it should be or how to debug it, I am not 100% sure how docker-compose links the containers.现在我已经尝试将主机设置为databaselocalhost0.0.0.0 ,甚至是容器 IP 但没有任何作用,我不知道它应该是什么或如何调试它,我不是 100% 确定docker-compose链接容器。

do not use depends_on.不要使用depends_on。 try it with "links"用“链接”试试

    version: '2'
    services:
      server:
        build: .
        ports:
          - 3030:3030
        links:
          - database
        #environment could be usefull too
        environment:
            DATABASE_HOST: database
        command: ["./setup/wait-for-postgres.sh", "localhost:5432", "--", "node", "src"]
      database:
        image: postgres
        environment:
          - "POSTGRES_USER=postgres"
          - "POSTGRES_PASSWORD=postgres"
          - "POSTGRES_DB=tide_server"
        ports:
          - 5432:5432

for more informations https://docs.docker.com/compose/compose-file/#links有关更多信息https://docs.docker.com/compose/compose-file/#links

The problem here is the host itself.这里的问题是主机本身。

psql -h "$host" -U "" -c '\\l' psql -h "$host" -U "" -c '\\l'

You are passing a wrong HOSTNAME "localhost:5432" / "192.168.64.2:5432"您正在传递错误的 HOSTNAME "localhost:5432" / "192.168.64.2:5432"

What I did is setup a ~/.pgpass that has localhost:5432:DB:USER:PASSWORD我所做的是设置一个 ~/.pgpass 有 localhost:5432:DB:USER:PASSWORD

and instead of passing "localhost:5432", omit the port.而不是传递“localhost:5432”,省略端口。 Just use "localhost"只需使用“本地主机”

This works for me ...这对我有用...

May be an old thread to answer but I have been using depends_on with the following docker-compose file可能是一个要回答的旧线程,但我一直在使用带有以下 docker-compose 文件的depends_on

version: '3.4'

volumes:
  postgres_data:
      driver: local

services:
  postgres:
      image: postgres
      volumes:
        - ./postgres_data:/var/lib/postgresql:rw
        - ./deployments:/opt/jboss/wildfly/standalone/deployments:rw
      environment:
        POSTGRES_DB: keycloak
        POSTGRES_USER: keycloak
        POSTGRES_PASSWORD: password
      ports:
        - 5432:5432
   keycloak:
      image: jboss/keycloak
      environment:
        POSTGRES_ADDR: postgres
        POSTGRES_DATABASE: keycloak
        POSTGRES_USER: keycloak
        POSTGRES_PASSWORD: password
        KEYCLOAK_USER: admin
        KEYCLOAK_PASSWORD: Pa55w0rd
      ports:
        - 8080:8080
        - 9990:9990
      depends_on:
        - postgres

The tutorial skips over a few things, and is confusing in that it mentions the wait-for-it.sh script, but then shows a much simplified version that doesn't work if you pass hostname:port as one argument to it.本教程跳过了一些内容,令人困惑的是它提到了wait-for-it.sh脚本,但随后显示了一个非常简化的版本,如果您将hostname:port作为一个参数传递给它,则该版本将不起作用。

I had a crack at getting this to work and both for future me and others I will add the steps below.我有办法让它发挥作用,对于未来的我和其他人,我将添加以下步骤。 I did this on MacOS, and have both docker and docker-compose installed as well as nodejs.我在 MacOS 上做了这个,并且安装了 docker 和 docker-compose 以及 nodejs。

I don't have your node app handy so I used the one as described here https://nodejs.org/de/docs/guides/nodejs-docker-webapp/我手头没有你的节点应用程序,所以我使用了这里描述的那个https://nodejs.org/de/docs/guides/nodejs-docker-webapp/

I have the following directory structure:我有以下目录结构:

/src/package.json
/src/server.js
/.pgpass
/docker-compose.yml
/Dockerfile
/wait-for-postgres.sh

The contents of these files is listed below.下面列出了这些文件的内容。

Steps脚步

  1. From the ./src directory run $ npm install (creates package-lock.json)./src目录运行$ npm install (创建 package-lock.json)
  2. Fix pgpass permissions with $ chmod 600 .pgpass使用$ chmod 600 .pgpass修复 pgpass 权限
  3. Make the script executable $ chmod +x wait-for-postgres.sh使脚本可执行$ chmod +x wait-for-postgres.sh
  4. From the root directory $ docker-compose up从根目录$ docker-compose up

It will pull the postgres image and build the node app container.它将拉取 postgres 映像并构建节点应用程序容器。 When that's done it will wait for postgres and when postgres is up you'll see it ready.完成后,它将等待 postgres,当 postgres 启动时,您会看到它已准备就绪。

Files文件

The src files are exactly as per the node js dockerize link above src 文件与上面的节点 js dockerize 链接完全相同

/src/package.json /src/package.json

{
    "name": "docker_web_app",
    "version": "1.0.0",
    "description": "Node.js on Docker",
    "author": "First Last <first.last@example.com>",
    "main": "server.js",
    "scripts": {
      "start": "node server.js"
    },
    "dependencies": {
      "express": "^4.16.1"
    }
  }

/src/server.js /src/server.js

'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello world\n');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

.pgpass .pgpass

This uses the username:password postgres:postgres and is purely for development demo purposes.这使用用户名:密码postgres:postgres并且纯粹用于开发演示目的。 In the wild you will use some other method of secrets management and never ever commit a pgpass file to version control在野外,您将使用其他一些秘密管理方法,并且永远不会将 pgpass 文件提交给版本控制

#host:port:db:user:pass
db:5432:*:postgres:postgres

docker-compose.yml docker-compose.yml

  • I have added the wait-for-postgres.sh script as a managed volume, in the original question it was bundling it in with the app src which was weird.我已将wait-for-postgres.sh脚本添加为托管卷,在原始问题中,它将它与 app src 捆绑在一起,这很奇怪。
  • I have also mounted the .pgpass file in the root user's home directory, which psql will look in for auto-password completion.我还在 root 用户的主目录中安装了.pgpass文件,psql 将在该目录中查找自动密码完成。 If you don't have some method of supplying this then you'll get an error:如果您没有某种方法来提供它,那么您将收到一个错误:

    psql: fe_sendauth: no password supplied psql:fe_sendauth:未提供密码

  • Notice the command for the server container is referring to database which is a valid docker-compose internal dns name for the postgres container.请注意, server容器的命令指的是database ,它是 postgres 容器的有效 docker-compose 内部 dns 名称。

version: '2'
services:

  server:
    build: .
    ports:
      - 3030:3030
    depends_on:
      - database
    volumes:
      - ./wait-for-postgres.sh:/usr/app/setup/wait-for-postgres.sh
      - ./.pgpass:/Users/root/.pgpass
    command: ["/usr/app/setup/wait-for-postgres.sh", "database", "--", "node", "src"]

  database:
    image: postgres
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=postgres"
      - "POSTGRES_DB=tide_server"
    ports:
      - 5432:5432

Dockerfile文件

  • I have modified this from the node js tutorial, pinning it to the Debian "buster" version and also installing psql which it needs for that script.我已经从 node js 教程中修改了它,将其固定到 Debian“buster”版本,并安装了该脚本所需的psql
FROM node:10-buster

RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8

RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" > /etc/apt/sources.list.d/pgdg.list && \
    wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -


RUN apt-get -y update - && \
    apt-get -y install libpq-dev && \
    apt-get -y install postgresql-client-11

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

wait-for-postgres.sh等待 postgres.sh

  • I have modified the script very slightly because I ran the "shellcheck" linter and it complained about a few things.我对脚本进行了很小的修改,因为我运行了“shellcheck” linter 并且它抱怨了一些事情。 I realise this script is from the docker tutorial page.我意识到这个脚本来自 docker 教程页面。
#!/bin/bash
# wait-for-postgres.sh

set -e

host="$1"
shift
cmd="$*"

export PGPASSFILE=./pgpass

until psql -h "$host" -U "postgres" -c '\l'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec "$cmd"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 Postgresql Docker 容器与另一个 Docker 容器连接 - How to connect Postgresql Docker Container with another Docker Container 从 DBeaver 连接到 Docker 容器中的 PostgreSQL 数据库 - Connect to PostgreSQL Database in Docker Container from DBeaver Docker容器,运行PostgreSQL不允许来自另一个容器的php pg_connect - Docker container, running PostgreSQL not allowing php's pg_connect from another container 从另一个 docker 容器中的 pgAdmin4 访问 docker 容器上的 PostgreSQL - Accessing PostgreSQL on docker container from pgAdmin4 in another docker container 从Docker容器连接到另一个Docker容器的端口 - Connect from a Docker container to port of another docker container Docker:springboot容器无法连接到PostgreSql容器 - Docker: Springboot container cannot connect to PostgreSql Container 连接到Docker容器上的PostgreSQL数据库 - Connect to a PostgreSQL database on a Docker container NodeJS:无法从另一个容器连接到postgreSQL容器 - NodeJS: Can't connect to postgreSQL container from another container 从 docker 开始的容器组合无法连接到另一个容器 - container started from docker compose is unable to connect to another container 如何从本地 R 连接到在 Docker 容器中运行的 PostgreSQL? - How to connect to PostgreSQL running in Docker container from local R?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM