Docker Nextcloud SSL - letsencrypt https

Um mit meiner NAS Kontakte, Termine und Fotos zu synchronisieren, habe ich Nextcloud getestet und damit anderen Cloudanbietern für meine privaten Daten ein Stück weit den Rücken gekehrt. Dank Docker ist die Installation einfacher und flexibler denn je und ermöglicht es, NextCloud auf einer beinahe beliebigen Hardware zu betreiben.  

Docker Basics
Docker ermöglicht es, Applikationen per Befehl in einem sogenannten Container zu starten.
Ein Container ist eine vom Betriebssystem (OS) unabhängige isolierte Umgebung:
Das OS spielt also keine Rolle, vorausgesetzt Docker lässt sich installieren.
Beim ersten Start eines Containers, lädt Docker selbstständig alle notwendigen Quellen
aus dem Internet.
Docker kann unter Windows, macOS oder einer Linux-Distribution installiert werden,
siehe auch: Docker

Neben Docker, habe ich als Basis für NextCloud ursprünglich folgendes Github-Projekt eingesetzt und später adaptiert: https://github.com/ichiTechs/Dockerized-SSL-NextCloud-with-MariaDB. Das Projekt besteht im wesentlichen aus zwei Dateien, welche ich in angepasster Version hier beschreibe. Der Hauptgrund für die Anpassung war die Trennung des Reverse-Proxy vom NextCloud-Setup, wodurch mehrere Webdienste mit einem jeweiligen SSL Zertifikat betrieben werden können. Die NextCloud-Installation auf einer Hardware, bei mir zu Hause, kann mit dem Let's Encrypt-Reverse-Proxy verschlüsselt und sicher vom Internet erreicht werden.

Schritt für Schritt

Docker und Let's Encrypt Reverse-Proxy:

  1. Hardware auswählen: PC, Notebook oder besser: virtueller Server, Raspberry PI oder eine NAS: QNAP, Synology oder Eigenbau-NAS
  2. OS installieren: Windows, Linux
  3. Docker installieren, siehe: Docker
  4. DNS-Eintrag im Internet auf die öffentliche IP-Adresse erstellen und
    nginx-Reverse Proxy Setup: nginx-LetsEncrypt Reverse Proxy in der Praxis

Container für NextCloud:

  1. docker-compose.yml und nginx.conf anlegen
  2. Container starten

docker-compose.yml

Die Datei docker-compose.yml beinhaltet die Konfig für die Container, wie z.B. den Datenbank-Benutzer, die Domäne und Netzwerksettings für die Kommunkation der einzelnen Container untereinander. Die Datei sollte entsprechend vor dem ersten Start angepasst werden. Wie bereits erwähnt, wird für das hier beschriebene Setup neben Docker und dem nginx-LetsEncrypt Reverse Proxy ein DNS-Eintrag auf die IP der Nextcloud-Installation vorausgesetzt. 

Inhalt der Datei: docker-compose.yml

[+]
version: '2'
services:
  web:
    image: nginx
    container_name: nextcloud_webserver
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    links:
      - app
    volumes_from:
      - app
    environment:
      - VIRTUAL_HOST=next.domain.tld
      - VIRTUAL_NETWORK=nginx-proxy
      - VIRTUAL_PORT=80
      - LETSENCRYPT_HOST=next.domain.tld
      - LETSENCRYPT_EMAIL=admin@domain.tld
    networks:
      - nextcloud
    restart: always
  app:
    image: nextcloud:fpm
    container_name: nextcloud_fpm
    links:
      - db
      - redis
    volumes:
      - ./apps:/var/www/html/apps
      - ./config:/var/www/html/config
      - ./data:/var/www/html/data
    networks:
      - nextcloud
    restart: always
  redis:
    image: redis
    container_name: nextcloud_redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - ./redis:/data
    entrypoint: redis-server --appendonly yes
    networks:
      - nextcloud
    restart: always
  db:
    image: mariadb:10.5
    container_name: nextcloud_db
    volumes:
      - ./db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=xxx
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=xxx
    networks:
      - nextcloud
    restart: always
