如何阻止Docker容器占用主机端口?Docker Compose启动Postgres失败排查
问题解答
为什么Postgres容器会占用主机端口?
你当前的docker-compose.yml里配置了ports: - "5432:5432",这个字段的作用是把容器内部的5432端口映射到主机的5432端口,所以Docker会尝试在主机上绑定5432端口,但你主机本身已经运行了Postgres占用这个端口,自然就启动失败了。
解决方法:取消主机端口映射
既然你的测试环境只需要容器间互相通信,不需要主机访问容器内的Postgres,直接删掉ports配置即可:
修改后的docker-compose.yml:
version: "3.6" services: db: container_name: db image: postgres:14-alpine environment: - POSTGRES_USER=test - POSTGRES_PASSWORD=test - POSTGRES_DB=test # 移除主机端口映射,容器间通过Docker内置网络通信 command: -c fsync=off -c synchronous_commit=off -c full_page_writes=off --max-connections=200 --shared-buffers=4GB --work-mem=20MB tmpfs: - /var/lib/postgresql web: container_name: web build: context: .. dockerfile: test_tools/Dockerfile shm_size: '2gb' volumes: - /dev/shm:/dev/shm depends_on: - db
容器间如何访问Postgres?
Docker Compose会自动为所有服务创建一个默认桥接网络,在这个网络里,服务名(这里是db)可以直接作为域名解析到容器的IP地址。所以你的web服务连接Postgres时,只需要用db:5432作为数据库地址即可,不需要使用主机IP或localhost。
额外注意点
depends_on仅保证db服务在web之前启动,但不保证Postgres已经完全就绪可以接受连接。如果web服务启动后立刻尝试连接数据库,可能会出现连接失败的情况。可以在web服务的启动脚本里加入等待逻辑,比如用pg_isready -h db -p 5432 -U test命令检测数据库就绪状态。
内容的提问来源于stack exchange,提问作者Cerin
相关产品推荐
相关产品推荐

