I have installed Nextcloud at least three times before this and abandoned it every single time. Not because it's bad, but because I always set it up the lazy way, got it just working enough to be impressed for an afternoon, and then watched it slowly fall over until I couldn't be bothered to fix it. The SQLite database that's fine for testing and miserable in real use. The PHP that was never quite tuned. The upgrade I put off until it became frightening. Each time, the install rotted because I'd treated it as a toy.
This time I decided to do it properly, which mostly meant doing the boring things I'd skipped every time before.
a real database
The first and biggest change: a proper database. Nextcloud will happily run on SQLite and it's the path of least resistance, which is exactly why it's a trap. The moment you have real files, real syncing clients, and more than one person, SQLite's single-writer nature turns into file locks and timeouts and "operation in progress" errors that make the whole thing feel broken. I moved to MariaDB in its own container, gave Nextcloud its own database and user, and the performance difference was not subtle.
db:
image: mariadb:10.6
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --log-bin=ROW
environment:
MARIADB_DATABASE: nextcloud
MARIADB_USER: nextcloud
MARIADB_PASSWORD_FILE: /run/secrets/nc_db_pass
volumes:
- ./db:/var/lib/mysql
I also added Redis for file locking and caching, which sounds like over-engineering for a household, and isn't. Transactional file locking on Redis is what stops the sync clients from tripping over each other, and it quietened a whole class of intermittent errors I used to just live with.
the reverse proxy and the trusted domains
Every previous install, I'd fought Nextcloud about what its own URL was. It's very particular. If the trusted_domains and overwrite.cli.url and the proxy headers don't all agree, you get login loops, broken share links, or that special joy where the desktop client connects but the web UI insists you're an imposter.
The fix was to stop hand-waving and write it down explicitly. Traefik terminates TLS and forwards to the container, and the container's config states, plainly, who it thinks it is.
'trusted_domains' => ['cloud.example.lan'],
'overwrite.cli.url' => 'https://cloud.example.lan',
'overwriteprotocol' => 'https',
'trusted_proxies' => ['172.18.0.0/16'],
Once the app and the proxy agreed on reality, every weird redirect bug I'd blamed on Nextcloud over the years quietly disappeared. They were never Nextcloud's fault. They were mine, for not telling it the truth.
backups that I've actually tested
Here's the part that separates "an install" from "infrastructure": I can lose the whole machine and get it back. Nextcloud's state is three things, and you need all three consistent with each other, or your restore is a museum of mismatched bits.
- The data directory, the actual files, which I back up with a nightly snapshot to off-site storage.
- The database, dumped with
mysqldumpwhile the instance is in maintenance mode so the dump and the files agree. - The config, the
config.phpand the secrets, kept with the rest of the stack's configuration.
The crucial habit is maintenance mode around the database dump. Snapshot the files and dump the database at different moments under load and you get a backup that's subtly inconsistent, the worst kind, the kind that restores cleanly and then behaves strangely. I put the instance into maintenance mode, dump, snapshot, drop out of maintenance mode, all from a small script on a timer. And, the bit everyone skips, I have actually restored it onto a spare machine to prove the backup works. A backup you've never restored is a rumour.
the maintenance I no longer skip
The reason my earlier installs died wasn't a dramatic failure, it was neglect. Nextcloud needs a background cron job to do its housekeeping, and run via the web AJAX trigger it's flaky. I set up a proper cron container that runs cron.php every five minutes, so maintenance happens whether or not anyone's using the web UI.
Upgrades I now do deliberately, one major version at a time, with a backup taken first and the release notes actually read. Nextcloud won't let you skip major versions and punishes you if you try, so I bump on purpose rather than letting the gap grow into something I'm scared of. That fear of the upgrade was what killed every previous install. Take it in small, regular, unscary steps and it never becomes the thing you avoid.
was it worth it
Yes, plainly. The difference between this install and the three corpses before it isn't the software, it's that I treated it like something I depend on instead of something I was trying out. Real database, honest proxy config, tested backups, scheduled maintenance. None of it clever, all of it boring, and the boring is exactly what makes it still be running in a year. My files sync, the calendar works, the share links don't break, and I no longer flinch when an upgrade notification appears. That's the whole win.