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.

Installation von Nextcloud im Docker-Container mit VPN-Schutz
Photo by Alex Machado / Unsplash

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:

  1. Docker und Docker-Compose sind installiert. Anleitungen findest du auf den offiziellen Seiten von Docker und Docker-Compose.
  2. 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.
  3. Server ist Docker-optimiert: Dein Server sollte ein aktuelles Betriebssystem, ausreichend Ressourcen und eine stabile Internetverbindung haben.
  4. 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.

  1. 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.