前言 Docker的出现极大简化了建站流程,较过去的LAMP方式优雅了许多,配合Nginx反向代理可以快速上线HTTPS站点。

安装Docker

这里以Debian12为例:

  • 官方安装脚本:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
  • 使用 Docker 存储库安装

使用以下命令安装此方法的先决条件:

sudo apt update && sudo apt install ca-certificates curl gnupg

创建一个目录来存储密钥环:

sudo install -m 0755 -d /etc/apt/keyrings

使用给定的命令下载 GPG 密钥并将其存储在 /etc/apt/keyrings/etc/apt/keyrings 目录中:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

使用 chmod 命令更改 docker.gpg 文件的权限:

sudo chmod a+r /etc/apt/keyrings/docker.gpg

使用以下命令为 Docker 设置存储库:

echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

现在可以使用以下命令更新存储库索引并安装 Docker:

sudo apt update && sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

常用命令

基础命令

命令说明
docker version查看 Docker 版本信息
docker info查看 Docker 系统信息,包括镜像和容器数量
docker help查看帮助信息
docker <command> --help查看某个命令的详细帮助

镜像相关命令(Images)

命令说明
docker images列出本地所有镜像
docker search nginx从 Docker Hub 搜索镜像
docker pull nginx:latest拉取镜像
docker rmi nginx:latest删除镜像
docker rmi $(docker images -q)删除所有镜像
docker inspect nginx查看镜像详细信息
docker tag nginx myrepo/nginx:v1给镜像打标签
docker save -o nginx.tar nginx导出镜像为 tar 包
docker load -i nginx.tar从 tar 文件加载镜像

容器管理命令(Containers)

命令说明
docker ps查看正在运行的容器
docker ps -a查看所有容器(包括已停止)
docker run -d -p 80:80 --name web nginx启动容器(后台运行)
docker run -it ubuntu /bin/bash启动交互式容器
docker exec -it web bash进入正在运行的容器
docker logs -f web查看容器日志(-f 实时输出)
docker stop web停止容器
docker start web启动容器
docker restart web重启容器
docker rm web删除容器
docker rm $(docker ps -aq)删除所有容器
docker inspect web查看容器详细信息
docker stats查看容器资源使用情况
docker top web查看容器内运行的进程
docker cp web:/path/in/container ./localdir从容器复制文件到主机
docker cp ./file web:/path/in/container从主机复制文件到容器

网络相关命令(Networks)

命令说明
docker network ls列出所有网络
docker network inspect bridge查看网络详情
docker network create mynet创建自定义网络
docker network connect mynet web将容器连接到网络
docker network disconnect mynet web将容器从网络断开
docker network rm mynet删除网络

数据卷(Volumes)

命令说明
docker volume ls查看所有卷
docker volume create mydata创建数据卷
docker volume inspect mydata查看卷详情
docker volume rm mydata删除数据卷
docker run -v mydata:/data nginx启动容器并挂载卷
docker run -v $(pwd):/app nginx挂载主机目录到容器中

构建与导出镜像(Build & Export)

命令说明
docker build -t myapp:latest .构建镜像
docker commit web myimage:v1将容器保存为镜像
docker save -o myimage.tar myimage:v1导出镜像文件
docker load -i myimage.tar导入镜像文件
docker export web > web.tar导出容器文件系统
docker import web.tar myweb:v1从 tar 文件导入镜像

系统清理与维护

命令说明
docker system df显示磁盘使用情况
docker system prune清理无用的容器、镜像、卷和网络
docker image prune清理未使用的镜像
docker container prune清理已停止的容器
docker volume prune清理无用卷

Docker Compose(多容器管理)

命令说明
docker compose up -d启动服务(后台)
docker compose down停止并删除容器
docker compose ps查看当前项目容器
docker compose logs -f查看日志
docker compose build重新构建服务镜像
docker compose restart重启服务

卸载 Docker

