Docker 使用nginx模板功能和重新加载解决方案

Docker 使用nginx模板功能和重新加载解决方案,docker,nginx,lets-encrypt,certbot,Docker,Nginx,Lets Encrypt,Certbot,我有一个docker项目,同时使用nginx和certbot进行加密。 我是docker的新手,对于我的nginx映像,我正在使用帮助我在nginx配置中使用环境变量的功能 在一个著名的教程中,他们使用此命令启动nginx并自动重新加载它 command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'&

我有一个docker项目,同时使用nginx和certbot进行加密。 我是docker的新手,对于我的nginx映像,我正在使用帮助我在nginx配置中使用环境变量的功能

在一个著名的教程中,他们使用此命令启动nginx并自动重新加载它

command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
问题是,当我使用这个命令而不是基本命令时,我的模板不再转换为工作的nginx conf

我希望能够重新加载nginx,但我也希望nginx能够在有效的nginx配置中转换我的模板

请问我怎样才能做到这一点

这是我的docker-compose.yml

version: '3'

services:
  db:
    image: mysql
    environment:
      - MYSQL_DATABASE=${DATABASE_NAME}
      - MYSQL_USER=${DATABASE_USER}
      - MYSQL_PASSWORD=${DATABASE_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DATABASE_ROOT_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - ./db/data:/var/lib/mysql

  adminer:
    image: adminer
    restart: always
    environment:
      - ADMINER_DESIGN=lucas-sandery
    ports:
      - 8080:8080

  php-fpm:
    build:
      context: ./php-fpm
    depends_on:
      - db
    environment:
      - APP_ENV=${APP_ENV}
      - APP_SECRET=${APP_SECRET}
      - DATABASE_URL=mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@db:3306/${DATABASE_NAME}?serverVersion=5.7
    volumes:
      - ../app:/var/www

  node:
    image: node:alpine
    volumes:
      - ../app:/var/www
    working_dir: /var/www
    command: "/bin/sh -c 'yarn install ; yarn run watch'"

  nginx:
    image: nginx:alpine
    volumes:
      - ../app:/var/www
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/templates:/etc/nginx/templates
      - ./logs:/var/log
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    depends_on:
      - php-fpm
    ports:
      - "80:80"
      - "443:443"
    environment:
      - APP_DOMAIN=${APP_DOMAIN}

  certbot:
    image: certbot/certbot
    volumes:
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
和my site.template.conf文件

upstream php-upstream {
    server php-fpm:9000;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name ${APP_DOMAIN};

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server ipv6only=on;

    ssl_certificate /etc/letsencrypt/live/${APP_DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${APP_DOMAIN}/privkey.pem;

    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    server_name ${APP_DOMAIN};
    root /var/www/public;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

谢谢

您可以在
docker compose.yml
nginx
部分添加一个
restart:always
来处理错误导致的服务退出,并且如果您想手动触发它,您可以在shell中的
yml
文件文件夹中发出一个
docker compose restart nginx

我不知道您是否有意遗漏了敏感信息,如
${APP_DOMAIN}
,但如果您想插入这些值,可以使用docker secrets。您可以在此处阅读有关docker机密的更多信息:

(提示:你不需要使用swarm来获取秘密,在这个链接的末尾有一个docker compose示例。只要你用它启动服务,你就不需要swarm)

编辑 因此,问题是您不能在nginx conf文件上替换环境变量。你看过这个吗

我在这里找到了这些信息:


如果您想每隔6小时重新加载nginx,为什么不使用
crontab
?您可以保持一切原样,并在crontab中执行以下操作:

* */6 * * * cd /home/to/docker-compose.yml/ && docker-compose exec nginx -s reload > /var/log/reloading_nginx.log

(我认为
docker compose exec
是正确的命令,而不是
docker compose run
)。

您可以在
docker compose.yml
nginx
部分添加
重新启动:始终
,以处理因错误而退出的服务,此外,如果您想手动触发它,您可以在shell中的
yml
文件文件夹中发出
docker compose restart nginx

我不知道您是否有意遗漏了敏感信息,如
${APP_DOMAIN}
,但如果您想插入这些值,可以使用docker secrets。您可以在此处阅读有关docker机密的更多信息:

(提示:你不需要使用swarm来获取秘密,在这个链接的末尾有一个docker compose示例。只要你用它启动服务,你就不需要swarm)

编辑 因此,问题是您不能在nginx conf文件上替换环境变量。你看过这个吗

我在这里找到了这些信息:


如果您想每隔6小时重新加载nginx,为什么不使用
crontab
?您可以保持一切原样,并在crontab中执行以下操作:

* */6 * * * cd /home/to/docker-compose.yml/ && docker-compose exec nginx -s reload > /var/log/reloading_nginx.log

(我认为
docker compose exec
是正确的命令,而不是
docker compose run
)。

感谢您的帮助。正如我所发布的,如果我保持nginx start命令不变,那么替换是有效的。当我在docker-compose.yml中添加带有特定脚本的命令(例如:每6小时重新加载一次nginx)时,我的模板不再从模板生成nginx conf。如果我阅读文档:“但是这个图像有一个函数,它将在nginx启动之前提取环境变量。”当我在docker compose中添加自定义命令时,这一步不再完成,我希望能够指定一个自定义命令来启动nginx,并仍然替换我的env。存储在.env中的变量来自此链接:当我添加自定义命令时,似乎没有播放此脚本:20-envsubt-on-templates.sh谢谢,我将尝试使用crontab(但我听说这不是一个很好的过程实践),我将遵循以下示例:),但我想了解为什么我的入口点在某些时候不起作用。谢谢你的帮助!你好这是因为只有当entrypont是dockerfile entrypoint.sh时才会调用20-ish脚本。我的意思是,20-envsubt-on-templates.sh在docker-entrypoint.sh内部调用,当您将entrypoint更改为脚本时,它不会触发它。好吗?谢谢你的帮助。正如我所发布的,如果我保持nginx start命令不变,那么替换是有效的。当我在docker-compose.yml中添加带有特定脚本的命令(例如:每6小时重新加载一次nginx)时,我的模板不再从模板生成nginx conf。如果我阅读文档:“但是这个图像有一个函数,它将在nginx启动之前提取环境变量。”当我在docker compose中添加自定义命令时,这一步不再完成,我希望能够指定一个自定义命令来启动nginx,并仍然替换我的env。存储在.env中的变量来自此链接:当我添加自定义命令时,似乎没有播放此脚本:20-envsubt-on-templates.sh谢谢,我将尝试使用crontab(但我听说这不是一个很好的过程实践),我将遵循以下示例:),但我想了解为什么我的入口点在某些时候不起作用。谢谢你的帮助!你好这是因为只有当entrypont是dockerfile entrypoint.sh时才会调用20-ish脚本。我的意思是,20-envsubt-on-templates.sh在docker-entrypoint.sh内部调用,当您将entrypoint更改为脚本时,它不会触发它。好吧