Nextcloud AIO Deployment Behind Nginx Reverse Proxy

This documentation describes the step-by-step process to deploy Nextcloud All-in-One (AIO) on a Proxmox VM, exposed securely via an Nginx reverse proxy running on the Proxmox host.

  • Proxmox Host runs Nginx as a reverse proxy, handling SSL termination via Let's Encrypt (Certbot)
  • Proxmox VM (e.g. 192.168.1.121) runs Nextcloud AIO via Docker Compose
  • Nginx forwards HTTPS traffic from the outside world to Nextcloud's Apache container on port 11000 inside the VM
  • Nextcloud AIO manages all its own sibling containers (Database, Redis, Collabora, Talk, etc.)


The Nextcloud AIO mastercontainer does not serve Nextcloud itself — it only manages sibling containers. The actual Nextcloud interface is served by the Apache sibling container on port 11000. Do not confuse port 8080 (AIO management UI) with port 11000 (Nextcloud).

Step 1. DNS Configuration

  • Point your domain (e.g. drive.yourdomain.com) to your public IP address via an A record in your DNS provider.
  • Verify propagation:
$ dig drive.yourdomain.com

Step 2. Obtain SSL Certificate on Proxmox Host

  • On the Proxmox host, obtain a Let's Encrypt certificate using Certbot (assuming Nginx and Certbot are already running via Docker Compose):
docker exec certbot certbot certonly --webroot \
  -w /var/www/certbot \
  -d drive.yourdomain.com \
  --email your@email.com \
  --agree-tos --non-interactive
  • The certificate will be stored at:
/etc/letsencrypt/live/drive.yourdomain.com/fullchain.pem
/etc/letsencrypt/live/drive.yourdomain.com/privkey.pem

Step 3. Configure Nginx Reverse Proxy on Proxmox Host

  • Create a new Nginx config file for your Nextcloud domain:
$ nano /etc/nginx/conf.d/drive.yourdomain.com.conf
  • Paste the following configuration:
upstream drive_backend {
    server 192.168.1.121:11000;
}
 
server {
    server_name drive.yourdomain.com;
    listen 80;
    return 301 https://$host$request_uri;
}
 
server {
    server_name drive.yourdomain.com;
    listen 443 ssl http2;
 
    ssl_certificate /etc/letsencrypt/live/drive.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/drive.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
 
    location / {
        proxy_pass http://drive_backend;
        proxy_set_header Host $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 https;
        proxy_set_header X-Forwarded-Host $host;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        client_max_body_size 0;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
 
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
        auth_basic off;
        allow all;
        try_files $uri =404;
    }
}
  • Reload Nginx to apply the configuration:
$ docker exec nginx nginx -s reload

Step 4. Deploy Nextcloud AIO on the VM

  • SSH into your Proxmox VM:
$ ssh sysadm@192.168.1.121
  • Create a working directory and the Docker Compose file:
$ mkdir ~/nextcloud-aio && cd ~/nextcloud-aio
$ nano compose.yaml
  • Paste the following compose configuration:
name: nextcloud-aio
services:
  nextcloud-aio-mastercontainer:
    image: ghcr.io/nextcloud-releases/all-in-one:latest
    init: true
    restart: always
    container_name: nextcloud-aio-mastercontainer
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config
      - /var/run/docker.sock:/var/run/docker.sock:ro
    network_mode: bridge
    ports:
      - 80:80
      - 8080:8080
      - 8443:8443
      # Do NOT add 11000:11000 here — Apache sibling container binds it automatically
    environment:
      APACHE_PORT: 11000
      SKIP_DOMAIN_VALIDATION: true

volumes:
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer

Do not add port 11000:11000 to the mastercontainer's ports section. The Apache sibling container binds this port on its own. Adding it to the mastercontainer will cause a port conflict and prevent the domain check from passing.

  • Start the mastercontainer:
$ docker compose up -d

Step 5. Access the AIO Management Interface

Since the VM is terminal-only, use an SSH tunnel from your local machine to access the AIO web UI:

$ ssh -L 9821:192.168.1.121:8080 admin@your-proxmox-host
  • Then open your browser and navigate to:
https://localhost:9821
  • Accept the self-signed certificate warning.
  • Retrieve the initial AIO passphrase from the container config:
$ sudo docker exec nextcloud-aio-mastercontainer \
    cat /mnt/docker-aio-config/data/configuration.json | python3 -m json.tool | grep -i password

Step 6. Complete Initial Setup via AIO Interface

  • Enter your domain drive.yourdomain.com in the AIO interface
  • Click “Start containers” — AIO will pull and launch all sibling containers:
    • Apache (port 11000)
    • Database (PostgreSQL)
    • Redis
    • Nextcloud
    • Notify Push
    • Collabora / Talk (optional)
  • Wait for all containers to reach Running state
  • Click “Click here to reveal the initial Nextcloud credentials” and save the admin username and password

Step 7. Verify Deployment

  • Confirm port 11000 is now active on the VM:
$ ss -tlnp | grep 11000
  • Test connectivity from the Proxmox host:
$ curl -I http://192.168.1.121:11000
  • Open your browser and navigate to:
https://drive.yourdomain.com
  • Log in with the admin credentials revealed in Step 6.

Step 8. Configure Backup

  • In the AIO interface, note the backup encryption password displayed on the main page — save it somewhere safe, it cannot be recovered if lost.
  • Set your backup directory (default: /mnt/backup/borg on the VM host)
  • Run an initial backup before enabling daily automated backups

Error Cause Fix
Connection reset by peer Nginx sending plain HTTP to an HTTPS backend Use proxy_pass http: not https: since Nginx terminates SSL
SSL handshake failed (alert 80) Caddy inside AIO trying to get its own cert, failing Set APACHE_PORT and SKIP_DOMAIN_VALIDATION: true in compose
Connection refused on port 11000 Apache sibling container not started yet, or port conflict Complete AIO setup via the web UI; remove 11000:11000 from mastercontainer ports
Domain check container not running Port 11000 already bound by mastercontainer Remove - 11000:11000 from compose ports section and restart
Wrong login or password AIO passphrase ≠ Nextcloud admin password Use credentials from “reveal initial credentials” button in AIO UI

Nadir Habib 2026/02/22 13:13

  • elosys/nextcloud.txt
  • Last modified: 2026/02/22 13:14
  • by nadir