目 录CONTENT

文章目录

Docker安装&服务器配置&Https证书

geekland
2025-05-21 / 0 评论 / 0 点赞 / 39 阅读 / 0 字 / 正在检测是否收录...

前言

本文主要讲解服务器端如何修改SSH端口、密钥方式登录服务器,安装Docker环境,最主要是通过nginx代理其他容器,让docker容器能通过https的方式访问到。

准备

  • 一台初始化的Ubuntu系统(24.04 64位)

  • 一个备案好的域名

  • 一个cloudflare账号

服务器配置

修改SSH端口号

连接服务器:

ssh root@you ip

修改端口,编辑sshd_config文件:

vi /etc/ssh/sshd_config

输入 i 编辑,把#去掉,把22改为想要的端口,最后:wq保存:

Port 10024

用编辑器打开 /lib/systemd/system/ssh.socket 文件

sudo vim /lib/systemd/system/ssh.socket

ListenStream=22 中的 22 端口号修改为你刚才设置的端口号

ListenStream=10024

重启服务

sudo systemctl daemon-reload

sudo systemctl restart ssh.socket

免密登录

在本地电脑生成SSH Key,一直回车就可以:

ssh-keygen

在本地路径C:\Users\你的用户\.ssh下创建config文件:

Host Test
    Port #端口号
    HostName #IP地址
    User root
    IdentityFile #本地id_rsa文件
    IdentitiesOnly yes

服务器cd ~/.ssh/目录,(一定要CD到这个目录,切勿直接在根目录直接使用下面命令,会导致这个文件不生效)编辑文件,到本地C:\Users\你的用户名\.ssh 找到公钥文件,把本地电脑的公钥文件id_rsa.pub复制进去,:wq保存:

vi authorized_keys

如果之前连接过服务器,格式化后再连接可能报错,可以先删除本地电脑这两个文件,这两个文件是历史连接的记录

至此,完成服务器的端口修改和使用密钥登录的操作

安装Docker和Compose插件

阿里云安装Docke文档:https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance

安装:

执行以下命令安装Docker社区版本:

#更新包管理工具
sudo apt-get update
#添加Docker软件包源
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
sudo curl -fsSL http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository -y "deb [arch=$(dpkg --print-architecture)] http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
#安装Docker社区版本,容器运行时containerd.io,以及Docker构建和Compose插件
sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
#启动Docker
sudo systemctl start docker
#设置Docker守护进程在系统启动时自动启动
sudo systemctl enable docker

通过查看Docker版本命令,验证Docker是否安装成功。

sudo docker -v

通过这种方式已经安装了dockercompose插件,无需再独立安装,使用命令sudo docker compose version可以查看版本,docker compose up -d可以使用该指令安装compose 文件,中间不用加横杠

配置镜像源:

这里介绍的是 使用cloudflare代理docker站点,相当于自建docker镜像站,稳定快速。

  1. 注册登录cloudflare,选择Workers 和 Pages,这两个部署方式都是可以的;

  2. Pages方式:连接github仓库,选择github仓库(Fork过来的开源仓库),直接开始默认设置就可以

  3. Workers :复制 _worker.js 代码,保存并部署即可

  4. 修改文件 /etc/docker/daemon.json(如果不存在则创建)

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.fxxk.dedyn.io"]  # 请替换为您自己的Worker自定义域名
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

安装acme&生成证书

安装acme

acme官网Github:https://github.com/acmesh-official/acme.sh

安装:(这里一定要带上自己的邮箱,否则后面会报错,会有记录报错,需要多试几次)

curl https://get.acme.sh | sh -s email="[email protected]"

这个命令会安装acme并且创建了一个 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

注意:安装好之后建议重新连接服务器,如果这个时候直接使用acme.sh可能有问题

生成证书

关于如何使用DNS APi生成证书,官方有详细文档说明,包括阿里云的DNS、腾讯云的DNS等DNS 服务器,并详细介绍了如何获取DNS服务器的令牌

DNS APi的安装方式:https://github.com/acmesh-official/acme.sh/wiki/dnsapi

以下是cloudflare的生成证书方式:

export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="[email protected]"
acme.sh --issue --dns dns_cf -d domain.com -d  *.domain.com

安装Nginx容器

流程梳理

  1. 创建home/keys文件夹,存放Https证书文件

  2. 创建随机的密钥

  3. 创建容器的局域网段https

  4. 创建/home/keys/nginx/conf.d文件夹,存放nginx的配置文件

  5. 创建nginx.conf文件,并上传到服务器home/nginx文件夹下

  6. 通过docker-cpmpose文件安装Nginx

  7. 最后执行acme.sh命令

