Dockerized Nginx:是否可以在不停止容器的情况下更新静态资产?
Dockerized Nginx: Can static assets be updated without stopping the container?
我设置了一个 Nginx 容器,它为静态网站提供资产。这个想法是让网络服务器始终保持运行状态,并在重新编译时覆盖资产。当前 docker 设置如下所示:
docker-compose.yml:
version: '3'
services:
web:
build: ./app
volumes:
- site-assets:/app/dist:ro
nginx:
build: ./nginx
ports:
- 80:80
- 443:443
volumes:
- site-assets:/app:ro
- https-certs:/etc/nginx/certs:ro
depends_on:
- web
volumes:
site-assets:
https-certs:
Web(资产构建器)Dockerfile:
FROM node:latest
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY ./ .
RUN npm run generate
Nginx Dockerfile:
FROM nginx:latest
RUN mkdir /app
COPY nginx.conf /etc/nginx/nginx.conf
certbot 容器是单独管理的,与我遇到的问题无关,但 Nginx 容器确实需要能够挂载 https-certs 卷。
这个设置看起来 不错,直到我意识到站点资产卷在第一次创建后不会更新。卷需要在每次应用程序部署时销毁并重新创建才能工作,需要停止 Nginx 容器以卸载卷。这种方法到此为止。
有没有办法在不关闭 Nginx 容器的情况下管理此设置中的应用程序数据?最好是,我想用 docker-compose 文件以声明方式执行此操作,避免 multiple application instances 因为这不需要扩展,并避免使用 docker inspect
在文件系统上查找卷直接修改。
我希望除了 "It's a static site, why aren't you using Netlify or GitHub Pages?" 之外还有一个理智的答案 :)
这是一个示例,可以将您的 npm run generate
从映像构建时间转移到容器 运行 时间。这是一个最小的示例,用于说明将进程移动到 运行 时间如何使卷在启动时可供 运行ning 容器使用,并在 运行 时间供将来的容器使用。
与以下docker-compose.yml
:
version: '3'
services:
web:
image: ubuntu
volumes:
- site-assets:/app/dist
command: bash -c "echo initial > /app/dist/file"
restart: "no"
nginx:
image: ubuntu
volumes:
- site-assets:/app:ro
command: bash -c "while true; do cat /app/file; sleep 5; done"
volumes:
site-assets:
我们可以在终端中使用 docker-compose up
启动它。我们的 nginx
服务器最初会丢失数据,但初始 web
服务将启动并生成我们的资产(内容为 initial
):
❯ docker-compose up
Creating network "multivol_default" with the default driver
Creating volume "multivol_site-assets" with default driver
Creating multivol_web_1 ... done
Creating multivol_nginx_1 ... done
Attaching to multivol_nginx_1, multivol_web_1
nginx_1 | cat: /app/file: No such file or directory
multivol_web_1 exited with code 0
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
在另一个终端中,我们可以更新我们的资产(您的 npm run generate
命令):
❯ docker-compose run web bash -c "echo updated > /app/dist/file"
现在我们可以看到我们的 nginx
服务提供更新的内容:
❯ docker-compose up
Creating network "multivol_default" with the default driver
Creating volume "multivol_site-assets" with default driver
Creating multivol_web_1 ... done
Creating multivol_nginx_1 ... done
Attaching to multivol_nginx_1, multivol_web_1
nginx_1 | cat: /app/file: No such file or directory
multivol_web_1 exited with code 0
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
nginx_1 | updated
nginx_1 | updated
nginx_1 | updated
nginx_1 | updated
^CGracefully stopping... (press Ctrl+C again to force)
Stopping multivol_nginx_1 ... done
希望这有助于说明在容器 运行 时利用卷安装的方法。
我设置了一个 Nginx 容器,它为静态网站提供资产。这个想法是让网络服务器始终保持运行状态,并在重新编译时覆盖资产。当前 docker 设置如下所示:
docker-compose.yml:
version: '3'
services:
web:
build: ./app
volumes:
- site-assets:/app/dist:ro
nginx:
build: ./nginx
ports:
- 80:80
- 443:443
volumes:
- site-assets:/app:ro
- https-certs:/etc/nginx/certs:ro
depends_on:
- web
volumes:
site-assets:
https-certs:
Web(资产构建器)Dockerfile:
FROM node:latest
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY ./ .
RUN npm run generate
Nginx Dockerfile:
FROM nginx:latest
RUN mkdir /app
COPY nginx.conf /etc/nginx/nginx.conf
certbot 容器是单独管理的,与我遇到的问题无关,但 Nginx 容器确实需要能够挂载 https-certs 卷。
这个设置看起来 不错,直到我意识到站点资产卷在第一次创建后不会更新。卷需要在每次应用程序部署时销毁并重新创建才能工作,需要停止 Nginx 容器以卸载卷。这种方法到此为止。
有没有办法在不关闭 Nginx 容器的情况下管理此设置中的应用程序数据?最好是,我想用 docker-compose 文件以声明方式执行此操作,避免 multiple application instances 因为这不需要扩展,并避免使用 docker inspect
在文件系统上查找卷直接修改。
我希望除了 "It's a static site, why aren't you using Netlify or GitHub Pages?" 之外还有一个理智的答案 :)
这是一个示例,可以将您的 npm run generate
从映像构建时间转移到容器 运行 时间。这是一个最小的示例,用于说明将进程移动到 运行 时间如何使卷在启动时可供 运行ning 容器使用,并在 运行 时间供将来的容器使用。
与以下docker-compose.yml
:
version: '3'
services:
web:
image: ubuntu
volumes:
- site-assets:/app/dist
command: bash -c "echo initial > /app/dist/file"
restart: "no"
nginx:
image: ubuntu
volumes:
- site-assets:/app:ro
command: bash -c "while true; do cat /app/file; sleep 5; done"
volumes:
site-assets:
我们可以在终端中使用 docker-compose up
启动它。我们的 nginx
服务器最初会丢失数据,但初始 web
服务将启动并生成我们的资产(内容为 initial
):
❯ docker-compose up
Creating network "multivol_default" with the default driver
Creating volume "multivol_site-assets" with default driver
Creating multivol_web_1 ... done
Creating multivol_nginx_1 ... done
Attaching to multivol_nginx_1, multivol_web_1
nginx_1 | cat: /app/file: No such file or directory
multivol_web_1 exited with code 0
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
在另一个终端中,我们可以更新我们的资产(您的 npm run generate
命令):
❯ docker-compose run web bash -c "echo updated > /app/dist/file"
现在我们可以看到我们的 nginx
服务提供更新的内容:
❯ docker-compose up
Creating network "multivol_default" with the default driver
Creating volume "multivol_site-assets" with default driver
Creating multivol_web_1 ... done
Creating multivol_nginx_1 ... done
Attaching to multivol_nginx_1, multivol_web_1
nginx_1 | cat: /app/file: No such file or directory
multivol_web_1 exited with code 0
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
nginx_1 | initial
nginx_1 | updated
nginx_1 | updated
nginx_1 | updated
nginx_1 | updated
^CGracefully stopping... (press Ctrl+C again to force)
Stopping multivol_nginx_1 ... done
希望这有助于说明在容器 运行 时利用卷安装的方法。