first commit

This commit is contained in:
mgutzeit 2025-03-04 18:32:20 +01:00
commit 68e9fa89af
36 changed files with 1366 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.env
vault.sh

0
README.md Normal file
View file

5
ansible-lint.yml Normal file
View file

@ -0,0 +1,5 @@
---
skip_list:
# - name[play]
# ...

35
ansible.cfg Normal file
View file

@ -0,0 +1,35 @@
[defaults]
nocows = 1
timeout = 30
forks = 50
interpreter_python = auto_silent
inventory = hosts.ini
# roles_path = ./roles
library = ./library
vault_password_file = vault.sh
# bin_ansible_callbacks = true
# stdout_callback = unixy
# callbacks_enabled = timer, profile_tasks, profile_roles
# force_handlers = true
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible/facts.cache
fact_caching_timeout = 3600
[ssh_connection]
pipelining = true
ssh_args = -o PreferredAuthentications=publickey -o ControlMaster=auto -o ControlPersist=60s
[privilege_escalation]
become = true
[diff]
always = true
context = 5

View file

@ -0,0 +1,134 @@
---
no_nginx: # es wird kein nginx template nach /etc/nginx/ kopiert
- jellyfin
docker:
containers:
ddns:
name: ddns
image: qmcgaw/ddns-updater:latest
port: 7080
user: 1200
url: ddns.mgutzeit.de
forgejo:
name: GIT_forgejo
image: codeberg.org/forgejo/forgejo:9
port: 3000
user: 1005
url: git.mgutzeit.de
jellyfin:
name: UN_jellyfin
image: lscr.io/linuxserver/jellyfin:latest
port: 8096
user: 1000
nextcloud:
name: NC_app
port: 5234
user: 1004
url: nextcloud.mgutzeit.de
vaultwarden:
name: VW_vaultwarden
bak_name: VW_backup
image: vaultwarden/server:latest
bak_image: ttionya/vaultwarden-backup:latest
port: 3080
user: 1003
url: pw.mgutzeit.de
wordpress:
name: WP_app
db_name: WP_db
web_name: WP_webserver
image: wordpress:6.7.1-fpm-alpine
db_image: mysql:8.4
port: 5080
user: 33
url: wordpress.mgutzeit.de
files:
extra_dirs:
#
# "/opt/docker/{{ docker.containers.keys() }}" wird automatisch angelegt
#
- ddns/data
- nextcloud/app
- vaultwarden/vw-data
- vaultwarden/vw-rclone-data/rclone
- wordpress/nginx-conf
- wordpress/only-nginx-conf
conf_files:
#
# name MUSS mit angegeben werden!
# Für docker-compose.yml's nur den directory namen angeben:
# <name>/docker-compose.yml.j2 > /opt/docker/<name>/docker-compose.yml
# Wenn andere Dateien src und dest:
# <src> > <dest> (duh)
# user kann angegeben werden, sonst root
#
# docker-compose.yml's:
#
- name: ddns
- name: forgejo
- name: nextcloud
- name: jellyfin
- name: vaultwarden
- name: wordpress
#
# andere Dateien
#
- src: ddns/config.json
dest: /opt/docker/ddns/data/config.json
user: 1200
name: ddns
- src: nextcloud/nginx.conf
dest: /opt/docker/nextcloud/nginx.conf
user: 1004
name: nextcloud
- src: nextcloud/Dockerfile
dest: /opt/docker/nextcloud/app/Dockerfile
user: 1004
name: nextcloud
- src: nextcloud/redis.config.php
dest: /opt/docker/nextcloud/app/redis.config.php
user: 1004
name: nextcloud
- src: nextcloud/php-fpm-www.conf
dest: /opt/docker/nextcloud/php-fpm-www.conf
user: 1004
name: nextcloud
- src: vaultwarden/.env.crypt
dest: /opt/docker/vaultwarden/.env
user: 0
name: vaultwarden
- src: vaultwarden/rclone.conf
dest: /opt/docker/vaultwarden/vw-rclone-data/rclone/rclone.conf
user: 1003
mode: "0600"
name: vaultwarden
force: no
- src: wordpress/nginx-conf/nginx.conf
dest: /opt/docker/wordpress/nginx-conf/nginx.conf
user: 33
name: wordpress
- src: wordpress/nginx-conf/options-ssl-nginx.conf
dest: /opt/docker/wordpress/nginx-conf/options-ssl-nginx.conf
user: 33
name: wordpress
- src: wordpress/only-nginx-conf/nginx.conf
dest: /opt/docker/wordpress/only-nginx-conf/nginx.conf
user: 33
name: wordpress
- src: wordpress/only-nginx-conf/options-ssl-nginx.conf
dest: /opt/docker/wordpress/only-nginx-conf/options-ssl-nginx.conf
user: 33
name: wordpress
- src: wordpress/.dockerignore
dest: /opt/docker/wordpress/.dockerignore
user: 33
name: wordpress
- src: wordpress/.env.crypt
dest: /opt/docker/wordpress/.env
user: 33
name: wordpress

