docker番外篇-最详细的安装及部署项目教程(net framework,netcore,java,nodejs,静态html,mysql,redis,私有仓库,https免费证书等)

目录

本地widows(win11)docker环境安装

安装Docker Desktop

Windows只需要安装Docker Desktop就可以完成docker和docker-compose的环境;系统要求至少win10版本号19041 以上

  1. 检查是否启动了虚拟平台;控制面板》程序》程序和功能》启动或关闭Windows功能
  • win10

  • win11

  1. 安装之前先检查系统是否已经有wsl2
  • 打开cmd命令窗口执行wsl --version,出现类似下图表示已经有
  • 如果没有 wsl2就得先安装,打开PowerShell(管理员)运行wsl --install
  • 如果有 存在了需要升级到最新版本wsl --update
  • 执行命令设置wsl版本wsl --set-default-version 2
  1. 下载Docker Desktop根据自己系统选择下载版本一般情况下应该是AMD64
  2. 修改配置

服务器liunx(ubuntu)docker环境安装

安装nginx

  1. 执行安装apt-install nginx 安装过程遇到提示直接选y
  2. 验证是否安装成功nginx -v

安装docker环境

  1. 执行安装apt-install docker.io
  2. 验证安装是否成功docker -v
  3. 配置镜像源和私有仓库编辑文件vim /etc/docker/daemon.json内容改为如下
bash 复制代码
{
  "registry-mirrors": [
     "https://l0xxxx85.mirror.aliyuncs.com",
     "https://mirrors.cloud.tencent.com",
     "https://registry.docker-cn.com",
     "https://docker.mirrors.ustc.edu.cn",
     "https://hub-mirror.c.163.com",
     "https://mirror.baidubce.com",
     "https://ccr.ccs.tencentyun.com"
     ],
  "insecure-registries": ["http://47.1xx.xx.xxx:6633"]
}
  1. 加载配置sudo systemctl daemon-reload然后重启dockersudo systemctl restart docker

安装docker compose

  1. 执行下载安装命令sudo curl -L "https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  2. 赋予执行权限sudo chmod +x /usr/local/bin/docker-compose
  3. 验证是否安装成功docker-compose --version
  4. 找个目录创建通用执行脚本,此脚本为了根据配置自动拉取镜像更新后续会常用,如在/home下创建一个文件夹dockersh,然后创建脚本文件名为update_docker_compose3.0.sh内容如下:
bash 复制代码
#!/bin/bash

# 检查是否提供了参数
if [ -z "$1" ] || [ -z "$2" ]; then
  echo "Usage: $0 <docker-compose-file> <image-version>"
  exit 1
fi

# 使用传入的参数作为 docker-compose 文件和镜像版本号
COMPOSE_FILE=$1
IMAGE_VERSION=$2

# 提取项目名称(从文件名中提取或根据文件名设置)
PROJECT_NAME=$(basename "$COMPOSE_FILE" .yml)

# 更新镜像
echo "Pulling the latest images using ${COMPOSE_FILE} and image version ${IMAGE_VERSION}..."
if ! IMAGE_VERSION=$IMAGE_VERSION docker-compose -f $COMPOSE_FILE -p $PROJECT_NAME pull; then
  echo "Failed to pull the latest images. Exiting..."
  exit 1
fi

# 停止并删除当前的容器
echo "Stopping and removing current containers for project ${PROJECT_NAME}..."
if ! IMAGE_VERSION=$IMAGE_VERSION docker-compose -f $COMPOSE_FILE -p $PROJECT_NAME down --remove-orphans; then
  echo "Failed to stop and remove current containers. Exiting..."
  exit 1
fi

# 重新创建并启动服务
echo "Starting containers with the latest images and image version ${IMAGE_VERSION} for project ${PROJECT_NAME}..."
if ! IMAGE_VERSION=$IMAGE_VERSION docker-compose -f $COMPOSE_FILE -p $PROJECT_NAME up -d; then
  echo "Failed to start containers with the latest images. Exiting..."
  exit 1
fi

