Dockerized Nginx : Can static assets be updated without stopping the container?

标签 docker nginx docker-compose static-site

我设置了一个 Nginx 容器,用于为静态网站提供 Assets 。这个想法是让网络服务器始终保持运行状态,并在重新编译时覆盖 Assets 。目前 docker 设置如下所示:

docker-app

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( Assets 构建器)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 卷。

这个设置看起来不错,直到我意识到站点 Assets 卷在第一次创建后不会更新。卷需要在每次应用程序部署时销毁并重新创建才能工作,需要停止 Nginx 容器以卸载卷。这种方法到此为止。

有没有办法在不关闭 Nginx 容器的情况下管理此设置中的应用程序数据?最好,我想用 docker-compose 文件以声明方式执行此操作,避免 multiple application instances因为这不需要扩展,并且避免使用 docker inspect 在文件系统上查找卷并直接修改它。

我希望除了“这是一个静态站点,你为什么不使用 Netlify 或 GitHub Pages?”之外还有一个理智的答案? :)

最佳答案

这是一个示例,可以将您的 npm run generate 从镜像构建时间转移到容器运行时间。这是一个最小的示例,用于说明将进程移至运行时如何使卷在启动时可供正在运行的容器和运行时的 future 容器使用。

使用以下 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 服务将启动并生成我们的 Assets (内容为 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

在另一个终端中,我们可以更新我们的 Assets (您的 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

希望这有助于说明在容器运行时利用卷安装的方法。

关于Dockerized Nginx : Can static assets be updated without stopping the container?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61551237/

相关文章:

ubuntu - Docker 容器卷不写入主机

docker - 在docker run命令中传递动态路径

nginx - Centos7 Nginx mod_security - 未知指令 "ModSecurityEnabled"

php - Docker Image 安装 php 模块

docker - 更改 docker 自定义网络的默认子网

Python docker 容器使用 print()

Docker 占用太多空间

nginx - 具有公共(public) IP 地址的 HAProxy

python - Flask, Gunicorn, Nginx::IOError: [Errno 32] 断管

docker - 如何使用docker-compose将环境变量设置到docker容器中