如何在Docker中正确启动PostgreSQL实例?

问题描述 投票:0回答:1

我是 PostgreSQL 新手,但我想在 Docker 中运行 PostgreSQL 实例以及与其通信的程序。 我的 dockerfile 看起来像这样:

FROM archlinux:latest
RUN pacman --sync -yu --noconfirm --needed base-devel curl postgresql postgresql-libs jansson

WORKDIR /srv

COPY main3.c /srv/

RUN gcc main3.c -lpq -ljansson -std=c99 -I/usr/include/postgresql
RUN su postgres -c 'initdb --locale=C.UTF-8 --encoding=UTF8 -D /var/lib/postgres/data --data-checksums'
RUN mkdir /run/postgresql
RUN chown postgres: /run/postgresql
RUN su postgres -c 'postgres -D /var/lib/postgres/data' &

EXPOSE 5432
EXPOSE 8000
EXPOSE 45510

CMD ["./a.out"]

然后我用

docker build -t myexample .
构建它并用
docker run -p 127.0.0.1:8000:8000 -e DATABASE_HOST=127.0.0.1 -e DATABASE_PORT=5432 -e DATABASE_NAME=mydb -e DATABASE_USER=ene -e DATABASE_PASSWORD=as_shrimple_as_that myexample
运行它。这些变量必须从外部传递,因为它们对于运行 docker 映像的其他人来说是不同的。

但是,我的输出出现错误:

connection to database failed: connection to server at "127.0.0.1", port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?

这是我的一段代码,用于检查数据库连接。

...
char* db_host = getenv("DATABASE_HOST");
char* db_port = getenv("DATABASE_PORT");
char* db_name = getenv("DATABASE_NAME");
char* db_user = getenv("DATABASE_USER");
char* db_password = getenv("DATABASE_PASSWORD");

char conninfo[256];
sprintf(conninfo, "host=%s port=%s dbname=%s user=%s password=%s", db_host, db_port, db_name, db_user, db_password);
PGconn *conn = PQconnectdb(conninfo);

if (PQstatus(conn) != CONNECTION_OK) {
    fprintf(stderr, "connection to database failed: %s\n", PQerrorMessage(conn));
    PQfinish(conn);
return 1;
}
...

我是否未正确启动 PostgreSQL 服务器,或者 Docker 的某些原因导致它在我的程序启动之前就消失了?

到目前为止我不需要修改数据库 - 我只是希望它能够连接。然后我的程序将提供数据库中的版本数据。

postgresql docker dockerfile
1个回答
0
投票

在 Docker 中运行 postgres 的正确方法是使用官方上游镜像在单独的容器中运行它,而不是尝试在与应用程序相同的容器中运行它。

通常,您可以使用

docker compose
文件来管理此操作,尽管这并不是绝对必要的(
docker compose
实际上只是
docker run
的包装器,因此您可以使用多个
docker run
命令完成相同的操作 - - 只是不太方便)。

可能看起来像下面这样。您可以将此内容放置在与您的

compose.yaml
相邻的名为
Dockerfile
的文件中:

volumes:
  pg_data:

services:
  postgres:
    image: docker.io/postgres:15
    volumes:
      - "pg_data:/var/lib/postgresql"
    environment:
      POSTGRES_USER: ene
      POSTGRES_PASSWORD: as_shrimple_as_that

  app:
    build:
      context: .
    environment:
      DATABASE_HOST: postgres
      DATABASE_PORT: 5432
      DATABASE_NAME: my_db
      DATABASE_USER: ene
      DATABASE_PASSWORD: as_shrimple_as_that

您可能会使用

.env
文件来管理环境变量,而不是像我在此处所示的那样将它们包含在撰写文件中。


查看您的 Dockerfile,请注意,这并不符合您的想法:

RUN su postgres -c 'postgres -D /var/lib/postgres/data' &

RUN
命令仅在映像构建过程中运行。由 RUN 启动的进程在隔离环境中运行,并在
RUN
命令完成时终止。从映像启动容器时,这些命令
不会
执行。

© www.soinside.com 2019 - 2024. All rights reserved.