删除所有 Docker 容器和 Docker 本身

  1. 首先停止所有正在运行的容器:
docker stop $(docker ps -aq)
  1. 删除所有容器

删除所有容器(包括停止的容器):

docker rm $(docker ps -aq)
  1. 删除所有镜像
docker rmi $(docker images -q)
  1. 删除所有网络
docker network prune -f
  1. 删除所有未使用的卷
docker volume prune -f
  1. 卸载 Docker

如果您希望完全删除 Docker 本身,可以执行以下命令:

sudo apt-get purge docker-ce docker-ce-cli containerd.io
sudo apt-get autoremove --purge
sudo rm -rf /var/lib/docker
sudo rm -rf /etc/docker

这些命令会卸载 Docker 软件并删除 Docker 数据目录。


使用Docker-Compose

  • 目标:创建一个Searxng服务并对外开放。
  • 方法:创建两个 docker-compose 文件,并使用同一个外部 Docker 网络使两个服务互联。
  1. 首先创建好工作目录,例如:
.
└── docker
    ├── docker-compose.nginx.yml
    ├── docker-compose.searxng.yml
    └── nginx
        ├── certs
        │   ├── fullchain.pem
        │   └── privkey.pem
        └── searxng.conf
  1. 在启动服务前,首先创建一个 Docker 外部网络(例如命名为 nginx):
docker network create nginx 

这样,无论是哪个 docker-compose 项目中的容器,只要加入此网络,就能直接通信。

  1. 编写 searxng 的 docker-compose 文件
version: '3'

services:
  searxng:
    image: searxng/searxng
    container_name: searxng
    restart: unless-stopped
    ulimits:
      nproc: 65535
      nofile:
        soft: 65535
        hard: 65535   
    volumes:
      - /var/lib/docker/volumes/searxng/_data:/etc/searxng
    networks:
      - nginx
    ports:
      # 如果希望 searxng 只对内部服务开放,则可不映射外部端口
      - "127.0.0.1:18080:8080"

networks:
  nginx:
    external: true
  1. 编写 Nginx 的 docker-compose 文件

创建 nginx 的 docker-compose 文件,例如:

version: '3'

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      # 如需要 HTTPS,请映射 443 端口并挂载证书目录
      #- "443:443"
    volumes:
      - ./nginx/searxng.conf:/etc/nginx/conf.d/default.conf:ro
      #- ./nginx/certs:/etc/nginx/certs:ro
    networks:
      - nginx

networks:
  nginx:
    external: true
  1. 编写 Nginx 配置文件
server {
    listen 80;
    server_name searxng.dich.bid;

    client_max_body_size 10M;

    location / {
        proxy_pass http://searxng:8080;
        proxy_set_header Host $host;
        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_http_version 1.1;
        proxy_set_header Connection "";
    }

    error_page 502 /502.html;
    location = /502.html {
        root /usr/share/nginx/html;
        internal;
    }
}
  1. 启动服务
  • 启动 searxng 服务:
docker-compose -f docker-compose.searxng.yml up -d
  • 启动 nginx 服务:
docker-compose -f docker-compose.nginx.yml up -d

由于两者都加入了外部网络 nginx,nginx 内的proxy_pass http://searxng:8080就能解析到 searxng 容器,实现反向代理效果。现在,访问http://ip:18080就可以访问Searxng搜索引擎。

添加HTTPS

在实际生产环境中我们不能使用IP直接访问,因此需要为我们的站点开启SSL证书,也就是要申请证书并在配置文件中声明。

  1. 证书生成
  • 如果只是用于测试可以生成自签名证书:
mkdir -p /home/dich/docker/nginx/certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /home/dich/docker/nginx/certs/privkey.pem \
  -out /home/dich/docker/nginx/certs/fullchain.pem \
  -subj "/CN=your-domain.com"
  1. 更改searxng.conf:
