commit 758ef900ff9626ae8b42d510e21c198623344da4 Author: chris Date: Wed Nov 3 09:09:32 2021 +0100 Initial commit, pihole not working diff --git a/.env b/.env new file mode 100644 index 0000000..511903d --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +DB_ROOT_PW=340985asdfklweo20350~ +REDIS_PW=230skdfjl~23409 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/home_server.iml b/.idea/home_server.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/home_server.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c6e247f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..d3845ca --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,277 @@ +version: "3.9" + +networks: + proxy: + external: true + internal: + external: false + driver: bridge + +volumes: + nextcloud: + name: nextcloud + nextcloud-data: + name: nextcloud-data + nextcloud-config: + name: nextcloud-config + mysql8-data: + name: mysql8-data + mysql8-backup: + name: mysql8-backup + psql14-data: + name: psql14-data + psql14-backup: + name: psql14-backup + redis-data: + name: redis-data + gitea: + name: gitea + vault: + name: vault + bookstack: + name: bookstack + kimai: + name: kimai + kimai-var: + name: kimai-var + pihole: + name: pihole + dnsmasq: + name: dnsmasq + +services: + traefik: + image: traefik:v2.5 + container_name: traefik + restart: unless-stopped + command: + - --global.sendAnonymousUsage=false + - --api.insecure=true + - --providers.docker=true + - --providers.docker.network=proxy + - --providers.docker.exposedByDefault=false + - --providers.docker.swarmMode=false + - --entryPoints.web.address=:80 + - --entryPoints.websecure.address=:443 + - --log=true + - --log.level=DEBUG + - --accessLog=true + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /${PWD} + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.entrypoints=web" + - "traefik.http.routers.traefik.rule=Host(`traefik.localhost`)" + - "traefik.http.services.traefik.loadbalancer.server.port=8080" + networks: + - proxy + + mysql8: + image: mysql:8 + container_name: mysql8 + command: --default-authentication-plugin=mysql_native_password + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: "${DB_ROOT_PW}" + volumes: + - mysql8-data:/var/lib/mysql + - mysql8-backup:/var/backups + - ${PWD}/mysql_databases.sql:/docker-entrypoint-initdb.d/01_create_databases.sql + networks: + - internal + + psql14: + image: postgres:14-alpine + container_name: psql14 + restart: unless-stopped + environment: + POSTGRES_PASSWORD: ${DB_ROOT_PW} + volumes: + - psql14-data:/var/lib/postgresql/data + - psql14-backup:/var/backups + - ${PWD}//postgres_databases.sql:/docker-entrypoint-initdb.d/01_create_databases.sql + networks: + - internal + + redis: + image: redis:alpine + container_name: redis + restart: unless-stopped + volumes: + - redis-data:/data + networks: + - internal + + nextcloud: + image: nextcloud:22-fpm-alpine + container_name: nextcloud + restart: unless-stopped + volumes: + - nextcloud:/var/www/html + - nextcloud-data:/var/www/html/data + - nextcloud-config:/var/www/html/config + networks: + - internal + environment: + - MYSQL_DATABASE:nextcloud + - MYSQL_USER:nextcloud + - MYSQL_PASSWORD:jX9hKI2POvt1VrjVbBs4 + - MYSQL_HOST:mysql8 + - REDIS_HOST:redis + - REDIS_HOST_PASSWORD:${REDIS_PW} + - NEXTCLOUD_ADMIN_USER:${NEXTCLOUD_ADMIN_USER} + - NEXTCLOUD_ADMIN_PASSWORD:${NEXTCLOUD_ADMIN_PW} + - NEXTCLOUD_TRUSTED_DOMAINS:cs-nextcloud.ddnss.de nextcloud.localhost + - VIRTUAL_HOST:nextcloud + depends_on: + - psql14 + - redis + + nginx-nc: + image: nginx:alpine + container_name: nginx-nc + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.nextcloud.entrypoints=web" + - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.localhost`)" + - "traefik.http.services.nextcloud.loadbalancer.server.port=80" + depends_on: + - nextcloud + networks: + - proxy + - internal + volumes: + - nextcloud:/var/www/html + - ${PWD}/nextcloud.conf:/etc/nginx/conf.d/default.conf + + gitea: + image: gitea/gitea + container_name: gitea + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST=psql14:5432 + - GITEA__database__NAME=gitea + - GITEA__database__USER=gitea + - GITEA__database__PASSWD=sadlkf0234lsdf + restart: unless-stopped + volumes: + - gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + depends_on: + - psql14 + networks: + - internal + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.gitea-web.entrypoints=web" + - "traefik.http.routers.gitea-web.rule=Host(`cs-gitea.ddnss.de`) || Host(`gitea.localhost`)" + - "traefik.http.services.gitea-web.loadbalancer.server.port=3000" + + vaultwarden: + image: vaultwarden/server + restart: unless-stopped + container_name: vaultwarden + volumes: + - vault:/data + labels: + - "traefik.enable=true" + - "traefik.http.routers.vaultwarden.entrypoints=web" + - "traefik.http.routers.vaultwarden.rule=Host(`vault.localhost`)" + - "traefik.http.services.vaultwarden.loadbalancer.server.port=80" + networks: + - internal + - proxy + + bookstack: + image: linuxserver/bookstack + restart: unless-stopped + container_name: bookstack + depends_on: + - mysql8 + volumes: + - bookstack:/config + environment: + - PUID=1000 + - GUID=1000 + - APP_URL=http://bookstack.localhost + - DB_HOST=mysql8 + - DB_USER=bookstack + - DB_PASS=sdfl39302klsdjf + - DB_DATABASE=bookstack + networks: + - internal + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.bookstack.entrypoints=web" + - "traefik.http.routers.bookstack.rule=Host(`bookstack.localhost`)" + - "traefik.http.services.bookstack.loadbalancer.server.port=80" + + nginx-kimai: + image: nginx:alpine + container_name: nginx-kimai + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.kimai.entrypoints=web" + - "traefik.http.routers.kimai.rule=Host(`kimai.localhost`)" + - "traefik.http.services.kimai.loadbalancer.server.port=80" + depends_on: + - kimai + networks: + - proxy + - internal + volumes: + - kimai:/opt/kimai/public:ro + - ${PWD}/kimai.conf:/etc/nginx/conf.d/default.conf + + kimai: + image: kimai/kimai2 + container_name: kimai + restart: unless-stopped + environment: + - ADMINMAIL=christiansteinle@arcor.de + - ADMINPASS=ZovJdPamHwSNCGTcOPDb + - DATABASE_URL=mysql://kimai:xXW5dnQoMpAmdXrQgUgU@mysql8/kimai + - TRUSTED_HOSTS=kimai.localhost + networks: + - internal + volumes: + - kimai:/opt/kimai/public + - kimai-var:/opt/kimai/var + + pihole: + image: pihole/pihole + container_name: pihole + restart: unless-stopped + ports: + - "53:53/tcp" + - "53:53/udp" + - "67:67/udp" + environment: + TZ: 'Europe/Berlin' + WEBPASSWORD: 'sicher123' + cap_add: + - NET_ADMIN + volumes: + - pihole:/etc/pihole/ + - dnsmasq:/etc/dnsmasq.d + networks: + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.pihole.entrypoints=web" + - "traefik.http.routers.pihole.rule=Host(`pihole.localhost`)" + - "traefik.http.services.pihole.loadbalancer.server.port=80" + +# https://sensepost.com/blog/2020/building-a-hipster-aware-pi-home-server/ +# https://github.com/chriscrowe/docker-pihole-unbound/blob/master/two-container/docker-compose.yaml \ No newline at end of file diff --git a/kimai.conf b/kimai.conf new file mode 100644 index 0000000..ceacb3f --- /dev/null +++ b/kimai.conf @@ -0,0 +1,25 @@ +server { + listen 80; + index index.php; + server_name kimai.localhost; + root /opt/kimai/public; + + # cache static asset files + location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ { + expires max; + log_not_found off; + } + + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + + location ~ ^/index\.php(/|$) { + fastcgi_pass kimai:9000; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $realpath_root; + internal; + } +} \ No newline at end of file diff --git a/mysql_databases.sql b/mysql_databases.sql new file mode 100644 index 0000000..034081e --- /dev/null +++ b/mysql_databases.sql @@ -0,0 +1,14 @@ +# create the databases +CREATE DATABASE IF NOT EXISTS `nextcloud`; +CREATE DATABASE IF NOT EXISTS `bookstack`; +CREATE DATABASE IF NOT EXISTS `kimai`; + +# create users and privileges +CREATE USER 'nextcloud'@'%' IDENTIFIED BY 'jX9hKI2POvt1VrjVbBs4'; +GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'%'; + +CREATE USER 'bookstack'@'%' IDENTIFIED BY 'sdfl39302klsdjf'; +GRANT ALL PRIVILEGES ON bookstack.* TO 'bookstack'@'%'; + +CREATE USER 'kimai'@'%' IDENTIFIED BY 'xXW5dnQoMpAmdXrQgUgU'; +GRANT ALL PRIVILEGES ON kimai.* TO 'kimai'@'%'; diff --git a/nextcloud.conf b/nextcloud.conf new file mode 100644 index 0000000..19d68cf --- /dev/null +++ b/nextcloud.conf @@ -0,0 +1,134 @@ +upstream php-handler { + server nextcloud:9000; +} + +server { + listen 80; + listen [::]:80; + server_name nextcloud.localhost cs-nextcloud.ddnss.de; + + + # set max upload size and increase upload timeout: + client_max_body_size 512M; + client_body_timeout 300s; + fastcgi_buffers 64 4K; + + # Enable gzip but do not remove ETag headers + 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; + + # Pagespeed is not supported by Nextcloud, so if your server is built + # with the `ngx_pagespeed` module, uncomment this line to disable it. + #pagespeed off; + + # HTTP response headers borrowed from Nextcloud `.htaccess` + 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 "none" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Remove X-Powered-By, which is an information leak + fastcgi_hide_header X-Powered-By; + + # Path to the root of your installation + root /var/www/html; + + # Specify how to handle directories -- specifying `/index.php$request_uri` + # here as the fallback means that Nginx always exhibits the desired behaviour + # when a client requests a path that corresponds to a directory that exists + # on the server. In particular, if that directory contains an index.php file, + # that file is correctly served; if it doesn't, then the request is passed to + # the front-end controller. This consistent behaviour means that we don't need + # to specify custom rules for certain paths (e.g. images and other assets, + # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus + # `try_files $uri $uri/ /index.php$request_uri` + # always provides the desired behaviour. + index index.php index.html /index.php$request_uri; + + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + 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; + } + + # Make a regex exception for `/.well-known` so that clients can still + # access it despite the existence of the regex rule + # `location ~ /(\.|autotest|...)` which would otherwise handle requests + # for `/.well-known`. + location ^~ /.well-known { + # The rules in this block are an adaptation of the rules + # in `.htaccess` that concern `/.well-known`. + + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + + # Let Nextcloud's API for `/.well-known` URIs handle all other + # requests by passing them to the front-end controller. + return 301 /index.php$request_uri; + } + + # Rules borrowed from `.htaccess` to hide certain paths from clients + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } + + # Ensure this block, which passes PHP files to the PHP process, is above the blocks + # which handle static assets (as seen below). If this block is not declared first, + # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` + # to the URI, resulting in a HTTP 500 error response. + location ~ \.php(?:$|/) { + # Required for legacy support + 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; # Avoid sending the security headers twice + fastcgi_param front_controller_active true; # Enable pretty urls + fastcgi_pass php-handler; + + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + } + + location ~ \.(?:css|js|svg|gif|png|jpg|ico)$ { + try_files $uri /index.php$request_uri; + expires 6M; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + location ~ \.woff2?$ { + try_files $uri /index.php$request_uri; + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + # Rule borrowed from `.htaccess` + location /remote { + return 301 /remote.php$request_uri; + } + + location / { + try_files $uri $uri/ /index.php$request_uri; + } +} \ No newline at end of file diff --git a/postgres_databases.sql b/postgres_databases.sql new file mode 100644 index 0000000..eb20379 --- /dev/null +++ b/postgres_databases.sql @@ -0,0 +1,11 @@ +-- create the databases; +CREATE DATABASE nextcloud; + +CREATE DATABASE gitea; + +-- create users and privileges +CREATE USER nextcloud WITH PASSWORD 'jX9hKI2POvt1VrjVbBs4'; +GRANT ALL PRIVILEGES ON DATABASE nextcloud TO nextcloud; + +CREATE USER gitea WITH PASSWORD 'sadlkf0234lsdf'; +GRANT ALL PRIVILEGES ON DATABASE gitea TO gitea; \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..3cca7c3 --- /dev/null +++ b/readme.md @@ -0,0 +1,43 @@ +# Containerized Home Server + +This repo is used to deploy the containers for the home server infrastructure. If you want to move infrastructure to another host you have to install docker and docker-compose at first. + +## Components and structure + +The root's docker-compose ist used to install common components like databases and traefik. +Subdirectories are used to structure and keep components independent. You have to run the common part, after that you can run single components. + +### Common + +- traefik 2 +- mysql 8 +- postgresql 14 +- redis + +### Development + +- gitea: Version control +- kimai: Time tracking +- nginx: Reverse proxy for kimai + +### Networking + +https://sensepost.com/blog/2020/building-a-hipster-aware-pi-home-server/ \ +https://github.com/chriscrowe/docker-pihole-unbound/blob/master/two-container/docker-compose.yaml + +- pihole +- unbound +- wireguard + +### Nextcloud + +- nextcloud-fpm +- nginx + +### Security + +- vaultwarden + +### Wiki + +- bookstack \ No newline at end of file