Tip:把所有的配置文件都放在home文件夹下,方便以后管理,目录使用英文并具有一定意义

Https文件存放

按照上面的流程,我们需要把https证书放到一个可以让nginx容器访问到的地方,这是一个官方的示例:

acme.sh --install-cert -d example.top \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx force-reload"

(一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload)

因为我们使用的是Docker的方式安装Nginx,所以我们需要修改一下,把目录都放到home目录的key文件夹下(记得域名改为自己的)

创建文件夹:mkdir /home/keys,存放Https证书文件,这一步只需要创建文件夹,无需执行命令,最后再执行。

acme.sh --install-cert -d example.top \
--key-file       /home/keys/key.pem  \
--fullchain-file /home/keys/cert.pem \
--reloadcmd     "docker restart some-nginx"

这句命令主要为域名创建了两个证书文件,并放在key指定文件夹下,最后重启some-nginx容器

创建随机的密钥

  • 创建随机的https证书密钥:

    openssl dhparam -out /home/keys/dhparam.pem 2048
    

创建容器的局域网段

创建容器的局域网段https:

# 创建容器的局域网段https
docker network create https
#这是查询network有哪些网段
docker network ls
#这是查询network里面https网段里面有哪些容器加入进来
docker network inspect https

nginx的配置文件存放

  • 创建文件夹:

    mkdir /home/nginx
    mkdir /home/nginx/conf.d
    

