如何使用 docker 映像生成静态文件以从 nginx 映像提供服务?

Posted

技术标签:

【中文标题】如何使用 docker 映像生成静态文件以从 nginx 映像提供服务?【英文标题】:How to use a docker image to generate static files to serve from nginx image? 【发布时间】:2021-02-12 05:15:05 【问题描述】:

我要么遗漏了一些非常明显的东西,要么我完全错误地处理了这个问题,无论哪种方式我都可以使用一些新的见解。

我有以下使用 docker-compose 链接在一起的 docker 图像(简化):

前端(一个 Vue.js 应用) 后端(Django 应用) nginx postgres

在开发中,我不使用 nginx,而是 Vue.js 应用程序作为观察者运行,使用 yarn serve,而 Django 使用 manage.py runserver

我想为生产做些什么(在 CI/CD 中):

构建并推送后端映像 构建并推送 nginx 镜像 使用yarn build 命令构建前端镜像 在nginx容器中获取生成的文件(通过一个volume?) 部署新映像

问题是:如果我将yarn build 作为CMD 放在Dockerfile 中,则编译会在容器启动 时发生,我希望它在构建步骤中完成CI/CD。 但是如果我把RUN yarn build 放在图像中,我把CMD 放在什么位置?以及如何获取生成的静态文件到nginx?

我能找到的解决方案使用多阶段构建的前端,最后一步是 nginx 映像,将两者结合起来。但我需要 nginx 映像独立于前端映像,所以这对我不起作用。

我觉得这是一个已经被很多人解决的问题,但我找不到一个例子。非常感谢您的建议!

【问题讨论】:

【参考方案1】:

在您的 docker-compose.yml 文件中创建一个卷,并将相同的卷挂载到您的前端容器(到构建文件所在的路径,例如 dist 文件夹)和 nginx 容器(到您的 Web 根路径) .这样两个容器都可以访问相同的卷。

另外,请将您的 yarn build 保留为 RUN 命令。

编辑:

容器需要运行程序或命令才能被归类为容器,因此它们可以启动、停止等。这是设计使然。

如果您不打算使用命令从前端容器提供服务,那么您应该从 docker-compose.yml 将其作为服务(因为它不是)删除并将其作为构建阶段添加到您的 nginx dockerfile 中,或者你可以使用某种在你的前端容器中无限期运行的命令,例如tail -f index.html。第一个解决方案是更好的做法。

在您的 nginx dockerfile 添加前端构建 dockerfile 作为第一个构建阶段:

From: node as frontend-build
WORKDIR /app
RUN yarn build

From:nginx
COPY --from=frontend-build /app/dist /usr/shared/nginx/html
...
CMD ["nginx"]

【讨论】:

然后我会将什么作为CMD?我可以使用多层构建基本上拥有一个 only 包含已编译资产的图像(在您所说的 dist 文件夹中)并将共享卷安装到该目录和 nginx,但我会从什么开始容器与?另外,我相信一个空卷是用容器目录中的数据初始化的,但我将如何部署新版本的资产? 我在想,也许我可以使用 cp 命令启动容器,该命令将 dist 文件夹复制到共享卷,覆盖任何以前的版本,并且容器将在复制命令后停止。 如果你没有从前端容器中提供任何东西,它不属于服务部分的设计。您应该只使用实际运行的服务。因此,请将其用作多阶段构建。我会更新我的答案 公平点,我想运行一个不做任何事情的容器是愚蠢的。但正如我在问题中提到的那样,我不想将 nginx 与我的前端服务联系起来,因为它也连接到后端服务,我不想将两者纠缠在一起。也许我可以找到一种方法来保持前端映像的干净和独立以进行开发和测试,并将构建的映像拉入我的 nginx Dockerfile 以复制资产,因为 nginx 无论如何都将前端和后端捆绑在一起。感谢您的见解! 你可以保持前端服务不变,只需将构建阶段添加到 nginx 的 Dockerfile 中。另外,如果你没有在开发中使用 nginx,你可以将它从 docker-compose.yml 移动到,比如说,docker-compose.production.yml,然后使用 docker-compose 的文件链接来启动生产环境,如下所示: compose -f docker-compose.yml -f docker-compose.production.yml up

以上是关于如何使用 docker 映像生成静态文件以从 nginx 映像提供服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 PostgreSQL 卷附加到使用 SBT 本机打包程序生成的 Docker 映像?

如何加载从原始 Docker 映像的 .tar 文件创建的 Docker 映像?

如何使用未提交的本地证书文件通过 GitHub 操作构建 Docker 映像

如何使用Docker save将本地映像备份到文件?

如何将文件夹从我的主机挂载到自定义 docker 映像,在目录中使用 Dockerfile 进行设置? [复制]

如何在“docker build”期间更新 Docker 映像中的 /etc/hosts 文件