17
group_vars/all/vault.yml Normal file
View file

@ -0,0 +1,17 @@
$ANSIBLE_VAULT;1.1;AES256
36306565353361636237316663653734626261323137356336653763616464346533633062316338
3834306536333430663437333435623961323937343634370a376161613262346338623064373931
66653564393432653633613236663533333035366565653334306663366338633231393463663338
6161376564376563640a306633623665363962363538613938366264653764616633343734353163
34333732303766353431393831326535343532393663383034636664373332666530323461303439
30323831303134333964643361643030313865306536313066616430353165613632396132643461
63363866306338323431633166613466303561333463313931383533303266656164373362663063
32663230376631653134383733336334653731386434633465333561333634306238666533313935
32336431373835326239666435323730316663386534613164336663636431306430346231383466
33646131313366373931373362393364633633333733363530643738386237633231386235383734
35376637363361633634663537613563373839303665366566323930316239303635323932326437
39386664366134393062663937313131376361653731626634646131613066386164646233643266
35613732613737613764386536383265656661333538643264653835656130623661363039636264
62356537353333323363396230393764383065323431616634346438323538653663646261363062
31303235663161366666353866373833636164653766326431303966343265386361383366356265
63653662646439323433

2
hosts.ini Normal file
View file

@ -0,0 +1,2 @@
[docker]
docker_host ansible_host=ansible@192.168.111.106

7
playbook.yml Normal file
View file

@ -0,0 +1,7 @@
---
- hosts: all
roles:
- docker
- nginx

View file

@ -0,0 +1,25 @@
---
- name: Stop_docker
community.docker.docker_compose_v2:
project_src: "/opt/docker/{{ item }}/"
state: absent
loop: "{{ docker.containers.keys() }}"
- name: Start_docker
community.docker.docker_compose_v2:
project_src: "/opt/docker/{{ item }}/"
build: always
state: present
pull: always
loop: "{{ docker.containers.keys() }}"
- name: Waitfor_docker
wait_for:
host: localhost
port: "{{ docker.containers.wordpress.port }}"
state: started
sleep: 1
delay: 2
timeout: 300

View file

@ -0,0 +1,71 @@
---
- tags: docker
block:
- name: Package
apt:
state: present
name:
- docker
update_cache: true
- name: Service
systemd:
state: started
name: docker
enabled: true
- name: Make sure standard directories exist for each container
ansible.builtin.file:
path: "/opt/docker/{{ item }}"
state: directory
owner: root
group: root
mode: '0755'
loop: "{{ docker.containers.keys() }}"
loop_control:
label: "/opt/docker/{{ item }}"
- name: Make sure extra directories exist
ansible.builtin.file:
path: "/opt/docker/{{ item }}"
state: directory
mode: '0755'
loop: "{{ docker.files.extra_dirs }}"
loop_control:
label: "/opt/docker/{{ item }}"
- name: Make sure ddns/data chown is correct
ansible.builtin.file:
path: /opt/docker/ddns/data
state: directory
owner: 1200
group: 1200
mode: '0755'
- name: Copy container config files
# no_log: true
template:
src: "{{ item.src | default (item.name + '/docker-compose.yml.j2') }}"
dest: "{{ item.dest | default ('/opt/docker/' + item.name + '/docker-compose.yml') }}"
owner: "{{ item.user | default ('root') }}"
group: "{{ item.user | default ('root') }}"
mode: "{{ item.mode | default('0644') }}"
force: "{{ item.force | default('yes') }}"
notify:
- Stop_docker
- Start_docker
loop_control:
label: "{{ item.src | default ( item.name + ' compose file') }}"
loop: "{{ docker.files.conf_files }}"
- name: Chown of rendering devices to usenet user
ansible.builtin.file:
path: "/dev/dri/{{ item }}"
owner: 1000
group: 1000
mode: '0660'
loop:
- card0
- renderD128

View file