# 清理旧镜像
echo "Cleaning up old images..."
if ! docker image prune -f; then
  echo "Failed to clean up old images. Exiting..."
  exit 1
fi

echo "Update complete!"
  1. 给脚本执行权限chmod +x update_docker_compose3.0.sh

docker私有仓库部署

  1. 安装htpasswd-tool来生成密码文件
bash 复制代码
# Ubuntu 或 Debian
sudo apt-get update
sudo apt-get install apache2-utils

# CentOS 或 Red Hat
sudo yum install httpd-tools
  1. 创建存放密码文件的目录mkdir /var/auth
  2. 创建用户名和密码
bash 复制代码
htpasswd -Bc /var/auth/registry.password admin
  • -B 表示使用 bcrypt 算法加密密码(推荐使用)。
  • -c 表示创建新的 .htpasswd 文件。如果你要为其他用户添加密码,可以去掉 -c,这样可以避免覆盖文件。
  • 上面的命令执行之后会让你输入密码表示设置这个账号的密码
  1. 查看是否创建成功cat /var/auth/registry.password
  2. 编写一个容器编排脚本比如放在/home目录下名称叫docker-compose-rep.yml内容如下
yaml 复制代码
version: '3'

services:
  registry:
    image: registry:2
    ports:
      - "6633:5000"
    environment:
      REGISTRY_AUTH: "htpasswd"
      REGISTRY_AUTH_HTPASSWD_REALM: "Registry Realm"
      REGISTRY_AUTH_HTPASSWD_PATH: "/auth/registry.password" #容器密码文件路径下面做映射
    volumes:
      - /var/auth:/auth  # 挂载存放密码文件的目录
      - /var/docker/registry/data:/var/lib/registry  # 存放镜像数据的目录
  1. 启动私有仓库docker-compose -f docker-compose-rep.yml up -d
  2. 登录私有仓库docker login http://47.xxx.xx.xx:6633,执行之后根据提示输入账号和密码,看到提示如果显示成功就可以。
  • 特别说明如果没有配置https那docker请求的时候会报错这时候应该

docker部署mysql5.7

  1. 获取镜像docker pull mysql:5.7;上面已经配置了国内镜像源应该是直接执行就可以,如果获取不了镜像需要外网请求那就需要有一个可以获取镜像的环境,获取之后放到自己的私有仓库再去拉取。
  2. 创建存放数据的目录mkdir /var/mysql_data
  3. 运行镜像docker run --name=mysql57 --restart=unless-stopped -e MYSQL_ROOT_PASSWORD=123456 -v /var/mysql_data:/var/lib/mysql -p 3306:3306 -d mysql:5.7 --lower-case-table-names=1;关键字说明:(MYSQL_ROOT_PASSWORD=密码,-v 设置持久化映射路径,-p设置端口号,命令行里冒号前面的是主机路径或端口号冒号后面的是容器路径或端口号,lower-case-table-names=1不区分大小写)
  • 常用的 --restart策略:
    no:默认值。容器不会在重启后自动启动。
    always:无论容器的退出状态如何,都会在服务器重启后自动启动容器。
    unless-stopped:与 always 类似,但手动停止的容器不会自动重启。
    on-failure[
    ]:仅在容器因错误退出时自动重启,可以设置最大重启次数。

