nginx 语法错误:未终止的引号字符串Docker Certbot

bnl4lu3b  于 2023-05-16  发布在  Nginx
关注(0)|答案(1)|浏览(219)

使用Docker Composite我正在做一个nextjs项目。这里的重点是专门设置容器来自动化服务器配置,包括使用Certbot进行SSL认证。我的目标是首先获得初始证书,然后运行一个cron作业来检查它是否需要更新。这对我来说是一个学习练习,并将感谢任何对我的知识差距的见解,谢谢。我有这个docker-compose.yml,错误似乎源于Certbot入口点。除此脚本外,没有其他Certbot配置。容器中的其他东西会导致错误吗?我无法让容器启动并运行,因为它会因错误而崩溃。我没有看到任何未终止的引号字符串。
下面是我的docker-compose.yml:

version: "3.9"
services:
  app:
    build:
      context: .
      args:
        NODE_ENV: production
    environment:
      NODE_ENV: production
    ports:
      - "3000:3000"
    volumes:
      - ./src:/app/src
      - ./public:/app/public
      - /app/node_modules
    container_name: nextjs

  nginx:
    build: ./nginx
    ports:
      - "80:80"
      - "443:443"
    environment:
      - DOMAIN_NAMES=${DOCKER_DOMAIN_NAMES}
      - CERTIFICATION_EMAIL=${DOCKER_CERTIFICATION_EMAIL}
    volumes:
      - ./ssl-dhparams.pem:/etc/letsencrypt/ssl-dhparams.pem
      - ./nginx/nginx.conf.template:/etc/nginx/nginx.conf.template:ro
      - ./nginx/options-ssl-nginx.conf:/etc/letsencrypt/options-ssl-nginx.conf:ro
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    depends_on:
      - app
  certbot:
    image: certbot/certbot
    entrypoint: "/bin/sh -c 'echo \"0 */12 * * * certbot renew --webroot -w /var/www/certbot --quiet --post-hook 'nginx -s reload'\" | crontab - && crond -f'"
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    depends_on:
      - nginx

不幸的是,我达到了letsencrypt的速率限制,但它将在明天到期,所以我可以再试一次。同时,我也在想我做错了什么,是否有更好的方法。到目前为止,我提出了这个替代方案,用命令替换入口点,并使用shell脚本检查https是否可用,如果失败,则运行续订:

certbot:
    image: certbot/certbot
    command: certonly --webroot --webroot-path=/var/www/certbot --email ${DOCKER_CERTIFICATION_EMAIL} --agree-tos --no-eff-email --staging --domains ${DOCKER_DOMAIN_NAMES} --non-interactive
    entrypoint: "/bin/sh -c 'chmod +x /scripts/cert_renewal.sh && /scripts/cert_renewal.sh && crond -f'"
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
      - ./nginx:/scripts
    depends_on:
      - nginx

这就是剧本

#!/bin/bash

DOMAIN_NAME="www.mydomainhere.com"
WEBROOT_PATH="/var/www/certbot"

# Check if the HTTPS site is available
if ! curl --head --silent --fail https://${DOMAIN_NAME}; then
    echo "HTTPS site is not available, running Certbot renewal"
    certbot renew --webroot -w ${WEBROOT_PATH} --quiet --post-hook 'nginx -s reload'
fi

# Add this script to crontab if it's not already there
if ! crontab -l | grep -q "${BASH_SOURCE[0]}"; then
    (crontab -l ; echo "0 */12 * * * ${BASH_SOURCE[0]}") | crontab -
    echo "Added Certbot renewal to crontab"
fi

有什么建议吗?想法?我哪里做错了?请留下一些信息,谢谢。

7y4bm7vi

7y4bm7vi1#

在你的certbot入口点中肯定有一些引用问题;您嵌套了单引号,导致--post-hook的参数位于包含sh -c '...'调用的单引号的外部。将命令行粘贴到https://www.shellcheck.net/中将有助于识别这些问题。
您可以通过利用(a)入口点命令的列表形式和(b)YAML的块引号操作符来避免一定程度的引号,并最大限度地减少转义引号的必要性。如果你像这样重写入口点:

entrypoint:
  - /bin/sh
  - -c
  - |
    echo "0 */12 * * * certbot renew --webroot -w /var/www/certbot --quiet --post-hook 'nginx -s reload'" |
      crontab - && crond -f

事情更清楚一点,只需要一个单一的报价水平。

相关问题