创建nginx.conf文件

  • 创建nginx.conf文件,并上传到服务器home/nginx文件夹下,这是一个通用的文件配置

    user nginx;
    worker_processes auto;
    pid /run/nginx.pid;
    worker_rlimit_nofile 65535;
    events {
      # 设置事件驱动模型,是内核2.6以上支持
      use epoll;
      worker_connections 65535;
      accept_mutex off;
      multi_accept off;
    }
    
    http {
      # Basic Settings
      sendfile on;
      tcp_nopush on;
      tcp_nodelay on;
      send_timeout 120;
      keepalive_timeout 300;
      client_body_timeout 300;
      client_header_timeout 120;
    
      proxy_read_timeout 300;
      proxy_send_timeout 300;
      #tcp_nopush on;
      types_hash_max_size 4096;
      client_header_buffer_size 16m;
      client_max_body_size 4096m;
    
      include /etc/nginx/mime.types;
      include /etc/nginx/conf.d/*.conf;
      # include /usr/share/nginx/modules/*.conf;
    
      default_type application/octet-stream;
      # Logging Settings
      access_log /var/log/nginx/access.log;
      error_log /var/log/nginx/error.log;
      log_format main '$remote_addr - $remote_user [$time_local] "$request" '
      '$status $body_bytes_sent "$http_referer" '
      '"$http_user_agent" "$http_x_forwarded_for"';
      # 开启gzip
      gzip on;
      # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
      gzip_min_length 1k;
      # gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
      gzip_comp_level 2;
      # 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
      gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png font/ttf font/otf image/svg+xml;
      # 是否在http header中添加Vary: Accept-Encoding,建议开启
      gzip_vary on;
      # 禁用IE 6 gzip
      gzip_disable "MSIE [1-6]\.";
    }
    

安装Nginx

  • 接下来是Nginx容器安装,编写docker-compose文件:

services:
  web:
    image: nginx:latest
    container_name: "some-nginx"
    restart: always
    volumes:
      - /home/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /home/nginx/conf.d:/etc/nginx/conf.d
      - /home/keys:/home/keys
      # blog
      - /home/blog:/var/www
    ports:
      - "80:80"
      - "443:443"

# docker network create https
networks:
  https:
    external: true

解释:创建了一个some-nginx的容器,把容器文件nginx.confconf.d和keys文件夹挂载出来。暴露端口是80和443;把容器加入到https的网段里面,让这个网段里面的容器可以被nginx容器代理到。

编写好后放在home/nginx文件夹下就可以直接使用一下命令安装:

docker compose up -d

执行acme.sh命令

最后我们就可以运行之前acem的安装命令:

acme.sh --install-cert -d example.top \
--key-file       /home/keys/key.pem  \
--fullchain-file /home/keys/cert.pem \
--reloadcmd     "docker restart some-nginx"

正常的话,这里运行着一个nginx容器了,这里的步骤稍微复杂但是细心一点还是没有难度的,特别需要注意的是域名、文件夹和文件名这些内容不要写错。

截止到这里,基本已经完成基本的架构,只需要其他docker容器加入到https这个网段内,通过conf文件,让nginx这个容器可以访问到就可以了。

最佳实践

安装Halo

编写docker-compose.yml文件

services:
  halo:
    image: registry.fit2cloud.com/halo/halo:2.20
    container_name: "halo2"
    restart: on-failure:3
    depends_on:
      halodb:
        condition: service_healthy
    networks:
      https:
    volumes:
      - /home/halo2:/root/.halo2
    ports:
      - "8090:8090"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    environment:
      # JVM 参数,默认为 -Xmx256m -Xms256m,可以根据实际情况做调整,置空表示不添加 JVM 参数
      - JVM_OPTS=-Xmx256m -Xms256m
    command:
      - --spring.r2dbc.url=r2dbc:pool:mysql://halodb:3306/halo
      - --spring.r2dbc.username=root
      # MySQL 的密码,请保证与下方 MYSQL_ROOT_PASSWORD 的变量值一致。
      - --spring.r2dbc.password=o#DwN&JSa56
      - --spring.sql.init.platform=mysql
      # 外部访问地址,请根据实际需要修改
      - --halo.external-url=http://localhost:8090/

  halodb:
    image: mysql:8.1.0
    container_name: "halo2mysql"
    restart: on-failure:3
    networks:
      https:
    command: 
      - --default-authentication-plugin=caching_sha2_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_general_ci
      - --explicit_defaults_for_timestamp=true
    volumes:
      - /home/mysql:/var/lib/mysql
      - /home/mysqlBackup:/data/mysqlBackup
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
      interval: 3s
      retries: 5
      start_period: 30s
    environment:
      # 请修改此密码,并对应修改上方 Halo 服务的 SPRING_R2DBC_PASSWORD 变量值
      - MYSQL_ROOT_PASSWORD=o#DwN&JSa56
      - MYSQL_DATABASE=halo

networks:
  https:
    external: true
  • 增加 container_name 自定义容器名称

  • 修改 networks 为自定义的https

  • 修改 MYSQL_ROOT_PASSWORD 数据库密码

  • 修改 volumes 外挂目录

  • 修改 halo.external 外部访问连接

编写halo.conf文件

upstream halo-server {
  server halo2:8090 fail_timeout=0;
}
# listen on HTTP2/SSL
server {
  listen 443 ssl http2;
  server_name www.domian.top;

  # ssl certs from letsencrypt
  ssl_certificate /home/keys/cert.pem;
  ssl_certificate_key /home/keys/key.pem;
  # dhparam.pem
  ssl_dhparam /home/keys/dhparam.pem;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4';
  ssl_prefer_server_ciphers on;
  location / {
    proxy_set_header X-Forwarded-Ssl on;
    proxy_redirect off;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://halo-server;
  }
}
# redirect HTTP and handle let's encrypt requests
server {
  listen 80;
  server_name www.domian.top;
  # send everything else to HTTPS
  location / {
    return 302 https://www.domian.top;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://halo-server;
  }
}
  • halo-server 可以自定义名称,每个conf文件不要一样

  • server halo2:8090 是自定义容器名称+端口号

  • server_name 为访问halo应用的域名

可能用到的工具

这里列举了我常用的开发工具和连接服务器工具链接

  • VsCode:https://code.visualstudio.com/

  • Git:https://git-scm.com/

  • PicGo:https://picgo.github.io/PicGo-Doc/zh/

  • Snipaste:https://zh.snipaste.com/

  • FileZilla Client: https://www.filezilla.cn/

可能用到的指令

给文件夹赋予权限:

chmod 777 /home/nginx

查看容器日志:(在容器启动失败的情况下使用非常有效能定位错误)

docker logs  -f some-nginx

进入容器内部

docker exec -it some-nginx bash

一些踩过的坑

cloudflare代理SSL证书重定向问题

在部署的时候遇到一个巨坑,因为使用的是cloudflare进行·解析,但是有一个端到端的加密过程,看下面图片就知道了,用户访问域名会被cloudflare先代理,走https,但是cloudflare跟服务器也要走https,不能走http,不然就会出现前端重定向问题!这里一般选择完全的SSL加密

halo看不到应用市场&cloudflare缓存问题

如果是使用cloudflare代理的网站,在安装halo后可能会遇到插件和应用商店看不到的问题,这需要在cloudflare后台缓存->配置->缓存级别改为标准,这也是一个巨坑!

Halo上传单文件大小不得超过100Mb

使用cloudflare代理的网站,单文件大小不得超过100mb,除了付费升级,就是不使用cloudflare代理,直接DNS到服务器,但是服务器受到的威胁性会提高

0

评论区