![](/img/trans.png)
[英]Docker compose is using the env which was built by Dockerfile, instead of using env_file located in docker-compose.yml directory because of webpack
[英]Dockerfile and Docker Compose for NestJS app with PSQL DB where env vars are expected at runtime
我正在 Dockerizing 一个简单的 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>
需要注意的是,在目前的非容器化形式中,您必须提前设置几个环境变量,包括 Postgres DB 连接信息(主机、端口、数据库名称、用户名、密码等)。 应用程序代码在运行时获取这些环境变量的值并使用它们连接到 Postgres。
所以,我需要一种方法来编写Dockerfile
和docker-compose.yml
,这样:
my-service
映像的容器,并想告诉它连接到任意 Postgres DB,我可以在 Docker CLI 命令上将这些环境变量作为(理想情况下)运行时 arguments 传递(但是请记住应用程序希望将它们设置为环境变量); 和my-service
and its Postgres together via the Docker Compose file, I need to also specify those as runtime args in the Docker Compose CLI, then Docker Compose needs to pass them on to the container's run arguments, and然后容器需要将它们设置为 web 服务使用的环境变量同样,我认为这是 go 的正确方法,但请保持诚实!
所以我最好的尝试——到目前为止的总在制品——看起来像这样:
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" ]
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:
谁能帮我推过终点线? 提前致谢!
??? 我是否需要在此处设置任何内容以便将其作为环境变量传递给 my-service 容器?
是的,您应该在那里传递变量。 这是12因素设计的原则
还需要在 Docker Compose CLI 中将它们指定为运行时参数,然后 Docker Compose 需要将它们传递给容器的运行 arguments
如果您不直接将它们放在 YAML 中,此选项是否适合您?
docker-compose --env-file app.env up
理想情况下,你也把
depends_on:
postgres
这样当您启动服务时,数据库也将启动。
如果要连接到不同的数据库实例,则可以在没有该数据库的情况下创建单独的 compose 文件,或使用不同的变量集(如前所述,写出或使用env_file
)
或者您可以使用 NPM dotenv
或config
包,并在运行时根据其他变量(例如NODE_ENV
)为不同的数据库环境设置不同的.env
文件。
??? 无论如何要说“在回购中构建什么?”
使用build
而不是image
指令。
Kubernetes 不适合我,仅供参考
您可以使用 Minikube 代替 Compose ... 没关系,但kompose
存在将 Docker Compose 转换为 k8s 资源。
您的Dockerfile
是正确的。 您可以在执行docker run
时指定环境变量,如下所示:
docker run --name my-service -it <image> -e PG_USER='user' -e PG_PASSWORD='pass'
-e PG_HOST='dbhost' -e PG_DATABASE='dbname' --expose <port>
或者您可以在.env
文件的帮助下指定环境变量。 我们称之为app.env
。 它的内容是:
PG_USER=user
PG_PASSWORD=pass
PG_DATABASE=dbname
PG_HOST=dbhost
OTHER_ENV_VAR1=someval
OTHER_ENV_VAR2=anotherval
现在,无需为docker run
命令指定多个-e
选项,您只需告知需要从何处获取环境变量的文件名。
docker run --name my-service -it <image> --env-file app.env --expose <port>
为了使用单个 docker compose 命令运行 postgres 和您的服务,需要在docker-compose.yml
中进行一些修改。 我们先来看看完整的YAML
。
version: '3.7'
services:
postgres:
container_name: postgres
image: postgres:14.3
environment:
POSTGRES_PASSWORD: $PG_PASSWORD
POSTGRES_USER: $PG_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
build: . #instead of image directive, use build to tell docker what folder to build
environment:
PG_USER: $PG_USER
PG_PASSWORD: $PG_PASSWORD
PG_HOST: postgres #note the name of the postgres service in compose yaml
PG_DATABASE: my-service-db
OTHER_ENV_VAR1: $OTHER_ENV_VAR1
OTHER_ENV_VAR2: $OTHER_ENV_VAR2
depends_on:
postgres
volumes:
pgdata:
现在您可以使用docker compose up
命令来运行服务。 如果您希望每次都构建my-service
容器,您可以像这样传递一个可选参数--build
: docker compose up --build
。
为了从 CLI 传递环境变量,只有一种方法是使用.env
文件。 在您的app.env
的情况下, docker-compose.yml
看起来像:
PG_USER=user
PG_PASSWORD=pass
#PG_DATABASE=dbname #not required as you're using 'my-service-db' as db name in compose file
#PG_HOST=dbhost #not required as service name of postgres in compose file is being used as db host
OTHER_ENV_VAR1=someval
OTHER_ENV_VAR2=anotherval
使用 docker compose CLI 命令传递此app.env
文件如下所示:
docker compose --env-file app.env up --build
PS:如果您每次构建my-service
只是为了代码更改以反映在 docker 容器中,您可以改用绑定挂载。 在这种情况下,更新后的docker-compose.yml
如下所示:
version: '3.7'
services:
postgres:
container_name: postgres
image: postgres:14.3
environment:
POSTGRES_PASSWORD: $PG_PASSWORD
POSTGRES_USER: $PG_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
build: .
volumes:
- .:/usr/src/app #note the use of volumes here
environment:
PG_USER: $PG_USER
PG_PASSWORD: $PG_PASSWORD
PG_HOST: postgres
PG_DATABASE: my-service-db
OTHER_ENV_VAR1: $OTHER_ENV_VAR1
OTHER_ENV_VAR2: $OTHER_ENV_VAR2
depends_on:
postgres
volumes:
pgdata:
这样,您不需要每次都运行 docker compose build,在源文件夹中进行代码更改将反映在 docker 容器中。
您只需在 docker-compose.yaml 文件和环境中的所有环境变量中添加 docker 文件的路径即可构建参数
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: path_to_your_dockerfile
environment:
your_environment_variables_here
container as env vars?
volumes:
pgdata
我猜你有这样的文件夹结构
project_folder/
docker-compose.yaml
my-service/
Dockerfile
.env
package.json
package-lock.json
src/
<lots of other stuff>
并且 your.env 包含以下内容
API_PORT=8082
Environment_var1=Environment_var1_value
Environment_var2=Environment_var2_value
因此,在您的情况下,您的 docker-compose 文件应如下所示
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: ./my-service/
environment:
- API_PORT=8082
- Environment_var1=Environment_var1_value
- Environment_var2=Environment_var2_value
volumes:
pgdata
仅供参考:对于这个 docker 配置,您的数据库连接主机应该是postgres (根据服务名称)而不是localhost和您的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.