docker 启动 nginx 并自动更新 SSL 证书

  1. docker运行nginx

    docker run -d --name=nginx -v /etc/nginx:/etc/nginx/conf.d:ro --network=host --restart=always nginx nginx -g 'daemon off;'
  2. 安装acme.sh申请证书

    curl  https://get.acme.sh | sh
    acme.sh --set-default-ca  --server  letsencrypt
  3. 创建/etc/init.d/nginx配合acme.sh实现自动重载nginx配置

    #!/bin/sh
    
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    NAME=nginx
    DOCKER_BIN=/usr/bin/docker
    NGINX_BIN="$DOCKER_BIN exec -i $NAME nginx"
    
    # 检查容器状态
    check_container_status() {
     # 使用 docker inspect 的格式化输出直接获取状态
     local status=$($DOCKER_BIN inspect --format='{{.State.Status}}' $NAME 2>/dev/null)
     echo $status
    }
    
    # 启动容器
    start_container() {
     echo -n "Starting $NAME... "
     $DOCKER_BIN start $NAME
     if [ "$?" != 0 ]; then
         echo " failed"
         exit 1
     else
         echo " done"
     fi
    }
    
    # 创建并启动容器
    create_and_start_container() {
     echo -n "Creating and starting $NAME... "
     $DOCKER_BIN run -d --name=$NAME -v /etc/nginx:/etc/nginx/conf.d:ro --network=host --restart=always nginx nginx -g 'daemon off;'
     if [ "$?" != 0 ]; then
         echo " failed"
         exit 1
     else
         echo " done"
     fi
    }
    
    # 停止容器
    stop_container() {
     echo -n "Stopping $NAME... "
     $DOCKER_BIN stop $NAME
     if [ "$?" != 0 ]; then
         echo " failed"
         exit 1
     else
         echo " done"
     fi
    }
    
    # 终止容器
    kill_container() {
     echo -n "Terminating $NAME... "
     $DOCKER_BIN kill $NAME
     if [ "$?" != 0 ]; then
         echo " failed"
         exit 1
     else
         echo " done"
     fi
    }
    
    # 执行命令
    case "$1" in
     start)
         # 检查容器是否存在
         if ! $DOCKER_BIN ps -a | grep -q $NAME; then
             # 如果容器不存在,创建并启动容器
             create_and_start_container
         else
             # 如果容器已存在,检查其状态
             container_status=$(check_container_status)
             case $container_status in
                 running)
                     echo "$NAME is already running."
                     ;;
                 exited|created)
                     start_container
                     ;;
                 *)
                     echo "$NAME is in an unknown state ($container_status)."
                     ;;
             esac
         fi
         ;;
    
     stop)
         # 检查容器是否在运行
         container_status=$(check_container_status)
         if [ "$container_status" = "running" ]; then
             stop_container
         elif [ "$container_status" = "exited" ] || [ "$container_status" = "created" ]; then
             echo "$NAME is not running."
         else
             echo "$NAME is in an unknown state ($container_status)."
         fi
         ;;
    
     force-quit)
         # 检查容器是否在运行
         container_status=$(check_container_status)
         if [ "$container_status" = "running" ]; then
             kill_container
         else
             echo "$NAME is not running."
         fi
         ;;
    
     restart)
         stop_container
         sleep 1
         create_and_start_container
         ;;
    
     reload)
         echo -n "Reload service $NAME... "
         # 检查容器状态
         container_status=$(check_container_status)
         if [ "$container_status" = "running" ]; then
             $NGINX_BIN -s reload
             if [ "$?" != 0 ]; then
                 echo " failed"
                 exit 1
             else
                 echo " done"
             fi
         else
             echo "$NAME is not running, can't reload."
         fi
         ;;
    
     configtest)
         echo -n "Test $NAME configure files... "
         # 检查容器状态
         container_status=$(check_container_status)
         if [ "$container_status" = "running" ]; then
             $NGINX_BIN -t
             if [ "$?" != 0 ]; then
                 echo " failed"
                 exit 1
             else
                 echo " configuration is valid."
             fi
         else
             echo "$NAME is not running, can't test configuration."
         fi
         ;;
    
     status)
         # 检查容器状态
         container_status=$(check_container_status)
         case $container_status in
             running)
                 echo "$NAME is running..."
                 ;;
             exited)
                 echo "$NAME is stopped"
                 ;;
             *)
                 echo "$NAME not running"
                 ;;
         esac
         ;;
    
     *)
         echo "Usage: $0 {start|stop|force-quit|restart|reload|status|configtest}"
         exit 1
         ;;
    esac

参考文档

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 4

我比较好奇的一点是为什么不用 docker 自带的 restart policy 来管理容器的生命周期呢?

7个月前 评论
GeorgeKing (作者) 7个月前
mrpzx001 (楼主) 7个月前
mrpzx001 (楼主) 7个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!