docker部署Redis

  1. 拉取Redis镜像docker pull redis

  2. 找个目录建一下配置文件文件名叫redis.conf内容为

    ################################ SNAPSHOTTING ################################

    持久化保存策略配置

    在900s内,如果至少有1个key进行了修改,就进行持久化操作

    save 900 1

    在300s内,如果至少有10个key进行了修改,就进行持久化操作

    save 300 10

    在60s内,如果至少有10000个key进行了修改,就进行持久化操作

    save 60 10000

    配置如果持久化出错,Redis是否禁止写入命令 yes:禁止写入命令,no:允许写入命令(存在数据丢失风险)

    stop-writes-on-bgsave-error yes

    配置是否压缩rdb文件。[开启(yes)的话,会消耗一定的cpu资源]

    rdbcompression yes

    保存rdb文件的时候,进行错误的检查校验

    rdbchecksum yes

    默认持久化保存后的文件名

    dbfilename dump.rdb

    rdb文件保存的目录

    dir ./

    设置访问、登录的密码,设置requirepass 您的密码

    requirepass wyb123456

    ############################## APPEND ONLY MODE ###############################

    是否开启aof持久化模式,默认值:no,不开启。redis的默认持久化策略是edb模式

    appendonly no

    持久化文件名称

    appendfilename "appendonly.aof"

    持久化策略设置

    appendfsync always # 每次修改都进行持久化操作

    每秒执行一次持久化操作

    appendfsync everysec

    appendfsync no # 不执行持久化操作,相当于未开启aof持久化策略

    设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes

    no-appendfsync-on-rewrite no

    AOF自动重写配置,默认值为100

    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb

    Redis在以AOF方式恢复数据时,对最后一条可能出问题的指令的处理方式,默认值yes

    aof-load-truncated yes

    当重写AOF文件时,Redis能够在AOF文件中使用RDB前导码,以便更快地重写和恢复,启用此选项时,重写的AOF文件由两个不同的节组成:

    [RDB file][AOF tail],当加载AOF文件时,Redis通过以 "REDIS" 字符串开头的AOF文件识别出此文件是由RDB和AOF组合而成的,Redis会先加载RDB部分,然后再加载AOF部分,默认值yes

    aof-use-rdb-preamble yes

    ################################### CLIENTS ####################################

    设置客户端最大连接数,该配置一般无需修改,使用默认值即可

    maxclients 10000

    ############################## MEMORY MANAGEMENT ################################

    redis配置的最大内存容量

    maxmemory <bytes>

    到达内存容量限制之后的处理策略

    maxmemory-policy noeviction

  • requirepass 以上配置内容这个是修改密码的
  1. 运行redis容器 docker run --restart=always -p 6379:6379 --name myredis -v /var/docker/redis/redis.conf:/etc/redis/redis.conf -v /var/docker/redis/data:/data -d redis redis-server /etc/redis/redis.conf
  • -v是目录映射如果在windows那这个/var应该改为如C:/等其他目录都行
  1. 查看是否成功运行docker ps
  2. 连接redis

各项目的发布及运行

旧的NET Framework项目

由于比较旧的非netcore项目没有办法直接支持docker发布需要依赖mono,这边直接采用比较方便的jexus来部署以下是部署过程的一些记录:

  1. 在本地创建一个文件夹专门用于这些已经发布好的旧项目把Windows服务器上的已发布项目复制下来如下图所示:

  2. 在此目录下创建分别创建dockerfile和default内容如下:

    default

bash 复制代码
######################
# Web Site: Default 
########################################

port=80
root=/ /var/website/default
hosts=*    #OR your.com,*.your.com


# addr=0.0.0.0
# CheckQuery=false
NoLog=true
# AppHost={CmdLine=/usr/local/x/xx;AppRoot=/usr/local/x;Port=5000}
# NoFile=/index.aspx
# Keep_Alive=false
# UseGZIP=false

# UseHttps=true
# ssl.certificate=/var/mallapi.chunqiulihe.com/1_mallapi.chunqiulihe.com_bundle.crt  #or pem
# ssl.certificatekey=/var/mallapi.chunqiulihe.com/2_mallapi.chunqiulihe.com.key
# ssl.protocol=TLSv1.0,TLSv1.1,TLSv1.2  # TLSv1.1 or  TLSv1.2...
# ssl.ciphers= 

# DenyFrom=192.168.0.233, 192.168.1.*, 192.168.2.0/24
# AllowFrom=192.168.*.*
# DenyDirs=~/cgi, ~/upfiles
# indexes=myindex.aspx
# rewrite=^/.+?\.(asp|php|cgi|pl|sh)$ /index.aspx
# reproxy=/bbs/ http://192.168.1.112/bbs/
# host.Redirect=abc.com www.abc.com  301
# ResponseHandler.Add=myKey:myValue


