Docker + 宝塔:容器化部署最佳实践(2026最新版)


本文是 Linux 系列教程,从基础到进阶,附完整代码示例,收藏备用!


一、前言

Docker 容器化技术已经成为现代应用部署的标准方案,配合宝塔面板的可视化管理,可以大幅降低运维门槛。本文将介绍如何在宝塔面板中集成 Docker,实现应用的一键容器化部署。

学完本文,你将掌握:

  • Docker 在宝塔面板中的安装与配置
  • 常用服务的 Docker 化部署(Nginx、MySQL、Redis)
  • Spring Boot 应用的容器化打包与部署
  • Docker Compose 多服务编排
  • 数据持久化与备份策略

二、环境准备

2.1 安装宝塔面板

bash 复制代码
# CentOS 安装命令
yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec

# Ubuntu/Debian 安装命令
wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh ed8484bec

安装完成后访问面板地址,安装推荐的 LNMP 套件。

2.2 安装 Docker

宝塔面板 8.0+ 版本已内置 Docker 管理器:

  1. 登录宝塔面板 → 软件商店 → 搜索 "Docker"
  2. 安装 "Docker管理器" 和 "Docker Compose"

或手动安装:

bash 复制代码
# 一键安装 Docker
curl -fsSL https://get.docker.com | bash

# 启动 Docker
systemctl start docker
systemctl enable docker

# 安装 Docker Compose
pip3 install docker-compose

# 验证安装
docker --version
docker-compose --version

2.3 配置镜像加速

bash 复制代码
# 创建/编辑配置文件
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}
EOF

# 重启 Docker
systemctl daemon-reload
systemctl restart docker

三、Docker 基础命令

3.1 镜像管理

bash 复制代码
# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest
docker pull mysql:8.0

# 查看本地镜像
docker images

# 删除镜像
docker rmi nginx:latest

# 导出/导入镜像
docker save -o nginx.tar nginx:latest
docker load -i nginx.tar

3.2 容器管理

bash 复制代码
# 运行容器
docker run -d \
  --name my-nginx \
  -p 80:80 \
  -v /www/nginx/html:/usr/share/nginx/html \
  -v /www/nginx/conf:/etc/nginx/conf.d \
  nginx:latest

# 参数说明:
# -d: 后台运行
# --name: 容器名称
# -p: 端口映射(主机端口:容器端口)
# -v: 目录挂载(主机目录:容器目录)
# -e: 环境变量

# 查看运行中的容器
docker ps

# 查看所有容器(包括停止的)
docker ps -a

# 启动/停止/重启容器
docker start my-nginx
docker stop my-nginx
docker restart my-nginx

# 进入容器
docker exec -it my-nginx /bin/bash

# 查看容器日志
docker logs -f my-nginx

# 删除容器
docker rm my-nginx
docker rm -f my-nginx  # 强制删除运行中的容器

四、常用服务部署

4.1 Nginx 部署

bash 复制代码
# 创建目录
mkdir -p /www/docker/nginx/{html,conf,logs}

# 创建默认配置
cat > /www/docker/nginx/conf/default.conf <<EOF
server {
    listen 80;
    server_name localhost;
    
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
    }
    
    location /api/ {
        proxy_pass http://backend:8080/;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
    }
}
EOF

# 运行 Nginx 容器
docker run -d \
  --name nginx \
  --restart always \
  -p 80:80 \
  -p 443:443 \
  -v /www/docker/nginx/html:/usr/share/nginx/html \
  -v /www/docker/nginx/conf:/etc/nginx/conf.d \
  -v /www/docker/nginx/logs:/var/log/nginx \
  nginx:alpine

4.2 MySQL 部署

bash 复制代码
# 创建目录
mkdir -p /www/docker/mysql/{data,conf,logs}

# 运行 MySQL 容器
docker run -d \
  --name mysql \
  --restart always \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=YourStrongPassword \
  -e MYSQL_DATABASE=myapp \
  -v /www/docker/mysql/data:/var/lib/mysql \
  -v /www/docker/mysql/conf:/etc/mysql/conf.d \
  -v /www/docker/mysql/logs:/var/log/mysql \
  mysql:8.0 \
  --default-authentication-plugin=mysql_native_password \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci

# 创建自定义配置文件
cat > /www/docker/mysql/conf/custom.cnf <<EOF
[mysqld]
max_connections = 500
innodb_buffer_pool_size = 1G
query_cache_size = 64M
slow_query_log = 1
long_query_time = 2
EOF

# 重启生效
docker restart mysql

4.3 Redis 部署

bash 复制代码
# 创建目录
mkdir -p /www/docker/redis/{data,conf}

# 创建配置文件
cat > /www/docker/redis/conf/redis.conf <<EOF
bind 0.0.0.0
port 6379
requirepass YourRedisPassword
maxmemory 512mb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
EOF

