diff --git a/apps/backend/docker-compose.yml b/apps/backend/docker-compose.yml new file mode 100644 index 0000000..22ac631 --- /dev/null +++ b/apps/backend/docker-compose.yml @@ -0,0 +1,36 @@ +### Backend (./apps/backend/docker-compose.yml) + +services: + backend: + container_name: ${INFRASTRUCTURE_LABEL}-laravel-${ENVIRONMENT} + profiles: ["laravel", "backend", "all", "app"] + env_file: + - ../../env/.env.all + - ../../env/${ENVIRONMENT}/.env.proxy + - ../../env/${ENVIRONMENT}/.env.database + - ../../env/${ENVIRONMENT}/.env.backend + depends_on: + - database + build: + context: ./src + dockerfile: Dockerfile + labels: + - "traefik.enable=${TRAEFIK_ENABLE}" + - "traefik.http.routers.backend.entrypoints=${TRAEFIK_ENTRYPOINT}" + - "traefik.http.routers.backend.rule=Host(`${BACKEND_DOMAIN}`)" + - "traefik.http.routers.backend.tls=true" + - "traefik.http.routers.backend.tls.certresolver=${TRAEFIK_CERT_RESOLVER}" + - "traefik.http.routers.backend.tls.domains[0].main=`${BACKEND_DOMAIN}`" + - "traefik.http.services.backend.loadbalancer.server.port=${BACKEND_PORT:-8000}" + - "traefik.docker.network=${TRAEFIK_NETWORK}" + # Traefik-Crowdsec Stack + backend-redis: + image: redis:alpine + container_name: ${INFRASTRUCTURE_LABEL}-laravelredis-${ENVIRONMENT} + profiles: ["redis", "backend", "all"] + restart: unless-stopped + command: redis-server --appendonly yes --requirepass laravel-redis-passwort # Redis Passwort eingeben + volumes: + - ../../volumes/backend/redis:/data +networks: + backend: diff --git a/apps/database/docker-compose.yml b/apps/database/docker-compose.yml new file mode 100644 index 0000000..f4f3687 --- /dev/null +++ b/apps/database/docker-compose.yml @@ -0,0 +1,40 @@ +### Database (./apps/database/docker-compose.yml) +# - [ ] Create a MariaDB service +# - [ ] Configure volumes for persistent storage of database data +# - [ ] Set up environment variables using the new structure (../../env/${ENVIRONMENT}/database.env) +# - [ ] Configure networking to allow connections from the backend service +# - [ ] Set up regular backup jobs for the database +# - [ ] Configure appropriate resource limits and restart policies +services: + database: + profiles: ["all", "mariadb", "backend", "app"] + image: mariadb:latest + container_name: ${INFRASTRUCTURE_LABEL}-mariadb-${ENVIRONMENT} + command: --bind-address=0.0.0.0 + hostname: ${MARIADB_HOST} + env_file: + - ../../env/.env.all + - ../../env/${ENVIRONMENT:-development}/.env.database + - ../../env/${ENVIRONMENT:-development}/.env.proxy + environment: + - MARIADB_USER=${MARIADB_USER} + - MARIADB_DATABASE=${MARIADB_DATABASE} + - MARIADB_PASSWORD=${MARIADB_PASSWORD} + - MARIADB_ROOT_PASSWORD=root-mindboost + volumes: + - ../../volumes/database/mariadb:/var/lib/mysql + networks: + - backend + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + retries: 3 + adminer: + profiles: ["all", "mariadb", "backend", "app"] + image: adminer + container_name: local_adminer + restart: always + ports: + - 8082:8080 + networks: + - backend \ No newline at end of file diff --git a/apps/develop/docker-compose.yml b/apps/develop/docker-compose.yml new file mode 100644 index 0000000..343142b --- /dev/null +++ b/apps/develop/docker-compose.yml @@ -0,0 +1,9 @@ +### Develop (./apps/develop/docker-compose.yml) +# - [ ] Create services for Gitea, Jenkins, and Adminer +# - [ ] Configure volumes for persistent storage of Git repositories, Jenkins data, and Adminer settings +# - [ ] Set up environment variables using the new structure (../../env/${ENVIRONMENT}/develop.env) +# - [ ] Configure networking to allow these services to communicate with each other and the necessary application services +# - [ ] Set up access controls and security measures for development tools + +include: + - ./gitea/docker-compose.yml diff --git a/apps/develop/gitea/docker-compose.yml b/apps/develop/gitea/docker-compose.yml new file mode 100644 index 0000000..344052b --- /dev/null +++ b/apps/develop/gitea/docker-compose.yml @@ -0,0 +1,44 @@ +services: + gitea: + image: gitea/gitea:latest + container_name: ${INFRASTRUCTURE_LABEL:-mindboost}-gitea + profiles: ["all", "gitea","develop"] + restart: always + volumes: + - ${GITEA_VOLUME_PATH}:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + depends_on: + - gitea_db + labels: + - "traefik.enable=${TRAEFIK_ENABLE}" + - "traefik.http.routers.gitea.entrypoints=${TRAEFIK_ENTRYPOINT}" + - "traefik.http.routers.gitea.rule=(Host(`${GITEA_DOMAIN})`)" + - "traefik.http.routers.gitea.tls=true" + - "traefik.http.routers.gitea.tls.certresolver=${TRAEFIK_CERT_RESOLVER}" + - "traefik.http.routers.gitea.service=gitea" + - 'traefik.http.services.gitea.loadbalancer.gitea.port=3000' + - "traefik.http.routers.gitea.tls.domains[0].main=`${GITEA_TLS_DOMAIN_MAIN}`" + + # SSH routing, can't route based on host so anything to port 222 will come to this container + - "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)" + - "traefik.tcp.routers.gitea-ssh.entrypoints=ssh" + - "traefik.tcp.routers.gitea-ssh.service=gitea-ssh-svc" + - "traefik.tcp.services.gitea-ssh-svc.loadbalancer.gitea.port=22" + + gitea_db: + image: mysql:latest + container_name: ${INFRASTRUCTURE_LABEL:-mindboost}-gitea_db + profiles: ["all", "gitea","develop"] + restart: always + environment: + - MYSQL_ROOT_PASSWORD=${GITEA_MYSQL_ROOT_PASSWORD} + - MYSQL_DATABASE=${GITEA_MYSQL_DATABASE} + - MYSQL_USER=${GITEA_MYSQL_USER} + - MYSQL_PASSWORD=${GITEA_MYSQL_PASSWORD} + volumes: + - ${GITEA_DATABASE_VOLUME_PATH}:/var/lib/mysql + +networks: + gitea: + diff --git a/apps/develop/jenkins/docker-compose.yml b/apps/develop/jenkins/docker-compose.yml new file mode 100644 index 0000000..f71dc7e --- /dev/null +++ b/apps/develop/jenkins/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3.8' + +services: + jenkins: + image: jenkins/jenkins:lts + container_name: jenkins + ports: + - "50000:50000" # Jenkins Agent Port + volumes: + - jenkins_home:/var/jenkins_home + environment: + - JAVA_OPTS=-Djenkins.install.runSetupWizard=false + networks: + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.jenkins.rule=Host(`j.haslach2025.de`)" + - "traefik.http.routers.jenkins.entrypoints=websecure" + - "traefik.http.routers.jenkins.tls=true" + - "traefik.http.routers.jenkins.tls.certresolver=http_resolver" + - "traefik.http.services.jenkins.loadbalancer.server.port=8080" # interner Port von Jenkins + - "traefik.docker.network=proxy" + +volumes: + jenkins_home: + driver: local + +networks: + proxy: + external: true diff --git a/apps/docker-compose.all.yml b/apps/docker-compose.all.yml new file mode 100644 index 0000000..61435db --- /dev/null +++ b/apps/docker-compose.all.yml @@ -0,0 +1,48 @@ +## +## ONE SCRIPT TO RULE THEM ALL +## +## Dieses Compose-File startet alle verfügbaren Services, abhängig von dem angegebenen ENVIRONMENT. + +## Um diese Konfiguration zu verwenden, kannst du folgende Befehle nutzen: +## Um alle Services zu starten: +## docker compose -f docker-compose.all.yml --env-file ../env/.env.all --profile all up -d + +## Um nur bestimmte Services zu starten (z.B. frontend und backend): +## docker compose -f docker-compose.all.yml --env-file ../env/.env.all --profile frontend --profile backend up -d + +## +## Stellen Sie sicher, dass die .env.all Datei im angegebenen Verzeichnis existiert und den ENVIRONMENT Wert enthält. +## + +include: + - path: ./proxy/docker-compose.yml + env_file: + - ../env/.env.all + - ../env/${ENVIRONMENT:-development}/.env.proxy + - path: ./frontend/docker-compose.yml + env_file: + - ../env/.env.all + - ../env/${ENVIRONMENT:-development}/.env.frontend + - ../env/${ENVIRONMENT:-development}/.env.proxy + - path: ./backend/docker-compose.yml + - path: ./database/docker-compose.yml + - path: ./website/docker-compose.yml + env_file: + - ../env/.env.all + - ../env/${ENVIRONMENT:-development}/.env.website + - ../env/${ENVIRONMENT:-development}/.env.proxy + - path: ./administration/docker-compose.yml + env_file: + - ../env/.env.all + - ../env/${ENVIRONMENT:-development}/.env.administration + - ../env/${ENVIRONMENT:-development}/.env.proxy + - path: ./develop/docker-compose.yml + env_file: + - ../env/.env.all + - ../env/${ENVIRONMENT:-development}/.env.develop + - ../env/${ENVIRONMENT:-development}/.env.proxy + - path: ./tools/docker-compose.yml + env_file: + - ../env/.env.all + - ../env/${ENVIRONMENT:-development}/.env.tools + - ../env/${ENVIRONMENT:-development}/.env.proxy \ No newline at end of file diff --git a/apps/frontend/docker-compose.yml b/apps/frontend/docker-compose.yml new file mode 100644 index 0000000..1660091 --- /dev/null +++ b/apps/frontend/docker-compose.yml @@ -0,0 +1,27 @@ +### Frontend (./apps/frontend/docker-compose.yml) +# - [ ] Create a Vue.js frontend service +# - [ ] Set up a Node.js environment for the frontend +# - [ ] Configure volumes for persistent storage of frontend assets +# - [ ] Set up environment variables using the new structure (../../env/${ENVIRONMENT}/frontend.env) +# - [ ] Configure networking to communicate with the backend service +# - [ ] Set up healthchecks for the frontend service +services: + webapp: + build: + context: ./src + dockerfile: Dockerfile + container_name: ${INFRASTRUCTURE_LABEL}-frontend-${ENVIRONMENT} + profiles: ["webapp", "frontend", "all", "app"] + depends_on: + - database + - backend + labels: + - "traefik.enable=${TRAEFIK_ENABLE}" + - "traefik.http.routers.webapp.entrypoints=${TRAEFIK_ENTRYPOINT}" + - 'traefik.http.routers.webapp.rule=Host(`${FRONTEND_DOMAIN}`) || Host(`${FRONTEND_DOMAIN_2}`)' + - "traefik.http.routers.webapp.tls=true" + - "traefik.http.routers.webapp.tls.certresolver=${TRAEFIK_CERT_RESOLVER}" + - "traefik.http.routers.webapp.tls.domains[0].main=${FRONTEND_DOMAIN}" + - "traefik.http.routers.webapp.tls.domains[0].sans=${FRONTEND_DOMAIN_2}" + - "traefik.http.services.webapp.loadbalancer.server.port=3000" + - "traefik.docker.network=${TRAEFIK_NETWORK}" \ No newline at end of file diff --git a/apps/security/docker-compose.linuxserver.yml b/apps/security/docker-compose.linuxserver.yml new file mode 100644 index 0000000..cf15d4c --- /dev/null +++ b/apps/security/docker-compose.linuxserver.yml @@ -0,0 +1,30 @@ +services: + wireguard: + image: linuxserver/wireguard + container_name: wireguard + cap_add: + - NET_ADMIN + - SYS_MODULE + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/Berlin + - SERVERURL=${SERVER_IP:?"❌ ERROR = SERVERURL is not set. Run set-server-ip.sh first."} + - SERVERPORT=51820 + - PEERS=3 # Number of VPN clients to generate + - PEERDNS=auto + - INTERNAL_SUBNET=22.22.22.0 + volumes: + - ../../volumes/security/wireguard/config:/config + - /lib/modules:/lib/modules + ports: + - "51820:51820/udp" + sysctls: + - net.ipv4.conf.all.src_valid_mark=1 + restart: unless-stopped + networks: + - wireguard_network + +networks: + wireguard_network: + driver: bridge diff --git a/apps/security/docker-compose.yml b/apps/security/docker-compose.yml new file mode 100644 index 0000000..5547c09 --- /dev/null +++ b/apps/security/docker-compose.yml @@ -0,0 +1,50 @@ +volumes: + etc_wireguard: + +services: + wg-easy: + environment: + # Change Language: + # (Supports: en, ua, ru, tr, no, pl, fr, de, ca, es, ko, vi, nl, is, pt, chs, cht, it, th, hi, ja, si) + - LANG=de + # ⚠️ Required: + # Change this to your host's public address + - WG_HOST=${SERVER_IP} + + # Optional: + # - PASSWORD_HASH=$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG # (needs double $$, hash of 'foobar123'; see "How_to_generate_an_bcrypt_hash.md" for generate the hash) + # - PORT=51821 + # - WG_PORT=51820 + # - WG_CONFIG_PORT=92820 + - WG_DEFAULT_ADDRESS=22.22.22.0 + # - WG_DEFAULT_DNS=1.1.1.1 + # - WG_MTU=1420 + # - WG_ALLOWED_IPS=192.168.15.0/24, 10.0.1.0/24 + # - WG_PERSISTENT_KEEPALIVE=25 + # - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt + # - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt + # - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt + # - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt + # - UI_TRAFFIC_STATS=true + # - UI_CHART_TYPE=0 # (0 Charts disabled, 1 # Line chart, 2 # Area chart, 3 # Bar chart) + # - WG_ENABLE_ONE_TIME_LINKS=true + # - UI_ENABLE_SORT_CLIENTS=true + # - WG_ENABLE_EXPIRES_TIME=true + # - ENABLE_PROMETHEUS_METRICS=false + # - PROMETHEUS_METRICS_PASSWORD=$$2a$$12$$vkvKpeEAHD78gasyawIod.1leBMKg8sBwKW.pQyNsq78bXV3INf2G # (needs double $$, hash of 'prometheus_password'; see "How_to_generate_an_bcrypt_hash.md" for generate the hash) + + image: ghcr.io/wg-easy/wg-easy + container_name: wg-easy + volumes: + - ../../volumes/wireguardeasy/:/etc/wireguard + ports: + - "51820:51820/udp" + - "51821:51821/tcp" + restart: unless-stopped + cap_add: + - NET_ADMIN + - SYS_MODULE + # - NET_RAW # ⚠️ Uncomment if using Podman + sysctls: + - net.ipv4.ip_forward=1 + - net.ipv4.conf.all.src_valid_mark=1 \ No newline at end of file diff --git a/apps/tools/docker-compose.yml b/apps/tools/docker-compose.yml new file mode 100644 index 0000000..15224f7 --- /dev/null +++ b/apps/tools/docker-compose.yml @@ -0,0 +1,67 @@ +### Tools (./apps/tools/docker-compose.yml) +# - [ ] Create services for Nextcloud, LimeSurvey, and LinkStack +# - [ ] Configure volumes for persistent storage of files, survey data, and link management data +# - [ ] Set up environment variables using the new structure (../../env/${ENVIRONMENT}/tools.env) +# - [ ] Configure networking to expose these services to the internet via the proxy +# - [ ] Set up regular backup jobs for critical data in these services + +services: + nextcloud-db: + image: mariadb:10.6 + container_name: ${INFRASTRUCTURE_LABEL}-nextcloud-db-${ENVIRONMENT} + profiles: ["all", "tools", "nextcloud"] + command: --transaction-isolation=READ-COMMITTED --innodb_read_only_compressed=OFF + restart: unless-stopped + volumes: + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + - ../../volumes/tools/${INFRASTRUCTURE_LABEL}_cloud/database:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=headpiece-constant1-denim-mindboost #SQL root Passwort eingeben + - MYSQL_PASSWORD=idealist9-frayed-murkiness-mindboost #SQL Benutzer Passwort eingeben + - MYSQL_DATABASE=nextcloud-mindboost #Datenbank Name + - MYSQL_USER=mindboostcloud #SQL Nutzername + - MYSQL_INITDB_SKIP_TZINFO=1 + - MARIADB_AUTO_UPGRADE=1 + nextcloud-redis: + image: redis:alpine + container_name: ${INFRASTRUCTURE_LABEL}-nextcloud-redis-${ENVIRONMENT} + profiles: ["all", "tools", "nextcloud"] + hostname: nextcloud-redis + restart: unless-stopped + command: redis-server --requirepass redis-mindboost-passwort # Redis Passwort eingeben + cloud: + image: nextcloud + container_name: ${INFRASTRUCTURE_LABEL}-nextcloud-app-${ENVIRONMENT} + profiles: ["all", "tools", "nextcloud"] + restart: unless-stopped + depends_on: + - nextcloud-db + - nextcloud-redis + environment: + TRUSTED_PROXIES: 172.16.255.254/16 + OVERWRITEPROTOCOL: https + OVERWRITECLIURL: https://${CLOUD_DOMAIN} + OVERWRITEHOST: ${CLOUD_DOMAIN} + REDIS_HOST: nextcloud-redis + REDIS_HOST_PASSWORD: redis-mindboost-passwort # Redis Passwort von oben wieder eingeben + volumes: + - ./app:/var/www/html + - ../../volumes/tools/${INFRASTRUCTURE_LABEL}_cloudapp/:/var/www/html/data + labels: + - "traefik.enable=true" + - "traefik.http.routers.${INFRASTRUCTURE_LABEL}_cloud.entrypoints=websecure" + - "traefik.http.routers.${INFRASTRUCTURE_LABEL}_cloud.rule=Host(`${CLOUD_DOMAIN}`)" + - "traefik.http.routers.${INFRASTRUCTURE_LABEL}_cloud.tls=true" + - "traefik.http.routers.${INFRASTRUCTURE_LABEL}_cloud.tls.certresolver=http_resolver" + - 'traefik.http.routers.${INFRASTRUCTURE_LABEL}_cloud.service=cloud' + - "traefik.http.services.cloud.loadbalancer.server.port=80" + - "traefik.docker.network=${TRAEFIK_NETWORK}" + - "traefik.http.routers.${INFRASTRUCTURE_LABEL}_cloud.middlewares=nextcloud-dav,default@file" + - "traefik.http.middlewares.nextcloud-dav.replacepathregex.regex=^/.well-known/ca(l|rd)dav" + - "traefik.http.middlewares.nextcloud-dav.replacepathregex.replacement=/remote.php/dav/" + networks: + - ${TRAEFIK_NETWORK} +networks: + nextcloud: + name: ${INFRASTRUCTURE_LABEL}_nextcloud diff --git a/apps/website/docker-compose.yml b/apps/website/docker-compose.yml new file mode 100644 index 0000000..c90bfcb --- /dev/null +++ b/apps/website/docker-compose.yml @@ -0,0 +1,23 @@ +services: + kirbycms: + build: + context: ./kirby + dockerfile: Dockerfile + image: kirbycms + container_name: ${INFRASTRUCTURE_LABEL}-kirbycms-${ENVIRONMENT} + profiles: ["website","kirbycms","all"] + volumes: + - ../../volumes/website/kirbycms:/var/www/html:rw # Persistente Daten + restart: unless-stopped + networks: + - ${TRAEFIK_NETWORK} + labels: + - "traefik.enable=${TRAEFIK_ENABLE}" + - "traefik.docker.network=${TRAEFIK_NETWORK}" + - "traefik.http.routers.kirbycms.service=kirbycms" + - "traefik.http.routers.kirbycms.tls.certresolver=${TRAEFIK_CERT_RESOLVER}" + - "traefik.http.routers.kirbycms.tls.domains[0].main=`${WEBSITE_DOMAIN}`" + - "traefik.http.routers.kirbycms.rule=Host(`${WEBSITE_DOMAIN}`)" + - "traefik.http.routers.kirbycms.entrypoints=${TRAEFIK_ENTRYPOINT}" + - "traefik.http.routers.kirbycms.tls=true" + - "traefik.http.services.kirbycms.loadbalancer.server.port=80"