【问题标题】:why postgres process doesn't run before execute RUN/CMD/ENTRYPOINT?为什么 postgres 进程在执行 RUN/CMD/ENTRYPOINT 之前不运行?
【发布时间】:2021-07-16 10:19:37
【问题描述】:

我的第一次尝试,我收到了这个 Dockerfile 的错误

FROM postgres:9.6-alpine
RUN psql

############# this is error message
 => ERROR [2/2] RUN psql                                                                                                                                                0.6s 
------
 > [2/2] RUN psql:
#6 0.349 psql: could not connect to server: No such file or directory
#6 0.349        Is the server running locally and accepting
#6 0.349        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

所以我虽然这个错误的原因是没有 postgres 进程。我测试了CMD psqlENTRYPOINT psql 然后当我在构建后运行这个图像时,所有容器都出现了同样的错误。为什么会出现这些问题?

【问题讨论】:

  • ENTRYPOINT 只能有一个,它要么是 postgres 服务器,要么是其他东西。你期望达到什么目标?
  • build 阶段运行 psql 似乎真的很糟糕。什么都不会运行然后你可以连接到。为什么不直接使用docker run -it --rm containername psql

标签: postgresql docker dockerfile


【解决方案1】:

如果你想直接使用 Docker 镜像使用 psql, 我有这个解决方案:

FROM alpine:latest
RUN apk --update add postgresql-client

ENTRYPOINT ["psql"]

之后:

docker build -t test .

alias psql='docker run --rm -it test:latest'

最后开始使用 psql :

psql --help

演示:

我希望这可以帮助您解决问题。

【讨论】:

    【解决方案2】:

    postgresql dockerfile:

    Dockerfile:

    ENTRYPOINT ["docker-entrypoint.sh"]
    CMD ["postgres"]
    

    docker-entrypoint.sh here:

    exec gosu postgres "$BASH_SOURCE" "$@"
    

    如果你在Dockerfile中定义了多个ENTRYPOINTCMD,只会使用最后一个。这意味着您的 CMD psql, ENTRYPOINT psql 将覆盖默认的 psql server 启动命令,这使您仍然没有 psql 服务器进程。

    【讨论】:

      【解决方案3】:

      一个 Docker 容器只运行一个进程。

      如果您将图像的CMD 设置为psql,则会运行而不是基本图像的普通CMD;你会得到一个 PostgreSQL 客户端而不是 PostgreSQL 服务器。

      设置ENTRYPOINT ["psql"] 对我来说真的没有意义,因为它的效果是导致实际的CMD 附加psql;像psql bash 这样的命令实际上没有意义。这也替换了基础映像中的大量启动时脚本。 (但是,请参阅 @rassakra's answer 了解使用它的特定模式。)

      如果您RUN psql,它实际上在构建阶段在其自己的容器中运行。 Docker 映像不会持久化正在运行的进程,因此这与 CMD 的情况相同:您有一个运行 psql 的容器,没有其他任何东西,因此没有可连接的数据库服务器。

      在构建过程中还有另外三个问题。如果您有一个在另一个容器中运行的数据库,则映像构建没有特别连接到任何网络,因此它无法连接到数据库。如果您计划运行附加了一些存储的数据库,那么在构建时还不可用。事实上,标准的 Docker Hub 数据库镜像已配置为无法创建包含嵌入数据的数据库镜像(因为服务器数据位于声明的 VOLUME 中,并且对 VOLUME 目录的更改不会持久化)。


      如果你只是想运行psql,你可以直接运行它,即使数据库在容器中。

      docker run -d -p 5678:5432 postgres
      psql -p 5678
      

      或者,如果安装标准客户端工具在某种程度上是不可接受的,您可以启动第二个 Docker 容器连接到第一个容器。两个容器都需要在同一个 Docker 网络上。 psql 客户端容器可以使用标准的postgres 映像,但指定在映像名称后运行的备用命令。

      docker network create some-network
      docker run -d --net some-network --name db postgres
      docker run --rm -it --net some-network --name client postgres \
        psql -h db
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-13
        • 1970-01-01
        相关资源
        最近更新 更多