1st commit - refined 2019 cfg + AI made README (I despise writing docs so it was either letting AI write README or having none, sorry)
This commit is contained in:
111
README.md
111
README.md
@@ -1,2 +1,113 @@
|
||||
# nextcloud
|
||||
|
||||
Config and compose files for my self-hosted Nextcloud at `drive.net.mulas.me`.
|
||||
|
||||
Two pieces:
|
||||
|
||||
- `nginx/` — the vhost, TLS profile, and header set I wrote and hardened for Nextcloud back in **2019** and have been using in production since then. I revised it in 2026 to match new Nextcloud docs directives.
|
||||
- `docker/` — a small Compose stack with MariaDB, Redis, and Memcached. Nextcloud itself runs on the host, served by NGINX and PHP-FPM, because I had an abysmal experience with Nextcloud's containerised setup, in particular on updating and adding modules. The containers only provide the backing services.
|
||||
|
||||
## Layout
|
||||
|
||||
`docker/docker-compose.yml` — the MariaDB + Redis + Memcached stack.
|
||||
|
||||
Everything under `nginx/` mirrors `/etc/nginx/` on the server:
|
||||
|
||||
- `nginx.conf` — main `http{}` block: tuning, real-ip, gzip, headers-more
|
||||
- `conf.d/header.conf` — HSTS and the Nextcloud-recommended hardening headers
|
||||
- `conf.d/ssl.conf` — TLS 1.2, AEAD ciphers, OCSP stapling
|
||||
- `sites-available/drive.mulas.me` — the vhost
|
||||
- `custom.d/` — mime types, cors, error pages, charset maps
|
||||
- `fcgi.d/` — fastcgi / scgi / uwsgi params
|
||||
- `snippets/` — letsencrypt ACME challenge, snakeoil
|
||||
|
||||
## Docker stack
|
||||
|
||||
Images are pinned, all overridable via env:
|
||||
|
||||
| Service | Default tag | Env override |
|
||||
|-------------|--------------------|---------------------------|
|
||||
| `db` | `mariadb:11.8-ubi9`| `ENV_MARIADB_VERSION` |
|
||||
| `redis` | `redis:7.4.9-alpine`| `ENV_REDIS_VERSION` |
|
||||
| `memcached` | `memcached:alpine3.23`| `ENV_MEMCACHED_VERSION` |
|
||||
|
||||
State, configs, and sockets land under `${ENV_BASE_DIR}/<service>/{data,config,socket}`. In production `ENV_BASE_DIR=/opt/nextcloud`.
|
||||
|
||||
MariaDB credentials are mounted as Docker secrets — files on the host, never in the repo:
|
||||
|
||||
```
|
||||
/opt/nextcloud/secrets/mariadb_root_password.txt
|
||||
/opt/nextcloud/secrets/mariadb_app_password.txt
|
||||
```
|
||||
|
||||
`MYSQL_USER` and `MYSQL_DATABASE` are intentionally blank in the compose file; fill them in (or move them to an `.env`) before bringing the stack up.
|
||||
|
||||
## Bringing it up
|
||||
|
||||
```bash
|
||||
# host paths
|
||||
sudo mkdir -p /opt/nextcloud/{mariadb,redis,memcached}/{data,config,socket}
|
||||
sudo mkdir -p /opt/nextcloud/secrets && sudo chmod 700 /opt/nextcloud/secrets
|
||||
|
||||
# secrets
|
||||
openssl rand -base64 48 | sudo tee /opt/nextcloud/secrets/mariadb_root_password.txt
|
||||
openssl rand -base64 48 | sudo tee /opt/nextcloud/secrets/mariadb_app_password.txt
|
||||
sudo chmod 600 /opt/nextcloud/secrets/*.txt
|
||||
|
||||
# env
|
||||
echo 'ENV_BASE_DIR=/opt/nextcloud' > docker/.env
|
||||
|
||||
# go
|
||||
( cd docker && docker compose up -d )
|
||||
```
|
||||
|
||||
Wait for the `db` healthcheck (it pings `mysqladmin`) to come up green before pointing Nextcloud at it.
|
||||
|
||||
## Nginx install
|
||||
|
||||
```bash
|
||||
sudo cp nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
sudo cp -r nginx/conf.d/* /etc/nginx/conf.d/
|
||||
sudo cp -r nginx/custom.d nginx/fcgi.d /etc/nginx/
|
||||
sudo cp -r nginx/snippets/* /etc/nginx/snippets/
|
||||
sudo cp nginx/sites-available/drive.mulas.me /etc/nginx/sites-available/
|
||||
sudo ln -sf /etc/nginx/sites-available/drive.mulas.me /etc/nginx/sites-enabled/drive.mulas.me
|
||||
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
What you need on the host for this to work:
|
||||
|
||||
- Nginx built with `headers-more` (the config uses `more_set_headers`)
|
||||
- PHP-FPM 8.5 with a socket at `/var/run/php/php8.5-fpm.sock`
|
||||
- A Let's Encrypt cert for `drive.net.mulas.me` and a `dhparams.pem` at `/etc/ssl/private/dhparams.pem`
|
||||
- Nextcloud unpacked at `/ssda1/www/drive.net.mulas.me/`
|
||||
|
||||
## Wiring Nextcloud to the stack
|
||||
|
||||
In `config/config.php` (not in this repo):
|
||||
|
||||
```php
|
||||
'dbtype' => 'mysql',
|
||||
'dbhost' => '127.0.0.1:3306',
|
||||
'dbname' => '<MYSQL_DATABASE>',
|
||||
'dbuser' => '<MYSQL_USER>',
|
||||
'dbpassword' => trim(file_get_contents('/opt/nextcloud/secrets/mariadb_app_password.txt')),
|
||||
|
||||
'memcache.local' => '\OC\Memcache\APCu',
|
||||
'memcache.distributed' => '\OC\Memcache\Memcached',
|
||||
'memcache.locking' => '\OC\Memcache\Redis',
|
||||
'redis' => ['host' => '127.0.0.1', 'port' => 6379],
|
||||
'memcached_servers' => [['127.0.0.1', 11211]],
|
||||
```
|
||||
|
||||
## Things worth knowing before reusing this elsewhere
|
||||
|
||||
- The compose file publishes 3306/6379/11211 on all interfaces — fine when Nextcloud runs on the same host and the box has a firewall, but bind them to `127.0.0.1` if you're not in that situation.
|
||||
- `set_real_ip_from` in `nginx.conf` trusts `127.0.0.1` and `192.168.1.0/24`. Change it for your network.
|
||||
- `ssl.conf` is TLS 1.2 only. There's a commented-out line to flip on TLS 1.3 when you're ready.
|
||||
- `client_max_body_size` is 50 GB and the proxy/fastcgi timeouts are essentially infinite — that's deliberate for large WebDAV uploads and long sync sessions, not an oversight.
|
||||
|
||||
## License
|
||||
|
||||
BSD 3-clause — see [LICENSE](LICENSE).
|
||||
|
||||
Reference in New Issue
Block a user