docker - 使用 Docker 和 GitlabCI 部署和自定义 VueJs 应用程序
问题描述
我制作了一个 VueJS 应用程序,基本上是一个网站管理应用程序,它允许使用不同的 API 显示/编辑数据。这个应用程序可以使用 env 变量 (VUE_APP_XXX) 进行定制:API 的 url、标题、颜色主题等......大约 30 个变量,但我肯定会在未来添加其他变量。
现在我使用 Gitlab CI 部署我的应用程序,我有这个 Dockerfile(我删除了大部分 env 变量以进行澄清):
# build
FROM node:lts-alpine as build-stage
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package*.json ./
RUN npm install
COPY . .
ARG VUE_APP_API_URL
ARG VUE_APP_DATA_URL
ENV VUE_APP_API_URL $VUE_APP_API_URL
ENV VUE_APP_DATA_URL $VUE_APP_DATA_URL
RUN npm run build
# production
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
和 gitlab-ci.yml :
docker-build:
# Official docker image.
image: docker:latest
stage: build
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- |
docker build --pull
--build-arg VUE_APP_API_URL="$CI_TEST_API_URL"
--build-arg VUE_APP_DATA_URL="$CI_TEST_DATA_URL"
-t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
only:
- dev
when: manual
然后在我的服务器上我只是docker run...
启动我的应用程序。一切正常,除了:
- 我必须在 Dockerfile 和 gitlab-ci.yml 中手动指定所有变量
- 生成的 docker 映像可能包含“敏感”数据,例如登录名和密码
- 我必须为我的应用程序的每个实例创建一个图像
出于法律原因,我需要为每个应用程序创建一个存储库,每个网站创建一个存储库(因为每个存储库都可能有不同的所有者)。
所以我的问题是:对于许多网站,部署此应用程序的许多实例的最佳方法是什么?知道每个网站都需要自己的管理应用程序,可以托管在自己的服务器上。
我是码头工人的新手,我在想:
- 使用默认环境变量为通用应用程序创建 docker 映像(可能只使用代码,没有 npm run build 步骤?)
- 使用这个 docker 映像为每个实例创建一个容器,使用它自己的环境变量(是否可以使用 docker compose 构建应用程序?)
我对在何处/何时构建 VueJs 应用程序以及为此使用什么工具感到非常困惑。任何帮助表示赞赏,谢谢!
更新: 按照 taleodor 的建议,我发现这个中型帖子似乎可以完成这项工作。我发现它有点“棘手”,但它有效:)
解决方案
当你有一个 docker 镜像然后部署它时,每个工具都有一种方法来覆盖烘焙到镜像本身的环境变量。
因此,对于您的示例,您可以使用普通的 docker
docker run -e VUE_APP_API_URL=http://my.url ...
这实际上会覆盖先前在容器上设置的 VUE_APP_API_URL 变量。同样,任何编排平台(docker compose、swarm、kubernetes 等)都具有覆盖环境变量的能力,因为这是一种非常常见的场景。
我使用的常用方法 - 使用最通用的值在图像中预填充环境变量,然后在实际部署中覆盖它们 - 然后你不需要很多图像(同一事物的许多图像将是反模式)。
如果您有更多问题 - 随时加入我们的社区 discord,您可以在那里问我 - https://discord.gg/UTxjBf9juQ
更新(下面的评论):对于具有编译 UI 代码的静态图像,算法是运行一些入口点脚本,该脚本将对编译文件进行替换。示例可行的模式如下(您可能需要调整才能正确完成,但这给出了想法):
假设您使用 nginx 作为基础映像,请创建类似于以下内容的 entrypoint.sh 文件(请参阅此 SO 以获取一些参考:Can envsubst not do in-place replacement?):
#!/bin/sh
find /usr/share/nginx/html/*.js -type f -exec sh -c "cat {} | envsubst | tee {}.tmp && mv {}.tmp {}" \;
nginx -g 'daemon off;'
- 将此 entrypoint.sh 文件复制到您的 docker 映像中,并将其与 ENTRYPOINT 指令一起使用。
推荐阅读
- python - 在 Python 中使用 Pandas 使用其 URL 导入 CSV 文件
- c# - 如何将循环文本框传递给 ASP.NET MVC 中的控制器变量
- python - 'Builtin_function_or_method' 对象不可下标。使用 NumPy 时出错
- visual-studio-code - Visual Studio Code - 从 NPM 脚本资源管理器中排除子目录
- angular - Angular http 请求在 Chrome 中正确返回 Observable 数组,但在 Internet Explorer 中为空数组
- python - 为什么 sklearn OneHotEncoder 不能与单个数据框列一起使用?
- c# - Microsoft Graph:无法更新事件的开始或结束日期
- c# - 字符不在水平轴上移动
- c# - C# .NET 图像未显示在本地资源中
- javascript - 使用 java 脚本代码在新页面重定向到用户