Why Nextcloud
Nextcloud is a well-known private file cloud, that can be hosted on any your server. It’s also interesting for having clients to run on almost all platforms.
This cloud did much about security. The other side of this is the requirement to run Nextcloud under HTTPS protection, it can’t be used under unencrypted HTTP. Here provided the info on how to set it up behind quite complicated nginx-proxy-letsencrypt-companion, but it’s not my favourite solution, I like traefik much more. Here we’ll describe how did I set up Nextcloud with Traefik proxying.
Traefik configuration
First, you should create traefik/traefik.toml and traefik/acme.json files as described here. The traefik.toml that I used for Nextcloud:
logLevel = "ERROR"
defaultEntryPoints = ["http","https"]
[accessLog]
filePath = "/dev/stdout"
[traefikLog]
filePath = "/dev/stdout"
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "mszuyev.xyz"
watch = true
exposedbydefault = false
[acme]
email = "[email protected]"
storage = "acme.json"
entryPoint = "https"
OnHostRule = true
[acme.httpChallenge]
entryPoint = "http"
Comparing to traefik.toml from here - only [docker].domain and [acme].email fields have changed, everything else remain intact.
Final docker-compose.yml (docker-compose.override.yml) part
version: '3.7'
services:
traefik:
image: traefik:alpine
container_name: traefik
command: --configFile=/traefik.toml
restart: unless-stopped
networks:
- main
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik/traefik.toml:/traefik.toml
- ./traefik/acme.json:/acme.json
labels:
- "traefik.enable=false"
db:
image: mariadb
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: always
volumes:
- db:/var/lib/mysql
networks:
main:
ipv4_address: 172.31.0.31
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_PASSWORD=
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
redis:
image: redis:alpine
container_name: redis
restart: always
networks:
- main
app:
image: nextcloud
links:
- redis
container_name: nextcloud
environment:
- REDIS_HOST=redis
volumes:
- nextcloud:/var/www/html
networks:
- main
labels:
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.docker.network=main"
- "traefik.frontend.rule=Host:$CLOUD_DOMAIN"
- "traefik.frontend.headers.SSLRedirect=true"
- "traefik.frontend.headers.SSLForceHost=true"
- "traefik.frontend.priority=1"
restart: always
volumes:
nextcloud:
db:
networks:
main:
external: true
Here $CLOUD_DOMAIN is a domain where our Nextcloud server is publicly available. It also should be used above in traefik/traefik.toml configuration
I used a static IPv4 address for MySQL server because Nextcloud can’t access MySQL server for some unknown (for me, of course) reason. Keep in mind that assigning static IPs is available only for custom networks, created with explicitly specfied subnet - that’s why we describe “main” network as external. To create it, run
docker network create --subnet="172.31.0.0/16" --gateway="172.31.0.1" main
Of course, you can use more narrow subnet, for example, 172.31.0.0/24.
Also, create .env file in the same dir as docker-compose.yml:
MYSQL_ROOT_PASSWORD=<YOUR_MYSQL_ROOT_PASSWORD>
Trouble shooting
In some cases you can get an infinite login procedure sequence (login page -> enter login && pass -> hit Enter -> login page -> enter login && pass -> hit Enter -> …) - here, for example, this problem has mentioned and the solution they suggest is to edit the Nextcloud config.
So, you need to replace
'overwrite.cli.url' => 'https://$CLOUD_DOMAIN',
in the config/config.php file of your Nextcloud to
'overwrite.cli.url' => 'https://$CLOUD_DOMAIN/',
'overwritehost' => '$CLOUD_DOMAIN',
'overwriteprotocol' => 'https',
Then, probably, the problem will go away.
The another possible reason is when you submitting your form, the error of kind “Refused to send form data to ‘http://cloud.domainname/' because it violates the following Content Security Policy directive: “form-action ‘self’”” occurs in your browser console. I actually don’t know the solution, and there are only two things that worked for me:
- connect to the VPN, clean cookies and try again. Here is a brief help how to set up VPN on any VPS.
- connect to another network, clean cookies and try again
The info from here, here, and so on - didn’t work for me, probably I’ve worked with insecure networks or incorrect routing (in 100% cases these issues was in public networks).