syntax error: unterminated quoted string Docker Certbot

huangapple go评论54阅读模式
英文:

syntax error: unterminated quoted string Docker Certbot

问题

I'm using docker compose. I'm working with a nextjs project. The focus here is setting up the containers specifically to automate server configuration, including SSL certification using Certbot. My objectives are to first get the initial certificate then run a cron job to check if it needs to be renewed. This is a learning exercise for me and would appreciate any insight into my knowledge gap, thank you. I have this docker-compose.yml and the error seems to originate from the Certbot entrypoint. There is no other Certbot configuration beyond this script. Could something else in the container be causing the error? I wasn't able to get the container up and running because it would crash with the error. I don't see any unterminated quoted string.

Here is my 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

Unfortunately, I reached the rate limit with Let's Encrypt, but it will expire tomorrow so I can try again. In the meantime, I'm trying to figure out what I did wrong and if there's a better way to do it. So far I came up with this alternative to instead replace entrypoint with command and use a shell script to check if HTTPS is available and if it fails, then run a renewal:

  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

And this would be the script:

#!/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

Any suggestions? Thoughts? What am I doing wrong? Please leave some input, thank you.

英文:

I'm using docker compose. I'm working with a nextjs project. The focus here is setting up the containers specifically to automate server configuration, including SSL certification using Certbot. My objectives are to first get the initial certificate then run a cron job to check if it needs to be renewed. This is a learning exercise for me and would appreciate any insight into my knowledge gap, thank you. I have this docker-compose.yml and the error seems to originate from the Certbot entrypoint. There is no other Certbot configuration beyond this script. Could something else in the container be causing the error? I wasn't able to get the container up and running because it would crash with the error. I don't see any unterminated quoted string.

Here is my 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

Unfortunately I reached the rate limit with letsencrypt, but it will expire tomorrow so I can try again. In the mean time I'm trying to figure out what I did wrong and if there's a better way to do it. So far I came up with this alternative to instead replace entrypoint with command and use a shell script to check if https is available and if it fails then run a renewal:

  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

and this would be the script:

#!/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

Any suggestions? Thoughts? What am I doing wrong? Please leave some input, thank you.

答案1

得分: 0

你在 certbot 入口处确实存在一些引用问题;你嵌套了单引号,导致 `--post-hook` 的参数位于包含你的 `sh -c '...'` 调用的单引号之外。将命令行粘贴到 https://www.shellcheck.net/ 可以帮助识别这些问题。

你可以通过利用入口命令的列表形式和 YAML 的块引用运算符,避免一层引用,并尽量减少引号转义的必要性。如果你像这样重写入口点:

entrypoint:

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

事情会变得更加清晰,只需要一个层次的引用。
英文:

There are certainly some quoting problems in your certbot entrypoint; you have nested single quotes that result in the arguments to --post-hook being outside of the single quotes that enclose your sh -c '...' invocation. Pasting the command line into https://www.shellcheck.net/ would help identify those issues.

You can avoid a level of quoting -- and minimize the necessity of escaping quotes -- by taking advantage of (a) the list form the of the entrypoint command and (b) YAML's block quote operators. If you rewrite the entrypoint like this:

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

Things are a bit more clear and only require a single level of quoting.

huangapple
  • 本文由 发表于 2023年5月10日 23:44:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76220379.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定