跳轉至

Nextcloud

概述

Nextcloud 係一個私有雲文件同步同協作平台,喺呢個基礎設施入面用 Docker 部署,主要負責 KardPilot 項目嘅文件管理、共享同備份。呢個實例支援 WebDAV、Federated Sharing、Office 文件預覽等核心功能,資料儲存層行 OCI Object Storage,metadata 行 PostgreSQL,cache 同 locking 就用 Redis。由於所有對外流量都經 Cloudflare Tunnel 入嚟,用戶只需要用 https://next.benhoweb.com 就可以安全存取。

架構

服務由兩個 container 組成:

  • nextcloud-app(固定 IP 172.21.0.19):行 PHP-FPM + Apache,處理所有 HTTP 請求,對外透過 Cloudflare Tunnel 連到 next.benhoweb.com
  • nextcloud-cron(固定 IP 172.21.0.47):用 /cron.sh 定時執行 background jobs,例如檔案掃描、Expired share 清理、通知等。

兩個 container 都掛載同一組 volumes:

  • nextcloud_html:程式主目錄
  • nextcloud_apps:自訂 app
  • nextcloud_config:config.php 存放位置
  • nextcloud_data:本地 data 目錄(用戶實際檔案其實放喺 Object Storage)

外部依賴包括:

  • PostgreSQLpg-main 主機,資料庫名 nextcloud,用戶 nextcloud_user
  • Redisredis-main,port 6379,用嚟做 distributed cache 同 file locking
  • OCI Object Storage:bucket Next,region eu-frankfurt-1,endpoint 係 Oracle 提供嘅 S3 compatible host
  • Cloudflare Tunnel:將 next.benhoweb.com 反向代理到 172.21.0.19:80
  • Infisical:集中管理 .env 入面嘅 secrets,例如 PostgreSQL 密碼、S3 credentials

網絡用 cf_network,呢個係 external network,IPAM 範圍係 172.21.0.0/16,等所有服務可以互相通訊。

部署(Docker Compose 片段)

實際部署使用以下 docker-compose.yml(敏感值統一由 Infisical 注入 .env):

services:
  nextcloud-app:
    image: nextcloud:latest
    container_name: nextcloud-app
    restart: unless-stopped
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_apps:/var/www/html/custom_apps
      - nextcloud_config:/var/www/html/config
      - nextcloud_data:/var/www/html/data
    environment:
      TZ: Asia/Hong_Kong
      POSTGRES_HOST: pg-main
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud_user
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      REDIS_HOST: redis-main
      REDIS_HOST_PORT: "6379"
      REDIS_HOST_PASSWORD: ${REDIS_HOST_PASSWORD}
      NEXTCLOUD_TRUSTED_DOMAINS: next.benhoweb.com nextcloud-app
      TRUSTED_PROXIES: 172.18.0.0/16
      OVERWRITEPROTOCOL: https
      OVERWRITECLIURL: https://next.benhoweb.com
      OBJECTSTORE_S3_BUCKET: Next
      OBJECTSTORE_S3_KEY: ${OBJECTSTORE_S3_KEY}
      OBJECTSTORE_S3_SECRET: ${OBJECTSTORE_S3_SECRET}
      OBJECTSTORE_S3_HOST: frwssraro9nb.compat.objectstorage.eu-frankfurt-1.oraclecloud.com
      OBJECTSTORE_S3_REGION: eu-frankfurt-1
      OBJECTSTORE_S3_PORT: "443"
      OBJECTSTORE_S3_SSL: "true"
      OBJECTSTORE_S3_USEPATH_STYLE: "true"
      OBJECTSTORE_S3_AUTOCREATE: "true"
    networks:
      cf_network:
        ipv4_address: 172.21.0.19

  nextcloud-cron:
    environment:
      - TZ=Asia/Hong_Kong
    image: nextcloud:latest
    container_name: nextcloud-cron
    restart: unless-stopped
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_apps:/var/www/html/custom_apps
      - nextcloud_config:/var/www/html/config
      - nextcloud_data:/var/www/html/data
    entrypoint: /cron.sh
    networks:
      cf_network:
        ipv4_address: 172.21.0.47

