Tengo un contenedor Nginx configurado que sirve activos para un sitio web estático. La idea es que el servidor web permanezca siempre activo y sobrescriba los activos cada vez que se vuelvan a compilar. Actualmente, la configuración de la ventana acoplable se ve así:
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 (constructor de activos) Dockerfile:
FROM node:latest WORKDIR /app COPY package*.json ./ RUN npm ci COPY ./ . RUN npm run generateNginx Dockerfile:
FROM nginx:latest RUN mkdir /app COPY nginx.conf /etc/nginx/nginx.confEl contenedor de certbot se administra por separado y no es relevante para el problema que tengo, pero el contenedor de Nginx debe poder montar el volumen de https-certs.
Esta configuración parecía buena, hasta que me di cuenta de que el volumen de activos del sitio no se actualizaría después de la primera creación. El volumen tendría que ser destruido y recreado en cada implementación de la aplicación para que esto funcione, lo que requiere que el contenedor de Nginx se detenga para desmontar el volumen. Tanto para ese enfoque.
¿Hay alguna manera de administrar los datos de la aplicación en esta configuración sin desactivar el contenedor Nginx? Preferiblemente, me gustaría hacer esto de forma declarativa con un archivo docker-compose, evitar múltiples instancias de aplicaciones ya que esto no necesita escalar y evitar usar docker inspect para encontrar el volumen en el sistema de archivos y modificarlo directamente.
Espero que haya una respuesta sensata a esto que no sea "Es un sitio estático, ¿por qué no estás usando Netlify o GitHub Pages?" :)
Aquí hay un ejemplo que movería su npm run generate desde el tiempo de creación de la imagen al tiempo de ejecución del contenedor. Es un ejemplo mínimo para ilustrar cómo mover el proceso al tiempo de ejecución hace que el volumen esté disponible tanto para el contenedor en ejecución en el inicio como para los futuros en tiempo de ejecución.
Con el siguiente 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: Podemos lanzarlo con docker-compose up en una terminal. Nuestro servidor nginx inicialmente perderá los datos, pero el servicio web inicial se iniciará y generará nuestro activo (con contenido 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 En otra terminal podemos actualizar nuestro activo (su npm run generate ):
❯ docker-compose run web bash -c "echo updated > /app/dist/file" Y ahora podemos ver nuestro servicio nginx sirviendo el contenido actualizado:
❯ 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 ... doneEspero que esto haya sido útil para ilustrar una forma de aprovechar el montaje de volumen en el tiempo de ejecución del contenedor.