---
# System prepended metadata

title: ownCloud + Cloudflare Tunnel 部署指南 (with docker)
tags: [Docker, Cloudflare, ownCloud]

---

# ownCloud + Cloudflare Tunnel 部署指南（with docker）

一份涵蓋**性能優化**、**安全配置**與**極簡維護**的完整手冊。

---

## 🧭 目錄

- [核心架構](#-核心架構)
- [部署步驟](#-部署步驟)
  - [第 1 步：準備項目文件結構](#-第-1-步準備項目文件結構)
  - [第 2 步：配置-env-文件](#-第-2-步配置-env-文件)
  - [第 3 步：撰寫-docker-composeyml](#-第-3-步撰寫-docker-composeyml)
  - [第 4 步：Cloudflare-設定](#-第-4-步cloudflare-設定)
  - [第 5 步：啟動與驗證](#-第-5-步啟動與驗證)
- [總結](#-總結)
- [📚 附錄 A: 版本升級指南 (極簡流程)](#-附錄-a-版本升級指南-極簡流程)
- [🛠️ 附錄 B: 進階性能調優](#-附錄-b-進階性能調優)

---

## 🏛️ 核心架構

- **⚙️ 配置外部化**: 使用 `.env` 文件集中管理**所有**可變參數，包括版本號。
- **↔️ 雙重訪問路徑**: 支持安全的 **公網訪問** 與快速的 **本地訪問**。
- **⚡️ 全棧性能優化**: 整合 Redis、優化的 PHP OPcache 及調優的 MariaDB。
- **🛡️ 網路安全與加速**: 依賴 Cloudflare Tunnel 和其 CDN 功能。

---

## 🚀 部署步驟

### 📦 第 1 步：準備項目文件結構

確保您的項目目錄包含以下所有文件。

```bash
/owncloud-project/
|-- .env                # 環境配置
|-- docker-compose.yml  # 主設定檔
|-- opcache.ini         # PHP OPcache 設定檔
|-- custom.cnf          # MariaDB 設定檔
```

### ✍️ 第 2 步：配置 `.env` ，`opcache.ini`， `custom.cnf`文件

`nano .env` ，根據註解填寫所有變數。**所有你需要手動修改的配置都在這裡**。

```dotenv
# --- Version Settings ---
# 指定要使用的 ownCloud 版本。推薦使用具體版本號以保證穩定性。
OWNCLOUD_VERSION=10.14.0

# --- Domain Settings ---
OWNCLOUD_DOMAIN=owncloud.your-domain.com
OWNCLOUD_TRUSTED_DOMAINS=localhost

# --- ownCloud Admin User ---
OWNCLOUD_ADMIN_USERNAME=admin
OWNCLOUD_ADMIN_PASSWORD=your_strong_admin_password

# --- Database Credentials ---
MYSQL_ROOT_PASSWORD=your_strong_root_password
OWNCLOUD_DB_PASSWORD=your_strong_db_password

# --- Cloudflare Tunnel Token ---
CLOUDFLARE_TUNNEL_TOKEN=

# --- External Port Mapping ---
OWNCLOUD_HTTP_PORT=8080
```
`nano opcache.ini` ，根據註解填寫所有變數。**所有你需要手動修改的配置都在這裡**。
```

; PHP OPcache settings for ownCloud performance
; https://doc.owncloud.com/server/admin_manual/installation/server_tuning.html#enable-php-opcache

; 啟用 OPcache
opcache.enable=1

; 啟用命令行環境的 OPcache (可選，但建議)
opcache.enable_cli=1

; 分配給 OPcache 的內存大小 (單位 MB)，可根據伺服器內存調整
; 128MB 對於大多數中小型 ownCloud 實例是個不錯的起點
opcache.memory_consumption=128

; 用於存儲 "interned" 字串的內存大小 (單位 MB)
; interned strings 是 PHP 引擎的一種優化，可以減少內存使用
opcache.interned_strings_buffer=16

; OPcache 可以緩存的最大文件數量
opcache.max_accelerated_files=10000

; 檢查文件時間戳的頻率 (秒)。設為 1 表示每秒檢查一次文件是否有變更。
; 在生產環境中，如果代碼不經常變動，可以設為更高的值 (如 60) 來減少 I/O。
opcache.revalidate_freq=1

; 如果啟用，OPcache 會在 revalidate_freq 過期後異步檢查文件更新，可以提升性能。
opcache.validate_timestamps=1

; 保存註釋可以讓一些依賴註釋的應用(如 Annotation)正常工作，ownCloud 建議開啟。
opcache.save_comments=1

```
`nano custom.cnf` ，根據註解填寫所有變數。**所有你需要手動修改的配置都在這裡**。
```

# Custom MariaDB/MySQL configuration for ownCloud performance

[mysqld]

# --- InnoDB Settings ---
# InnoDB buffer pool size. This is the most important setting for InnoDB performance.
# It should be set to 50-70% of your system's available RAM if the server is dedicated to the database.
# Since we are running multiple containers, we'll start with a more conservative value like 512M or 1G.
# **IMPORTANT**: Adjust this value based on your server's total RAM.
# Example for a server with 4GB RAM: 1G
# Example for a server with 2GB RAM: 512M
innodb_buffer_pool_size = 512M

# InnoDB log file size. Larger log files can improve performance but increase recovery time after a crash.
innodb_log_file_size = 128M

# Helps with I/O performance for certain types of SSDs/storage.
innodb_flush_log_at_trx_commit = 2

# --- Query Cache (for older MariaDB versions) ---
# The query cache is deprecated in modern MySQL/MariaDB versions and often disabled by default.
# These settings are here for reference but may not have an effect on recent images.
# query_cache_type = 1
# query_cache_size = 32M

# --- Other settings ---
# Allow larger packets, which can be useful for large file uploads or other operations.
max_allowed_packet = 128M
```
> 各項說明可到 **附錄 B** 下查看

### 📄 第 3 步：撰寫 `docker-compose.yml`

`docker-compose.yml` 文件現在是一個**通用**的模板，它引用 `.env` 文件中定義的所有變數。在正常情況下，你**不再需要修改此文件**。

```yaml
version: '3.8'

services:
  owncloud:
    image: owncloud/server:${OWNCLOUD_VERSION}
    container_name: owncloud_server
    restart: always
    ports:
      - ${OWNCLOUD_HTTP_PORT}:8080
    depends_on:
      - mariadb
      - redis
    environment:
      - OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
      - OWNCLOUD_TRUSTED_DOMAINS=${OWNCLOUD_TRUSTED_DOMAINS}
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=owncloud
      - OWNCLOUD_DB_USERNAME=owncloud
      - OWNCLOUD_DB_PASSWORD=${OWNCLOUD_DB_PASSWORD}
      - OWNCLOUD_DB_HOST=mariadb
      - OWNCLOUD_ADMIN_USERNAME=${OWNCLOUD_ADMIN_USERNAME}
      - OWNCLOUD_ADMIN_PASSWORD=${OWNCLOUD_ADMIN_PASSWORD}
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=redis
      - OWNCLOUD_REDIS_PORT=6379
    volumes:
      - owncloud_files:/mnt/data
      - ./opcache.ini:/usr/local/etc/php/conf.d/opcache.ini
    networks:
      - owncloud-net

  mariadb:
    image: mariadb:10.11
    container_name: owncloud_db
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=owncloud
      - MYSQL_USER=owncloud
      - MYSQL_PASSWORD=${OWNCLOUD_DB_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
      - ./custom.cnf:/etc/mysql/conf.d/custom.cnf
    networks:
      - owncloud-net

  redis:
    image: redis:6.2-alpine
    container_name: owncloud_redis
    restart: always
    networks:
      - owncloud-net

  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: owncloud_tunnel
    restart: always
    depends_on:
      - owncloud
    command: tunnel --no-autoupdate --protocol http2 run --token ${CLOUDFLARE_TUNNEL_TOKEN}
    networks:
      - owncloud-net

volumes:
  owncloud_files:
  db_data:

networks:
  owncloud-net:
    driver: bridge
```

### ☁️ 第 4 步：Cloudflare 設定

1.  **建立 Tunnel**: 在 Cloudflare Zero Trust 儀表板中建立 Tunnel，獲取 Token 並填入 `.env` 文件中的 `CLOUDFLARE_TUNNEL_TOKEN`。
2.  **設定 Public Hostname**: 將你的域名 (例如 `owncloud.your-domain.com`) 指向服務 `http://owncloud:8080`。
3.  **網站性能優化**: 
    -   進入 `Caching` -> `Configuration`，設定 `Caching Level` 為 `Standard`。
    -   進入 `Speed` -> `Optimization`，開啟 `JavaScript`、`CSS`、`HTML` 的 `Auto Minify` 和 `Brotli` 壓縮。

### ✅ 第 5 步：啟動與驗證

1.  在 `owncloud-project` 目錄下，確認你已根據 `.env.example` 創建並填寫好 `.env` 文件。
2.  執行 `docker compose up -d` 啟動所有服務。
3.  **驗證訪問**: 
    -   **🌍 公網訪問**: 打開瀏覽器，訪問 `https://${OWNCLOUD_DOMAIN}`。您應該能看到登入頁面。
    -   **🏠 本地訪問**: 在運行 Docker 的伺服器上，打開瀏覽器，訪問 `http://localhost:${OWNCLOUD_HTTP_PORT}` (例如 `http://localhost:8080`)。你也應該能看到登入頁面。

---

## 🎉 總結

通過將**包括版本號在內的所有配置**都提取到 `.env` 文件中，我們實現了最理想的部署方案：`docker-compose.yml` 作為一個穩定的、不需改動的模板，而所有客製化設定都在 `.env` 中完成，極大地簡化了未來的管理和維護工作。

---
---

## 📚 附錄 A: 版本升級指南 (極簡流程)

> **🚨 極度重要: 在開始任何操作之前，請務必完整備份！**

### 步驟 1: 完整備份 (關鍵第一步)

我們需要備份三個部分：**資料庫**、**用戶文件**和**設定檔**。

1.  **備份設定檔**:
    將你的整個 `owncloud-project` 目錄複製一份。這份拷貝就包含了您所有的設定檔。

2.  **備份資料庫**:
    在 `owncloud-project` 目錄中，執行以下指令將資料庫導出為 `.sql` 文件。

    ```bash
    docker compose exec -T mariadb mysqldump -u root -p"${MYSQL_ROOT_PASSWORD}" --all-databases > owncloud-db-backup.sql
    ```

3.  **備份用戶文件**:
    執行以下指令將用戶文件的 volume 打包成 `.tar.gz` 壓縮檔。

    ```bash
    docker compose exec -T owncloud tar -czvf - /mnt/data > owncloud-data-backup.tar.gz
    ```

### 步驟 2: 啟用維護模式

為了在升級過程中阻止用戶訪問，需要讓 ownCloud 進入維護模式。

```bash
docker compose exec -u www-data owncloud occ maintenance:mode --on
```

### 步驟 3: 修改 `.env` 文件

這是新的、簡化後的升級核心步驟。

1.  打開你的 `.env` 文件。
2.  找到 `OWNCLOUD_VERSION` 變數。
3.  將其修改為您想升級到的新版本號。

    **修改前:**
    ```dotenv
    OWNCLOUD_VERSION=10.13.0
    ```

    **修改後:**
    ```dotenv
    OWNCLOUD_VERSION=10.14.0
    ```

### 步驟 4: 拉取新映像並執行升級

1.  **拉取新版本映像**:
    ```bash
    docker compose pull owncloud
    ```

2.  **啟動新容器並自動升級**:
    ```bash
    docker compose up -d
    ```

3.  **監控升級過程** (可選但建議):
    ```bash
    docker compose logs -f owncloud
    ```
    看到 `Update successful` 日誌表示後台升級已完成。

### 步驟 5: 關閉維護模式並驗證

1.  **關閉維護模式**:
    ```bash
    docker compose exec -u www-data owncloud occ maintenance:mode --off
    ```

2.  **驗證**: 登入您的 ownCloud，檢查功能和版本號是否正常。

### 步驟 6: 如果升級失敗怎麼辦？

這就是備份的用武之地。你可以通過回滾 `.env` 文件中的 `OWNCLOUD_VERSION`，並從備份文件中恢復資料庫和用戶文件來還原到升級前的狀態。

1.  將 `.env` 中的 `OWNCLOUD_VERSION` 改回**舊的版本號**。
2.  徹底關閉並刪除所有容器和 volume（**警告：此操作會刪除現有數據**）：
    ```bash
    docker compose down -v
    ```
3.  從備份中恢復數據（此處為示例，具體指令可能需要調整）：
    ```bash
    # 恢復資料庫
    cat owncloud-db-backup.sql | docker compose exec -T mariadb mysql -u root -p"${MYSQL_ROOT_PASSWORD}"

    # 恢復用戶文件
    cat owncloud-data-backup.tar.gz | docker compose exec -T owncloud tar -C / -xzvf -
    ```
4.  重新啟動服務：
    ```bash
    docker compose up -d
    ```

---
---

## 🛠️ 附錄 B: 進階性能調優

本節專為希望根據自己的伺服器硬體，進一步壓榨 ownCloud 性能的進階用戶準備。我們將深入探討 `opcache.ini` 和 `custom.cnf` 的配置。

> **⚠️ 警告**
> 修改這些設定可能會影響系統的穩定性。建議一次只修改一個參數，並在修改後監控應用程式日誌和伺服器資源使用情況。

### 💨 PHP OPcache 調優 (`opcache.ini`)

OPcache 通過將預編譯的 PHP 腳本存儲在共享內存中來加速應用。以下是關鍵參數的調優建議：

-   `opcache.memory_consumption`
    -   **作用**: 分配給 OPcache 使用的內存大小 (MB)。內存越大，能緩存的 PHP 腳本就越多。
    -   **調優建議**: `128` (MB) 是一個很好的起點。如果您的伺服器內存充裕（例如 >= 8GB），可以嘗試增加到 `256` 或 `512`。如果內存耗盡，OPcache 會清空並重建緩存，反而降低性能。

-   `opcache.interned_strings_buffer`
    -   **作用**: 用於存儲 PHP "interned strings" 的內存大小 (MB)，這是一種字符串優化，可以減少重複字符串的內存佔用。
    -   **調優建議**: `16` (MB) 對於絕大多數 ownCloud 實例都已足夠。只有在超大型部署中才可能需要增加到 `32`。

-   `opcache.max_accelerated_files`
    -   **作用**: OPcache 能緩存的最大 PHP 文件數量。
    -   **調優建議**: `10000` 是一個非常慷慨的數值，通常無需修改。如果您的緩存命中率低，且確認是因為文件過多，可以適當增加此值。

-   `opcache.revalidate_freq`
    -   **作用**: OPcache 檢查 PHP 文件是否有更新的時間間隔（秒）。
    -   **調優建議**: `1` 適合開發環境，因為您需要立即看到代碼變更。在一個穩定的**生產環境**中，代碼不經常變動，將此值設為 `60` 或更高可以減少不必要的磁碟 I/O，帶來微小的性能提升。

### 🗃️ MariaDB 資料庫調優 (`custom.cnf`)

資料庫是 ownCloud 的性能核心。合理的配置能極大地提升響應速度。

-   `innodb_buffer_pool_size`
    -   **作用**: **這是最重要的資料庫性能參數**。它決定了 InnoDB 存儲引擎能用多少內存來緩存數據和索引。緩存池越大，從磁碟讀取數據的次數就越少，查詢速度就越快。
    -   **調優建議**: 這個值需要根據您伺服器的**總內存**以及**其他服務的內存使用情況**來權衡設定。以下是一些經驗法則：
        -   伺服器總內存 2GB: 建議值 `256M` - `512M`
        -   伺服器總內存 4GB: 建議值 `1G`
        -   伺服器總內存 8GB: 建議值 `2G` - `4G`
        -   伺服器總內存 16GB: 建議值 `4G` - `8G`
    -   **注意**: 不要將所有內存都分配給資料庫！您需要為操作系統、ownCloud 容器、Redis 容器以及其他可能的服務預留足夠的內存。

-   `innodb_log_file_size`
    -   **作用**: InnoDB 重做日誌（redo log）的大小。較大的日誌文件可以提升寫入密集型操作的性能，但會增加崩潰後恢復的時間。
    -   **調優建議**: `128M` 對於中小型 ownCloud 實例是一個相當均衡的設定，通常無需修改。

-   `max_allowed_packet`
    -   **作用**: 限制單個 SQL 查詢或數據包的大小。
    -   **調優建議**: `128M` 是一個安全值，可以防止因處理大型文件元數據或日誌時出現的 "Packet for query is too large" 錯誤，通常無需修改。