@ -0,0 +1,54 @@
$ANSIBLE_VAULT;1.1;AES256
38616561366432383036333466613164336139643134306435643830343730353631313232343432
3633653932656633653832613035643963363535356264340a386330343235393662316465373765
35373137313034316632383964383532356639306133336235663835656638386436336133386433
3165376630393034310a336561326435366664376363643133326139613938323436323636626136
32316364396562623935303036616335336431336236626236616538636464623563306138633263
65323837343461666530373630343831636336356166656265393439383866633139623262353763
31616237366133613438633930366563336566303335396537303664643466383738626638346164
34326565326263373233383964643364343633613034623064623265646235396566343434333563
61613232363231376433643638623338373230653132353231653038326665383862376333656361
64646336646264363437363233663236306465613035333161646432626365343062636233323231
34646462316639636433633934646563636230623930636462303162336230393565643961636131
66313838303332623262633132646137353366306264313764393935346233386662616262383931
32346633323537666131313331653266396562616437633463656365303134373065373938646631
32356137326437653331316233313365323432663531636137353634636234666666656661343163
31313030383365363035646636623233656636383863623061393833613035653861366239643264
62306161303433653163356337656361316333383764383630346266303537313134323963653761
38333064356332623235373434313730333335653965323665643536373665393463363561666166
38366338663662346361386637616530316163653466616633653734306465356438306236323564
31323530653833313065643932653333353162626330616463373230626635326638623262386263
66626366616631633532633065396431313635626363346433363638363762646435663832346632
35353538336532646666346639643430656565653766626135333863636665643738653939306230
35373465353034376565616430643238303236363765393237316636663262313462666439663061
64303261373038333832616538396565343966363166613837376262396436396164653262396238
61313264313833343562356233353639353535386163383131373764343932373265663139303733
63666138373466326139396537366235326535333533363834373365356366646636653633613530
30383366383139643833393434336531346164333866333563623030373633356137386239303637
36383736323938636366323166346561613035343936616262636463613235643466656239653261
34666565333839383465303366313931313535643537373839366561393836366334616232303036
64666431333032393062626162366561336362383232373062363938386230353230386163666438
64363434373136623535623035343738666233393538633931313065646264663562396431663635
62303431333830643964333464303331346633666561333539663238626632663166323536373266
38623862393861646461616465343731633162326161336363613939323064356237656633353761
30393134363364353532343766343362366431663032383165383331353338313034643734383838
36363639353538663733623437656136643665303561316566653832353934626339393138613665
36626665363862313835653566363037666132336564653138303461333831666332393965356466
39343136626535393930633239326530386464303164343730393435333966616366663065633366
64386433613164386162663437616438636533663834313433643532326637326137303063383539
66353839363533393039363434326238396561323936643364616533656130373466356632393132
61653430663638663833366466623233323166613134633965303861313463633863633731346230
30346361653533383139663234313761396339346439323230303035643166323861376339393939
61613263333637316632376666373234303037353331613438633061613636326537363939326532
36336132656335663231633831626133646339616161373964363666653762393034303835326466
62313662653235643062306130616466376638626364323330336366343235316438646361343939
35326463333537353136353664343261383734623430353139373165366430663837616165383539
38313932643633366537646335613134333433376165616638383332356165656166656665626139
33323032366463343030376136393736346537393565386234663033633134626234623962323363
30616532666439363266616666616633663461323533323135313764666566383261626338313834
63306139383535626531363532326238383037666163373836373263623663633834353338633235
62313930363262613630636435623335366639656237303239313338366334626330646635633061
31316536313238363564323064303133663865346531343736393962666639363030633036393565
31353338313935663231623761653365336135343464393336383664313133663834396464373635
38623535636234366239663961643931323436353438663564666139336463633065653062393062
65316366623231653336643833396331626632323539643035383631393161363535

View file

@ -0,0 +1,37 @@
---
services:
ddns-updater:
image: "{{ docker.containers.ddns.image }}"
container_name: "{{ docker.containers.ddns.name }}"
network_mode: bridge
user: {{ docker.containers.ddns.user }}:{{ docker.containers.ddns.user }}
ports:
- {{ docker.containers.ddns.port }}:8000/tcp
volumes:
- ./data:/updater/data
environment:
- PERIOD=15m
- UPDATE_COOLDOWN_PERIOD=1m
- PUBLICIP_FETCHERS=all
- PUBLICIP_HTTP_PROVIDERS=all
- PUBLICIPV4_HTTP_PROVIDERS=all
- PUBLICIPV6_HTTP_PROVIDERS=all
- PUBLICIP_DNS_PROVIDERS=all
- PUBLICIP_DNS_TIMEOUT=3s
- HTTP_TIMEOUT=10s
- TZ=Europe/Berlin
# Web UI
- LISTENING_ADDRESS=:8000
- ROOT_URL=/
# Backup
- BACKUP_PERIOD=0 # 0 to disable
- BACKUP_DIRECTORY=/updater/data
# Other
- LOG_LEVEL=info
- LOG_CALLER=hidden
- SHOUTRRR_ADDRESSES=
restart: always

View file