volumes:
  nextcloud_html:
  nextcloud_apps:
  nextcloud_config:
  nextcloud_data:

networks:
  cf_network:
    external: true

配置與環境變數

部署入面用到幾組關鍵環境變數:

  • POSTGRES_*:指向 pg-main,PostgreSQL 密碼由 .env 讀入,唔好 hardcode。
  • REDIS_*:用嚟連接 redis-main,如果 Redis 有密碼,必須要正確填入。
  • NEXTCLOUD_TRUSTED_DOMAINS:一定要包含公開域名 next.benhoweb.com 同內部 container name nextcloud-app,否則會出現 Access through untrusted domain。
  • TRUSTED_PROXIES:設定 172.18.0.0/16,令 Nextcloud 信任 Cloudflare Tunnel 或者 reverse proxy 傳過嚟嘅 X-Forwarded-For
  • OVERWRITEPROTOCOL: https:強制所有生成 URL 用 HTTPS,避免喺 Tunnel 後面出現 HTTP redirect。
  • OBJECTSTORE_S3_*:OCI Object Storage 用 S3 compatible API,USEPATH_STYLE 一定要係 true,因為 Oracle 原生支援 path-style access;AUTOCREATE 可以自動建立 bucket(如果未存在)。

注意 nextcloud_data volume 理論上只用嚟存放 appdata_* 同本地暫存,實際用戶檔案已經放上 S3,所以容量唔會因為檔案多而爆。

維運與監控

日常維運主要靠 docker composeocc 命令:

# 睇 service 狀態
docker compose ps

# 睇 Nextcloud log
docker compose logs -f nextcloud-app

# 執行 occ 命令(要用 www-data 身份)
docker compose exec -u www-data nextcloud-app php occ status
docker compose exec -u www-data nextcloud-app php occ files:scan --all
docker compose exec -u www-data nextcloud-app php occ maintenance:mode --off

監控方面:

  • 確認 nextcloud-cron 有行,正常情況下佢每 5 分鐘喚醒一次,可以睇 log 有冇異常。
  • docker compose exec nextcloud-app php occ db:status 檢查 database 狀態。
  • 檢查 Redis 連線:docker compose exec nextcloud-app redis-cli -h redis-main ping 如果有設定密碼要加 -a $REDIS_HOST_PASSWORD
  • 測試 PostgreSQL 連線:docker compose exec nextcloud-app pg_isready -h pg-main -U nextcloud_user(可能需要安裝 postgresql-client)。

建議定期做以下嘢:

  • 備份 nextcloud_config volume 同 PostgreSQL database(用 pg_dump),因為 Object Storage 入面嘅檔案雖然安全,但 metadata 冇咗就乜都搵唔返。
  • 監察 S3 bucket 容量同 API 錯誤,尤其注意 throttle。
  • 更新 image 前先做 snapshot,並用 occ upgrade 升級。

常見問題

  • Access through untrusted domain:檢查 NEXTCLOUD_TRUSTED_DOMAINS 有冇包括 next.benhoweb.com,改完要 restart nextcloud-app
  • 502 Bad Gateway(經 Cloudflare Tunnel):多數係 Tunnel 指向 172.21.0.19:80 嘅連接唔通,先確認 container 係咪行緊,再睇 nextcloud-app log。如果係 proxy header 問題,檢查 TRUSTED_PROXIESOVERWRITEPROTOCOL
  • S3 Object Storage 上傳失敗:先手動用環境變數入面嘅 key/secret 試下連接 endpoint,確認 OBJECTSTORE_S3_USEPATH_STYLE: "true",並睇 nextcloud-app log 內有冇 S3 相關 error。
  • Background jobs 唔行:確認 nextcloud-cron container 仲行緊,如果佢唔小心停咗,可以用 docker compose restart nextcloud-cron。另外可以手動執行 php occ background-job:execute 測試。
  • Redis locking 問題:如果 redis-main 重啟過而 password 冇變,Nextcloud 通常會自己重連;但若出現 "Locked" 錯誤,可以試下清 Redis cache:docker compose exec redis-main redis-cli FLUSHDB(要小心,呢個會清所有 DB)。

相關鏈接

docker postgres redis cloudflare-tunnel infisical OCI Object Storage KardPilot