networks:
  nextcloud:
    external:
      name: webproxy

nginx.conf

Inhalt der Datei nginx.conf

[+]
# config file for nginx webserver to work with NextCloud app.

user www-data;

events {
  worker_connections 2048;
}

http {
  upstream backend {
      server app:9000;
  }
  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  server {
    listen 80;

    # Add headers to serve security related headers
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;

    root /var/www/html;
    client_max_body_size 0; # 0=unlimited - set max upload size
    fastcgi_buffers 64 4K;

    gzip off;

    index index.php;
    error_page 403 /core/templates/403.php;
    error_page 404 /core/templates/404.php;

    rewrite ^/.well-known/carddav /remote.php/dav/ permanent;
    rewrite ^/.well-known/caldav /remote.php/dav/ permanent;

    location = /robots.txt {
      allow all;
      log_not_found off;
      access_log off;
    }

    location ~ ^/(build|tests|config|lib|3rdparty|templates|data)/ {
      deny all;
    }

    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
      deny all;
    }

    location / {
      rewrite ^/remote/(.*) /remote.php last;
      rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
      try_files $uri $uri/ =404;
    }

    location ~ \.php(?:$|/) {
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
      fastcgi_param HTTPS on;
      fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
      fastcgi_pass backend;
      fastcgi_intercept_errors on;
    }

    # Adding the cache control header for js and css files
    # Make sure it is BELOW the location ~ \.php(?:$|/) { block
    location ~* \.(?:css|js)$ {
      add_header Cache-Control "public, max-age=7200";
      # Add headers to serve security related headers
      add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
      add_header X-Content-Type-Options nosniff;
      add_header X-Frame-Options "SAMEORIGIN";
      add_header X-XSS-Protection "1; mode=block";
      add_header X-Robots-Tag none;
      add_header X-Download-Options noopen;
      add_header X-Permitted-Cross-Domain-Policies none;
      # Optional: Don't log access to assets
      access_log off;
    }

    # Optional: Don't log access to other assets
    location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|swf)$ {
      access_log off;
    }
  }
}

Erstellen der Konfig und Start der Container

Folgender Befehl erstellt die Container mit der in der docker-compose.yml hinterlegten Konfig.

docker-compose up -d

Container hinzufügen / docker-compose.yml anpassen

Collabora hinzufügen