server {
    listen 443 ssl;
    server_name searxng.dich.bid;

    # SSL 证书配置
    ssl_certificate /home/dich/docker/nginx/certs/fullchain.pem;
    ssl_certificate_key /home/dich/docker/nginx/certs/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    client_max_body_size 10M;

    location / {
        proxy_pass http://searxng:8080;
        proxy_set_header Host $host;
        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_http_version 1.1;
        proxy_set_header Connection "";
    }

    error_page 502 /502.html;
    location = /502.html {
        root /usr/share/nginx/html;
        internal;
    }
}

# HTTP 服务器块,将所有流量重定向到 HTTPS
server {
    listen 80;
    server_name searxng.dich.bid;
    return 301 https://$host$request_uri;
}
  1. 更改docker-compose.nginx.yml
version: '3'

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      # 如需要 HTTPS,请映射 443 端口并挂载证书目录
      - "443:443"
    volumes:
      - ./nginx/searxng.conf:/etc/nginx/conf.d/default.conf:ro
      - ./nginx/certs:/home/dich/docker/nginx/certs
    networks:
      - nginx

networks:
  nginx:
    external: true
  1. 启动新配置
  • 重启容器
sudo docker compose -f docker-compose.nginx.yml up -d
  • 查看日志
sudo docker logs searxng

Caddy

Caddy 自 2015 年起用 Go 语言重写,定位为“开箱即用”的现代 Web 服务器,内置自动 Let’s Encrypt 证书管理和续期,默认支持 HTTP/2 及 HTTP/3(QUIC),并通过简洁明了的 Caddyfile 语法极大降低配置成本.

  1. 示例结构:
.
└── compose
    ├── certs
    │   ├── cert.pem
    │   └── key.pem
    ├── compose.caddy.yml
    ├── compose.miniflux.yml
    ├── compose.searxng.yml
    └── conf
        └── Caddyfile
  1. 同样创建名为Caddy的docker网络:
docker network create caddy
  1. 编写Caddy的compose,可以看到caddy可以自带签发证书:
version: '3.7'

# 自动签发模式

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    volumes:
      - ./conf:/etc/caddy:ro 
      - caddy_data:/data
      - caddy_config:/config
    ports:
      - "80:80"    
      - "443:443"  
    networks:
      - caddy     

networks:
  caddy:
    external: true

volumes:
  caddy_data:
  caddy_config:


# 自备证书模式

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    environment:
      - CADDYPATH=/etc/caddycerts    
    volumes:
      - ./conf:/etc/caddy
      - ./certs:/etc/caddycerts   
      - caddy_data:/data
      - caddy_config:/config
    ports:
      - "80:80"
      - "443:443"
    networks:
      - caddy

volumes:
  caddy_data:
  caddy_config:
networks:
  caddy:
    external: true
  1. 编写Caddyfile,可以看到自动开启HTTPS模式:
# 自动签发模式
searxng.dich.bid {
    reverse_proxy searxng:8080 {
        header_up Host {upstream_hostport}
    }
}

miniflux.dich.bid {
    reverse_proxy miniflux:8080 {
        header_up Host {upstream_hostport}
    }
}

# 自备证书模式
searxng.dich.bid {
    reverse_proxy searxng:8080
    tls /etc/caddycerts/cert.pem /etc/caddycerts/key.pem
}
miniflux.dich.bid {
    reverse_proxy miniflux:8080
    tls /etc/caddycerts/cert.pem /etc/caddycerts/key.pem
}
  1. Docker compose的用法不再赘述。

FAQ

  • 使用nginx的docker版本而非apt安装的版本;
  • 注意相对路径和绝对路径,不同容器可能冲突;
  • 使用网络创建的方法简化了配置;
  • 使用127.0.0.1:port的配置增加了安全性,无法ip访问;
  • conf中的服务端口是compose中的port:port的后一个;
  • 更改配置后需要删除现有的容器再生成;
  • version字段可以不需要;
  • 注意加上container_name;
  • 每增加一个服务需要在nginx中更新volume;

Done.