[英]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.现在我已经尝试将主机设置为database
、 localhost
、 0.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.下面列出了这些文件的内容。
./src
directory run $ npm install
(creates package-lock.json)从./src
目录运行$ npm install
(创建 package-lock.json)$ chmod 600 .pgpass
使用$ chmod 600 .pgpass
修复 pgpass 权限$ chmod +x wait-for-postgres.sh
使脚本可执行$ chmod +x wait-for-postgres.sh
$ 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 启动时,您会看到它已准备就绪。
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
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文件
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
#!/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.