强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Nextcloud 私有云部署教程 / 13 - Docker 部署

13 - Docker 部署

使用 Docker 和 Docker Compose 部署 Nextcloud,涵盖 AIO (All-in-One) 模式、自定义编排、反向代理与数据持久化。


13.1 Docker 部署方案对比

方案 说明 适用场景
AIO (All-in-One) 官方一站式容器,包含所有组件 快速部署、个人使用
Docker Compose 自定义 手动编排各组件容器 需要精细控制、生产环境
Docker + 外部数据库 仅容器化 Nextcloud,数据库外置 已有数据库基础设施

13.2 Nextcloud AIO 部署

AIO 是官方推荐的最简部署方式,一个命令启动所有组件。

AIO 包含的组件

组件 说明
Nextcloud 主应用
PostgreSQL 数据库
Redis 缓存
Collabora 在线 Office
ClamAV 病毒扫描
Fulltextsearch 全文搜索
Talk 视频通话 TURN 服务器
Imaginary 图片处理
Backup 自动备份

AIO 部署命令

# 创建数据目录
mkdir -p /data/nextcloud-aio

# 启动 AIO 主容器
docker run -d \
  --name nextcloud-aio-mastercontainer \
  --restart always \
  -p 80:80 \
  -p 8080:8080 \
  -p 8443:8443 \
  -v nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -e APACHE_PORT=443 \
  -e APACHE_IP_BINDING=0.0.0.0 \
  -e NEXTCLOUD_DATADIR=/data/nextcloud-aio \
  nextcloud/all-in-one:latest

AIO 初始设置

1. 浏览器访问: https://your-server-ip:8080
2. 获取初始密码(查看容器日志):
   docker logs nextcloud-aio-mastercontainer
3. 输入初始密码登录
4. 选择域名配置方式
5. 勾选需要的可选组件
6. 点击 "Start containers"

AIO 环境变量

变量 说明 默认值
APACHE_PORT Apache 端口 443
APACHE_IP_BINDING 绑定 IP 0.0.0.0
NEXTCLOUD_DATADIR 数据目录 内部卷
NEXTCLOUD_MEMORY_LIMIT 内存限制 512M
COLLABORA_ENABLED 启用 Collabora false
CLAMAV_ENABLED 启用 ClamAV false
FULLTEXTSEARCH_ENABLED 启用全文搜索 false
TALK_ENABLED 启用 Talk TURN false

13.3 Docker Compose 自定义部署

完整 docker-compose.yml

# docker-compose.yml
version: '3.8'

services:
  # ======== Nextcloud 主应用 ========
  nextcloud:
    image: nextcloud:29-apache
    container_name: nextcloud
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=ncuser
      - StrongPassword123!
      - REDIS_HOST=redis
      - NEXTCLOUD_ADMIN_USER=admin
      - NEXTCLOUD_ADMIN_PASSWORD=AdminPassword123!
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.example.com
      - OVERWRITEPROTOCOL=https
      - OVERWRITECLIURL=https://cloud.example.com
      - PHP_MEMORY_LIMIT=512M
      - PHP_UPLOAD_LIMIT=16G
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - nextcloud-net

  # ======== PostgreSQL 数据库 ========
  db:
    image: postgres:16-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    environment:
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=ncuser
      - POSTGRES_PASSWORD=StrongPassword123!
    volumes:
      - nextcloud_db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ncuser -d nextcloud"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - nextcloud-net

  # ======== Redis 缓存 ========
  redis:
    image: redis:7-alpine
    container_name: nextcloud-redis
    restart: unless-stopped
    command: redis-server --requirepass RedisPassword123!
    volumes:
      - nextcloud_redis:/data
    networks:
      - nextcloud-net

  # ======== Cron 定时任务 ========
  cron:
    image: nextcloud:29-apache
    container_name: nextcloud-cron
    restart: unless-stopped
    user: www-data
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    entrypoint: /cron.sh
    depends_on:
      - nextcloud
    networks:
      - nextcloud-net

