问题描述
我有以下docker-compose文件。我想与react
和Nginx
服务共享web
服务中的静态文件
version: '3.6'
services:
web:
image: shahrukh/learnup:web
networks:
- main
command: >
sh -c "python manage.py collectstatic --no-input
&& gunicorn learnup.wsgi:application --bind 0.0.0.0:8000 --reload"
volumes:
- static_cdn:/var/www/learnup/static_cdn
depends_on:
- react
react:
image: shahrukh/learnup:react
volumes:
- static_cdn:/app/Learnup-Frontend/learnup/export-build/static
Nginx:
image: shahrukh/learnup:Nginx
restart: always
ports:
- 80:80
command: Nginx -g 'daemon off;'
volumes:
- static_cdn:/var/www/static
networks:
- main
depends_on:
- web
- react
networks:
main:
volumes:
static_cdn:
为此,我创建了一个命名卷static_cdn
,将在其上执行以下步骤
这是我面临的问题。
使用最新的构建版本更新react
容器映像时,卷static_cdn
没有最新的静态文件,因为在使用{{1}之后不会重新创建该卷}
所以我的问题是在这种情况下,在服务之间共享文件的最佳方法是什么?,以便它负责更新。
请注意,我知道首先使用docker-compose up -d
来停止和删除卷然后执行docker-compose down -v
的解决方案。但这会导致停机,而这是我不想在生产中进行的。
也执行docker-compose up -d
来提取docker-compose pull react
的最新图像,然后再进行react
无效,因为该卷不会更新。到目前为止,Docker compose还没有提供任何选项来强制在启动时重新创建卷。卷正在使用时,我也不能使用docker-compose -d
。
另外,请注意,我可以在启动时创建react build文件,而不是将其作为解决问题的映像的一部分。但是我无法做到这一点,因为我正在资源有限的系统上运行应用程序,docker volume rm ...
崩溃了。
解决方法
您似乎想使用docker-compose进行生产。
docker-compose不适用于生产。例如,它不会尝试重新启动失败的容器。它还会在重新创建容器之前销毁容器,从而导致停机。请考虑使用docker-swarm(更简便)或kubernetes(行业实际标准)。
这些工具知道如何执行更新,管理持久卷,处理硬件故障等。
处理生产中的静态文件
如果实际上您的静态内容是代码,基本上是一个开发更改,则可能需要在发生错误的情况下还原并使用git之类的版本,然后使用该容器创建一个版本并对其进行版本化。
发布新版本并通知产品集群时,它将使用健全的更新策略自动更新所有生产节点。如果发现新版本存在问题,则可以回滚。
如果它确实是动态的,则可能需要另一个驱动程序来驱动您的卷,例如映射到网络文件系统。
无论如何,docker-swarm&kubernetes的工作方式一目了然,它将阐明对产品环境有什么好处。
在本地工作
在本地,完全可以接受使用-v选项来删除容器,并有几秒钟的停机时间。
,通常,如果要构建React应用程序,则需要将其编译为静态文件以进行部署。您将使用Webpack之类的工具来生成一组内置的HTML,Javascript和CSS文件,然后可以使用Nginx直接为其提供服务。如果您使用的是诸如Create React App之类的入门工具包,通常可以运行
npm run build
,它将使用生成的文件创建一个dist
目录。
由于您已经有了Nginx容器,因此这第一件事就是您不需要单独的React容器;您可以只从Nginx容器中提供已编译的文件。另外,后端容器可能不需要直接访问已构建的前端代码,而只需要从Nginx代理获得服务即可。
这意味着您可以在单个多阶段构建中使用构建的React应用程序构建Nginx代理映像。那个Dockerfile或多或少看起来像:
FROM node:lts AS react
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
RUN npm run build
FROM nginx
COPY --from=react /app/dist /usr/share/nginx/html
COPY default.conf.template /etc/nginx/templates/
# Base image includes a useful CMD
在Compose设置中,您不需要专用的React容器,如前所述;您不需要卷,因为您已经将应用程序构建到静态文件中了;您不需要重新声明图像中已经声明的command:
之类的内容;并且您可以使用Compose为您提供的default
网络。这将为您提供一个大大简化的docker-compose.yml
文件:
version: '3.6'
services:
web:
build: ./backend
image: shahrukh/learnup-web:latest
nginx:
build: ./frontend
image: shahrukh/learnup-nginx:latest
restart: always
ports:
- 80:80
depends_on:
- web