@ -0,0 +1,46 @@
---
networks:
forgejo:
external: false
services:
server:
image: {{ docker.containers.forgejo.image }}
container_name: {{ docker.containers.forgejo.name }}
environment:
- USER_UID={{ docker.containers.forgejo.user }}
- USER_GID={{ docker.containers.forgejo.user }}
- FORGEJO__database__DB_TYPE=mysql
- FORGEJO__database__HOST=db:3306
- FORGEJO__database__NAME=forgejo_db
- FORGEJO__database__USER={{ vault.forgejo.dbuser }}
- FORGEJO__database__PASSWD={{ vault.forgejo.dbpass }}
restart: always
networks:
- forgejo
volumes:
- /mnt/content/forgejo/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "{{ docker.containers.forgejo.port }}:3000"
- "222:22"
depends_on:
- db
db:
image: mysql:8
container_name: GIT_mysql
restart: always
environment:
- USER_UID={{ docker.containers.forgejo.user }}
- USER_GID={{ docker.containers.forgejo.user }}
- MYSQL_ROOT_PASSWORD={{ vault.forgejo.dbroot }}
- MYSQL_USER={{ vault.forgejo.dbuser }}
- MYSQL_PASSWORD={{ vault.forgejo.dbpass }}
- MYSQL_DATABASE=forgejo_db
networks:
- forgejo
volumes:
- /mnt/content/forgejo/mysql:/var/lib/mysql

View file

@ -0,0 +1,104 @@
---
services:
jellyfin:
image: {{ docker.containers.jellyfin.image }}
container_name: {{ docker.containers.jellyfin.name }}
environment:
- PUID={{ docker.containers.jellyfin.user }}
- PGID={{ docker.containers.jellyfin.user }}
- TZ=Europe/Berlin
volumes:
- /mnt/content/jellyfin/config:/config
- /mnt/content/jellyfin/cache:/cache
- /mnt/content:/media
restart: 'unless-stopped'
ports:
- {{ docker.containers.jellyfin.port }}:8096
- 8920:8920
devices:
- /dev/dri/renderD128:/dev/dri/renderD128
- /dev/dri/card0:/dev/dri/card0
sabnzbd:
image: lscr.io/linuxserver/sabnzbd:latest
container_name: UN_sabnzbd
environment:
- PUID={{ docker.containers.jellyfin.user }}
- PGID={{ docker.containers.jellyfin.user }}
- TZ=Europe/Berlin
volumes:
- /mnt/content/sabnzbd-config:/config
- /mnt/content/downloads:/downloads #optional
- /mnt/content/incomplete-downloads:/incomplete-downloads #optional
restart: unless-stopped
network_mode: "service:gluetun"
depends_on:
- gluetun
radarr:
image: lscr.io/linuxserver/radarr:latest
container_name: UN_radarr
environment:
- PUID={{ docker.containers.jellyfin.user }}
- PGID={{ docker.containers.jellyfin.user }}
- TZ=Europe/Berlin
volumes:
- /mnt/content/radarr/config:/config
- /mnt/content/movies:/movies #optional
- /mnt/content/downloads:/downloads #optional
ports:
- 7878:7878
restart: unless-stopped
jellyseerr:
image: fallenbagel/jellyseerr:latest
container_name: UN_jellyseerr
environment:
- PUID={{ docker.containers.jellyfin.user }}
- PGID={{ docker.containers.jellyfin.user }}
- LOG_LEVEL=debug
- TZ=Europe/Berlin
ports:
- 5055:5055
volumes:
- /mnt/content/jellyseerr/config:/app/config
restart: unless-stopped
sonarr:
image: lscr.io/linuxserver/sonarr:latest
container_name: UN_sonarr
environment:
- PUID={{ docker.containers.jellyfin.user }}
- PGID={{ docker.containers.jellyfin.user }}
- TZ=Europe/Berlin
volumes:
- /mnt/content/sonarr/config:/config
- /mnt/content/shows:/tv #optional
- /mnt/content/downloads:/downloads #optional
ports:
- 8989:8989
restart: unless-stopped
gluetun:
container_name: UN_gluetun
image: qmcgaw/gluetun:latest
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
restart: unless-stopped
volumes:
- /mnt/gluetun:/gluetun
ports:
- 8083:8080
- 9090:80/tcp
environment:
- VPN_SERVICE_PROVIDER={{ vault.gluetun.VPN_SERVICE_PROVIDER }}
- OPENVPN_USER={{ vault.gluetun.OPENVPN_USER }}
- OPENVPN_PASSWORD={{ vault.gluetun.OPENVPN_PASSWORD }}
- SERVER_REGIONS=Luxembourg
- TZ=Europe/Berlin
- PUID={{ docker.containers.jellyfin.user }}
- PGID={{ docker.containers.jellyfin.user }}
network_mode: bridge

View file

@ -0,0 +1,3 @@
FROM nextcloud:apache
COPY redis.config.php /usr/src/nextcloud/config/redis.config.php

View file

