{"id":168167,"date":"2026-05-28T02:03:54","date_gmt":"2026-05-27T23:03:54","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=168167"},"modified":"2026-05-28T02:03:54","modified_gmt":"2026-05-27T23:03:54","slug":"install-cloudreve-ubuntu-debian-docker-compose","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/install-cloudreve-ubuntu-debian-docker-compose\/","title":{"rendered":"Install Cloudreve v4 with Docker Compose on Ubuntu and Debian"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/cloudreve.org\/\" rel=\"noopener\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudreve<\/a> is an open source, self-hosted file management platform written in Go and React. Version 4 ships PostgreSQL support, ten storage backends (Local, S3, MinIO, Cloudflare R2, Backblaze B2, GCS, OneDrive, Aliyun OSS, Tencent COS, and Remote slave nodes), WebDAV, OnlyOffice and Collabora co-editing through WOPI, Aria2 and qBittorrent remote downloads, full text search via Apache Tika plus Meilisearch, and a clean React UI that runs comfortably on a 2 vCPU, 4 GB RAM machine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide installs the latest Cloudreve v4 release using the upstream Docker Compose stack (Cloudreve plus PostgreSQL 17 plus Redis) on Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, and Debian 13 (trixie). The same commands work on all three because Docker abstracts away the distro. The production notes at the end cover the start order race you will hit if you copy the upstream compose file as is.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Cloudreve v4<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cloudreve sits in the same self hosted file space as <a href=\"https:\/\/computingforgeeks.com\/install-nextcloud-ubuntu-2604\/\">Nextcloud<\/a>, Seafile, and FileBrowser, but the v4 release pushes it ahead of all three on a few points that matter to operators. It is a single Go binary fronting a React SPA, so the runtime footprint is small. It speaks ten storage backends out of the box and lets you assign different backends to different user groups. It ships native WebDAV, native Aria2 and qBittorrent integration for remote downloads, and a real AI semantic search option that calls OpenAI, Hugging Face, or AWS Bedrock embeddings. The community edition is GPL-3.0; the Pro edition adds OIDC SSO, desktop sync, Stripe paid shares, and audit events.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A server running Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, or Debian 13 (trixie) with sudo access<\/li>\n\n<li>2 vCPU, 4 GB RAM, and at least 20 GB free disk. The Cloudreve image plus PostgreSQL plus Redis pull about 600 MB; the rest is for file uploads and database growth<\/li>\n\n<li>Outbound HTTPS to <code>download.docker.com<\/code> and <code>docker.io<\/code><\/li>\n\n<li>TCP 5212 open for the web UI, plus TCP and UDP 6888 if you plan to use BitTorrent remote downloads<\/li>\n\n<li>A DNS A record pointing to the server if you intend to expose Cloudreve to the public internet (the production notes section at the end covers reverse proxy and TLS)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Update the system and install base utilities<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Pull the latest package indexes and install <code>curl<\/code>, <code>ca-certificates<\/code>, and the QEMU guest agent if you are running on a Proxmox, KVM, or cloud hypervisor.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get update\nsudo apt-get install -y ca-certificates curl qemu-guest-agent<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Install Docker CE and the Compose plugin<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cloudreve runs as a Docker container, so you need a current Docker Engine plus the Compose v2 plugin. Use the official Docker apt repository because the distro packaged Docker on Ubuntu and Debian is often months behind the upstream release.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ubuntu 24.04 LTS and Ubuntu 26.04 LTS<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo install -m 0755 -d \/etc\/apt\/keyrings\nsudo curl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg \\\n  -o \/etc\/apt\/keyrings\/docker.asc\nsudo chmod a+r \/etc\/apt\/keyrings\/docker.asc\n\necho \"deb [arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/docker.asc] \\\nhttps:\/\/download.docker.com\/linux\/ubuntu $(. \/etc\/os-release && echo \"$VERSION_CODENAME\") stable\" \\\n  | sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null\n\nsudo apt-get update\nsudo apt-get install -y docker-ce docker-ce-cli containerd.io \\\n  docker-buildx-plugin docker-compose-plugin<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you want a deeper walkthrough of the Docker install itself, the dedicated <a href=\"https:\/\/computingforgeeks.com\/install-docker-ce-ubuntu-2604\/\">Install Docker CE on Ubuntu 26.04 LTS<\/a> guide covers cgroup tweaks, log rotation, and the rootless mode.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Debian 13 (trixie)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo install -m 0755 -d \/etc\/apt\/keyrings\nsudo curl -fsSL https:\/\/download.docker.com\/linux\/debian\/gpg \\\n  -o \/etc\/apt\/keyrings\/docker.asc\nsudo chmod a+r \/etc\/apt\/keyrings\/docker.asc\n\necho \"deb [arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/docker.asc] \\\nhttps:\/\/download.docker.com\/linux\/debian $(. \/etc\/os-release && echo \"$VERSION_CODENAME\") stable\" \\\n  | sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null\n\nsudo apt-get update\nsudo apt-get install -y docker-ce docker-ce-cli containerd.io \\\n  docker-buildx-plugin docker-compose-plugin<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Add your user to the docker group<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo usermod -aG docker $USER\nsudo systemctl enable --now docker qemu-guest-agent\nnewgrp docker\ndocker --version\ndocker compose version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see Docker Engine 29.x (or whatever is current) and Docker Compose v2.30 or newer. If <code>newgrp docker<\/code> drops you into a sub shell, exit and re open the SSH session so the group membership sticks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Create the Cloudreve Docker Compose project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a dedicated directory for the stack so the named volumes and the compose file live together. Then drop the Cloudreve plus PostgreSQL plus Redis stack in it. This is the upstream stack from <a href=\"https:\/\/github.com\/cloudreve\/docker-compose\" rel=\"noopener\" target=\"_blank\" rel=\"noreferrer noopener\">github.com\/cloudreve\/docker-compose<\/a>, lightly trimmed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/cloudreve && cd ~\/cloudreve\ncat &gt; docker-compose.yml &lt;&lt;'EOF'\nservices:\n  cloudreve:\n    image: cloudreve\/cloudreve:v4\n    container_name: cloudreve\n    depends_on:\n      postgresql:\n        condition: service_healthy\n      redis:\n        condition: service_started\n    restart: unless-stopped\n    ports:\n      - 5212:5212\n      - 6888:6888\n      - 6888:6888\/udp\n    environment:\n      - CR_CONF_Database.Type=postgres\n      - CR_CONF_Database.Host=postgresql\n      - CR_CONF_Database.User=cloudreve\n      - CR_CONF_Database.Name=cloudreve\n      - CR_CONF_Database.Port=5432\n      - CR_CONF_Redis.Server=redis:6379\n    volumes:\n      - backend_data:\/cloudreve\/data\n\n  postgresql:\n    image: postgres:17\n    container_name: postgresql\n    restart: unless-stopped\n    environment:\n      - POSTGRES_USER=cloudreve\n      - POSTGRES_DB=cloudreve\n      - POSTGRES_HOST_AUTH_METHOD=trust\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U cloudreve -d cloudreve\"]\n      interval: 5s\n      timeout: 5s\n      retries: 10\n    volumes:\n      - database_postgres:\/var\/lib\/postgresql\/data\n\n  redis:\n    image: redis:latest\n    container_name: redis\n    restart: unless-stopped\n    volumes:\n      - redis_data:\/data\n\nvolumes:\n  backend_data:\n  database_postgres:\n  redis_data:\nEOF<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The change from the upstream compose file: a real PostgreSQL healthcheck (<code>pg_isready<\/code>) plus <code>condition: service_healthy<\/code> on the Cloudreve dependency. Without those two lines, Cloudreve starts before PostgreSQL accepts connections, panics with a <code>connection refused<\/code> on the first migration call, and only comes up after the <code>restart: unless-stopped<\/code> policy kicks it back. It works, but it pollutes the logs with a panic and a stack trace on every fresh start. The healthcheck eliminates the race.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For a deeper dive on the database side, the <a href=\"https:\/\/computingforgeeks.com\/install-postgresql-18-ubuntu-2604\/\">Install PostgreSQL 18 on Ubuntu 26.04 LTS<\/a> guide and the <a href=\"https:\/\/computingforgeeks.com\/install-postgresql-debian\/\">Install PostgreSQL 17 on Debian 13 \/ 12<\/a> guide cover the host packaged builds if you would rather run PostgreSQL on the host instead of in a container.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Launch the Cloudreve stack<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/cloudreve\ndocker compose pull\ndocker compose up -d\ndocker compose ps<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see all three containers listed as <code>Up<\/code>. Cloudreve binds to <code>5212\/tcp<\/code> for the web UI and to <code>6888\/tcp<\/code> plus <code>6888\/udp<\/code> for the bundled Aria2 BitTorrent listener. PostgreSQL and Redis only expose ports inside the Docker network, which is what you want.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-ubuntu-2404-wm.png\" alt=\"Terminal output of docker compose ps showing cloudreve, postgresql, and redis containers Up on Ubuntu 24.04 LTS with ports 5212 and 6888\" class=\"wp-image-168163\" width=\"1100\" height=\"760\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-ubuntu-2404-wm.png 1100w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-ubuntu-2404-wm-300x207.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-ubuntu-2404-wm-1024x707.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-ubuntu-2404-wm-768x531.png 768w\" sizes=\"auto, (max-width: 1100px) 100vw, 1100px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">On Debian 13, the output looks effectively identical because Docker normalises the runtime across distros.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-debian-13-wm.png\" alt=\"Terminal output of docker compose ps showing cloudreve, postgresql, and redis containers Up on Debian 13 trixie with ports 5212 and 6888\" class=\"wp-image-168161\" width=\"1100\" height=\"760\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-debian-13-wm.png 1100w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-debian-13-wm-300x207.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-debian-13-wm-1024x707.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-docker-compose-ps-debian-13-wm-768x531.png 768w\" sizes=\"auto, (max-width: 1100px) 100vw, 1100px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Confirm the Cloudreve container is serving HTTP and the version banner matches the release you intended to install.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -sI http:\/\/localhost:5212\/ | head -3\ndocker logs cloudreve 2&gt;&amp;1 | grep -E \"V4|Pro=\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output: an <code>HTTP\/1.1 200 OK<\/code> on the curl, and a banner line like <code>V4.16.0 Commit #54dc81d Pro=false<\/code> on the log grep. The Community build always reports <code>Pro=false<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Register the administrator account<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cloudreve v4 does not pre create an admin user and does not print credentials in the logs. The first user who registers becomes the administrator. Browse to <code>http:\/\/YOUR_SERVER_IP:5212\/<\/code>, click <strong>Sign up now<\/strong>, and submit your email plus a strong password.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-signup-page-wm.png\" alt=\"Cloudreve v4 sign up form on first launch, where the first registered account becomes the administrator\" class=\"wp-image-168159\" width=\"1440\" height=\"900\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-signup-page-wm.png 1440w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-signup-page-wm-300x188.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-signup-page-wm-1024x640.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-signup-page-wm-768x480.png 768w\" sizes=\"auto, (max-width: 1440px) 100vw, 1440px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">After submitting the form you get a green <strong>Sign up successful<\/strong> toast and are redirected to the sign in screen. The sign in flow is two steps: enter your email, click <strong>Next<\/strong>, then enter your password.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-after-signup-wm.png\" alt=\"Cloudreve v4 sign in screen after registering the first administrator account, with a Sign up successful toast\" class=\"wp-image-168160\" width=\"1440\" height=\"900\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-after-signup-wm.png 1440w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-after-signup-wm-300x188.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-after-signup-wm-1024x640.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-after-signup-wm-768x480.png 768w\" sizes=\"auto, (max-width: 1440px) 100vw, 1440px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can verify the user was inserted by querying the PostgreSQL container directly.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker exec postgresql psql -U cloudreve -d cloudreve \\\n  -c \"SELECT id, email, nick, status FROM users;\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first row should show your email with <code>status<\/code> set to <code>active<\/code>. If signups need to be locked down after this point (which is what you want on any server reachable from the internet), open the admin panel, navigate to <strong>Settings &rarr; Login and registration<\/strong>, and disable public registration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Tour the Cloudreve dashboard<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After signing in, you land on the file browser. The left sidebar exposes virtual folders (My Files, Photos, Videos, Music, Documents), the trash, sharing, mounted remote backends, and remote downloads. The header has the global <strong>+ New<\/strong> button and a search bar.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-files-dashboard-wm.png\" alt=\"Cloudreve v4 main files dashboard after logging in showing My Files sidebar and drag and drop upload area\" class=\"wp-image-168165\" width=\"1440\" height=\"900\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-files-dashboard-wm.png 1440w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-files-dashboard-wm-300x188.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-files-dashboard-wm-1024x640.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-files-dashboard-wm-768x480.png 768w\" sizes=\"auto, (max-width: 1440px) 100vw, 1440px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>+ New<\/strong> button is the entry point for everything you can put into Cloudreve: file uploads, folder uploads, paste from clipboard, Aria2 or qBittorrent remote downloads, new folders, and new files in the bundled in browser editors (Markdown, draw.io, plain text, Excalidraw).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-upload-menu-wm.png\" alt=\"Cloudreve v4 New menu open, listing Upload files, Upload folder, Upload from clipboard, New remote download, New folder, New file, Markdown, draw.io, Text, and Excalidraw\" class=\"wp-image-168162\" width=\"1440\" height=\"900\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-upload-menu-wm.png 1440w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-upload-menu-wm-300x188.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-upload-menu-wm-1024x640.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-upload-menu-wm-768x480.png 768w\" sizes=\"auto, (max-width: 1440px) 100vw, 1440px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Click the <strong>Dashboard<\/strong> entry in the sidebar to enter the admin panel. The first thing Cloudreve does on a fresh install is prompt you to confirm the site URL. Set it to whatever your reverse proxy will serve (for now, <code>http:\/\/YOUR_SERVER_IP:5212<\/code>; once you put Caddy or Nginx in front, change it to <code>https:\/\/your.domain<\/code>).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-dashboard-wm.png\" alt=\"Cloudreve v4 admin Summary page with the Confirm site URL modal prompting to register the current address as the primary site URL\" class=\"wp-image-168164\" width=\"1440\" height=\"900\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-dashboard-wm.png 1440w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-dashboard-wm-300x188.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-dashboard-wm-1024x640.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-dashboard-wm-768x480.png 768w\" sizes=\"auto, (max-width: 1440px) 100vw, 1440px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The admin sidebar lists every subsystem you will touch over the life of a Cloudreve deployment: Settings, Filesystem, Storage Policy, Nodes (for slave nodes), Groups, Users, Files, File Blobs, Shares, Background Tasks, OAuth Apps, plus four Pro only entries (Payments, Events, Abuse report, and OAuth Apps).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>Storage Policy<\/strong> page is where the ten storage backends actually live. A fresh install has one Default storage policy bound to the Local filesystem and assigned to both the Admin and User groups.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-storage-policies-wm.png\" alt=\"Cloudreve v4 admin Storage Policy list showing the default Local storage policy assigned to Admin and User groups\" class=\"wp-image-168166\" width=\"1440\" height=\"900\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-storage-policies-wm.png 1440w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-storage-policies-wm-300x188.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-storage-policies-wm-1024x640.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/cloudreve-v4-admin-storage-policies-wm-768x480.png 768w\" sizes=\"auto, (max-width: 1440px) 100vw, 1440px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Open the firewall ports<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If UFW or nftables is enabled (default on most cloud images), allow the Cloudreve ports.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Ubuntu (ufw)\nsudo ufw allow 5212\/tcp comment 'Cloudreve web UI'\nsudo ufw allow 6888\/tcp comment 'Cloudreve Aria2 BT'\nsudo ufw allow 6888\/udp comment 'Cloudreve Aria2 BT'\nsudo ufw reload\n\n# Debian 13 (nftables)\nsudo nft add rule inet filter input tcp dport 5212 accept\nsudo nft add rule inet filter input tcp dport 6888 accept\nsudo nft add rule inet filter input udp dport 6888 accept<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If Cloudreve will sit behind a reverse proxy (recommended on any public host), only port 443 needs to face the internet; <code>5212<\/code> can stay bound to <code>127.0.0.1<\/code>. Change the <code>ports:<\/code> mapping in <code>docker-compose.yml<\/code> to <code>127.0.0.1:5212:5212<\/code> and recreate the container.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Production notes<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Put it behind a reverse proxy with TLS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Never expose Cloudreve directly on port 5212 on the public internet. Front it with <a href=\"https:\/\/computingforgeeks.com\/install-caddy-ubuntu-2604\/\">Caddy<\/a> (one line site block, automatic Let&#8217;s Encrypt) or Nginx. A minimal Caddyfile reads:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>files.example.com {\n    reverse_proxy 127.0.0.1:5212\n    encode zstd gzip\n    request_body {\n        max_size 10GB\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Bump <code>max_size<\/code> to whatever your largest expected upload is. After the proxy is live, update the primary site URL inside Cloudreve (<strong>Dashboard &rarr; Settings &rarr; Basic<\/strong>) to the HTTPS URL so share links and email callbacks point to the right host.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Switch off trust authentication on PostgreSQL<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The upstream compose file sets <code>POSTGRES_HOST_AUTH_METHOD=trust<\/code> on the PostgreSQL container. That is fine for a single host lab because the database port is not exposed outside the Docker network, but it is not what you want long term. Replace it with a real password:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># In docker-compose.yml, postgresql.environment:\n- POSTGRES_PASSWORD=use_a_strong_password_here\n\n# Then in cloudreve.environment, add:\n- CR_CONF_Database.Password=use_a_strong_password_here<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Recreate the stack with <code>docker compose down &amp;&amp; docker compose up -d<\/code>. The Cloudreve container reads the new env var at boot and updates <code>conf.ini<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Back up three things<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The PostgreSQL database (<code>docker exec postgresql pg_dump -U cloudreve cloudreve<\/code>)<\/li>\n\n<li>The <code>backend_data<\/code> volume (holds <code>conf.ini<\/code>, the avatar cache, and the local storage policy uploads)<\/li>\n\n<li>The remote object store, if you have moved off the Local storage policy<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The PostgreSQL dump alone is not enough; without the <code>backend_data<\/code> volume you lose the master encryption key (if file encryption is enabled) and the local uploads.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pin the image tag for reproducible upgrades<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The upstream compose uses <code>cloudreve\/cloudreve:v4<\/code>, a moving tag that follows the latest 4.x release. For a production deployment, pin to a specific patch version (<code>cloudreve\/cloudreve:4.16.0<\/code>) so a <code>docker compose pull<\/code> on a different day does not silently roll the database forward. Watch the <a href=\"https:\/\/github.com\/cloudreve\/cloudreve\/releases\" rel=\"noopener\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudreve release page<\/a> for new tags and read the changelog before bumping.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s next<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Local storage policy works for a homelab. For real deployments, the next steps are wiring an S3 compatible bucket (MinIO, Cloudflare R2, AWS S3, Backblaze B2) so uploads survive a host rebuild, putting Cloudreve behind Caddy or Nginx with a real TLS certificate, and enabling the bundled WebDAV endpoint for macOS Finder, Windows Explorer, and <code>rclone<\/code> mounts. Those guides ship next in this series.<\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>Step by step guide to deploy Cloudreve v4 with Docker Compose, PostgreSQL 17, and Redis on Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, and Debian 13 trixie.<\/p>\n","protected":false},"author":7,"featured_media":168165,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[316,47,50],"tags":[39868,10432,759,39870,39869,2254],"cfg_series":[39867],"class_list":["post-168167","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-containers","category-linux","category-linux-tutorials","tag-cloudreve","tag-debian","tag-docker-compose","tag-file-management","tag-self-hosted","tag-ubuntu","cfg_series-cloudreve"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/168167","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=168167"}],"version-history":[{"count":1,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/168167\/revisions"}],"predecessor-version":[{"id":168175,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/168167\/revisions\/168175"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/168165"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=168167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=168167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=168167"},{"taxonomy":"cfg_series","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/cfg_series?post=168167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}