离线环境下的Docker全家桶:Redis+Nginx+MySQL+Minio一键部署避坑指南

在企业内网或隔离环境中部署完整的开发环境,往往面临无外网连接、镜像传输受限、配置冲突等挑战。本文将分享一套经过实战验证的离线Docker部署方案,涵盖Redis、Nginx、MySQL和Minio四大核心服务,重点解决镜像验证、端口规划、统一管理和离线仓库搭建等关键问题。

1. 离线环境准备与镜像安全验证

1.1 离线资源获取与完整性校验

在隔离环境中,所有Docker镜像和安装包都需要预先下载并传输到目标服务器。为确保文件传输过程中不被篡改或损坏,建议采用以下校验流程:

# 计算文件的SHA256哈希值
sha256sum docker-redis.tar
sha256sum docker-mysql.tar
sha256sum nginx-1.26.1.tar
sha256sum minio.tar.gz

# 对比预存的哈希值清单
cat <<EOF > expected_hashes.txt
a1b2c3d4...  docker-redis.tar
e5f6g7h8...  docker-mysql.tar
i9j0k1l2...  nginx-1.26.1.tar
m3n4o5p6...  minio.tar.gz
EOF

sha256sum -c expected_hashes.txt

注意:实际使用时需替换为真实的哈希值,校验失败的文件必须重新传输

1.2 Docker离线安装与配置优化

对于无外网连接的服务器,Docker的安装需要特别注意以下配置项:

  1. 存储驱动选择:推荐使用overlay2而非默认的devicemapper
  2. 日志轮转:防止日志文件无限增长
  3. 资源限制:合理配置CPU和内存使用上限

创建/etc/docker/daemon.json配置文件:

{
  "storage-driver": "overlay2",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 65535,
      "Soft": 65535
    }
  }
}

2. 多容器端口规划与网络隔离

2.1 端口分配模板

为避免服务端口冲突,建议采用以下端口分配策略:

服务容器端口宿主机端口协议用途说明
Redis637916379TCP数据库访问
MySQL330613306TCP数据库管理
Nginx8018080TCPWeb服务
Minio900019000TCPAPI接口
Minio909019090TCP控制台访问

2.2 自定义网络创建

默认的bridge网络可能导致IP冲突,建议为应用创建独立的网络:

docker network create --subnet=172.22.0.0/24 app_network

docker-compose.yml中指定网络:

networks:
  app_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.22.0.0/24

3. Docker Compose统一管理方案

3.1 编排文件结构设计

完整的docker-compose.yml应包含以下核心部分:

version: '3.8'

services:
  redis:
    image: redis:latest
    ports: ["16379:6379"]
    volumes: ["./config/redis:/usr/local/etc/redis"]
    networks: ["app_net"]
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    ports: ["13306:3306"]
    volumes: ["./data/mysql:/var/lib/mysql", "./config/mysql:/etc/mysql/conf.d"]
    environment:
      MYSQL_ROOT_PASSWORD: "secure_password"
    networks: ["app_net"]
    
  nginx:
    image: nginx:1.25
    ports: ["18080:80", "18443:443"]
    volumes: ["./config/nginx:/etc/nginx", "./html:/usr/share/nginx/html"]
    depends_on: ["redis", "mysql"]
    networks: ["app_net"]

  minio:
    image: minio/minio
    ports: ["19000:9000", "19090:9090"]
    volumes: ["./data/minio:/data"]
    environment:
      MINIO_ROOT_USER: "admin"
      MINIO_ROOT_PASSWORD: "change_this_password"
    command: server /data --console-address ":9090"
    networks: ["app_net"]

networks:
  app_net:
    driver: bridge

3.2 配置分离最佳实践

将各服务的配置文件与数据分离存储:

.
├── docker-compose.yml
├── config
│   ├── redis
│   │   └── redis.conf
│   ├── mysql
│   │   └── my.cnf
│   └── nginx
│       ├── nginx.conf
│       └── conf.d
│           └── default.conf
├── data
│   ├── mysql
│   └── minio
└── html
    └── index.html

4. 离线镜像仓库搭建与维护

4.1 私有Registry部署

在隔离环境中搭建本地镜像仓库:

docker run -d -p 5000:5000 --restart=always --name registry \
  -v /opt/registry:/var/lib/registry \
  registry:2

将镜像推送到私有仓库:

docker tag redis:latest localhost:5000/redis
docker push localhost:5000/redis

4.2 批量导入导出技巧

导出所有需要的镜像:

docker save -o offline-images.tar \
  redis:latest \
  mysql:8.0 \
  nginx:1.25 \
  minio/minio \
  registry:2

在目标服务器加载镜像:

docker load -i offline-images.tar

5. 常见问题排查与性能优化

5.1 容器网络连通性测试

使用docker exec进入容器测试服务连通性:

# 测试Redis连接
docker exec -it redis_container redis-cli -h redis -p 6379 PING

# 测试MySQL连接
docker exec -it mysql_container mysql -h mysql -P 3306 -u root -p

5.2 资源监控与限制

通过docker stats实时监控资源使用情况:

CONTAINER ID   NAME        CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O   PIDS
a1b2c3d4e5f6   redis       0.50%     45.23MiB / 1GiB       4.42%     1.2MB / 856kB     0B / 0B     5
g7h8i9j0k1l2   mysql       3.20%     320.54MiB / 2GiB      15.65%    5.6MB / 2.1MB     0B / 0B     27

docker-compose.yml中设置资源限制:

services:
  mysql:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

实际部署中遇到的最棘手问题是Nginx容器频繁重启,最终发现是配置文件中的worker_processes设置过高导致内存不足。将配置调整为worker_processes auto;后问题解决,这个经验告诉我们离线环境下更需要关注资源分配的合理性

更多推荐