@ -0,0 +1,48 @@
---
services:
db:
image: mariadb:10.11
container_name: NC_mariadb-db
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
volumes:
- /mnt/content/nextcloud/db-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD
- MYSQL_USER
- MYSQL_PASSWORD
- MYSQL_DATABASE
restart: unless-stopped
redis:
image: redis:alpine
container_name: NC_redis-dbcache
restart: unless-stopped
app:
build: ./app
container_name: NC_app
restart: always
ports:
- 5234:80
volumes:
- /mnt/content/nextcloud/nextcloud-data:/var/www/html
environment:
- MYSQL_HOST=db
- MYSQL_ROOT_PASSWORD
- MYSQL_USER
- MYSQL_PASSWORD
- MYSQL_DATABASE
depends_on:
- db
- redis
cron:
build: ./app
container_name: NC_cron
volumes:
- /mnt/content/nextcloud/nextcloud-data:/var/www/html
entrypoint: /cron.sh
restart: unless-stopped
depends_on:
- db
- redis

View file

@ -0,0 +1,108 @@
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
server_tokens off;
keepalive_timeout 65;
#gzip on;
upstream php-handler {
server nextcloud:9000;
}
server {
listen 80;
client_max_body_size 512M;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
root /var/www/html;
index index.php index.html /index.php$request_uri;
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
location ~ \.php(?:$|/) {
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
#fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ \.(?:css|js|svg|gif)$ {
try_files $uri /index.php$request_uri;
expires 6M;
access_log off;
}
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
expires 7d;
access_log off;
}
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
}

View file

@ -0,0 +1,7 @@
user = www-data
group = www-data
pm = dynamic
pm.max_children = 281
pm.start_servers = 140
pm.min_spare_servers = 93
pm.max_spare_servers = 187

View file

@ -0,0 +1,10 @@
<?php
$CONFIG = array (
'memcache.local' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'filelocking.enabled' => 'true',
'redis' => array(
'host' => 'redis',
'port' => 6379,
),
);

View file

@ -0,0 +1,15 @@
$ANSIBLE_VAULT;1.1;AES256
63383365633765666633616561653434333131363330393339383034323636626362306331646165
3537636562373661626463633934633532316439613230310a656635346435616534326133623330
39386561646561643765633739313132663333306532326130393932353161353836356531383130
3432666630626362630a393762653161313738633031336432326534643032656331363933303362
33383638363233333236346536663262326533633834383864666531313562643233333661313466
66333231303961343934353139656264666266386233376665623732353763363835363638653766
64343135366361356331626234626366333663326261343630353366313863613935343930363465
38306161316232646539646137326437346138663333343537653765643130303431343232343932
34646337323930353962656133643938343165356533663936663332336162626366343330613137
38363430383932306461636162363466626665373232313134303265616638353335376561323037
32393362306633303766396437366362616439336232636134393039336464613932353231323163
32633866643963353363616162383233396366383034363662303762363732373435643738306564
65383731666632393263663534326533373132613262373931336537373766323236616334383630
6163306637396235333235393433636464323961373434653064

View file

@ -0,0 +1,42 @@
---
services:
vaultwarden:
image: {{ docker.containers.vaultwarden.image }}
user: {{ docker.containers.vaultwarden.user }}:{{ docker.containers.vaultwarden.user }}
container_name: {{ docker.containers.vaultwarden.name }}
restart: always
env_file: .env
environment:
DOMAIN: "https://pw.mgutzeit.de" # required when using a reverse proxy; your domain; vaultwarden needs to know it's https to work properly with attachments
SIGNUPS_ALLOWED: "false" # Deactivate this with "false" after you have created your account so that no strangers can register
# Domains: gmail.com, googlemail.com
volumes:
- ./vw-data:/data
- /etc/localtime:/etc/localtime:ro
ports:
- {{ docker.containers.vaultwarden.port }}:80
backup:
image: {{ docker.containers.vaultwarden.bak_image }}
container_name: {{ docker.containers.vaultwarden.bak_name }}
restart: always
env_file: .env
environment:
RCLONE_REMOTE_NAME: 'BitwardenBackup'
RCLONE_REMOTE_DIR: '/BitwardenBackup/'
RCLONE_GLOBAL_FLAG: ''
CRON: '0 */6 * * *'
ZIP_ENABLE: 'TRUE'
ZIP_TYPE: 'zip'
BACKUP_FILE_SUFFIX: '%Y%m%d'
BACKUP_KEEP_DAYS: 30
MAIL_SMTP_ENABLE: 'TRUE'
MAIL_SMTP_VARIABLES: '-S v15-compat -S smtp-use-starttls -S mta=smtp://gutzeit.moritz%40gmail.com:${SMTP_PASSWORD}@smtp.gmail.com:587 -S smtp-auth=login -S from=gutzeit.moritz@gmail.com'
MAIL_TO: 'gutzeit.moritz@gmail.com'
MAIL_WHEN_SUCCESS: 'FALSE'
MAIL_WHEN_FAILURE: 'TRUE'
TIMEZONE: 'CET'
volumes:
- ./vw-data:/bitwarden/data/
- ./vw-rclone-data:/config/