volumes:
  nextcloud_html:
  nextcloud_data:
  nextcloud_db:
  nextcloud_redis:

networks:
  nextcloud-net:
    driver: bridge

启动与管理

# 启动所有服务
docker compose up -d

# 查看日志
docker compose logs -f nextcloud

# 停止服务
docker compose down

# 停止并删除数据(危险!)
docker compose down -v

# 更新镜像
docker compose pull
docker compose up -d

运行 occ 命令

# 执行 occ 命令
docker exec -u www-data nextcloud php occ status

# 安装应用
docker exec -u www-data nextcloud php occ app:install talk

# 查看配置
docker exec -u www-data nextcloud php occ config:list system

13.4 Nginx 反向代理配置

# /etc/nginx/sites-available/nextcloud

upstream nextcloud {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name cloud.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name cloud.example.com;

    # SSL 证书
    ssl_certificate     /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;

    # 安全头
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "no-referrer" always;

    # 上传大小
    client_max_body_size 16G;
    client_body_timeout 300s;

    # 代理配置
    location / {
        proxy_pass http://nextcloud;
        proxy_http_version 1.1;
        proxy_set_header Host $http_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_set_header X-Forwarded-Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        proxy_request_buffering off;
    }

    # WebSocket 支持(Talk)
    location /ocs/v2.php/apps/spreed/ {
        proxy_pass http://nextcloud;
        proxy_http_version 1.1;
        proxy_set_header Host $http_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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;
    }
}

启用并重启 Nginx:

sudo ln -sf /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

13.5 Docker 网络与安全

网络隔离

# docker-compose.yml
services:
  nextcloud:
    networks:
      - frontend     # 可访问外部
      - backend      # 仅内部通信

  db:
    networks:
      - backend      # 不暴露到外部

  redis:
    networks:
      - backend      # 不暴露到外部

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true   # 禁止外部访问

容器安全配置

services:
  nextcloud:
    security_opt:
      - no-new-privileges:true
    read_only: false
    tmpfs:
      - /tmp
      - /var/run

13.6 数据持久化

卷类型对比

类型 说明 持久性 性能
Named Volume Docker 管理的卷
Bind Mount 挂载宿主机目录 最好
tmpfs 内存文件系统 最快

推荐的卷配置

services:
  nextcloud:
    volumes:
      # Nextcloud 应用文件(Named Volume)
      - nextcloud_html:/var/www/html

      # 用户数据(Bind Mount,便于备份)
      - /data/nextcloud-data:/var/www/html/data

      # 自定义配置(Bind Mount,便于编辑)
      - ./config/custom.config.php:/var/www/html/config/custom.config.php:ro

  db:
    volumes:
      # 数据库数据(Bind Mount,便于备份)
      - /data/nextcloud-db:/var/lib/postgresql/data

  redis:
    volumes:
      - nextcloud_redis:/data

volumes:
  nextcloud_html:
  nextcloud_redis:

备份 Docker 卷

# 备份 Named Volume
docker run --rm \
  -v nextcloud_html:/source:ro \
  -v /backup:/backup \
  alpine tar czf /backup/nextcloud_html_$(date +%Y%m%d).tar.gz -C /source .

# 恢复
docker run --rm \
  -v nextcloud_html:/target \
  -v /backup:/backup:ro \
  alpine sh -c "rm -rf /target/* && tar xzf /backup/nextcloud_html_20260510.tar.gz -C /target"

13.7 SSL/TLS 配置

使用 Let’s Encrypt (Certbot)

# 安装 Certbot
sudo apt install -y certbot python3-certbot-nginx

# 获取证书
sudo certbot --nginx -d cloud.example.com

# 自动续期测试
sudo certbot renew --dry-run

使用 Traefik 自动 SSL