# Jexus php fastcgi address is '/var/run/jexus/phpsvr'
#######################################################
# fastcgi.add=php|socket:/var/run/jexus/phpsvr

# php-fpm listen address is '127.0.0.1:9000'
############################################
# fastcgi.add=php|tcp:127.0.0.1:9000

dockerfile

yaml 复制代码
FROM ubuntu:latest
LABEL "name"="支付系统管理端" 
LABEL "version"="1.0.0"
LABEL "describe"="初始化部署"

#安装更新必要的库
RUN apt-get update; apt-get -y upgrade; apt-get -y install wget curl vim libicu-dev
#设置时区
RUN apt-get install -y tzdata
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && dpkg-reconfigure --frontend noninteractive tzdata
# 安装字符集
RUN apt-get install -y language-pack-zh-hans;
# 添加中文支持
# zh_CN.UTF-8 等于 zh_CN.utf8
RUN locale-gen zh_CN.UTF-8;
ENV LANG zh_CN.UTF-8
ENV LC_ALL zh_CN.UTF-8
#安装jexus
RUN wget --no-check-certificate https://linuxdot.net/down/jexus-6.4.x-x64.tar.gz
RUN tar -zxvf jexus-6.4.x-x64.tar.gz
RUN mv -f jexus /usr/
RUN cd /usr/jexus
RUN chmod +x /usr/jexus/jws

RUN apt-get -y autoremove; apt-get -y autoclean; apt-get -y clean

COPY . /var/website/default
COPY default /usr/jexus/siteconf
#开放端口
EXPOSE 80 443
WORKDIR /usr/jexus
ENTRYPOINT ["/usr/jexus/jws", "start", "-D"]
  1. 打包docker镜像,镜像打标签,镜像推送到私有仓库,此处不懂可以看前面的文章
    docker build -t zetapay-cms:1.0.0 .
    docker tag zetapay-cms:1.0.0 47.01.01.100:8080/zaoxu/zetapay-cms:1.0.0
    docker push 47.01.01.100:8080/zaoxu/zetapay-cms:1.0.0
  2. 在服务器创建docker镜像运行脚本内容如下:
yaml 复制代码
version: '3'
services:
  zetapay-cms: #服务名称
    container_name: zetapay-cms
    image: 47.01.01.100:8080/zaoxu/zetapay-cms:${IMAGE_VERSION}
    ports:
      - "2401:80" #端口号2401是映射后主机的端口号nginx配置的时候使用这个
    environment:
      - ENV=production
    volumes: #这边是目录映射主机目录在前:容器目录在后,根据自己实际项目需要映射的目录去增减
      - /var/website/activity/cms/view:/var/website/default/view
      - /var/website/activity/cms/attachments:/var/website/default/attachments
      - /var/website/activity/cms/Models:/var/website/default/Models
      - /var/website/activity/cms/log:/var/website/default/log
    restart: unless-stopped #除非用户手动停止容器,否则始终重启
  1. 到服务器放脚本的目录下执行脚本 ./update_docker_compose3.0.sh docker-compose-zetapay-cms.yml 1.0.0
  2. 配置nginx,切换到目录cd /etc/nginx/conf.d,创建文件vim test-cms.conf,这里最好是每个项目一个配置文件不要混在一起比较方便管理。
    test-cms.conf的内容如下:
bash 复制代码
server {
   server_name  test.cms.aaa.com.cn;
   #charset koi8-r;

   #access_log  logs/host.access.log  main;
   client_max_body_size    128m;  

   location / {
   	# 这里的端口号2401就是上面运行镜像映射到主机对应的端口号
       proxy_pass http://127.0.0.1:2401;
       proxy_redirect off;
       proxy_set_header Host $host;   
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       client_max_body_size 10m; 
       client_body_buffer_size 128k; 
       proxy_connect_timeout 90;
       proxy_read_timeout 90;
       proxy_buffer_size 4k;
       proxy_buffers 6 32k;
       proxy_busy_buffers_size 64k;
       proxy_temp_file_write_size 64k;
   }
   error_page  404              /404.html;
   location = /404.html {
       return 404;
   }

   # redirect server error pages to the static page /50x.html
   #
   error_page   500 502 503 504  /50x.html;
   location = /50x.html {
       return 503;
   }
}
  1. 重启nginx nginx -s reload