View file

@ -0,0 +1,98 @@
$ANSIBLE_VAULT;1.1;AES256
33646561313731623830663463623162623963626530343139373436613839336139323537643537
3232396630316161323534353064373362303234366533610a356463613331343066663331396664
63316430633063653363373738633865643165623137643630663762626130386463346238393439
3762633032313534660a326164653364306265346338313030326266383130366238613762633436
66376236623839326330366431383930616333306135326337336237373132623939653335613137
33396366656664663534383064356137366131633665313465623232316137623564623066303666
39613933663763353130656561613335626161306539623431303464363233663666373035613036
34396362333136343863303538336561383038376165613364326438383933376136383232363166
37326363373933623164346336626437653031663139363538343262613661653234333535323739
31396539636265626637366434383435633963343232306466343333383533383536623432656130
33353961643865656233306432643735656262663232646366636134646437623664383432666266
39353232336661616534313339343336336435393537373266393864646663356266333561393464
35306339386438633139313564376461386239306334336563643538333764393831363735316565
63353233643937613664643633373539373337626234336633656634636661373163393634616637
38613566306361666562386335616132643436363763613161353964306563366661316661636164
62356566626366353236666634623161653738303966666238663732346238356231613234666337
62613530623530643736666634313864303638626232643339613635386130613436396235323935
38383936326135623365393966323938303731316639346564626538613866386337346633623033
61316439666365666461303835656536636563623263666166626362326565303732663531393865
34613561656439656362303963343739313833333161633564656534383765323065323033353937
61323934333030653438643134663139636465386436393235643639316339366138653162623838
66306365353634376465626130303865333830313532663032663937653861366564343665613431
33343961303836646562323964623431333938353231313266643139666433346433363337336462
63306534626330633662313535623239623832666465633337373838653564306437333831383663
61313538306637343466633166366132323831396335653935623830323535333531633239356333
36373166373932373066616137633337663437373438313639656335633232333030386238623034
36306531363938663939336530613865316330636562636335383839666631346237636365623463
33356564623735663633636166613665383132656662393366626237626632346433373130313966
62653265306162373336346636666261363336306635613633376132303965393461653262333532
34333363306162353631626230316634366361306134366230333036363838636330333861303939
30626538326132616333313762653162393634366539323032393766363366303535386239653264
66336239616462633237663338306234656335656131626166336530636263653839353837666264
62376566666431313434663234343635343238343131653761386532656133316538656263373939
36653565626663643266633839376633636463363362393438616161613862323932643066306662
66356335373965616566323666353366636162663163306366336534346637306336663037353963
64663633383532363239353937626637643436333266313630313563626562336237333738373562
63373362343931326362396631626137383531306336393432386165393432646462373433303566
37646166346465316562383366363633363737646164333662633731663064333261333139323038
66346139343237383736626139313966356462353762383238306436616163623664386332386438
61663361656662356336663236306531656463623161663134386536336531623435386334616139
61303935656133633032663035626334303038343364633664356533656531353235343839333238
63626637653630393363613839613338616165643033396338336135653835313132383232333036
30636636326363363361343838316462616235333030663136313562303430333034373734366436
37666239343461383162316132636338343866623339343738653132613235306633306563376130
65343335333938393235363361636462393036343431363238346336303433313735383231353637
33656234363130383163613837393733636131666337336231623163666163653866313035646166
63383864316135623733633830316136306164653730623837396563373565373730643832653461
62383837376530636363396238633835636361326238303066393035333830653330636364363039
30353432363165626134383262643839336165356365383066323135323131643235633161346535
36326539396433303065613835316137363430376435386466636366373264613433366437626530
33623164383437356331376336373762313663616333373965366361396665653133356636336238
61616166373433353631623235323032616562323838363765323766386238366631363663613730
31383736633161646237383231336539333339653265316263643265613131383234363731656462
37383934643662326137383939653432316132616434313531653833336235663162393133646238
64333165333035333531343463613633626464366666343764396365616332363763663165626466
63316239663836613931616230643064646332346233313130353837386431623537336138663131
35646164323265633963666361623161386365303436386230663364396533383537636637313736
66666232616265643538653933386131363861626466363732343166353033646263643263383837
61363338376630656133343663393163393833623433626437303131383831353063306235623533
65643830323461323337333938656462623734663032316234336632373830646232613630636538
65316231376234306664306430663332656134663938383139383637613134303937313736356133
62336338376165346439376139353030363630326133613030353033363762346662316538316665
62656433303263343831623038626539313931613965363933653438373536376165396434333132
30623361366333363033336537666363633066326239333533346263643939623832353831333162
32356130396531353937623530626635633062336638656335656137613163356162353934363039
62313339363530353738323035353232656235356333303866356635666130643634386139633234
38623563333735613263376637393234613561383933646333633434633938396661376262396466
66653438613431346332353362323562353966356137333365313931663566346166623561393461
31336261333564363236373038666561396262313464666639303038346431376433396532636266
66616266646563623932663835393764343362646431643064373838333137646438623163356236
63343730376437356263363533633964616634643162303361363232633161313365363236303938
64383330313339373939623236653466333831386233613365346163613231613730643733373666
66343039323862303734623739323735396362353336373263356537323962333563616530373663
62643938363765653637396132386266666133313365323535646562396161616264393738633034
61336635343631326433346464356262393134313761336136363862363166326534336633376563
33363966313464656336653265663934306230653134313764303634333235396332353965616432
37666533356262326464323333376462613062633332626166343832653065363662646365613835
37646164633431336539326464623064313536336661393833633633663935653335373866383439
66633131353061653862643033386135633062356433333532646237366361313534373533306532
39646534383564363637313434623035393662656334653734393764383865326234323362653966
37313136303638316564303232373631333432623834343964323934646332393864356634666562
66323034636136373132396137356633396139323064663330383433623861663934656162316662
63633538623135336263316263303565386330643866306362323839656266353536326262336266
37616462333631646135636434336437646663343139613164373936373864326633303961373538
62656232333261366231613161306435666439386166616338323661343563656566306363636632
39623161376232303263646331663631623866336339386534653166653037346234336439613630
32303933313864373633316263333634623433363861353764373766366266323461306439376538
65333465656135356565363065353761393036366535306236383963623861663833353834653132
38363862333834636433386132343461316130323963363034323138613336353865303439626235
66613562653661656237383063356234346465623863323835613731356236343731663365643236
64663534643231376434643138333734306234643065356439303437346138393039373435303133
63646662303963323238316233613839306632366538333163616638306531303665656462336336
33306464356436613935326531323639636563633636333936376566356436363032376333623538
30666131316664663963653861653764383965343362346232633637643839373762396332393339
39373337386164326435393234353630313236353936653865306237316562376464643334643634
32323739333461616539303439343466343063373831383864633537303665353236646236313865
30396138636566313331306165303066656534656665626365313661633937633365

