Dockerfile 和 Docker Compose for NestJS 应用程序与 PSQL DB,其中运行时需要环境变量

hot*_*oup 5 postgresql node.js docker docker-compose nestjs

我正在 Docker 化一个简单的 Node/JS(NestJS——但我认为这对于这个问题来说并不重要)Web​​ 服务,并且有一些问题。该服务与 Postgres DB 进行通信。我想编写一个Dockerfile可用于构建服务映像(让我们称之为my-service),然后编写一个docker-compose.yml定义 Postgres DB 服务以及my-service使用它的服务的服务。这样我就可以构建镜像,my-service而且还可以有一个 Docker Compose 配置来同时运行服务及其数据库。我认为这就是做到这一点的方法(但请保持诚实!)。Kubernetes 对我来说不是一个选择,仅供参考。

Web 服务具有如下所示的顶级目录结构:

my-service/
    .env
    package.json
    package-lock.json
    src/
    <lots of other stuff>
Run Code Online (Sandbox Code Playgroud)

值得注意的是,在目前的非容器化形式中,您必须提前设置几个环境变量,包括 Postgres DB 连接信息(主机、端口、数据库名称、用户名、密码等)。应用程序代码在运行时获取这些环境变量的值并使用它们连接到 Postgres。

所以,我需要一种方法来编写Dockerfile这样docker-compose.yml的:

  • 如果我只是单独运行图像的容器my-service,并且想要告诉它连接到任意 Postgres DB,我可以将这些环境变量作为(理想情况下)Docker CLI 命令上的运行时参数传递(但请记住应用程序)期望它们被设置为环境变量);和
  • 如果我通过 Docker Compose 文件将 及其 Postgres 一起旋转my-service,我还需要在 Docker Compose CLI 中将它们指定为运行时参数,然后 Docker Compose 需要将它们传递给容器的运行参数,然后容器需要将它们设置为环境变量以供 Web 服务使用

再说一遍,我认为这是正确的方法,但请保持诚实!

所以我最好的尝试——到目前为止的总WIP——看起来像这样:

Dockerfile

FROM node:18

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

# creates "dist" to run out of
RUN npm run build

# ideally the env vars are already set at this point via
## docker CLI arguments, so nothing to pass in here (???)
CMD [ "node", "dist/main.js" ]
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml

version: '3.7'

services:
  postgres:
    container_name: postgres
    image: postgres:14.3
    environment:
      POSTGRES_PASSWORD: ${psql.password}
      POSTGRES_USER: ${psql.user}
      POSTGRES_DB: my-service-db
      PG_DATA: /var/lib/postgresql2/data
    ports:
      - 5432:5432
    volumes:
      - pgdata:/var/lib/postgresql2/data
  my-service:
    container_name: my-service
    image: ???  anyway to say "build whats in the repo?"
    environment:
      ??? do I need to set anything here so it gets passed to the my-service
          container as env vars?
volumes:
  pgdata:
Run Code Online (Sandbox Code Playgroud)

谁能帮助我冲过终点线?提前致谢!

cri*_*007 1

??? 我是否需要在此处设置任何内容,以便将其作为环境变量传递到 my-service 容器?

是的,您应该将变量传递到那里。这是12因素设计的原则

还需要在 Docker Compose CLI 中将它们指定为运行时参数,然后 Docker Compose 需要将它们传递给容器的运行参数

如果您不将它们直接放入 YAML,此选项对您有用吗?

docker-compose --env-file app.env up
Run Code Online (Sandbox Code Playgroud)

理想情况下,您还可以放置

depends_on:
  postgres
Run Code Online (Sandbox Code Playgroud)

这样当您启动服务时,数据库也会启动。

如果您想连接到不同的数据库实例,那么您可以创建一个不带该数据库的单独的撰写文件,或者使用一组不同的变量(写出或使用env_file,如上所述)

或者,您可以使用 NPMdotenvconfig包,并.env根据NODE_ENV运行时的其他变量(例如 )为不同的数据库环境设置不同的文件。

??? 无论如何要说“在回购协议中构建什么?”

使用build而不是image指令。

Kubernetes 不是我的选择,仅供参考

可以使用 Minikube 而不是 Compose...这并不重要,但kompose可以将 Docker Compose 转换为 k8s 资源。