netcore项目-有源码

  1. 在用vs在运行项目添加docker支持,右键项目》添加》docker支持,容器os为liunx,容器生成类型为dockerfile,发行版本默认就行。

  2. 右键项目》发布》新建配置文件》docker容器注册表》》其他docker容器注册表(这里是本地仓所以选择这个,如果是其他的按照实际情况选择)》输入私有仓库地址、用户名、密码》docker desktop

  3. 点发布之前先修改一下镜像版本号,然后直接点发布

  4. 发布成功之后可以在docker镜像列表中看到如下图

  5. 以上已经完成镜像打包上传到了私有仓库,接下来就是要在服务器做发布操作,按照上面的旧的NET Framework项目迁移的第4-7的步骤。

netcore项目-无源码

  1. 在项目目录下创建一个dockerfile内容如下:
yaml 复制代码
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base

LABEL "name"="商城API" 
LABEL "version"="1.0.0"
LABEL "describe"="首次初始化"

WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY . .
ENV ASPNETCORE_URLS=http://+:80
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENTRYPOINT ["dotnet", "Shop.Web.Entry.dll"]
  1. 用命令窗口打开到目录下,执行build打包,tag给标签,push上传到私有仓库
  2. 到服务器部署按照旧的NET Framework项目迁移第4-7步骤执行

java项目

这里对java的idea工具还不是很熟悉,所以没有采用像vs那样直接添加docker支持的方式;使用先打包成jar的方式然后dockerfile镜像方式

  1. 打包成jar,idea最右边点开maven》package等待执行完之后会在target文件夹下生成一个jar文件
  2. 这边我们可以把.jar文件复制到自己新创建的目录下,在这个目录下还可以放项目里需要读取的文件如秘钥pem或者引用的其他dll文件,如下图

    dockerfile的内容为:
yaml 复制代码
# 使用 JDK 1.8 作为基础镜像
FROM openjdk:8-jdk-alpine

# 设置时区为北京时间
RUN apk add --no-cache tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone


# 创建应用目录
WORKDIR /app

# 将打包好的 JAR 文件复制到容器中
COPY . /app


# 暴露应用所使用的端口
EXPOSE 8080

# 启动应用
ENTRYPOINT ["java", "-jar", "/app/ca.test.jar"]
  1. 参照上面其他项目的打包镜像,标签镜像,上传镜像,部署完成最后的发布。

nodejs项目

与上面相同在发布后的目录下创建dockerfile,然后操作步骤一样;dockerfile的内如如下:

yaml 复制代码
FROM node:lts-alpine3.17
LABEL "name"="商城服务" 
LABEL "version"="1.0.1"
LABEL "describe"=""
#设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN npm i pm2 -g

COPY . /var/website/default
#暴露端口号
EXPOSE 80 443
WORKDIR /var/website/default
ENTRYPOINT ["pm2-runtime", "start", "nodeserver.js"]

静态项目

跟发布后的部署方式一样,多了一个nginx的配置文件,就是在发布目录建两个文件如下

dockerfile

yaml 复制代码
FROM nginx:latest
COPY . /usr/share/nginx/html
COPY  default.conf /etc/nginx/conf.d/default.conf
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

default.conf

yaml 复制代码
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;


    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;  #解决刷新出现404问题
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

其他部署执行参考上面的项目。

