首先输入代码,解释之后的内容会更容易。
docker-compose.yml
version: '3.4'
services:
db:
user: '${UID}:${GID}'
image: postgres
container_name: postgres
ports:
- '5432:5432'
restart: always
environment:
POSTGRES_HOST: db
POSTGRES_USER: root
POSTGRES_PASSWORD: secret
POSTGRES_DATABASE: foo
PGDATA: /var/lib/postgresql/data/db
volumes:
- ./db/data:/var/lib/postgresql/data/db
- db-init.sh:/docker-entrypoint-initdb.d/:ro
cache:
image: redis:alpine
container_name: redis
sysctls:
net.core.somaxconn: '511'
ports:
- '6379:6379'
command: ['--requirepass "secret"']
api:
image: node:alpine
container_name: api
working_dir: /var/www/app
command: sh -c "npm start"
ports:
- '5000:5000'
volumes:
- node_modules:/var/www/app/node_modules
- .:/var/www/app
env_file: .env
depends_on:
- db
- cache
volumes:
node_modules:
node.js
应用的postgres 连接设置:
export const {
POSTGRES_USER = 'root',
POSTGRES_PASSWORD = 'secret',
POSTGRES_HOST = 'db',
POSTGRES_PORT = 5432,
POSTGRES_DATABASE = 'foo',
} = process.env
问题:
在db
应用的postgres
设置中使用服务或容器名称(POSTGRES_HOST
或node
)时:
我不能从主机运行会影响容器的命令。例如,播种db将不起作用:
npx knex --esm seed:run
这很有意义,因为docker负责db
/ postgres
的DNS解析,而这些解析仅在连接容器的网络上有意义。从主机运行命令,针对该容器的命令将失败,因为主机不知道如何在此处解析DNS。
另一方面,在localhost
应用的POSTGRES_HOST
设置中使用node
时:
postgres
对api
的查询将失败。npx knex --esm seed:run
)将成功。同样,这很合理。由于localhost
中的端口转发,因此可以从主机将容器命名为docker-compose.yml
。但是在容器的上下文中,它指的是那个容器:因为api
localhost
表示自身,并且试图在localhost:5432
或api:5432
上查找数据库。 / p>
我希望容器间网络正常工作,并且还希望从主机运行命令,以解决上述容器问题。我知道有两种方法可以实现这一目标:
使用容器/服务名称为POSTGRES_HOST
,并使用以下命令对容器运行命令:
docker exec -it <container_name> <command>
为容器分配静态ip
,并使用它们代替服务/容器名称。
我在这里还有其他选择吗?
答案 0 :(得分:0)
由于要在主机上公开数据库端口,因此可以执行以下操作。
$ export POSTGRES_HOST=127.0.0.1
$ npx knex --esm seed:run
或一步一步
$ POSTGRES_HOST=127.0.0.1 npx knex --esm seed:run