gpt4 book ai didi

node.js - 自定义 docker 图像未运行 postgres

转载 作者:行者123 更新时间:2023-11-29 12:56:02 25 4
gpt4 key购买 nike

我正在尝试为 circleci v2 创建我自己的自定义 docker 文件。但是,我遇到了 postgres 服务器未运行的问题。我已经运行 service postgresql start 到 no available。

我收到的消息是:

psql: could not connect to server: Connection refused
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

docker 文件:

FROM ubuntu:16.04

ENV NODEJS_VERSION 6
ENV POSTGRESQL_VERSION 9.6

RUN apt-get update && apt-get -y install curl
RUN curl -sL https://deb.nodesource.com/setup_$NODEJS_VERSION.x | bash -
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/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
RUN apt-get update

RUN apt-get install -y \
nodejs \
make \
git \
g++ \
python-software-properties \
software-properties-common \
postgresql-$POSTGRESQL_VERSION \
postgresql-client-$POSTGRESQL_VERSION \
postgresql-contrib-$POSTGRESQL_VERSION

RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/$POSTGRESQL_VERSION/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/$POSTGRESQL_VERSION/main/postgresql.conf

USER postgres
RUN service postgresql start && \
psql -c "create database pgdb;" && \
psql -c "create role pgrole with login password 'pgrole'; grant all privileges on database pgdb to pgrole;"

另见:

谢谢

最佳答案

问题

问题是您没有定义您的镜像应该运行哪个命令,因此它默认为在 Ubuntu 基础镜像中设置的命令:/bin/bash

查看 CMD 的文档:

Note: Don’t confuse RUN with CMD. RUN actually runs a command and commits the result; CMD does not execute anything at build time, but specifies the intended command for the image.

因此,您的RUN service postgresql start构建时 执行,并且该命令的结果作为一个层提交到图像。当您启动图像时,例如在 CircleCI 上,图像的 CMD 被执行。由于您没有设置它,它使用 Ubuntu 指定的那个:/bin/bash。这意味着在运行时,事实上 Postgres 正在运行。

要记住的另一件事是 CMD 不能是守护进程。只要进程在前台执行,Docker 就会保持容器运行,因此如果您执行 CMD service postgresql start,Docker 将在命令返回后退出容器。

解决方案

我建议您重做整个 CI 设置。如果您在 CMD 中启动 Postgres,则无法覆盖该命令来运行您的测试(否则 Postgres 将不会再次运行)。

相反,使用两张图片,一张用于您的应用,一张用于 Postgres。您启动 Postgres,等待它接受连接,然后在您的 app 容器中运行测试。

您可以重用现有的 postgresql 镜像,它会在您启动时为您创建一个数据库和用户。您需要添加一个脚本来等待数据库准备就绪,否则您的测试将在数据库接受连接之前运行。看到这个帖子:https://discuss.circleci.com/t/waiting-for-database/10946

使用这种方法,一次运行多个服务要容易得多,并且仍然可以完全自由地决定要在 Circle CI 上运行哪些命令。

替代方案

创建一个启动 Postgres 并等待它准备就绪的入口点的选项更容易一些,但只是为了测试。创建一个脚本,将其复制到 Dockerfile 并将 ENTRYPOINT 指向它。在脚本中,运行 services postgresql start,创建数据库,然后等待 Postgres 接受连接。完成后,使用 exec $@ 执行您传递给容器的任何命令。

您可以在这里找到我们用来等待 Postgres 的脚本:https://gist.github.com/jdno/09377bde65095773e5daf1aaa8e62ef4

此脚本也可以轻松扩展为 ENTRYPOINT

  • 使用 services postgresql start 启动 Postgres。
  • 等待 Postgres 接受连接(即脚本现在执行的操作)。
  • 运行 psql 命令来创建您的数据库。
  • exec $@ 结束脚本以执行 Docker CMD

这更容易设置,但不适合生产。

关于node.js - 自定义 docker 图像未运行 postgres,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43176340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com