Collabora ist eine Online-Version von LibreOffice und ermöglicht es, Office-Dokumente online über den Webbrowser zu erstellen oder gemeinsam zu bearbeiten. Voraussetzung für die Nutzung aus dem Internet ist ein zusätzlicher DNS-Name, also ein A-Record auf die öffentliche IP des Servers und ein zusätzliches Let`s Encrypt-Zertifikat, welches wiederum über die Environment-Variablen definiert werden kann und automatisch vom nginx-LetsEncrypt Reverse Proxy ausgestellt und verlängert wird.

Um Callabora in Nextcloud zu verwenden, kann folgenden Block in docker-compose.yml angepasst und eingefügt werden:

[+]
collabora:
 image: collabora/code
 container_name: nextcloud_collabora
 expose:
 - 9980
 cap_add:
 - MKNOD
 environment:
 - domain=next.deineDomain
 - VIRTUAL_HOST=office.deineDomain
 - VIRTUAL_NETWORK=nginx-proxy
 - VIRTUAL_PORT=9980
 - VIRTUAL_PROTO=https
 - LETSENCRYPT_HOST=office.deineDomain
 - LETSENCRYPT_EMAIL=deineEmail-Addresse
 networks:
 - nextcloud
 restart: always

OnlyOffice hinzufügen

Auch mit Only-Office können Word, Excel oder PowerPoint-Dokumente online bearbeitet werden. Auch hier wird für den Zugriff aus dem Internet ein zusätzlicher DNS-Name vorausgesetzt: nginx-LetsEncrypt Reverse Proxy. Only-Office ist im Vergleich zu Collabora etwas schlanker, da wesentlich mehr Programmlogik im Browser stattfindet. Verglichen mit Collabora hatte ich bisher mit OnlyOffice auch keine Verbindungsabbrüche beim Bearbeiten von Dokumenten und somit Collabora mittlerweile mit OnlyOffice ersetzt.

[+]
 onlyoffice:
 image: onlyoffice/documentserver
 container_name: nextcloud_onlyoffice
 stdin_open: true
 tty: true
 volumes:
  - ./onlyoffice/data:/var/lib/onlyoffice/documentserver/App_Data 
 expose:
 - '80'
 - '443'
 environment:
 - VIRTUAL_HOST=document.domain.xx
 - VIRTUAL_NETWORK=nginx-proxy
 - LETSENCRYPT_HOST=document.domain.xx
 - LETSENCRYPT_EMAIL=email@domain.xx
 - JWT_ENABLED=true
 - JWT_SECRET=secretwithoutnumbers
 - JWT_HEADER=Authorization
 networks:
 - nextcloud
 restart: always

Angepasstes docker-compose.yml mit OnlyOffice

[+]
version: '2'

services:
  web:
    image: nginx
    container_name: nextcloud_webserver
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    links:
      - app
    volumes_from:
      - app
    environment:
      - VIRTUAL_HOST=next.domain.tld
      - VIRTUAL_NETWORK=nginx-proxy
      - VIRTUAL_PORT=80
      - LETSENCRYPT_HOST=next.domain.tld
      - LETSENCRYPT_EMAIL=admin@.domain.tld
    networks:
      - nextcloud
    restart: always
  app:
    image: nextcloud:fpm
    container_name: nextcloud_fpm
    links:
      - db
      - redis
      - onlyoffice
    volumes:
      - ./apps:/var/www/html/apps
      - ./config:/var/www/html/config
      - ./data:/var/www/html/data
    networks:
      - nextcloud
    restart: always
  redis:
    image: redis
    container_name: nextcloud_redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - ./redis:/data
    entrypoint: redis-server --appendonly yes
    networks:
      - nextcloud
    restart: always
  onlyoffice:
     image: onlyoffice/documentserver
     container_name: nextcloud_onlyoffice
     stdin_open: true
     tty: true 
     volumes:
        - ./onlyoffice/data:/var/lib/onlyoffice/documentserver/App_Data 
     expose:
        - '80'
        - '443'
     environment:
        - VIRTUAL_HOST=document.domain.tld
        - VIRTUAL_NETWORK=nginx-proxy
        - LETSENCRYPT_HOST=document.domain.tld
        - LETSENCRYPT_EMAIL=adin@domain.tld
        - JWT_ENABLED=true
        - JWT_SECRET=xxx
        - JWT_HEADER=Authorization
     networks:
        - nextcloud
     restart: always 
  db:
    image: mariadb:10.5
    container_name: nextcloud_db
    volumes:
      - ./db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=xxx
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=xxx
    networks:
      - nextcloud
    restart: always
networks:
  nextcloud:
    external:
      name: webproxy

OnlyOffice leere Dokumente

ACHTUNG: Wenn die Adresse für die internen Anforderungen nicht aufgelöst werden kann, werden die Dokumente in NextCloud nicht upgedated, sie befinden sich dann noch im Container, in dem Ordner: /var/lib/onlyoffice/documentserver/App_Data. Aus diesem Grund sollte der Ordner unbedingt auf einen lokalen Ordner gemappt werden um einen Datenverlust zu vermeiden. Verantwortlich für das Updaten der Only-Office-Dokumente in NextCloud ist der Cron-Job, daher ist es auch nicht unwesentlich, dass dieser regelmäßig läuft.

Wartung

Container updaten

docker-compose up -d

Unter Umständen wird beim nächsten Aufruf der Weboberfläche Nextcloud upgedated:

Ev. müssen div. Apps erneut aktiviert werden, entweder über die GUI, oder per Command:

docker exec --user www-data nextcloud_fpm php occ app:enable twofactor_totp calendar news contacts onlyoffice phonetrack previewgenerator spreed audioplayer

Files scannen

docker exec --user www-data nextcloud_fpm php occ files:scan --all

Geburtstagskalender neu aufbauen

docker exec --user www-data nextcloud_fpm php occ dav:sync-birthday-calendar User

Backup: Datenbank Dump

docker exec db mysqldump --user=root --password=Password -h localhost nextcloud > dump.sql.gz

Tuning - Einstellungen - Optimierungen

CronJob

am Host-OS

sudo crontab -e
*/5 * * * * docker exec --user www-data nextcloud_fpm php -f /var/www/html/cron.php  > /dev/null 2>&1

Sicherheits und Einrichtungswarnungen

docker exec --user www-data nextcloud_fpm php occ maintenance:mode --on
docker exec --user www-data nextcloud_fpm php occ db:convert-filecache-bigint
docker exec --user www-data nextcloud_fpm php occ maintenance:mode --off
docker exec --user www-data nextcloud_fpm php occ db:add-missing-indices

Brute Force Protection und Reverse Proxy:

in Protokollierung:

/config/config.php:

hinzufügen von:

'trusted_proxies' => array('172.18.0.2'),
 'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR')

Connections:

root@soxn:/nextcloud# nano nginx.conf

events {
worker_connections 768;
}

changed to 2048; 

NGINX Bad Gateway - OnlyOffice

Anfangs habe ich folgenen Workaround für den Start von OnlyOffice benötigt, mittlerweile ist dieser hinfällig ...

Bash-Script:

#!/bin/bash 

url="https://document.DOMAIN"
keyword="Bad Gateway"

if curl -s "$url" | grep "$keyword"
then
    # if the keyword is in the conent
    echo " ERROR"
	docker restart onlyoffice
else
    echo "the website is working fine"
fi

sudo crontab -e

*/10 * * * * . /nextcloud/check.sh > /dev/null 2>&1

Preview Images

Anzeigen der zuletzt geänderten Dateien:

find . -type f -cmin 5

Setting lesen: docker exec --user www-data nextcloud_fpm php -d memory_limit=4G occ config:app:get previewgenerator squareSizes

docker exec --user www-data nextcloud_fpm php -d memory_limit=4G occ config:app:set --value "256" previewgenerator squareSizes

Client_max_body_size

File uploadsize.conf

client_max_body_size 10G;

docker-compose.yml 

services:
 proxy:
 image: jwilder/nginx-proxy
 container_name: proxy
 ports:
 - 80:80
 - 443:443
 volumes:
 - ./proxy/conf.d:/etc/nginx/conf.d
 - ./proxy/vhost.d:/etc/nginx/vhost.d
 - ./proxy/html:/usr/share/nginx/html
 - ./proxy/certs:/etc/nginx/certs:ro
 - /var/run/docker.sock:/tmp/docker.sock:ro
 - ./uploadsize.conf:/etc/nginx/conf.d/uploadsize.conf:ro

Redis

config/apcu.config.php

<?php
$CONFIG = array (
 'memcache.local' => '\OC\Memcache\APCu',
 'redis' => array(
 'host' => 'nextcloud_redis',
 'port' => 6379,
 ),
 'memcache.locking' => '\OC\Memcache\Redis',
); 

Docker .env

Wird in dem Ordner in dem sich die docker-compose.yml Datei befindet eine .env-Datei angelegt, können damit Docker-Parameter geändert werden:

#.env
COMPOSE_HTTP_TIMEOUT=200

Troubleshooting

Internal Server Error

Nach einem Stromausfall hatte ich folgendes Problem:

Internal Server Error

The server encountered an internal error and was unable to complete your request.
Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.
More details can be found in the server log.

Der Redis-Container hat dabei ständig neugestartet. Im Log konnte ich folgenden Eintrag finden:

Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

Nachdem ich den Redis-Ordner ./nextcloud/redis gelöscht habe, konnte die Installation wieder gestartet werden.

WARNING: [pool www] server reached pm.max_children setting (5), consider raising it 

Mit den Standardsettings wurde im Log des nextcloud:fpm Containers folgende Warnung angzeigt:

WARNING: [pool www] server reached pm.max_children setting (5), consider raising it 

Das Limit kann in der FPM-Config-Datei www.conf erhöht werden, diese ist im nextcloud:fpm Container versteckt:

Um die Datei anzuzeigen, können wir uns in den Container verbinden:

docker exec --user www-data -it nextcloud_fpm bash

Damit die Änderungen an der Konfig-Datei auch nach einem Reboot vorhanden sind, kann die Datei außerhalb des Containers abgelegt werden, dazu muss die Datei aber vorhanden sein:

mit cat /usr/local/etc/php-fpm.d/www.conf den Inhalt der www.conf anzeigen lassen und im Root Ordner www.conf anlegen:

Folgende Zeile in nextcloup_fpm hinzufügen:

- ./www.conf:/usr/local/etc/php-fpm.d/www.conf #added 4 max-childs-config

mit nano.conf kann die www.conf angepasst werden:

Nachdem ich in meiner NAS 8GB Ram habe habe ich folgende Werte angepasst:

pm.max_children = 80 #(vorher 5)
pm.start_servers = 2
pm.min_spare_servers = 2 #(voher 1)
pm.max_spare_servers = 15 #(vorher 3)

Die komplette Datei schaut bei mir wie folgt aus:

www.conf

[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 80
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 15

 

Exception: Database error when running migration latest for app core

An exception occurred while executing a query: SQLSTATE[HY000]: General error: 4047 InnoDB refuses to write tables with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE.

Das Problem liegt an der MariaDB-Version. Ab Version 10.6 werden keine komprimierten Spalten mehr unterstützt. 

Ich habe das Problem fürs erste gelöst, indem ich die Version 10.5 von MariaDB verwende:

docker-compose.yml

...
  db:
    image: mariadb:10.5
    container_name: nextcloud_db
...

siehe: help.nextcloud.com/t/update-to-22-failed-with-database-error-updated/120682

Docker als Benutzer / ohne Root-Rechte

sudo groupadd docker
sudo gpasswd -a $USER docker

Router OpenWrt- interne IP

Nachdem meine NAS und somit die NextCloud-Installation zu Hause direkt über das WLAN erreichbar ist, ohne Umweg: WLAN - Router - Internet - Router, macht es natürlich Sinn die Installation direkt aufzurufen, dazu reicht ein zusätzlicher DNS-Eintrag am Router: Split-DNS. Die NextCloud-Domain wird im WLAN somit mit einer internen IP aufgelöst.

Hier als Beispiel die Anpassung meines auf OpenWrt-basierenden Router:

vi /etc/config/dhcp

config 'domain'
option name 'next.domain.xx'
option ip 192.168.1.5

config 'domain'
option name 'office.domain.xx'
option ip 192.168.1.5

config 'domain'
option name 'document.domain.xx'
option ip 192.168.1.5

Windows Webdav

\\next.domain.xx@SSL\DavWWWRoot\remote.php\dav\files\user

OrdnerSync Rasperry PI

Installieren:

sudo apt install owncloud-client-cmd

und eintragen in crontab:

crontab -e

* * * * * owncloudcmd /lokalerOrdner https://user:password@nextcloudURL/remote.php/webdav/Ordner >/dev/null 2>&1

Fazit

NextCloud wertet meine NAS um unzählige Funktionen auf und bietet mir die Möglichkeit Cloud-Dienste wieder nach Hause zu bringen:
Mit NextCloud habe ich jetzt Sync-Clients für Android, Windows und Linux, kann im Browser Office-Dokumente, Diagramme oder Abstimmungen erstellen. Neben den Fotos vom SmartPhone kann ich zudem meine Kontakte und Kalendereinträge synchronisieren oder mit anderen teilen und könnte sogar einen eigenen Messenger inkl. Anruf- und Video- Funktion betreiben und vieles mehr ...

positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE für deine Bewertung!


veröffentlicht am 17.07.2018 von Bernhard
geändert am 16.11.2021 von Bernhard


Top-Artikel in diesem Bereich

Preview ioBroker installieren - Docker

ioBroker installieren - Docker

geändert: 13.11.2020 von Bernhard (Erstveröffentlichung: 06.11.2020)

Mit ioBroker können verschiedene Automatisierungslösungen oder Geräte in einem System zusammengefasst werden. Um bestimmte Gateways oder Geräte ansprechen zu können, werden in ioBroker verschiedene Adapter verwendet.  ... weiterlesen

Preview Conbee 2: Phoscon deCONZ - Docker Inbetriebnahme | Review

Conbee 2: Phoscon deCONZ - Docker Inbetriebnahme | Review

geändert: 01.08.2021 von Bernhard (Erstveröffentlichung: 20.08.2020)

Mit dem kleinen USB-Stick Conbee2 habe ich meine NAS um ein Zigbee-Gateway erweitert. Conbee2 kann auf Raspbian, Ubuntu, Docker oder Windows installiert werden. ... weiterlesen

Preview Home-Assistant Docker und deCONZ

Home-Assistant Docker und deCONZ

geändert: 08.11.2021 von Bernhard (Erstveröffentlichung: 06.11.2020)

Dank zahlreicher Integrationsmöglichkeiten ist Home-Assistant eine einfache Plattform für das Steuern verschiedenster Smart-Home Geräte. Im Vergleich zu ioBroker ist mir der Start mit Home Assistant wesentlich einfacher gefallen. Während ich für ioBroker noch am Suchen war, welches Frontend ich für meine Dashboards verwenden könnte, hatte ich mit Home-Assistant Out of the box ein fertig eingerichtetes System. Die Lovelance Dashboards von Home Assistant kön... ... weiterlesen


Fragen / Kommentare


(sortiert nach Bewertung / Datum) [alle Kommentare(neueste zuerst)]

✍anonym
erstellt am 09.02.2020 09:02
User: Jens 
Ich bekomme nach der Installation immer nur ein 504 Gateway Time-out, wo sollte ich mit der Suche ansetzen? (Installiert ist nur: proxy, companion, db, fpm & webserver)

✍anonym
erstellt am 05.11.2019 10:11
User: Raphael 
Vielen Dank für das hilfreiche Manual!
Den Absatz um die pm.max_children zu ändern hab ich, so denke ich, nicht ganz verstanden.
Stimmt das so:?
Man verbindet sich mit dem Docker Container und bearbeitet darin die www.conf datei, indem man die Zeile mit dem Verweis auf die neue Config Datei hinzufügt.
Anschließend legt man eine www.conf Date im root ordner des Servers (außerhalb des containers) an und fügt die 4 Zeilen mit den pm.max children ein.
Aber wird nicht bei jedem neuen build des containers die www.conf im docker auf die ursprüngliche Version zurückgesetzt?

Würde mich über eine Antwort freuen... raphael_unterrainer(AT)hotmail.com

✍anonym
erstellt am 09.10.2019 20:10
User: Hallo 
Benötige mal deine Hilfe

✍anonym
erstellt am 09.10.2019 20:10
User: Zinnik 
Hallo ich habe ein Problem mit der nextcloud im docker auf einer qnap nas. Ich kann kein letsencrypt zertifikat erstellen.
Kannst du mir helfen?

Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Außerdem geben wir Informationen zu Ihrer Nutzung unserer Website an unsere Partner für soziale Medien, Werbung und Analysen weiter. Details anzeigen.