Nextcloud · deploy guide
Self-host Nextcloud on a VPS with Docker Compose and Caddy
Run Nextcloud (files, calendar, contacts) on a bashrack VPS with MariaDB, Redis and automatic HTTPS from Caddy.
about 20 minutes of hands-on time
Who it's for
Families and teams replacing a public cloud drive with storage they control.
You'll need
- An Ubuntu or Debian VPS with your SSH key
- A domain, e.g. cloud.example.com, with an A record to the VPS IP
Steps
step 1
Open only SSH and HTTPS
Enable the firewall before exposing anything. Port 80 is needed for the certificate challenge and the redirect to HTTPS.
bashsudo apt-get update && sudo apt-get install -y ufw sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw --force enablestep 2
Install Docker
Log in to the VPS as your sudo user and install Docker Engine with the official convenience script, then allow your user to run it.
bashcurl -fsSL https://get.docker.com | sudo sh sudo usermod -aG docker "$USER" newgrp docker docker compose versionstep 3
Create the Compose stack
Create a directory with the Compose file and a Caddyfile. Caddy obtains and renews the certificate automatically.
yaml# ~/nextcloud/compose.yaml services: db: image: mariadb:lts restart: unless-stopped command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: nextcloud MYSQL_USER: nextcloud MYSQL_PASSWORD: ${DB_PASSWORD} volumes: - db:/var/lib/mysql redis: image: redis:alpine restart: unless-stopped app: image: nextcloud restart: unless-stopped depends_on: [db, redis] environment: MYSQL_HOST: db MYSQL_DATABASE: nextcloud MYSQL_USER: nextcloud MYSQL_PASSWORD: ${DB_PASSWORD} REDIS_HOST: redis NEXTCLOUD_TRUSTED_DOMAINS: ${DOMAIN} OVERWRITEPROTOCOL: https volumes: - nextcloud:/var/www/html caddy: image: caddy:2 restart: unless-stopped ports: - 80:80 - 443:443 volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data volumes: db: nextcloud: caddy_data:step 4
Add the Caddyfile and secrets
Replace the domain, then generate the passwords into a .env file next to compose.yaml.
bashcd ~/nextcloud cat > Caddyfile <<'EOF' cloud.example.com { reverse_proxy app:80 } EOF cat > .env <<EOF DOMAIN=cloud.example.com DB_PASSWORD=$(openssl rand -hex 24) DB_ROOT_PASSWORD=$(openssl rand -hex 24) EOFstep 5
Start and finish the installer
Start the stack, open https://cloud.example.com and create the admin account in the web installer.
bashdocker compose up -d docker compose logs -f app
Security and upkeep
- Finish the web installer immediately so nobody else can create the admin account.
- Back up the nextcloud and db volumes; files live in the nextcloud volume.
- Upgrade one major version at a time, as Nextcloud requires.