Installation von Nextcloud im Docker-Container mit VPN-Schutz
Sichere deine Nextcloud-Installation mit Docker und VPN! In dieser Anleitung lernst du, wie du Gluetun als VPN-Client einrichtest.
In diesem Artikel zeige ich dir, wie du Nextcloud sicher über Docker mit Gluetun als VPN-Client betreibst. Dabei wird Nextcloud über ein internes Docker-Netzwerk mit Gluetun verbunden, sodass nur die IP des VPN-Providers verwendet wird. Dieses Setup schützt deine Daten und bietet eine sichere Umgebung für deine Anwendungen.
Voraussetzungen
Bevor du mit der Installation beginnst, stelle sicher, dass folgende Voraussetzungen erfüllt sind:
- Docker und Docker-Compose sind installiert. Anleitungen findest du auf den offiziellen Seiten von Docker und Docker-Compose.
- Zugriff auf einen unterstützten VPN-Provider: Gluetun benötigt Zugangsdaten zu einem VPN-Anbieter. Die Liste der unterstützten Anbieter findest du in der Gluetun-Dokumentation.
- Server ist Docker-optimiert: Dein Server sollte ein aktuelles Betriebssystem, ausreichend Ressourcen und eine stabile Internetverbindung haben.
- Grundkenntnisse in Docker und Netzwerken: Für das Setup benötigst du ein Basiswissen in diesen Bereichen.
1. Verzeichnisstruktur anlegen
Erstelle zunächst die Verzeichnisse für Gluetun und Nextcloud:
mkdir -p /opt/gluetun
mkdir -p /opt/nextcloud
Diese Verzeichnisse enthalten später die Konfigurationsdateien sowie die docker-compose.yml
.
2. Gluetun VPN einrichten
Wechsle in das Verzeichnis /opt/gluetun
und erstelle eine docker-compose.yml
:
cd /opt/gluetun
nano docker-compose.yml
Inhalt der docker-compose.yml
:
version: "3.8"
services:
gluetun:
image: qmcgaw/gluetun
container_name: gluetun
cap_add:
- NET_ADMIN
volumes:
- ./config:/gluetun
environment:
- VPN_SERVICE_PROVIDER=your-vpn-provider
- VPN_TYPE=openvpn
- VPN_USERNAME=your-username
- VPN_PASSWORD=your-password
- SERVER_COUNTRIES=Germany
- TZ=Europe/Berlin
networks:
gluetun_network:
ipv4_address: 192.168.100.2
ports:
- 8888:8888 # Gluetun Dashboard (optional)
- 127.0.0.1:8000:8000/tcp # Control server
- 127.0.0.1:9200:9200 #elasticsearch Nextcloud
- 127.0.0.1:9980:9980 #onlyoffice
- 127.0.0.1:12999:12999 #youtube signatur
restart: always
networks:
gluetun_network:
driver: bridge
ipam:
config:
- subnet: 192.168.100.0/24
Gluetun starten:
docker-compose up -d
Überprüfe, ob Gluetun läuft:
docker ps
Das interne Netzwerk 192.168.100.0/24
stellt sicher, dass die Container über Gluetun verbunden sind.
Weitere Tipps zur Optimierung von VPN-Setups in Docker findest du in meinem Artikel OpenVPN Setup mit Docker.
3. Nextcloud mit Redis, MariaDB und Elasticsearch einrichten
Wechsle in das Verzeichnis /opt/nextcloud
und erstelle eine neue docker-compose.yml
:
cd /opt/nextcloud
nano docker-compose.yml
Inhalt der docker-compose.yml
:
version: "3.8"
services:
nextcloud:
build:
context: .
dockerfile: Dockerfile
image: custom-nextcloud
container_name: nextcloud
depends_on:
- mariadb
- redis
- elasticsearch
environment:
- MYSQL_HOST=192.168.100.4
- NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.example.com
- NEXTCLOUD_DATA_DIR=/var/www/html/data
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=strongpassword
- REDIS_HOST=192.168.100.5
- OVERWRITEPROTOCOL=https
- OVERWRITECLIURL=https://cloud.domain.tld/
- PHP_OPCACHE_MEMORY_CONSUMPTION=512
volumes:
- ./config:/var/www/html/config
- ./dateien:/var/www/html/data
- ./apps:/var/www/html/apps
- ./custom_apps:/var/www/html/custom_apps
- ./opcache-recommed.ini:/usr/local/etc/php/conf.d/opcache-recommend.ini
restart: always
networks:
gluetun_network:
ipv4_address: 192.168.100.3
mariadb:
image: mariadb
container_name: mariadb
environment:
- MYSQL_ROOT_PASSWORD=strongrootpassword
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=strongpassword
volumes:
- ./db:/var/lib/mysql
networks:
gluetun_network:
ipv4_address: 192.168.100.4
restart: always
redis:
image: redis:alpine
container_name: redis
command: redis-server --requirepass strongredispassword
networks:
gluetun_network:
ipv4_address: 192.168.100.5
restart: always
elasticsearch:
image: elasticsearch:8.10.2
container_name: elasticsearchcommand: sh -c "bin/elasticsearch-plugin install --batch ingest-attachment; /bin/tini -s /usr/local/bin/docker-entrypoint.sh eswrapper"
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
user: 1000:1000
ulimits:
memlock:
soft: -1
hard: -1
networks:
gluetun_network:
ipv4_address: 192.168.100.6
restart: always
networks:
gluetun_network:
external: true
Möchtest du Nextcloud zusätzlich mit einem Reverse-Proxy wie Nginx nutzen? Dann sieh dir meinen Artikel Setup: Nextcloud mit Nginx an.
Dockerfile erstellen
Um beispielsweise in Nextcloud die App "NCDownloader" nutzen zu können, muss das Nextcloud Image neu erstellt werden, dies geschieht mit einem Dockerfile.
nano Dockerfile
FROM nextcloud:latest
RUN apt-get update && \
apt-get install -y aria2 curl ffmpeg python3 && \
curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp && \
chmod a+rx /usr/local/bin/yt-dlp && \
apt-get clean && rm -rf /var/lib/apt/lists/*
Für benötigte PHP Anpassungen wird noch eine Datei benötigt.
nano opcache-recommend.ini
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=12000
opcache.memory_consumption=512
opcache.save_comments=1
opcache.revalidate_freq=60
Falls das Netzwerk gluetun_network
noch nicht existiert, erstelle es manuell:
docker network create \
--driver bridge \
--subnet=192.168.100.0/24 \
gluetun_network
5. Nextcloud-Container starten
Starte die Nextcloud-Container:
docker-compose up -d
Prüfe den Status der Container:
docker ps
6. VPN-Verbindung testen
Stelle sicher, dass die Nextcloud-Container ausschließlich über das VPN kommunizieren:
Überprüfe die öffentliche IP:
curl ifconfig.me
Öffne eine Shell im Nextcloud-Container:
docker exec -it nextcloud bash
Die angezeigte IP sollte die des VPN-Providers sein.
Teste, ob die Verbindung ohne VPN funktioniert, indem du Gluetun stoppst:
docker stop gluetun
Ohne Gluetun sollte die Nextcloud-Instanz nicht mehr erreichbar sein.
- Nginx Konfiguration
Nun wird noch eine Nextcloud Konfiguration benötigt damit Nextcloud überhaupt erreichbar ist. Dazu wird ein Letsencrypt Zertifikat erstellt, sowie das passende Nginx File. Damit wird der Gluetun Container eingebunden in den location Block.
certbot certonly --nginx -d cloud.domain.tld
nano /etc/nginx/sites-available/nginx
server {
listen 80;
listen [::]:80;
server_name cloud.domain.tld;
# Umleitung von HTTP auf HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.domain.tld;
# SSL-Zertifikate
ssl_certificate /etc/letsencrypt/live/cloud.domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.domain.tld/privkey.pem;
# SSL-Optionen
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'HIGH:!aNULL:!MD5';
# Hauptlocation für Nextcloud
location / {
proxy_pass http://192.168.100.2; # dies ist die adresse zu Gluetun
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
#add_header Content-Security-Policy "default-src 'self'; connect-src 'self'; font-src 'self'; img-src 'self'";
client_max_body_size 512M;
access_log /var/log/nginx/nextcloud.access.log;
error_log /var/log/nginx/nextcloud.error.log;
}
}
service nginx restart
Mit diesem Setup ist deine Nextcloud-Instanz sicher über das VPN verbunden und verwendet ausschließlich die IP-Adresse des VPN-Providers. Weitere Schritte wie SSL-Integration oder Monitoring kannst du für eine optimierte Umgebung hinzufügen.
Bei einem Neustart von Gluetun muss der Container von Nextcloud ebenfalls neu gestartet werden. Dann sollte alles wieder laufen.
IP-Adresse einmal am Tag erneuern
Damit wir jeden Tag eine neue Adresse erhalten, muss ein Skript her der immer nachts läuft. Dazu dieses Skript erstellen.
nano /opt/gluetun/restartvpn.sh
Hier wird folgendes eingetragen
#!/usr/bin/env bash
echo "BEGIN $(date --rfc-3339=seconds)" 2>&1 | tee -a /var/log/restartvpn.log
curl -s -X GET "http://127.0.0.1:8000/v1/publicip/ip" 2>&1 | tee -a /var/log/restartvpn.log # Print the original IP
curl -s -X PUT -H "Content-Type: application/json" -d '{"status":"stopped"}' "http://127.0.0.1:8000/v1/openvpn/status" 2>&1 | tee -a /var/log/restartvpn.log # Stop OpenVPN
sleep 5
curl -s -X PUT -H "Content-Type: application/json" -d '{"status":"running"}' "http://127.0.0.1:8000/v1/openvpn/status" 2>&1 | tee -a /var/log/restartvpn.log # Start OpenVPN (changing the server it's connecting to)
sleep 5
curl -s -X GET "http://127.0.0.1:8000/v1/openvpn/status" 2>&1 | tee -a /var/log/restartvpn.log # Print the Gluetun status
curl -s -X GET "http://127.0.0.1:8000/v1/publicip/ip" 2>&1 | tee -a /var/log/restartvpn.log # Print the new IP
echo "END $(date --rfc-3339=seconds)" 2>&1 | tee -a /var/log/restartvpn.log
und anschliessend im Crontab des Root Nutzers täglich laufen lassen.
Cronjob einrichten für Nextcloud
Damit die benötigten Cronjob für Nextcloud laufen folgendes eintragen im Crontab File des Root Nutzers.
#nextcloud
@hourly docker exec -u www-data nextcloud php /var/www/html/occ files:scan --all
@hourly docker exec -u www-data nextcloud php /var/www/html/occ news:updater:all-feed
*/30 * * * * docker exec -u www-data nextcloud php /var/www/html/occ preview:pre-generate
*/30 * * * * docker exec -u www-data nextcloud php /var/www/html/occ news:updater:update-user
* */12 * * * docker exec -u www-data nextcloud php /var/www/html/occ memories:index
*/5 * * * * docker exec -u www-data nextcloud php /var/www/html/cron.php
0 0 1 * * docker exec -u www-data nextcloud php /var/www/html/occ versions:cleanup
0 4 * * 0 docker exec -u www-data nextcloud php /var/www/html/occ files:cleanup
*/10 * * * * docker exec -u www-data nextcloud php /var/www/html/occ background:cron
0 1 * * * docker exec -u www-data nextcloud php /var/www/html/occ preview:pre-generate
*/10 * * * * docker exec -u www-data nextcloud php /var/www/html/occ music:scan --all
Damit sollte nun alles funktionieren. lasst es mich wissen. Würde mich auch über ein Abo freuen. Damit würdet ihr auf dem laufenden bleiben bei neuen Artikeln.