# docker-compose.yml (with Traefik)
services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik_certs:/letsencrypt

  nextcloud:
    image: nextcloud:29-apache
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.rule=Host(`cloud.example.com`)"
      - "traefik.http.routers.nextcloud.entrypoints=websecure"
      - "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt"
      - "traefik.http.services.nextcloud.loadbalancer.server.port=80"
    # ...

13.8 Docker 环境变量参考

环境变量 说明 默认值
POSTGRES_HOST 数据库主机 db
POSTGRES_DB 数据库名 nextcloud
POSTGRES_USER 数据库用户 nextcloud
POSTGRES_PASSWORD 数据库密码
MYSQL_HOST MySQL 主机 db
MYSQL_DATABASE MySQL 数据库名 nextcloud
MYSQL_USER MySQL 用户 nextcloud
MYSQL_PASSWORD MySQL 密码
REDIS_HOST Redis 主机 redis
NEXTCLOUD_ADMIN_USER 管理员用户名 admin
NEXTCLOUD_ADMIN_PASSWORD 管理员密码
NEXTCLOUD_TRUSTED_DOMAINS 可信域名
OVERWRITEPROTOCOL 强制协议
OVERWRITECLIURL CLI URL
PHP_MEMORY_LIMIT PHP 内存限制 512M
PHP_UPLOAD_LIMIT 上传大小限制 16G
SMTP_HOST SMTP 主机
SMTP_SECURE SMTP 加密方式 tls
SMTP_PORT SMTP 端口 587
SMTP_NAME SMTP 用户名
SMTP_PASSWORD SMTP 密码
MAIL_FROM_ADDRESS 发件人地址 nextcloud
MAIL_DOMAIN 发件人域名

13.9 Docker 更新策略

更新流程

# 1. 备份数据
docker exec -u www-data nextcloud php occ maintenance:mode --on
docker exec nextcloud-db pg_dump -U ncuser nextcloud | gzip > /backup/db-$(date +%Y%m%d).sql.gz

# 2. 拉取新镜像
docker compose pull

# 3. 停止旧容器(保留数据卷)
docker compose down

# 4. 启动新容器
docker compose up -d

# 5. 运行升级
docker exec -u www-data nextcloud php occ upgrade
docker exec -u www-data nextcloud php occ maintenance:mode --off

# 6. 验证
docker exec -u www-data nextcloud php occ status

自动更新脚本

#!/bin/bash
# nextcloud-docker-update.sh

set -euo pipefail

COMPOSE_DIR="/opt/nextcloud"
BACKUP_DIR="/backup/nextcloud"

echo "=== Nextcloud Docker Update ==="

# 备份
echo "1. Backing up..."
cd "$COMPOSE_DIR"
docker exec -u www-data nextcloud php occ maintenance:mode --on
docker compose exec -T db pg_dump -U ncuser nextcloud | gzip > "$BACKUP_DIR/db-$(date +%Y%m%d).sql.gz"

# 更新
echo "2. Pulling new images..."
docker compose pull

echo "3. Restarting containers..."
docker compose down
docker compose up -d

echo "4. Running upgrade..."
sleep 10
docker exec -u www-data nextcloud php occ upgrade
docker exec -u www-data nextcloud php occ maintenance:mode --off

echo "5. Verification..."
docker exec -u www-data nextcloud php occ status

echo "=== Update Complete ==="

13.10 注意事项

  1. 数据卷: 用户数据务必使用 Bind Mount 挂载到宿主机,不要依赖 Named Volume
  2. 备份: 更新前必须备份数据库和数据目录
  3. 网络隔离: 数据库和 Redis 不应暴露到外部网络
  4. 日志管理: 配置日志驱动和日志轮转,防止日志占满磁盘
  5. 资源限制: 为每个容器设置 CPU 和内存限制
  6. 健康检查: 为所有服务配置 healthcheck
services:
  nextcloud:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

13.11 扩展阅读


上一章: 12 - 备份恢复 下一章: 14 - 故障排查 — 常见问题诊断与解决方案。