View file

@ -0,0 +1 @@
.env

View file

@ -0,0 +1,10 @@
$ANSIBLE_VAULT;1.1;AES256
31616238636234396338363165646236643064326666356232326233376161343465663065333534
3437346562636537323362623763666662363632326163340a643233643339666437613061316562
34346631656239326466316334663334656538623130386465386332393631636336373063353439
6436376635663566610a663532653032353865336636623662383937306532643231316563636430
37663232633463613430323934316439303537346563343265303638376664313561643139393463
63643363303331393632623961613032366431386333363934633361313937363965316564373764
64313565636563313362653066366630623966313334363764303833666333333264383637633466
65346339323231613563386632373162343062393339646165373363316363643931383565373931
33393030373766313530346639316136643964643339356164366335336534313338

View file

@ -0,0 +1,51 @@
services:
db:
image: {{ docker.containers.wordpress.db_image }}
container_name: {{ docker.containers.wordpress.db_name }}
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=wordpress
volumes:
- /mnt/content/wordpress/dbdata:/var/lib/mysql
command: '--mysql-native-password=ON'
networks:
- app-network
wordpress:
depends_on:
- db
image: {{ docker.containers.wordpress.image }}
container_name: {{ docker.containers.wordpress.name }}
restart: unless-stopped
env_file: .env
environment:
- TZ=Europe/Berlin
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=$MYSQL_USER
- WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
- WORDPRESS_DB_NAME=wordpress
volumes:
- /mnt/content/wordpress/wpdata:/var/www/html
networks:
- app-network
webserver:
depends_on:
- wordpress
image: nginx:latest
container_name: {{ docker.containers.wordpress.web_name }}
restart: unless-stopped
ports:
- "{{ docker.containers.wordpress.port }}:80"
volumes:
- /mnt/content/wordpress/wpdata:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
environment:
- TZ=Europe/Berlin
networks:
- app-network
networks:
app-network:
driver: bridge

View file

@ -0,0 +1,43 @@
server {
listen 80;
server_name localhost;
index index.php index.html index.htm;
root /var/www/html;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}

View file

@ -0,0 +1,14 @@
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file. Contents are based on https://ssl-config.mozilla.org
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

View file

@ -0,0 +1,68 @@
server {
listen 80;
listen [::]:80;
server_name {{ docker.containers.wordpress.url }};
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ docker.containers.wordpress.url }};
index index.php index.html index.htm;
root /var/www/html;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/{{ docker.containers.wordpress.url }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ docker.containers.wordpress.url }}/privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}

