如何在不推送 .env 文件的情况下使用环境变量构建 docker-image
How to build docker-image with environment variables while not pushing .env-file
我是 Dev-Ops 的新手,发现自己有点困惑。
我有一个启动服务器的节点项目。该服务器的一个端点应该写入数据库。在我的本地机器上,我使用本地数据库测试此行为。
我创建了一个 .env.prod 文件和一个 .env.dev 文件来确定我是使用本地数据库还是我的服务器数据库(运行 在我的服务器上)。我还在博客文章中读到我永远不应该将我的 .env 文件推送到远程存储库。
然后我创建了一个 Dockerfile 来构建和发布我的应用程序。
在我的远程 Gitlab-Repository 上,我创建了一个 .gitlab-ci.yml,它应该在每次有新的 master 提交时从 Dockerfile 构建 docker-image。
但现在我面临的问题是,当我想构建 docker-image 时,我需要 .env.prod 文件,但我永远不应该推送此文件,因此 GitLab 无法访问它。
这种描述方式是合适的解决方案还是我做错了什么(我是否遗漏了 Dev-ops 中的一些核心概念)?
这是我的 Dockerfile
FROM node:12.7-alpine AS build
WORKDIR /usr/graphql-server
COPY package.json /usr/graphql-server/
RUN npm install
COPY ./ /usr/graphql-server
RUN npm run build
COPY ./ /usr/graphql-server
EXPOSE 4000
CMD ["npm", "run", "start:prod"]
和 npm run start:prod
这样做:
tsc && cross-env NODE_ENV=prod node dist/index.js
这就是我确定要使用哪种配置的方式 (index.ts):
function getConfig(): void {
let path;
if (process.env.NODE_ENV === 'prod') {
path = `${__dirname}/../src/.env.prod`;
} else {
path = `${__dirname}/../src/.env.dev`;
}
dotenv.config({ path });
}
最后,感谢@AndreasJägle,我想出了一个完全不同的解决方案来解决我最初想到的问题。
我不需要 .env-file 并且不再将描述的 getConfig() 方法用于此解决方案。同样也不需要在 Gitlab 中存储 environment-variables。
首先,我现在通过在节点命令末尾传递环境变量来启动我的节点进程,例如 node dist/index.js variable1
。
这个环境变量可以在运行时读取:const baseUrl = process.argv[2]
。
baseUrl-variable 可以用来向这个特定的 url 发送请求。
其次,因为我正在使用 docker 构建我的项目,所以我必须将 environment-variables 的值注入到我的 docker-image 中。为此,我像这样修改了我的 docker 文件。
FROM node:12.7-alpine AS build
ENV BASE_URL=localhost
...
CMD ["sh", "-c", "node dist/index.js $BASE_URL"]
(注意 localhost 是 BASE_URL 环境变量的默认值,将被覆盖)
最后,我在服务器上的 docker-compose 文件中使用了之前构建的映像,并像这样设置了环境变量。
version: "3"
services:
test-service:
image: my-image:latest
container_name: 'my-container'
environment:
- BASE_URL=mydomain.com
我是 Dev-Ops 的新手,发现自己有点困惑。 我有一个启动服务器的节点项目。该服务器的一个端点应该写入数据库。在我的本地机器上,我使用本地数据库测试此行为。 我创建了一个 .env.prod 文件和一个 .env.dev 文件来确定我是使用本地数据库还是我的服务器数据库(运行 在我的服务器上)。我还在博客文章中读到我永远不应该将我的 .env 文件推送到远程存储库。
然后我创建了一个 Dockerfile 来构建和发布我的应用程序。
在我的远程 Gitlab-Repository 上,我创建了一个 .gitlab-ci.yml,它应该在每次有新的 master 提交时从 Dockerfile 构建 docker-image。
但现在我面临的问题是,当我想构建 docker-image 时,我需要 .env.prod 文件,但我永远不应该推送此文件,因此 GitLab 无法访问它。
这种描述方式是合适的解决方案还是我做错了什么(我是否遗漏了 Dev-ops 中的一些核心概念)?
这是我的 Dockerfile
FROM node:12.7-alpine AS build
WORKDIR /usr/graphql-server
COPY package.json /usr/graphql-server/
RUN npm install
COPY ./ /usr/graphql-server
RUN npm run build
COPY ./ /usr/graphql-server
EXPOSE 4000
CMD ["npm", "run", "start:prod"]
和 npm run start:prod
这样做:
tsc && cross-env NODE_ENV=prod node dist/index.js
这就是我确定要使用哪种配置的方式 (index.ts):
function getConfig(): void {
let path;
if (process.env.NODE_ENV === 'prod') {
path = `${__dirname}/../src/.env.prod`;
} else {
path = `${__dirname}/../src/.env.dev`;
}
dotenv.config({ path });
}
最后,感谢@AndreasJägle,我想出了一个完全不同的解决方案来解决我最初想到的问题。 我不需要 .env-file 并且不再将描述的 getConfig() 方法用于此解决方案。同样也不需要在 Gitlab 中存储 environment-variables。
首先,我现在通过在节点命令末尾传递环境变量来启动我的节点进程,例如 node dist/index.js variable1
。
这个环境变量可以在运行时读取:const baseUrl = process.argv[2]
。
baseUrl-variable 可以用来向这个特定的 url 发送请求。
其次,因为我正在使用 docker 构建我的项目,所以我必须将 environment-variables 的值注入到我的 docker-image 中。为此,我像这样修改了我的 docker 文件。
FROM node:12.7-alpine AS build
ENV BASE_URL=localhost
...
CMD ["sh", "-c", "node dist/index.js $BASE_URL"]
(注意 localhost 是 BASE_URL 环境变量的默认值,将被覆盖)
最后,我在服务器上的 docker-compose 文件中使用了之前构建的映像,并像这样设置了环境变量。
version: "3"
services:
test-service:
image: my-image:latest
container_name: 'my-container'
environment:
- BASE_URL=mydomain.com