Initial commit

This commit is contained in:
Florian Zirker 2020-11-28 22:51:37 +01:00 committed by Florian Zirker
commit 05f7cbc1af
12 changed files with 552 additions and 0 deletions

18
.editorconfig Normal file
View file

@ -0,0 +1,18 @@
root = true
[*]
indent_style = space
indent_size = 3
tab_width = 3
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120
[*.{yml,yaml}]
indent_size = 2
tab_width = 2
[*.md]
trim_trailing_whitespace = false

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.env
**/.vscode/*

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Florian Zirker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

23
README.md Normal file
View file

@ -0,0 +1,23 @@
# Selfhost of Services
Hosting the following web services using docker-compose.
* [Nextcloud](https://nextcloud.com/)
* [Gitea](https://gitea.io/)
* [Wallabag](https://www.wallabag.it)
* Small HTML-Site
As a reverse proxyy [Traefik](https://traefik.io/traefik/) is used. Traefik also secures all Services with TLS and redirects all HTTP requests to HTTPS. SSL certificates are automatically generated using [Let's Encrypt](https://letsencrypt.org/)
## Deploy it
1. [Install Docker](https://docs.docker.com/engine/install/debian/)
1. [Install Docker-compose](https://docs.docker.com/compose/install/)
1. Clone this repository
1. create .env file in each folder and set environment variables
1. cd into folder
1. docker-compose up -d
## Links:
* [Nextcloud docker](https://github.com/nextcloud/docker/)
* [Gitea Doku: Install with Docker](https://docs.gitea.io/en-us/install-with-docker/)
* [Docker Swarm Rocks](https://dockerswarm.rocks/)

56
gitea/docker-compose.yaml Normal file
View file

@ -0,0 +1,56 @@
version: "3"
services:
web:
image: gitea/gitea:1.13
volumes:
- ${VOLUMES_PATH}/gitea_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "2222:22"
networks:
- web
- gitea
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`gitea.${DOMAIN}`)"
- "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.tls.certresolver=myresolver"
- "traefik.http.routers.gitea.tls.options=intermediate@file"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
- "traefik.docker.network=web"
- "docker.group=gitea"
depends_on:
- db
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- DB_TYPE=mysql
- DB_TYPE=postgres
- DB_HOST=db:5432
- DB_NAME=${POSTGRES_DB}
- DB_USER=${POSTGRES_USER}
- DB_PASSWD=${POSTGRES_PASSWORD}
db:
image: postgres:9.6
restart: unless-stopped
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
networks:
- gitea
volumes:
- ${VOLUMES_PATH}/gitea_db:/var/lib/postgresql/data
networks:
gitea:
web:
external: true

View file

@ -0,0 +1,112 @@
version: "3"
services:
web:
#nginx container
build: ./web
depends_on:
- app
volumes:
- ${VOLUMES_PATH}/nextcloud_html:/var/www/html:ro
restart: unless-stopped
networks:
- web
- nextcloud
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`cloud.${DOMAIN}`)"
- "traefik.http.routers.nextcloud.entrypoints=websecure"
- "traefik.http.routers.nextcloud.tls.certresolver=myresolver"
- "traefik.http.routers.nextcloud.tls.options=intermediate@file"
- "traefik.docker.network=web"
- "traefik.http.middlewares.nextcloudHeader.headers.customRequestHeaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.nextcloudHeader.headers.stsSeconds=15552000"
- "traefik.http.middlewares.nextcloudHeader.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.nextcloudHeader.headers.stsPreload=true"
- "traefik.http.middlewares.nextcloudHeader.headers.forceSTSHeader=true"
- "traefik.http.routers.nextcloud.middlewares=nextcloudHeader"
- "docker.group=nextcloud"
app:
image: nextcloud:20-fpm
volumes:
- ${VOLUMES_PATH}/nextcloud_html:/var/www/html
- ${VOLUMES_PATH}/nextcloud_data:/var/www/html/data
restart: unless-stopped
networks:
- nextcloud
environment:
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS}
- MYSQL_HOST=db
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- REDIS_HOST=redis
- REDIS_HOST_PASSWORD=${REDIS_HOST_PASSWORD}
depends_on:
- db
- redis
db:
image: mariadb:10
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- ${VOLUMES_PATH}/nextcloud_db:/var/lib/mysql
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
networks:
- nextcloud
redis:
image: redis:alpine
restart: unless-stopped
command: redis-server --requirepass ${REDIS_HOST_PASSWORD}
networks:
- nextcloud
volumes:
- ${VOLUMES_PATH}/nextcloud_redis:/data
office:
image: onlyoffice/documentserver:latest
stdin_open: true
tty: true
restart: unless-stopped
networks:
- nextcloud
- web
expose:
- '80'
- '443'
volumes:
- ${VOLUMES_PATH}/nextcloud_documents:/var/www/onlyoffice/Data
# - ${VOLUMES_PATH}/onlyoffice_log:/var/log/onlyoffice
labels:
- "traefik.enable=true"
- "traefik.http.routers.office.rule=Host(`office.${DOMAIN}`)"
- "traefik.http.routers.office.entrypoints=websecure"
- "traefik.http.routers.office.tls.certresolver=myresolver"
- "traefik.http.routers.office.tls.options=intermediate@file"
- "traefik.docker.network=web"
- "traefik.http.middlewares.officeHeader.headers.customRequestHeaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.officeHeader.headers.stsSeconds=15552000"
- "traefik.http.middlewares.officeHeader.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.officeHeader.headers.stsPreload=true"
- "traefik.http.middlewares.officeHeader.headers.forceSTSHeader=true"
- "traefik.http.routers.office.middlewares=officeHeader"
- "docker.group=nextcloud"
networks:
web:
external: true
nextcloud:
external: false

2
nextcloud/web/Dockerfile Normal file
View file

@ -0,0 +1,2 @@
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf

168
nextcloud/web/nginx.conf Normal file
View file

@ -0,0 +1,168 @@
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;
keepalive_timeout 65;
#gzip on;
upstream php-handler {
server app:9000;
}
server {
listen 80;
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this
# topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
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;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
# The following rule is only needed for the Social app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
location = /.well-known/carddav {
return 301 https://$host:443/remote.php/dav;
}
location = /.well-known/caldav {
return 301 https://$host:443/remote.php/dav;
}
# set max upload size
client_max_body_size 10G;
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;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
rewrite ^ /index.php;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
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;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js, css and map files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
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;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
try_files $uri /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}
}
}

51
proxy/docker-compose.yaml Normal file
View file

@ -0,0 +1,51 @@
version: "3.3"
services:
traefik:
image: traefik:v2.3
restart: unless-stopped
command:
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
#- "--log.level=DEBUG"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.myresolver.acme.email=${LETSENCRYPT_MAIL}"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
- "--providers.file.filename=/etc/traefik/tls.toml"
ports:
- "80:80"
- "443:443"
networks:
- web
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- ${VOLUMES_PATH}/letsencrypt:/letsencrypt
- $PWD/tls.toml:/etc/traefik/tls.toml
labels:
- "docker.group=web"
# whoami:
# image: containous/whoami
# networks:
# - web
# labels:
# - "traefik.enable=true"
# - "traefik.http.routers.whoami.rule=Host(`whoami.${DOMAIN}`)"
# - "traefik.http.routers.whoami.entrypoints=websecure"
# - "traefik.http.routers.whoami.tls.certresolver=myresolver"
# - "docker.group=web"
# restart: unless-stopped
networks:
web:
external: true

14
proxy/tls.toml Normal file
View file

@ -0,0 +1,14 @@
# generated 2020-12-09, Mozilla Guideline v5.6, Traefik 2.3, intermediate configuration
# https://ssl-config.mozilla.org/#server=traefik&version=2.3&config=intermediate&guideline=5.6
[tls.options]
[tls.options.intermediate]
minVersion = "VersionTLS12"
cipherSuites = [
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
]

View file

@ -0,0 +1,57 @@
version: '3'
services:
app:
image: wallabag/wallabag
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SYMFONY__ENV__DATABASE_DRIVER=pdo_mysql
- SYMFONY__ENV__DATABASE_HOST=db
- SYMFONY__ENV__DATABASE_PORT=3306
- SYMFONY__ENV__DATABASE_NAME=wallabag
- SYMFONY__ENV__DATABASE_USER=${MYSQL_USER}
- SYMFONY__ENV__DATABASE_PASSWORD=${MYSQL_PASSWORD}
- SYMFONY__ENV__DATABASE_CHARSET=utf8mb4
- SYMFONY__ENV__MAILER_HOST=127.0.0.1
- SYMFONY__ENV__MAILER_USER=~
- SYMFONY__ENV__MAILER_PASSWORD=~
- SYMFONY__ENV__FROM_EMAIL=wallabag@${DOMAIN}
- SYMFONY__ENV__DOMAIN_NAME=https://wallabag.${DOMAIN}
networks:
- web
- wallabag
volumes:
- /var/dockervolumes/wallabag_images:/var/www/wallabag/web/assets/images
labels:
- "traefik.enable=true"
- "traefik.http.routers.wallabag.rule=Host(`wallabag.${DOMAIN}`)"
- "traefik.http.routers.wallabag.entrypoints=websecure"
- "traefik.http.routers.wallabag.tls.certresolver=myresolver"
- "traefik.http.routers.wallabag.tls.options=intermediate@file"
- "traefik.docker.network=web"
- "docker.group=wallabag"
depends_on:
- db
- redis
db:
image: mariadb:10
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
networks:
- wallabag
volumes:
- /var/dockervolumes/wallabag_db:/var/lib/mysql
redis:
image: redis:alpine
restart: unless-stopped
networks:
- wallabag
networks:
web:
external: true
wallabag:

28
www/docker-compose.yml Normal file
View file

@ -0,0 +1,28 @@
version: "3.3"
services:
app:
image: nginx
volumes:
- ${HTML}:/usr/share/nginx/html:ro
networks:
- web
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.entrypoints=http"
- "traefik.http.routers.web.rule=Host(`${DOMAIN}`) || Host(`www.${DOMAIN}`)"
- "traefik.http.middlewares.web-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.web.middlewares=web-https-redirect"
- "traefik.http.routers.web-secure.entrypoints=websecure"
- "traefik.http.routers.web-secure.rule=Host(`${DOMAIN}`) || Host(`www.${DOMAIN}`)"
- "traefik.http.routers.web-secure.tls=true"
- "traefik.http.routers.web-secure.tls.certresolver=myresolver"
- "traefik.http.routers.web-secure.tls.options=intermediate@file"
- "traefik.docker.network=web"
- "docker.group=www"
networks:
web:
external: true