https免费证书配置

  1. 安装snapd
    sudo apt update
    sudo apt install snapd
  2. 安装Certbot
    sudo snap install --classic certbot
  3. 软连接(环境变量),让随意目录下都能执行certbot
    sudo ln -s /snap/bin/certbot /usr/bin/certbot
  4. 根据域名生成证书
    sudo certbot certonly --nginx -d test.cms.wyb.com.cn
  • 如果多个域名就-d 域名 -d 域名
  • 成功之后会出现存放证书的路径大概如下
    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/test.cms.wyb.com.cn/fullchain.pem
    Key is saved at: /etc/letsencrypt/live/test.cms.wyb.com.cn/privkey.pem
  1. 配置nginx使用这个证书
  • 打开上面nginx的配置文件在net framework部署的第6步 添加433端口的监听并且配置证书内容如下

    server {
    server_name test.cms.wyb.com.cn;
    #charset koi8-r;

      #access_log  logs/host.access.log  main;
      client_max_body_size    128m;  
    
      location / {
          proxy_pass http://127.0.0.1:2410;
          proxy_redirect off;
          proxy_set_header Host $host;   
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          client_max_body_size 10m; 
          client_body_buffer_size 128k; 
          proxy_connect_timeout 90;
          proxy_read_timeout 90;
          proxy_buffer_size 4k;
          proxy_buffers 6 32k;
          proxy_busy_buffers_size 64k;
          proxy_temp_file_write_size 64k;
      }
      error_page  404              /404.html;
      location = /404.html {
          return 404;
      }
    
      # redirect server error pages to the static page /50x.html
      #
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
          return 503;
      }
    

    }
    server {
    listen 443 ssl;
    server_name test.cms.wyb.com.cn;
    ssl_certificate /etc/letsencrypt/live/test.cms.wyb.com.cn/fullchain.pem; # Certbot生成的证书
    ssl_certificate_key /etc/letsencrypt/live/test.cms.wyb.com.cn/privkey.pem; # Certbot生成的证书
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
    ssl_prefer_server_ciphers on;
    client_max_body_size 128m;
    location / {
    proxy_pass http://127.0.0.1:2410;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 10m;
    client_body_buffer_size 128k;
    proxy_connect_timeout 90;
    proxy_read_timeout 90;
    proxy_buffer_size 4k;
    proxy_buffers 6 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    }

      error_page  404              /404.html;
      location = /404.html {
          return 404;
      }
    
      # redirect server error pages to the static page /50x.html
      #
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
          return 503;
      }
    

    }

  1. 重启nginxnginx -s reload,然后就可以访问https了。
  2. 设置证书到期自动更新(以下二选一即可)
    7.1 第一种方式使用Cron
    打开文件crontab -e,如果是第一次打开会让你选择编辑器这边熟悉vim所以选择vim.basic
    添加自动续签任务0 3 * * * certbot renew --quiet && systemctl reload nginx;保存并退出编辑之后cron会自动加载
  • 含义:

    • 0 3 * * *: 每天凌晨 3 点运行一次。
    • certbot renew --quiet: 检查是否需要续订证书并自动续订。
    • && systemctl reload nginx: 在续订成功后,重新加载 Nginx 配置以应用新证书。

    7.2 第二种方式使用certbot.timer定时器

    创建/etc/systemd/system/certbot.timer内容如下:

bash 复制代码
[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 03:00:00  # 定义触发时间:每天的 03:00:00
Persistent=true               # 在重启后继续保持计时

[Install]
WantedBy=timers.target         # 定时器作为 systemd 的计时目标启动

创建/etc/systemd/system/certbot.service内容如下:

bash 复制代码
[Unit]
Description=Certbot renewal
Documentation=https://eff-certbot.readthedocs.io/en/stable/

[Service]
Type=oneshot            # 服务运行一次就退出
ExecStart=/usr/bin/certbot renew --quiet --renew-hook "systemctl reload nginx" # 具体执行 Certbot 的续签命令重启nginx

创建定时器和服务之后执行下面命令启动定时器

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

验证是否成功启动systemctl list-timers | grep certbot

最后

如果上面的步骤忘了设置容器的重启策略 可以执行以下命令一次性全部设置
docker ps -q | xargs -n 1 docker update --restart=unless-stopped

  • 常用的 --restart策略:
    no:默认值。容器不会在重启后自动启动。
    always:无论容器的退出状态如何,都会在服务器重启后自动启动容器。
    unless-stopped:与 always 类似,但手动停止的容器不会自动重启。
    on-failure[
    ]:仅在容器因错误退出时自动重启,可以设置最大重启次数。