View file

@ -0,0 +1,14 @@
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file. Contents are based on https://ssl-config.mozilla.org
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

View file

@ -0,0 +1,15 @@
---
- name: Restart
systemd:
name: nginx
state: restarted
- name: Waitfor
wait_for:
host: localhost
port: 80
state: started
sleep: 1
delay: 2
timeout: 300

View file

@ -0,0 +1,43 @@
---
- tags: nginx
block:
- name: Packages
apt:
state: latest
name:
- nginx
- certbot
update_cache: true
- name: Services
systemd:
state: started
name: nginx
enabled: true
- name: Copy nginx config files and restart if necessary
template:
src: "{{ item }}.j2"
dest: "/etc/nginx/sites-available/{{ item }}"
owner: root
group: root
mode: '0644'
notify:
- Restart
- Waitfor
loop: "{{ docker.containers.keys() }}"
when: item not in no_nginx
- name: Create symlinks and restart if necessary
file:
src: "/etc/nginx/sites-available/{{ item }}"
dest: "/etc/nginx/sites-enabled/{{ item }}"
owner: root
group: root
state: link
notify:
- Restart
- Waitfor
loop: "{{ docker.containers.keys() }}"
when: item not in no_nginx

View file

@ -0,0 +1,51 @@
server {
server_name {{ docker.containers.ddns.url }};
index index.php;
location / {
proxy_pass http://localhost:{{ docker.containers.ddns.port }}/; # set this to the nextcloud port set in doccker-compose file
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;
client_max_body_size 0;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
access_log /var/log/nginx/ddns.access.log;
error_log /var/log/nginx/ddns.error.log;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/{{ docker.containers.ddns.url }}/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/{{ docker.containers.ddns.url }}/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
if ($allowed_country = no) {
return 444;
}
}
server {
if ($host = {{ docker.containers.ddns.url }}) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name {{ docker.containers.ddns.url }};
return 404; # managed by Certbot
}

View file

@ -0,0 +1,47 @@
server {
server_name {{ docker.containers.forgejo.url }};
index index.php;
location / {
proxy_pass http://localhost:{{ docker.containers.forgejo.port }}/; # set this to the nextcloud port set in doccker-compose file
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;
client_max_body_size 0;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
access_log /var/log/nginx/ddns.access.log;
error_log /var/log/nginx/ddns.error.log;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/{{ docker.containers.forgejo.url }}/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/{{ docker.containers.forgejo.url }}/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = {{ docker.containers.forgejo.url }}) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name {{ docker.containers.forgejo.url }};
return 404; # managed by Certbot
}

View file

@ -0,0 +1,49 @@
server {
server_name {{ docker.containers.nextcloud.url }};
root /var/www/{{ docker.containers.nextcloud.url }};
index index.html;
location / {
proxy_pass http://localhost:{{ docker.containers.nextcloud.port }}/; # set this to the nextcloud port set in doccker-compose file
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;
client_max_body_size 0;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
access_log /var/log/nginx/nextcloud.access.log;
error_log /var/log/nginx/nextcloud.error.log;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/{{ docker.containers.nextcloud.url }}/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/{{ docker.containers.nextcloud.url }}/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = {{ docker.containers.nextcloud.url }}) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80 ipv6only=on;
server_name {{ docker.containers.nextcloud.url }};
return 404; # managed by Certbot
}

View file

@ -0,0 +1,41 @@
server {
server_name {{ docker.containers.vaultwarden.url }};
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/{{ docker.containers.vaultwarden.url }}/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/{{ docker.containers.vaultwarden.url }}/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
if ($allowed_country = no) {
return 444;
}
location / {
proxy_pass http://127.0.0.1:{{ docker.containers.vaultwarden.port }}/;
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;
client_max_body_size 0;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
access_log /var/log/nginx/vaultwarden.access.log;
error_log /var/log/nginx/vaultwarden.error.log;
}
}
server {
if ($host = {{ docker.containers.vaultwarden.url }}) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name {{ docker.containers.vaultwarden.url }};
return 404; # managed by Certbot
}

View file

@ -0,0 +1,49 @@
server {
server_name wordpress.mgutzeit.de;
root /var/www/wordpress.mgutzeit.de;
index index.php;
location / {
proxy_pass http://localhost:5080/; # set this to the nextcloud port set in doccker-compose file
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;
client_max_body_size 0;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
access_log /var/log/nginx/wordpress.access.log;
error_log /var/log/nginx/wordpress.error.log;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/wordpress.mgutzeit.de/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/wordpress.mgutzeit.de/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = wordpress.mgutzeit.de) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name wordpress.mgutzeit.de;
return 404; # managed by Certbot
}