我有一个 Python/PostgreSQL 项目,我正在尝试将其放入 Docker 容器中。 当我尝试在容器内运行 psql 命令以在构建映像时创建用户和数据库时,出现此错误:
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
这是一个 Dockerfile:
FROM python:2.7-slim
WORKDIR /app
ADD . /app
RUN apt-get update && apt-get install -y postgresql postgresql-contrib libgeos-c1
RUN service postgresql start
RUN su postgres bash -c "psql -c \"CREATE USER myuser WITH PASSWORD 'password';\"" \
&& su postgres bash -c "psql -c \"CREATE DATABASE db WITH OWNER = myuser;\""```
请注意,我什至尝试在 psql 命令之前启动 postgresql 服务。
我尝试了另一种方法,即使用基础映像
postgres:9.6.3
并在其上安装Python pip。我仍然遇到同样的错误。这是第二个 Dockerfile 供参考:
FROM postgres:9.6.3
WORKDIR /app
ADD . /app
RUN apt-get update && apt-get install -y python-pip libgeos-c1
RUN service postgresql start
RUN su postgres bash -c "psql -c \"CREATE USER myuser WITH PASSWORD 'password';\"" \
&& su postgres bash -c "psql -c \"CREATE DATABASE db WITH OWNER = myuser;\""
坦白:我是一个 docker 菜鸟。
这个相关Dockerfile 中的多重 RUN 与单链 RUN,哪个更好?
我作为一个 docker noob 也遇到过这个问题。 每次运行可能不在相同的“上下文”中。 查看此输出,请注意启动命令和 psql 命令的容器是不同的。 似乎它在构建图像时正在构建容器的快照。
Step 25/30 : RUN service postgresql start
---> Running in 5c22e985359c
Starting PostgreSQL 9.6 database server: main.
Removing intermediate container 5c22e985359c
---> db1f2c2cdb33
Step 26/30 : USER postgres
---> Running in 6d56501e7286
Removing intermediate container 6d56501e7286
---> b35d3912eacf
Step 27/30 : RUN psql -c "CREATE USER user with password 'password'"
---> Running in 8c9130d2daa5
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain
我使用以下命令将这些命令链接在一起
RUN service postgresql start &&\
sudo -u postgres psql -c "CREATE USER user with password 'password'"
导致成功的 CREATE USER 命令,并且应该能够在需要时继续进一步的 &&\
Step 23/23 : RUN service postgresql start && sudo -u postgres psql -c "CREATE USER user with password 'password'"
---> Running in f234f6074f56
Starting PostgreSQL 9.6 database server: main.
CREATE ROLE
最好使用
docker-entrypoint-initdb.d
中的脚本。
在Dockerfile
COPY ./init-user-db.sh /docker-entrypoint-initdb.d/init-user-db.sh
脚本本身:
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL
更多详细信息请参见:https://docs.docker.com/samples/library/postgres/#how-to-extend-this-image
我认为我在这里试图实现的目标(在同一个容器中运行 Python 和 Postgres)并不是最好的方法。应该使用 docker-compose 来代替。这是一个示例
docker-compose.yml
(它可能不起作用,但展示了技术):
volumes:
local_postgres_data: {}
services:
django:
build:
context: .
dockerfile: ./compose/local/django/Dockerfile
image: django
container_name: django
depends_on:
- postgres
volumes:
- .:/app:z
ports:
- "8000:8000"
command: /start
postgres:
image: kartoza/postgis:13.0
container_name: postgres
volumes:
- ./data:/var/lib/postgresql/data