VM 102 · Docker Stack
Nextcloud with MariaDB deployed as a Docker Compose stack - self-hosted file storage, accessible externally atcloud.munyakazi.org.
| Internal URL | http://192.168.86.53:8080 |
| External URL | https://cloud.munyakazi.org |
| Database | MariaDB 11 |
| Image | nextcloud:latest |
| Status | Live |
Nextcloud is an open-source self-hosted cloud platform - the self-hosted alternative to Google Drive or OneDrive. This deployment provides personal file storage, accessible from anywhere via browser or mobile app, running entirely on homelab infrastructure.
Nextcloud demonstrates a realistic production-style deployment: a stateful web application with a separate database backend, persistent volumes, reverse proxy integration, and secure external access. It's a strong portfolio piece because it combines multiple real-world skills in one service.
version: "3.8"
services:
nextcloud-db:
image: mariadb:11
container_name: nextcloud-db
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- nextcloud_db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: [redacted]
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: [redacted]
networks:
- default
nextcloud:
image: nextcloud:latest
container_name: nextcloud
restart: unless-stopped
ports:
- "8080:80"
volumes:
- nextcloud_data:/var/www/html
environment:
MYSQL_HOST: nextcloud-db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: [redacted]
depends_on:
- nextcloud-db
networks:
- default
- npm_default
volumes:
nextcloud_db:
nextcloud_data:
networks:
default:
npm_default:
external: true
nextcloud-db is intentionally isolated - it only joins the private default network shared with the nextcloud container. It has no external port mapping and is unreachable from NPM or the internet.
nextcloud joins both networks: default (to communicate with the database) and npm_default (so Nginx Proxy Manager can reach it by container name).
Two settings configured via the occ command-line tool inside the Nextcloud container:
Add external domain to trusted_domains:
php occ config:system:set trusted_domains 1 --value=cloud.munyakazi.org
Set protocol override for reverse proxy:
php occ config:system:set overwriteprotocol --value="https"
Without these, Nextcloud either blocks requests from the external domain or generates broken HTTP links behind the HTTPS proxy.
The existing Block Direct IP Access WAF rule on munyakazi.org was blocking the new subdomain. The rule originally used:
http.host ne "munyakazi.org"
Updated to allow all legitimate subdomains:
http.host ne "munyakazi.org" and not ends_with(http.host, ".munyakazi.org")
This fix applies to all *.munyakazi.org subdomains added going forward - no further WAF changes needed for new services.
| Issue | Cause | Fix |
|---|---|---|
| Setup wizard timed out twice | Portainer 5-minute security window expired | Restarted container, grabbed fresh setup_token from logs immediately |
| "Access through untrusted domain" | cloud.munyakazi.org not in trusted_domains | Added via occ command |
| App Store fetch failed on first login | Outbound DNS hiccup at container startup | Non-blocking, resolved on next load |