Hi!
Recently I’m struggling to run Docker based Nextcloud 30 with nginx.
I use for that 2 Ubuntu 24.10 VMs (also tried on 24.04). They are fresh installs, run in the same subnet with almost no local FWs (Nextcloud AiO doesn’t deploy if you flush iptables before). I can’t assign public IP to any of them, so I do port 80 & 443 translation towards Nginx VM.
The network settings
- Mikrotik ISP home GW
[admin@RB4011.home] > ip firewall nat print
Flags: X - disabled, I - invalid; D - dynamic
0 ;;; defconf: masquerade
chain=srcnat action=masquerade out-interface-list=WAN log=no log-prefix=“” ipsec-policy=out,none
1 chain=dstnat action=dst-nat to-addresses=192.168.1.52 to-ports=443 protocol=tcp in-interface=pppoe-out1 dst-port=443 log=no log-prefix=“”
2 chain=dstnat action=dst-nat to-addresses=192.168.1.52 protocol=tcp in-interface=pppoe-out1 dst-port=80 log=no log-prefix=“”
- VM with nginx has address: 192.168.1.52/24, local FW settings:
shadow@Ubuntu-24:~$ sudo ufw status
Status: inactive
shadow@Ubuntu-24:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
- Element listy
VM with NC has address: 192.168.1.47/24, local FW settings after NC install:
shadow@Ubuntu-24:~/docker/nextcloud$ sudo ufw status
Status: inactive
shadow@Ubuntu-24:~/docker/nextcloud$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all – anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all – anywhere anywhere
ACCEPT all – anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all – anywhere anywhere
ACCEPT all – anywhere anywhere
ACCEPT all – anywhere anywhere
ACCEPT all – anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all – anywhere anywhere
ACCEPT all – anywhere anywhere
ACCEPT all – anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp – anywhere 172.17.0.2 tcp dpt:http-alt
ACCEPT tcp – anywhere 172.18.0.6 tcp dpt:11000
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
RETURN all – anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all – anywhere anywhere
DROP all – anywhere anywhere
RETURN all – anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all – anywhere anywhere
The NC config
I followed the manuals for NextCloud AiO, I took suggesterd compose file from compose.yaml and I removed the 80 and 8443 ports from there. I uncommented the proxy related lines (APACHE_PORT, APACHE_IP_BINDIGNG) I setup my own datadir (I tried also without this setting). Due to no option to assign public IP to any VM (these are Vmware ESXi 8 based VMs in my home LAN) I skip the domain check SKIP_DOMAIN_VALIDATION: true.
Below is my full docker-compose.yml (with deleted commented lines for convenience):
services:
nextcloud-aio-mastercontainer:
image: nextcloud/all-in-one:latest
init: true
restart: unless-stopped
container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work
- /var/run/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don’t forget to also set ‘WATCHTOWER_DOCKER_SOCKET_PATH’!
network_mode: bridge # add to the same network as docker run would do
ports:
- 8080:8080
environment: # Is needed when using any of the options below
APACHE_PORT: 11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else). See all-in-one/reverse-proxy.md at main · nextcloud/all-in-one · GitHub
APACHE_IP_BINDING: 127.0.0.1 # Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else) that is running on the same host. See reverse-proxy.md
NEXTCLOUD_DATADIR: /home/shadow/docker/nextcloud/appdata # Allows to set the host directory for Nextcloud’s datadir. Warning: do not set or adjust this value after the initial Nextcloud installation is done! See how-to-change-the-default-location-of-nextclouds-datadir
how-to-add-php-extensions-permanently-to-the-nextcloud-container
SKIP_DOMAIN_VALIDATION: true
volumes: # If you want to store the data on a different drive, see how-to-store-the-filesinstallation-on-a-separate-drive
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer # This line is not allowed to be changed as otherwise the built-in backup solution will not work
The nginx config
Firstly I installed nginx and certbot and created certs for my website. Next I followed the reverse-proxy.md focusing on section Nginx, Freenginx, Openresty.
Below my /etc/nginx/sites-available/default file:
shadow@Ubuntu-24:/etc/nginx/sites-available$ cat default
map $http_upgrade $connection_upgrade {
default upgrade;
‘’ close;
}
server {
listen 80;
listen [::]:80; # comment to disable IPv6
if ($scheme = "http") {
return 301 https://$host$request_uri;
}
# listen 443 ssl http2; # for nginx versions below v1.25.1
# listen [::]:443 ssl http2; # for nginx versions below v1.25.1 - comment to disable IPv6
listen 443 ssl; # for nginx v1.25.1+
# listen [::]:443 ssl; # for nginx v1.25.1+ - keep comment to disable IPv6
# http2 on; # uncomment to enable HTTP/2 - supported on nginx v1.25.1+
# http3 on; # uncomment to enable HTTP/3 / QUIC - supported on nginx v1.25.0+
# quic_retry on; # uncomment to enable HTTP/3 / QUIC - supported on nginx v1.25.0+
# add_header Alt-Svc 'h3=":443"; ma=86400'; # uncomment to enable HTTP/3 / QUIC - supported on nginx v1.25.0+
# listen 443 quic reuseport; # uncomment to enable HTTP/3 / QUIC - supported on nginx v1.25.0+ - please remove "reuseport" if there is already another quic listener on port 443 with enabled reuseport
# listen [::]:443 quic reuseport; # uncomment to enable HTTP/3 / QUIC - supported on nginx v1.25.0+ - please remove "reuseport" if there is already another quic listener on port 443 with enabled reuseport - keep comment to disable IPv6
server_name drive.shadow.com;
location / {
proxy_pass http://192.168.1.47:11000$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_request_buffering off;
proxy_read_timeout 86400s;
client_max_body_size 0;
# Websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# If running nginx on a subdomain (eg. nextcloud.example.com) of a domain that already has an wildcard ssl certificate from certbot on this machine,
# the <your-nc-domain> in the below lines should be replaced with just the domain (eg. example.com), not the subdomain.
# In this case the subdomain should already be secured without additional actions
ssl_certificate /etc/letsencrypt/live/drive.shadow.com/fullchain.pem; # managed by certbot on host machine
ssl_certificate_key /etc/letsencrypt/live/drive.shadow.com/privkey.pem; # managed by certbot on host machine
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on;
# Optional settings:
# OCSP stapling
# ssl_stapling on;
# ssl_stapling_verify on;
# ssl_trusted_certificate /etc/letsencrypt/live/<your-nc-domain>/chain.pem;
# replace with the IP address of your resolver
# resolver 127.0.0.1; # needed for oscp stapling: e.g. use 94.140.15.15 for adguard / 1.1.1.1 for cloudflared or 8.8.8.8 for google - you can use the same nameserver as listed in your /etc/resolv.conf file
}
The NC behavior
After enabling the proxy and installing NC 30 via initial setup
on localhost port 8080/setup I cannot reach the website - from NC VM nor from nginx VM, using the outside address I’m getting “ERR_CONNECTION_REFUSED”.
From outside world I’m getting nginx 502 Bad Gateway
I took a look using Wireshark and I see that traffic to nginx VM is correct
https://i.imgur.com/4iouKiE.png
But next session is actively reset by NC VM:
https://i.imgur.com/lWBkFvG.png
I see that NC VM is listening on APACHE_PORT
shadow@Ubuntu-24:~/docker/nextcloud$ sudo netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 1150/systemd-resolv
tcp 0 0 127.0.0.54:53 0.0.0.0:* LISTEN 1150/systemd-resolv
tcp 0 0 127.0.0.1:11000 0.0.0.0:* LISTEN 2596/docker-proxy
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 2546/docker-proxy
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1839/cupsd
tcp6 0 0 ::1:631 :::* LISTEN 1839/cupsd
tcp6 0 0 :::8080 :::* LISTEN 2552/docker-proxy
udp 0 0 192.168.1.47:58415 0.0.0.0:* 2963/chrome-remote-
udp 0 0 172.17.0.1:33970 0.0.0.0:* 2963/chrome-remote-
udp 0 0 172.17.0.1:42595 0.0.0.0:* 2963/chrome-remote-
udp 0 0 0.0.0.0:51603 0.0.0.0:* 1307/avahi-daemon:
udp 0 0 172.18.0.1:44926 0.0.0.0:* 2963/chrome-remote-
udp 0 0 192.168.1.47:37935 0.0.0.0:* 2963/chrome-remote-
udp 0 0 0.0.0.0:5353 0.0.0.0:* 1307/avahi-daemon:
udp 0 0 172.17.0.1:46379 0.0.0.0:* 2963/chrome-remote-
udp 0 0 172.18.0.1:39047 0.0.0.0:* 2963/chrome-remote-
udp 0 0 192.168.1.47:49141 0.0.0.0:* 2963/chrome-remote-
udp 0 0 127.0.0.54:53 0.0.0.0:* 1150/systemd-resolv
udp 0 0 127.0.0.53:53 0.0.0.0:* 1150/systemd-resolv
udp 0 0 172.18.0.1:49531 0.0.0.0:* 2963/chrome-remote-
udp6 0 0 :::33926 :::* 1307/avahi-daemon:
udp6 0 0 :::5353 :::* 1307/avahi-daemon:
But connections to that port are being refused:
shadow@Ubuntu-24:~/docker/nextcloud$ telnet 192.168.1.47 11000
Trying 192.168.1.47…
telnet: Unable to connect to remote host: Connection refused
shadow@Ubuntu-24:~/docker/nextcloud$ curl http://192.168.1.47:11000
curl: (7) Failed to connect to 192.168.1.47 port 11000 after 0 ms: Could not connect to server
I also see that nc aio apache container is having some issues every time few minutes after starting it up:
shadow@Ubuntu-24:~/docker/nextcloud$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aea2ea0c8075 nextcloud/aio-apache:latest “/start.sh /usr/bin/…” 9 hours ago Up 52 minutes (unhealthy) 80/tcp, 127.0.0.1:11000->11000/tcp nextcloud-aio-apache
31187fe951a9 nextcloud/aio-notify-push:latest “/start.sh” 9 hours ago Up 52 minutes (healthy) nextcloud-aio-notify-push
ee2b7831a460 nextcloud/aio-nextcloud:latest “/start.sh /usr/bin/…” 9 hours ago Up 52 minutes (healthy) 9000/tcp nextcloud-aio-nextcloud
16fb658421b4 nextcloud/aio-redis:latest “/start.sh” 9 hours ago Up 52 minutes (healthy) 6379/tcp nextcloud-aio-redis
4a41ec9907de nextcloud/aio-postgresql:latest “/start.sh” 9 hours ago Up 52 minutes (healthy) 5432/tcp nextcloud-aio-database
4d575a2c6ff9 nextcloud/all-in-one:latest “/start.sh” 9 hours ago Up 52 minutes (healthy) 80/tcp, 8443/tcp, 9000/tcp, 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp nextcloud-aio-mastercontainer
After checking netstat on that apache container it seems like it listens on IPv6 only:
aea2ea0c8075:/usr/local/apache2$ netstat -tulpn
netstat: showing only processes with your user ID
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2019 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.11:35469 0.0.0.0:* LISTEN -
tcp 0 0 :::8000 :::* LISTEN 42/httpd
tcp 0 0 :::11000 :::* LISTEN -
udp 0 0 127.0.0.11:40073 0.0.0.0:*
I’m not sure what to do next in order to make it run. I already tried to deploy this multiple times (struggling for a week already). I managed to run docker based nextcloud (not AiO) using nginx on the same VM, but I need this on 2 separate VMs, cause I have to use Sophos FW as proxy in near future.
Any hints?