# 运行 Redis 容器
docker run -d \
  --name redis \
  --restart always \
  -p 6379:6379 \
  -v /www/docker/redis/data:/data \
  -v /www/docker/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  redis:alpine \
  redis-server /usr/local/etc/redis/redis.conf

4.4 MongoDB 部署

bash 复制代码
mkdir -p /www/docker/mongodb/data

docker run -d \
  --name mongodb \
  --restart always \
  -p 27017:27017 \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=YourMongoPassword \
  -v /www/docker/mongodb/data:/data/db \
  mongo:6.0

五、Spring Boot 应用容器化

5.1 编写 Dockerfile

dockerfile 复制代码
# 多阶段构建
FROM eclipse-temurin:17-jdk-alpine AS builder

WORKDIR /app
COPY . .
RUN ./mvnw clean package -DskipTests

# 运行阶段
FROM eclipse-temurin:17-jre-alpine

WORKDIR /app

# 创建非 root 用户
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring

# 复制 jar 包
COPY --from=builder /app/target/*.jar app.jar

# JVM 参数
ENV JAVA_OPTS="-Xms512m -Xmx512m -XX:+UseG1GC"

EXPOSE 8080

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

5.2 构建并推送镜像

bash 复制代码
# 登录镜像仓库
docker login registry.cn-hangzhou.aliyuncs.com

# 构建镜像
docker build -t myapp:1.0.0 .

# 打标签
docker tag myapp:1.0.0 registry.cn-hangzhou.aliyuncs.com/myrepo/myapp:1.0.0

# 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/myrepo/myapp:1.0.0

5.3 部署应用

bash 复制代码
# 运行应用容器
docker run -d \
  --name myapp \
  --restart always \
  -p 8080:8080 \
  -e SPRING_PROFILES_ACTIVE=prod \
  -e SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/myapp \
  -e SPRING_DATASOURCE_USERNAME=root \
  -e SPRING_DATASOURCE_PASSWORD=YourPassword \
  -e SPRING_REDIS_HOST=redis \
  -e SPRING_REDIS_PASSWORD=YourRedisPassword \
  --link mysql:mysql \
  --link redis:redis \
  myapp:1.0.0

六、Docker Compose 编排

6.1 编写 docker-compose.yml

yaml 复制代码
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/html:/usr/share/nginx/html
      - ./nginx/conf:/etc/nginx/conf.d
      - ./nginx/logs:/var/log/nginx
      - ./nginx/ssl:/etc/nginx/ssl
    networks:
      - app-network
    depends_on:
      - app

  mysql:
    image: mysql:8.0
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/logs:/var/log/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d
    networks:
      - app-network
    command: >
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci

  redis:
    image: redis:alpine
    container_name: redis
    restart: always
    command: redis-server --requirepass ${REDIS_PASSWORD}
    ports:
      - "6379:6379"
    volumes:
      - ./redis/data:/data
    networks:
      - app-network

  app:
    image: ${APP_IMAGE}:${APP_VERSION}
    container_name: myapp
    restart: always
    environment:
      SPRING_PROFILES_ACTIVE: prod
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/${DB_NAME}
      SPRING_DATASOURCE_USERNAME: ${DB_USER}
      SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}
      SPRING_REDIS_HOST: redis
      SPRING_REDIS_PASSWORD: ${REDIS_PASSWORD}
      JAVA_OPTS: "-Xms512m -Xmx512m -XX:+UseG1GC"
    networks:
      - app-network
    depends_on:
      - mysql
      - redis
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

networks:
  app-network:
    driver: bridge

6.2 环境变量文件 .env

bash 复制代码
# 数据库配置
DB_ROOT_PASSWORD=Root@123456
DB_NAME=myapp
DB_USER=appuser
DB_PASSWORD=App@123456

# Redis 配置
REDIS_PASSWORD=Redis@123456

# 应用配置
APP_IMAGE=registry.cn-hangzhou.aliyuncs.com/myrepo/myapp
APP_VERSION=1.0.0

6.3 Compose 常用命令

bash 复制代码
# 启动所有服务(后台运行)
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f app

# 重启服务
docker-compose restart app

# 停止服务
docker-compose stop

# 停止并删除容器
docker-compose down

# 停止并删除容器和数据卷(慎用)
docker-compose down -v

# 重新构建并启动
docker-compose up -d --build

# 扩展服务实例数
docker-compose up -d --scale app=3

七、数据备份与恢复

7.1 MySQL 自动备份脚本

bash 复制代码
#!/bin/bash
# /www/docker/mysql/backup/backup.sh

BACKUP_DIR="/www/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="myapp"
RETENTION_DAYS=7

# 创建备份目录
mkdir -p $BACKUP_DIR

# 执行备份
docker exec mysql mysqldump -u root -p'YourPassword' \
  --single-transaction \
  --routines \
  --triggers \
  $DB_NAME > $BACKUP_DIR/${DB_NAME}_${DATE}.sql

# 压缩备份文件
gzip $BACKUP_DIR/${DB_NAME}_${DATE}.sql

# 删除过期备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: ${DB_NAME}_${DATE}.sql.gz"

7.2 添加定时任务

bash 复制代码
# 编辑 crontab
crontab -e

# 每天凌晨 2 点备份
0 2 * * * /www/docker/mysql/backup/backup.sh >> /var/log/mysql_backup.log 2>&1

7.3 数据恢复

bash 复制代码
# 解压备份文件
gunzip myapp_20240115_020000.sql.gz

# 恢复数据
docker exec -i mysql mysql -u root -p'YourPassword' myapp < myapp_20240115_020000.sql

八、监控与日志

8.1 部署 Portainer(Docker 可视化管理)

bash 复制代码
# 创建数据卷
docker volume create portainer_data

# 运行 Portainer
docker run -d \
  --name portainer \
  --restart always \
  -p 9000:9000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest

访问 http://服务器IP:9000 进行初始化设置。

8.2 日志收集方案

yaml 复制代码
# docker-compose.yml 添加日志服务
services:
  # ... 其他服务
  
  loki:
    image: grafana/loki:latest
    container_name: loki
    restart: always
    ports:
      - "3100:3100"
    volumes:
      - ./loki/config:/etc/loki
    command: -config.file=/etc/loki/loki-config.yaml
    networks:
      - app-network

  promtail:
    image: grafana/promtail:latest
    container_name: promtail
    restart: always
    volumes:
      - /var/log:/var/log:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - ./promtail/config:/etc/promtail
    command: -config.file=/etc/promtail/promtail-config.yaml
    networks:
      - app-network

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - app-network

九、常见问题

❌ 问题1:容器无法访问外部网络

解决

bash 复制代码
# 检查 Docker 网络
iptables -L -n -v

# 开启 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward

# 永久生效
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

❌ 问题2:MySQL 中文乱码

解决

bash 复制代码
# 进入容器修改配置
docker exec -it mysql bash

# 修改 my.cnf
echo '[mysqld]' >> /etc/mysql/my.cnf
echo 'character-set-server=utf8mb4' >> /etc/mysql/my.cnf
echo 'collation-server=utf8mb4_unicode_ci' >> /etc/mysql/my.cnf

docker restart mysql

❌ 问题3:容器时区不正确

解决

bash 复制代码
# 运行容器时挂载时区文件
docker run -d \
  -v /etc/localtime:/etc/localtime:ro \
  -v /etc/timezone:/etc/timezone:ro \
  ...

# 或在 Dockerfile 中设置
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

❌ 问题4:磁盘空间不足

bash 复制代码
# 清理未使用的镜像、容器、卷
docker system prune -a -f --volumes

# 查看占用空间
docker system df -v

十、总结

Docker + 宝塔部署方案对比:

方案 优点 缺点
宝塔原生 可视化操作,适合新手 灵活性差
Docker 单容器 简单快速 服务多时不便管理
Docker Compose 编排方便,配置清晰 需要学习 YAML
K8s 大规模集群管理 复杂度高

推荐方案:中小型项目使用 Docker Compose,配合宝塔的文件管理和计划任务功能,实现高效运维。


💬 觉得有用的话,点个赞+收藏,关注我,每周持续更新实战教程!

标签:docker | linux | 宝塔 | 运维 | 容器化 | 部署

相关推荐
克莱因3582 小时前
Linux 进程监控
linux·运维·服务器
Agent产品评测局2 小时前
企业 HR 自动化落地,入转调离全流程自动化实现方法:基于企业级智能体的技术路径与方案盘点
运维·人工智能·ai·chatgpt·自动化
建军啊2 小时前
k8s云安全、devsecops等知识
云原生·容器·kubernetes
牛奶咖啡132 小时前
DevOps自动化运维实践_自动化运维工具Ansible
运维·自动化·ansible·devops·ansible的安装·ansible的架构与运行原理·ansible的主机和组配置
我爱学习好爱好爱2 小时前
Ansible Playbook介绍 playbook的编写要求 playbook多任务案例
linux·运维·ansible
我爱学习好爱好爱2 小时前
Ansible 常用模块详解:firewalld、setup实战
linux·运维·ansible
我科绝伦(Huanhuan Zhou)2 小时前
MySQL数据库备份管理系统新增备份任务巡检功能
运维·数据库·mysql
❀͜͡傀儡师2 小时前
使用 Docker CLI 部署 Tugtainer 容器镜像自动更新系统
docker·容器·tugtainer
奇树谦2 小时前
Ubuntu 24 常用截图工具一键安装脚本+自定义快捷键配置指南
linux·运维·ubuntu