Table of Contents

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.

Architecture Overview


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

$ dig drive.yourdomain.com

Step 2. Obtain SSL Certificate on Proxmox Host

docker exec certbot certbot certonly --webroot \
  -w /var/www/certbot \
  -d drive.yourdomain.com \
  --email your@email.com \
  --agree-tos --non-interactive
/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

$ nano /etc/nginx/conf.d/drive.yourdomain.com.conf
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;
    }
}
$ docker exec nginx nginx -s reload

Step 4. Deploy Nextcloud AIO on the VM

$ ssh sysadm@192.168.1.121
$ mkdir ~/nextcloud-aio && cd ~/nextcloud-aio
$ nano compose.yaml
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.

$ 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
https://localhost:9821
$ 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

Step 7. Verify Deployment

$ ss -tlnp | grep 11000
$ curl -I http://192.168.1.121:11000
https://drive.yourdomain.com

Step 8. Configure Backup


Troubleshooting

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