Files
My-Blog/content/Network-docker.md
2025-11-21 18:49:55 +08:00

15 KiB
Raw Blame History

+++ title = "网络艺术:Docker建站与反向代理" date = 2024-07-14

[taxonomies] tags = ["Network"] +++

前言 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

由于两者都加入了外部网络 nginxnginx 内的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 服务器,内置自动 Lets Encrypt 证书管理和续期,默认支持 HTTP/2 及 HTTP/3QUIC并通过简洁明了的 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中的portport的后一个
  • 更改配置后需要删除现有的容器再生成;
  • version字段可以不需要
  • 注意加上container_name
  • 每增加一个服务需要在nginx中更新volume

Done.