19 Commits

Author SHA1 Message Date
61853ac2cd update repo dependency 2025-03-19 14:42:56 +01:00
56e6a53f0a add backend overwrite compose file for laravel and sql 2025-03-19 14:41:47 +01:00
62a96dc243 improve kirby 2025-03-13 19:24:28 +01:00
d4f202f204 add readme to env folder 2025-03-05 15:21:52 +01:00
49badb74a7 different script approaches to start the app 2025-03-05 15:20:01 +01:00
71d080a87e added some fallback values 2025-03-05 15:19:42 +01:00
138525835d move adminer to develop 2025-03-05 15:11:14 +01:00
f6e3793193 added scripts for deploy backend 2025-03-04 18:23:37 +01:00
c9b55aa0ed restructure backend folder and database 2025-03-04 18:22:02 +01:00
b8a6abe100 update env stucture for frontend deployment 2025-03-04 18:18:21 +01:00
2930854814 setup scripts for global env, project root and proxy env 2025-02-28 18:09:25 +01:00
d4abe64b0b changes in development environtments 2025-02-28 18:08:52 +01:00
1d04638be8 add healthcheck and init user script for database 2025-02-28 18:08:23 +01:00
02f20a277c add invoiceninja as git module 2025-02-28 18:07:07 +01:00
0f08168947 update the docker files for almost all apps 2025-02-28 18:06:47 +01:00
c976fea1c3 clean up 2025-02-28 10:12:13 +01:00
e981a365cc fall back für ROOT_DIR based on the current directory in file system 2025-02-26 12:48:56 +01:00
42b71394df updating the readme file environment explaination 2025-02-26 12:46:46 +01:00
a9143ae8f8 delete the docker compose files with where not neccesary for the code to run 2025-02-26 12:46:24 +01:00
47 changed files with 729 additions and 632 deletions

3
.gitmodules vendored
View File

@@ -4,3 +4,6 @@
[submodule "apps/frontend/src"]
path = apps/frontend/src
url = https://gitea.mindboost.team/Mindboost/mindboost-webapp.git
[submodule "apps/tools/invoiceninja/dockerfiles"]
path = apps/tools/invoiceninja/dockerfiles
url = https://github.com/invoiceninja/dockerfiles.git

View File

@@ -111,7 +111,7 @@ Each service's `docker-compose.yml` file references the appropriate `.env` file
services:
backend:
env_file:
- ../../env/${ENVIRONMENT}/backend.env
- ../../env/${ENVIRONMENT:-development}/backend.env
```
## Networking
@@ -128,12 +128,6 @@ Our infrastructure uses a two-tier network model to enhance security and isolate
- These networks are not directly accessible from the internet and provide secure communication between public and internal services.
- Examples: backend_network, database_network, etc.
Service Network Configuration:
- Frontend: Connected to proxy_network and backend_network
- Backend API: Connected to backend_network and database_network
- Database: Connected only to database_network
- Traefik: Connected only to proxy_network
This structure ensures that:
- The proxy (Traefik) can route traffic to public-facing services.
- Internal services (like databases) are not directly accessible from the proxy network.
@@ -163,7 +157,7 @@ The `volumes/` folder contains subdirectories for different volumes used by vari
Each subdirectory corresponds to a specific service or group of services, containing the persistent data that needs to be preserved across container restarts or redeployments.
When configuring Docker Compose files, reference these volume paths to ensure data persistence. For example:
When configuring Docker Compose files, reference these volume paths to ensure data persistence.
```yaml
volumes:

View File

@@ -0,0 +1,36 @@
### Database (./apps/database/docker-compose.yml)
# - [ ] Create a MariaDB service
# - [ ] Configure volumes for persistent storage of database data
secrets:
mariadb_root:
file: ${ROOT_DIR:-../../..}/env/secrets.env
services:
database:
secrets:
- mariadb_root
profiles: ["all", "database", "backend", "app"]
image: mariadb:latest
container_name: ${INFRASTRUCTURE_LABEL:-default}-mariadb-${ENVIRONMENT:-development}
command: --bind-address=0.0.0.0
env_file:
- ${ROOT_DIR:-../../..}/env/${ENVIRONMENT:-development}/.env.database
volumes:
- backend_mariadb_data:/var/lib/mysql
- ./healthcheck.sh:/usr/local/bin/healthcheck.sh
networks:
- backend
- database
healthcheck:
test: ["CMD", "bash", "/usr/local/bin/healthcheck.sh"]
interval: 1s
retries: 3
# TODO: ADMINER IS NOT PREPARED FOR TRAEFIK
networks:
backend:
name: ${INFRASTRUCTURE_LABEL:-default}-backend-${ENVIRONMENT:-development}
database:
name: ${INFRASTRUCTURE_LABEL:-default}-database-${ENVIRONMENT:-development}
volumes:
backend_mariadb_data:
driver: local
name: ${INFRASTRUCTURE_LABEL:-default}_mariadb_${ENVIRONMENT:-development}

View File

@@ -0,0 +1,33 @@
#!/bin/bash
# Credentials from environment variables
MYSQL_USER="${MARIADB_USER:-default}"
MYSQL_PASSWORD="${MARIADB_PASSWORD:-default}"
MYSQL_HOST="127.0.0.1"
ROOT_PASSWORD=$(cat /run/secrets/mariadb_root)
echo "🔑 READ ROOT PASSWORD FROM SECRETS"
# Check if MariaDB is running
if ! mariadb -h "$MYSQL_HOST" -u root -p"$ROOT_PASSWORD" -e "SELECT 1;" &>/dev/null; then
echo "❌ MariaDB is not responding"
exit 1
fi
# Check if a specific user exists
USER_EXISTS=$(mariadb -h "$MYSQL_HOST" -u root -p"$ROOT_PASSWORD" -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '${MYSQL_USER}');" | tail -n 1)
if [ "$USER_EXISTS" -ne 1 ]; then
echo "❌ User '${MYSQL_USER}' does not exist"
exit 1
fi
# Check if the user can log in with the provided password
if ! mariadb -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "SELECT 1;" &>/dev/null; then
echo "❌ User '${MYSQL_USER}' exists, but authentication failed with the provided password."
exit 1
fi
echo "✅ MariaDB is healthy"
exit 0

View File

@@ -0,0 +1,74 @@
#!/bin/bash
echo "🔄 Running MariaDB initialization script..."
# Wait until MariaDB is ready
until mysqladmin ping -h localhost --silent; do
sleep 2
done
echo "✅ MariaDB is ready. Checking root credentials..."
# Try logging in with the root password
if ! mysql -u root -p"$MARIADB_ROOT_PASSWORD" -e "SELECT 1;" &>/dev/null; then
echo "❌ ERROR: Root password in .env does not match the database!"
echo "🔄 Attempting to reset the root password..."
# Stop MariaDB safely
echo "⚠️ Stopping MariaDB..."
service mysql stop || pkill mysqld
sleep 5
# Start MariaDB in recovery mode
echo "🚀 Starting MariaDB in recovery mode..."
mysqld_safe --skip-grant-tables --skip-networking &
sleep 5
# Reset root password
echo "🔐 Resetting root password..."
mysql -u root <<EOSQL
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MARIADB_ROOT_PASSWORD}';
ALTER USER 'root'@'%' IDENTIFIED BY '${MARIADB_ROOT_PASSWORD}';
FLUSH PRIVILEGES;
EOSQL
echo "✅ Root password reset successfully!"
# Restart MariaDB in normal mode
echo "🔄 Restarting MariaDB in production mode..."
service mysql stop || pkill mysqld
sleep 3
mysqld_safe &
sleep 5
else
echo "✅ Root password is correct."
fi
# Check if the database exists
DB_EXISTS=$(mysql -u root -p"$MARIADB_ROOT_PASSWORD" -e "SHOW DATABASES LIKE '${MARIADB_DATABASE}';" | grep "${MARIADB_DATABASE}" > /dev/null; echo "$?")
if [ "$DB_EXISTS" -ne 0 ]; then
echo "⚠️ Database '${MARIADB_DATABASE}' does not exist. Creating it now..."
mysql -u root -p"$MARIADB_ROOT_PASSWORD" -e "CREATE DATABASE ${MARIADB_DATABASE};"
echo "✅ Database '${MARIADB_DATABASE}' created!"
else
echo "✅ Database '${MARIADB_DATABASE}' already exists."
fi
# Ensure the database user exists and has the correct password
USER_EXISTS=$(mysql -u root -p"$MARIADB_ROOT_PASSWORD" -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '${MARIADB_USER}');" | tail -n 1)
if [ "$USER_EXISTS" -eq 0 ]; then
echo "⚠️ User '${MARIADB_USER}' does not exist. Creating it now..."
mysql -u root -p"$MARIADB_ROOT_PASSWORD" <<EOSQL
CREATE USER '${MARIADB_USER}'@'%' IDENTIFIED BY '${MARIADB_PASSWORD}';
GRANT ALL PRIVILEGES ON ${MARIADB_DATABASE}.* TO '${MARIADB_USER}'@'%';
FLUSH PRIVILEGES;
EOSQL
echo "✅ User '${MARIADB_USER}' created and granted access to '${MARIADB_DATABASE}'!"
else
echo "✅ User '${MARIADB_USER}' already exists. Ensuring correct password."
mysql -u root -p"$MARIADB_ROOT_PASSWORD" -e "ALTER USER '${MARIADB_USER}'@'%' IDENTIFIED BY '${MARIADB_PASSWORD}'; FLUSH PRIVILEGES;"
echo "✅ Password for '${MARIADB_USER}' updated!"
fi
echo "🎉 MariaDB initialization complete!"

View File

@@ -0,0 +1,48 @@
### Backend (./apps/backend/docker-compose.yml)
include:
- ./database/docker-compose.yml
services:
backend:
container_name: ${INFRASTRUCTURE_LABEL:-default}-backend-laravel-${ENVIRONMENT:-development}
profiles: ["laravel", "backend", "all", "app"]
ports:
- "${LARAVEL_PORT:-8000}:8000"
- "${LARAVEL_VITE_PORT:-5173}:5173"
env_file:
- ../../env/${ENVIRONMENT:-development}/.env.backend
volumes:
- ./src/entrypoint.sh:/usr/local/bin/entrypoint.sh
depends_on:
- database
build:
context: ./src
dockerfile: Dockerfile
networks:
- backend
labels:
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
- "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}"
backend-redis:
image: redis:alpine
container_name: ${INFRASTRUCTURE_LABEL:-default}-backend-redis-${ENVIRONMENT:-development}
profiles: ["redis", "backend", "all"]
env_file:
- ../../env/${ENVIRONMENT:-development}/.env.backend
restart: unless-stopped
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-laravel-redis-passwort} # Redis Passwort eingeben
volumes:
- backend_redis_data:/data
networks:
- backend
volumes:
backend_redis_data:
driver: local
name: "${INFRASTRUCTURE_LABEL:-default}_backend_redis_data"

View File

@@ -1,21 +1,23 @@
### Backend (./apps/backend/docker-compose.yml)
include:
- ./database/docker-compose.yml
services:
backend:
container_name: ${INFRASTRUCTURE_LABEL}-laravel-${ENVIRONMENT}
container_name: ${INFRASTRUCTURE_LABEL:-default}-backend-laravel-${ENVIRONMENT:-development}
profiles: ["laravel", "backend", "all", "app"]
env_file:
- ../../env/.env.all
- ../../env/${ENVIRONMENT}/.env.proxy
- ../../env/${ENVIRONMENT}/.env.database
- ../../env/${ENVIRONMENT}/.env.backend
- ../../env/${ENVIRONMENT:-development}/.env.backend
volumes:
- ./src/entrypoint.sh:/usr/local/bin/entrypoint.sh
depends_on:
- database
build:
context: ./src
dockerfile: Dockerfile
networks:
- backend
labels:
- "traefik.enable=${TRAEFIK_ENABLE}"
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
- "traefik.http.routers.backend.entrypoints=${TRAEFIK_ENTRYPOINT}"
- "traefik.http.routers.backend.rule=Host(`${BACKEND_DOMAIN}`)"
- "traefik.http.routers.backend.tls=true"
@@ -23,14 +25,21 @@ services:
- "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}
container_name: ${INFRASTRUCTURE_LABEL:-default}-backend-redis-${ENVIRONMENT:-development}
profiles: ["redis", "backend", "all"]
env_file:
- ../../env/${ENVIRONMENT:-development}/.env.backend
restart: unless-stopped
command: redis-server --appendonly yes --requirepass laravel-redis-passwort # Redis Passwort eingeben
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-laravel-redis-passwort} # Redis Passwort eingeben
volumes:
- ../../volumes/backend/redis:/data
- backend_redis_data:/data
networks:
backend:
- backend
volumes:
backend_redis_data:
driver: local
name: "${INFRASTRUCTURE_LABEL}_backend_redis_data"

View File

@@ -1,39 +0,0 @@
### 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:-development}/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:-default}-mariadb-${ENVIRONMENT:-development}
command: --bind-address=0.0.0.0
env_file:
- ../../env/.env.all
- ../../env/${ENVIRONMENT:-development}/.env.backend
- ../../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: ${INFRASTRUCTURE_LABEL:-default}-adminer-${ENVIRONMENT:-development}
restart: always
ports:
- 8082:8080
networks:
- backend

View File

@@ -0,0 +1,8 @@
services:
adminer:
profiles: ["all", "database", "backend", "adminer", "app"]
image: adminer
container_name: ${INFRASTRUCTURE_LABEL:-default}-adminer-${ENVIRONMENT:-development}
restart: always
ports:
- ${ADMINER_PORT:-0}:8080

View File

@@ -0,0 +1,20 @@
services:
adminer:
profiles: ["all", "database", "backend", "adminer", "app"]
image: adminer
container_name: ${INFRASTRUCTURE_LABEL:-default}-adminer-${ENVIRONMENT:-development}
restart: always
ports:
- ${ADMINER_PORT:-0}:8080
networks:
- database
- proxy
labels:
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_adminer.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_adminer.rule=Host(`${ADMINER_DOMAIN:-adminer.local}`)"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_adminer.tls=true"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_adminer.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-http_resolver}"
- 'traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_adminer.service=adminer'
- "traefik.http.adminer.cloud.loadbalancer.server.port=8080"
- "traefik.docker.network=${TRAEFIK_NETWORK:-default}"

View File

@@ -11,7 +11,7 @@ services:
depends_on:
- gitea_db
labels:
- "traefik.enable=${TRAEFIK_ENABLE}"
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
- "traefik.http.routers.gitea.entrypoints=${TRAEFIK_ENTRYPOINT}"
- "traefik.http.routers.gitea.rule=(Host(`${GITEA_DOMAIN})`)"
- "traefik.http.routers.gitea.tls=true"

View File

@@ -14,6 +14,9 @@
## Stellen Sie sicher, dass die .env.all Datei im angegebenen Verzeichnis existiert und den ENVIRONMENT Wert enthält.
##
configs:
all:
file: ../env/.env.all
include:
- path: ./proxy/docker-compose.yml
env_file:
@@ -23,7 +26,6 @@ include:
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

View File

@@ -1,65 +0,0 @@
##
## DIESES COMPOSE FILE IST FÜR DIE LOKALE ENTWICKLUNG MITTELS DOCKER
##
## Der Inhalt von frontend und von backend wird über ein volume eingebunden, dass
## bedeutet Änderungen innerhalb der Projektordner ./frontend/src und ./backend/src
## Ändern direkt die Werte innerhalb des Containers wie z.B. das Austauschen einer Grafik.
##
## Datenbank ebenfalls lokal und KEIN reverse-Proxy (traefik)
## Image der DB ist auf ARM Archtektur (Apple Silicon) ausgelegt
##
services:
mariadb:
image: mariadb:latest
container_name: local_mariadb
command: --bind-address=0.0.0.0
environment:
- ALLOW_EMPTY_PASSWORD
- MARIADB_USER=mindboost
- MARIADB_DATABASE=mindboost
- MARIADB_PASSWORD=mindboost
- MARIADB_ROOT_PASSWORD=root-mindboost
volumes:
- ../volumes/daten/mariadb:/var/lib/mysql
networks:
- backend
frontend:
build:
context: ./frontend/src
dockerfile: Dockerfile.dev
container_name: local_frontend
volumes:
- ./frontend/src:/app
- /app/node_modules
ports:
- "3000:3000"
networks:
- backend
environment:
NODE_ENV: development
backend:
build:
context: ./backend/src
dockerfile: Dockerfile.dev
container_name: local_backend
ports:
- "8000:8000"
- "5173:5173"
volumes:
- ./backend/src:/var/www
networks:
- backend
depends_on:
- mariadb
adminer:
image: adminer
container_name: local_adminer
restart: always
ports:
- 8080:8080
networks:
- backend
networks:
backend:
external: false

View File

@@ -1,107 +0,0 @@
##
## DIESES COMPOSE FILE IST FÜR DIE LOKALE ENTWICKLUNG MITTELS DOCKER
##
## Der Inhalt von frontend und von backend wird über ein volume eingebunden, dass
## bedeutet Änderungen innerhalb der Projektordner ./frontend/src und ./backend/src
## Ändern direkt die Werte innerhalb des Containers wie z.B. das Austauschen einer Grafik.
##
## Datenbank ebenfalls lokal und KEIN reverse-Proxy (traefik)
## Image der DB ist auf ARM Archtektur (Apple Silicon) ausgelegt
##
services:
prod-mariadb:
image: mariadb:latest
container_name: prod-mariadb
hostname: mariadb
command: --bind-address=0.0.0.0
env_file:
- ../config/.env.db
networks:
- ${BACKEND_NETWORK}
volumes:
- ../volumes/daten/mariadb:/var/lib/mysql
prod-redis:
image: redis:alpine
container_name: prod-redis
hostname: redis
networks:
- ${BACKEND_NETWORK}
restart: unless-stopped
command: redis-server --appendonly yes --requirepass laravel-redis-passwort # Redis Passwort eingeben
volumes:
- ../volumes/daten/redis:/data
prod-frontend:
build:
context: ./frontend/src
dockerfile: Dockerfile
container_name: prod-frontend
networks:
- ${BACKEND_NETWORK}
- ${TRAEFIK_NETWORK}
env_file:
- ../config/.env.frontend
- ../config/.env.traefik
labels:
- "traefik.enable=${TRAEFIK_ENABLE}"
- "traefik.http.routers.prod-frontend.entrypoints=${TRAEFIK_ROUTER_FRONTEND_ENTRYPOINT}"
- "traefik.http.routers.prod-frontend.rule=${TRAEFIK_ROUTER_FRONTEND_RULE}"
- "traefik.http.routers.prod-frontend.tls=${TRAEFIK_ROUTER_FRONTEND_TLS}"
- "traefik.http.routers.prod-frontend.tls.certresolver=${TRAEFIK_ROUTER_FRONTEND_CERTRESOLVER}"
- "traefik.http.routers.prod-frontend.tls.domains[0].main=${TRAEFIK_ROUTER_FRONTEND_TLS_DOMAIN_MAIN}"
- "traefik.http.routers.prod-frontend.tls.domains[0].sans=${TRAEFIK_ROUTER_FRONTEND_TLS_DOMAIN_SANS}"
- "traefik.http.services.prod-frontend.loadbalancer.server.port=${TRAEFIK_SERVICE_FRONTEND_PORT}"
- "traefik.docker.network=${TRAEFIK_NETWORK}"
prod-backend:
build:
context: ./backend/src
dockerfile: Dockerfile
env_file:
- ../config/.env.backend
- ../config/.env.traefik
labels:
- "traefik.enable=${TRAEFIK_ENABLE}"
- "traefik.http.routers.prod-backend.entrypoints=${TRAEFIK_ROUTER_BACKEND_ENTRYPOINT}"
- "traefik.http.routers.prod-backend.rule=${TRAEFIK_ROUTER_BACKEND_RULE}"
- "traefik.http.routers.prod-backend.tls=${TRAEFIK_ROUTER_BACKEND_TLS}"
- "traefik.http.routers.prod-backend.tls.certresolver=${TRAEFIK_ROUTER_BACKEND_CERTRESOLVER}"
- "traefik.http.routers.prod-backend.tls.domains[0].main=${TRAEFIK_ROUTER_BACKEND_TLS_DOMAIN_MAIN}"
- "traefik.http.services.prod-backend.loadbalancer.server.port=${TRAEFIK_SERVICE_BACKEND_PORT}"
- "traefik.docker.network=${TRAEFIK_NETWORK}"
networks:
- ${BACKEND_NETWORK}
- ${TRAEFIK_NETWORK}
depends_on:
- prod-mariadb
# Traefik-Crowdsec Stack
crowdsec:
extends:
file: ./proxy/docker-compose.yml
service: crowdsec
networks:
- ${TRAEFIK_NETWORK}
traefik:
extends:
file: ./proxy/docker-compose.yml
service: traefik
networks:
- ${TRAEFIK_NETWORK}
depends_on:
- crowdsec
traefik_crowdsec_bouncer:
extends:
file: ./proxy/docker-compose.yml
service: traefik_crowdsec_bouncer
networks:
- ${TRAEFIK_NETWORK}
depends_on:
- crowdsec
- traefik
networks:
prod-backend:
external: false
proxy:
external: true

View File

@@ -0,0 +1,19 @@
services:
webapp:
build:
context: ./src
dockerfile: Dockerfile
args:
BACKEND_URL: ${BACKEND_URL:-http://localhost:8000} # this argument is important on build to set the server url!
container_name: ${INFRASTRUCTURE_LABEL:-default}-frontend-${ENVIRONMENT:-development}
profiles: ["webapp", "frontend", "all", "app"]
ports:
- 3000:3000
labels:
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
- "traefik.http.routers.webapp.service=webapp"
- "traefik.http.routers.webapp.entrypoints=${TRAEFIK_ENTRYPOINT}"
- 'traefik.http.routers.webapp.rule=Host(`${FRONTEND_DOMAIN}`) || Host(`${FRONTEND_DOMAIN_2}`)'
- "traefik.http.services.webapp.loadbalancer.server.port=3000"
- "traefik.docker.network=${TRAEFIK_NETWORK}"

View File

@@ -1,27 +1,17 @@
### 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:-development}/frontend.env)
# - [ ] Configure networking to communicate with the backend service
# - [ ] Set up healthchecks for the frontend service
services:
webapp:
build:
context: ./src
dockerfile: Dockerfile
args:
BACKEND_URL: ${BACKEND_URL:-http://localhost:8000} # this argument is important on build to set the backend server url!
container_name: ${INFRASTRUCTURE_LABEL:-default}-frontend-${ENVIRONMENT:-development}
profiles: ["webapp", "frontend", "all", "app"]
depends_on:
- database
- backend
labels:
- "traefik.enable=${TRAEFIK_ENABLE}"
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
- "traefik.http.routers.webapp.service=webapp"
- "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}"

View File

@@ -5,63 +5,7 @@
# - [ ] 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:-default}-nextcloud-db-${ENVIRONMENT:-development}
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:-default}_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:-default}-nextcloud-redis-${ENVIRONMENT:-development}
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:-default}-nextcloud-app-${ENVIRONMENT:-development}
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:-cloud}
OVERWRITEHOST: ${CLOUD_DOMAIN:-cloud}
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:-default}_cloudapp/:/var/www/html/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.entrypoints=websecure"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.rule=Host(`${CLOUD_DOMAIN}`)"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.tls=true"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.tls.certresolver=http_resolver"
- 'traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.service=cloud'
- "traefik.http.services.cloud.loadbalancer.server.port=80"
- "traefik.docker.network=${TRAEFIK_NETWORK:-default}"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_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:-default}_nextcloud
include:
- path: ./nextcloud/docker-compose.yml
- path: ./limesurvey/docker-compose.yml
- path: ./invoiceninja/dockerfiles/debian/docker-compose.yml

View File

View File

@@ -0,0 +1,59 @@
services:
nextcloud-db:
image: mariadb:10.6
container_name: ${INFRASTRUCTURE_LABEL:-default}-nextcloud-db-${ENVIRONMENT:-development}
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:-default}_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:-default}-nextcloud-redis-${ENVIRONMENT:-development}
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:-default}-nextcloud-app-${ENVIRONMENT:-development}
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:-cloud}
OVERWRITEHOST: ${CLOUD_DOMAIN:-cloud}
REDIS_HOST: nextcloud-redis
REDIS_HOST_PASSWORD: redis-mindboost-passwort # Redis Passwort von oben wieder eingeben
volumes:
- ../../volumes/tools/${INFRASTRUCTURE_LABEL:-default}_cloudapp/:/var/www/html/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.entrypoints=websecure"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.rule=Host(`${CLOUD_DOMAIN}`)"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.tls=true"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.tls.certresolver=http_resolver"
- 'traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_cloud.service=cloud'
- "traefik.http.services.cloud.loadbalancer.server.port=80"
- "traefik.docker.network=${TRAEFIK_NETWORK:-default}"
- "traefik.http.routers.${INFRASTRUCTURE_LABEL:-default}_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:-default}_nextcloud

View File

@@ -7,17 +7,23 @@ services:
container_name: ${INFRASTRUCTURE_LABEL:-default}-kirbycms-${ENVIRONMENT:-development}
profiles: ["website","kirbycms","all"]
volumes:
- ../../volumes/website/kirbycms:/var/www/html:rw # Persistente Daten
- kirbycms_data:/var/www/html:rw # Persistente Daten
restart: unless-stopped
ports:
- 0:80
networks:
- ${TRAEFIK_NETWORK}
- ${TRAEFIK_NETWORK:-default}
labels:
- "traefik.enable=${TRAEFIK_ENABLE}"
- "traefik.docker.network=${TRAEFIK_NETWORK}"
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
- "traefik.docker.network=${TRAEFIK_NETWORK:-default}"
- "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.certresolver=${TRAEFIK_CERT_RESOLVER:-default}"
- "traefik.http.routers.kirbycms.tls.domains[0].main=`${WEBSITE_DOMAIN:-kirby.local}`"
- "traefik.http.routers.kirbycms.rule=Host(`${WEBSITE_DOMAIN:-kirby.local}`)"
- "traefik.http.routers.kirbycms.entrypoints=${TRAEFIK_ENTRYPOINT:-default}"
- "traefik.http.routers.kirbycms.tls=true"
- "traefik.http.services.kirbycms.loadbalancer.server.port=80"
volumes:
kirbycms_data:
driver: local

View File

@@ -1 +1 @@
USERID=0
USERID=${USERID:-0}

191
env/.env.all vendored
View File

@@ -37,194 +37,3 @@ SERVER_IP=127.0.0.1
# ✅ If needed, manually override variables in the shell or CLI.
#
#################################################################################################
## ______________________________________________________________________________________________
## SEVICE GROUP ADMINISTRATION
## ______________________________________________________________________________________________
# ----------------------------------
# Portainer
# ----------------------------------
PORTAINER_IMAGE=portainer/portainer-ce:latest
PORTAINER_DATA_PATH=../../../volumes/administration/portainer/data
## ______________________________________________________________________________________________
## SEVICE GROUP DATABASE
## ______________________________________________________________________________________________
# ----------------------------------
# Datenbank (MariaDB)
# ----------------------------------
MARIADB_USER=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}
MARIADB_DATABASE=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}
MARIADB_PASSWORD=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}
MARIADB_ROOT_PASSWORD=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}-root
MARIADB_PORT=3306
MARIADB_HOST=${INFRASTRUCTURE_LABEL:-default}_database_${ENVIRONMENT:-development}
## ______________________________________________________________________________________________
## SEVICE GROUP BACKEND
## ______________________________________________________________________________________________
# ----------------------------------
# Redis
# ----------------------------------
REDIS_PASSWORD=laravel-redis-passwort
REDIS_PORT=6379
# ----------------------------------
# Laravel Backend
# ----------------------------------
BACKEND_NETWORK=backend
APP_NAME="mindboost backend - Compose Deployment"
APP_URL=https://backend.local
LARAVEL_PORT=8000
LARAVEL_VITE_PORT=5173
DB_HOST=${MARIADB_HOST:-mariadb}
DB_PORT=${MARIADB_PORT:-3306}
DB_PASSWORD=${MARIADB_PASSWORD:-default}
DB_USERNAME=${MARIADB_USER:-default}
DB_DATABASE=${MARIADB_DATABASE:-default}
JWT_SECRET=zMtO8sgsnc4UixWSsYWE1pK9EdpNLzxNSoIPlUpTe6dDlarM3bu4cwM80tH3jA0F
# ----------------------------------
# Adminer
# ----------------------------------
ADMINER_PORT=8080
## ______________________________________________________________________________________________
## SEVICE GROUP DEVELOP
## ______________________________________________________________________________________________
# ----------------------------------
# GITEA AND GITEA DB
# ----------------------------------
USER_UID=1000
USER_GID=1000
GITEA_VOLUME_PATH=../../../volumes/develop/gitea/gitea
GITEA_DATABASE_VOLUME_PATH=../../../volumes/develop/gitea/gitea_db
GITEA_MYSQL_ROOT_PASSWORD=very-difficult-passwort-gitea
GITEA_MYSQL_USER=gitea
GITEA_MYSQL_PASSWORD=very-difficult-gitea
GITEA_MYSQL_DATABASE=gitea
GITEA_MYSQL_ALLOW_EMPTY_PASSWORD=true
## ______________________________________________________________________________________________
## SEVICE GROUP FRONTEND
## ______________________________________________________________________________________________
# ----------------------------------
# VUE APP
# ----------------------------------
BACKEND_URL="backend.local"
## ______________________________________________________________________________________________
## SEVICE GROUP PROXY
## ______________________________________________________________________________________________
# ----------------------------------
# TRAEFIK
# ----------------------------------
TRAEFIK_ENABLE=true
TRAEFIK_NETWORK=proxy
TRAEFIK_BASIC_AUTH_USERS=${ADMIN_USER:-admin}:${ADMIN_PASSWORD_HASH}
TRAEFIK_CERT_RESOLVER=
## Domains when TRAEFIK is ENABLED
PORTAINER_DOMAIN=portainer.local
FRONTEND_DOMAIN=frontend.local
FRONTEND_DOMAIN_2=app.frontend.local
BACKEND_DOMAIN=backend.local
WEBSITE_DOMAIN=web.local
GITEA_DOMAIN=gitea.local
LIMESURVEY_DOMAIN=survey.local
LINKSTACK_DOMAIN=linkstack.local
TRAEFIK_DOMAIN=traefik.local
CLOUD_DOMAIN=cloud.local
### TLS for Domains
PORTAINER_TLS_DOMAIN_MAIN=${PORTAINER_DOMAIN}
FRONTEND_TLS_DOMAIN_MAIN=${FRONTEND_DOMAIN}
FRONTEND_TLS_DOMAIN_SANS=${FRONTEND_DOMAIN_2}
BACKEND_TLS_DOMAIN_MAIN=${BACKEND_DOMAIN}
WEBSITE_TLS_DOMAIN_MAIN=${WEBSITE_DOMAIN}
GITEA_TLS_DOMAIN_MAIN=${GITEA_DOMAIN}
LIMESURVEY_TLS_DOMAIN_MAIN=${LIMESURVEY_DOMAIN}
LINKSTACK_TLS_DOMAIN_MAIN=${LINKSTACK_DOMAIN}
TRAEFIK_TLS_DOMAIN_MAIN=${TRAEFIK_DOMAIN}
CLOUD_TLS_DOMAIN_MAIN=${CLOUD_DOMAIN}
## MIDDLEWARES
TRAEFIK_HTTPS_REDIRECT_MIDDLEWARE=${INFRASTRUCTURE_LABEL:-default}-https-redirect
TRAEFIK_BASIC_AUTH_MIDDLEWARE=${INFRASTRUCTURE_LABEL:-default}-basic-auth
## ENTRYPOINTS
TRAEFIK_ENTRYPOINT=websecure
TRAEFIK_ENTRYPOINT_HTTP=web
## ______________________________________________________________________________________________
## SEVICE GROUP SECURITY
## ______________________________________________________________________________________________
# ----------------------------------
# WIREGUARD
# ----------------------------------
WG_DEFAULT_ADDRESS=22.22.22.0
WG_HOST=${SERVER_IP:-127.0.0.1}
WG_LANG=de
## ______________________________________________________________________________________________
## SEVICE GROUP TOOLS
## ______________________________________________________________________________________________
# ----------------------------------
# NEXTCLOUD DB
# ----------------------------------
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 CLOUD
# ----------------------------------
TRUSTED_PROXIES=172.16.255.254/16
OVERWRITEPROTOCOL=https
OVERWRITECLIURL=https://${CLOUD_DOMAIN:-cloud}
OVERWRITEHOST=${CLOUD_DOMAIN:-cloud}
REDIS_HOST=nextcloud-redis
REDIS_HOST_PASSWORD=redis-mindboost-passwort
## ______________________________________________________________________________________________
## SEVICE GROUP WEBSITE
## ______________________________________________________________________________________________
# ----------------------------------
# KIRBY CMS
# ----------------------------------
KIRBY_USER_ID=0

49
env/.env.backend vendored
View File

@@ -1,49 +0,0 @@
# ----------------------------------
# Datenbank (MariaDB)
# ----------------------------------
MARIADB_USER=mindboost
MARIADB_DATABASE=mindboost
MARIADB_PASSWORD=1stronges-mindboostdb-passwort
MARIADB_ROOT_PASSWORD=1stronges-passwort-fuer-diedb
# ----------------------------------
# Redis
# ----------------------------------
REDIS_PASSWORD=laravel-redis-passwort
REDIS_PORT=6379
# ----------------------------------
# Vue Frontend (Nuxt.js)
# ----------------------------------
VUE_APP_BACKEND_HOST_ADDRESS=https://dev.b.mindboost.team
VUE_FRONTEND_PORT=3001
VUE_INTERNAL_PORT=3000
VUE_FRONTEND_DOMAIN_1=app.mindboost.team
VUE_FRONTEND_DOMAIN_2=mindboost.app
# ----------------------------------
# Laravel Backend
# ----------------------------------
BACKEND_NETWORK=backend
APP_NAME="mindboost backend - Compose Deployment"
APP_URL=https://b.mindboost.team
LARAVEL_PORT=8000
LARAVEL_VITE_PORT=5173
DB_HOST=mariadb
DB_PORT=3306
DB_PASSWORD=1stronges-mindboostdb-passwort
DB_USERNAME=mindboost
DB_DATABASE=mindboost
LARAVEL_DOMAIN=b.mindboost.team
JWT_SECRET=zMtO8sgsnc4UixWSsYWE1pK9EdpNLzxNSoIPlUpTe6dDlarM3bu4cwM80tH3jA0F
# ----------------------------------
# Traefik
# ----------------------------------
TRAEFIK_CERT_RESOLVER=http_resolver
TRAEFIK_ENTRYPOINT=websecure
TRAEFIK_NETWORK=proxy
# ----------------------------------
# Adminer
# ----------------------------------
ADMINER_PORT=8080

8
env/.env.db vendored
View File

@@ -1,8 +0,0 @@
# ----------------------------------
# Datenbank (MariaDB)
# ----------------------------------
MARIADB_USER=mindboost
MARIADB_DATABASE=mindboost
MARIADB_PASSWORD=1stronges-mindboostdb-passwort
MARIADB_ROOT_PASSWORD=1stronges-passwort-fuer-diedb
ADMINER_PORT=8000

1
env/.env.frontend vendored
View File

@@ -1 +0,0 @@
DB_HOST= BLALBLAB

1
env/.env.shared vendored
View File

@@ -1 +0,0 @@
DB_HOST= BLALBLAB

24
env/.env.traefik vendored
View File

@@ -1,24 +0,0 @@
# ----------------------------------
# Traefik
# ----------------------------------
# Allgemein
TRAEFIK_ENABLE=true
TRAEFIK_NETWORK=proxy
# Backend
TRAEFIK_ROUTER_BACKEND_ENTRYPOINT=websecure
TRAEFIK_ROUTER_BACKEND_RULE=Host(`b.mindboost.team`)
TRAEFIK_ROUTER_BACKEND_TLS=true
TRAEFIK_ROUTER_BACKEND_CERTRESOLVER=http_resolver
TRAEFIK_ROUTER_BACKEND_TLS_DOMAIN_MAIN=b.mindboost.team
TRAEFIK_SERVICE_BACKEND_PORT=8000
# Frontend
TRAEFIK_ROUTER_FRONTEND_ENTRYPOINT=websecure
TRAEFIK_ROUTER_FRONTEND_RULE=Host(`app.mindboost.team`)
TRAEFIK_ROUTER_FRONTEND_TLS=true
TRAEFIK_ROUTER_FRONTEND_CERTRESOLVER=http_resolver
TRAEFIK_ROUTER_FRONTEND_TLS_DOMAIN_MAIN=app.mindboost.team
TRAEFIK_ROUTER_FRONTEND_TLS_DOMAIN_SANS=mindboost.app
TRAEFIK_SERVICE_FRONTEND_PORT=3000

50
env/README.md vendored Normal file
View File

@@ -0,0 +1,50 @@
# 🔧 Environment Configuration Guide
## 🌍 Overview
This project uses **environment variables** to manage configuration across different environments (development, staging, production, etc.). These variables are loaded from `.env` files and can be overridden at multiple levels.
---
## 📌 **Environment Variable Priority (Lowest to Highest)**
| 🔢 Priority | 📄 Source | 🔍 Description |
|------------|-----------------------------|------------------------------------------------|
| 1**Fallback Values** | hardcoded defaults | Used only if no other configuration is provided |
| 2**Global Defaults** | `.env.all` | Shared settings for all services |
| 3**Service-Specific Overrides** | `.env.backend`, `.env.proxy`, etc. | Overrides `.env.all` with service-specific values |
| 4**Shell Environment Variables** | `export VAR=value` before running | Takes precedence over `.env` files |
| 5**CLI Overrides** | `docker compose --env-file` or `-e VAR=value` | **Highest priority** (for temporary overrides) |
---
## 🔄 **Overwriting Behavior**
- 🏗 **Variables defined in `.env.all`** override fallback values.
- 🏗 **Variables defined in `.env.<service>`** (e.g., `.env.backend`) override `.env.all`.
- 🔧 **Manually exported environment variables** in the shell take priority over `.env` files.
- 🚀 **Variables passed via CLI (`--env-file` or `-e VAR=value`)** override everything.
---
## 🚀 **Best Practices**
✔️ **Use `.env.all` for global configurations** (e.g., `ENVIRONMENT=development`, `INFRASTRUCTURE_LABEL=myinfra`).
✔️ **Use `.env.<service>` for service-specific configurations** (e.g., `.env.backend` for Laravel, `.env.database` for MariaDB).
✔️ **If needed, manually override variables in the shell** using `export VAR=value`.
✔️ **Use CLI `--env-file` for temporary overrides** in testing/debugging scenarios.
---
## 🏗 **Example File Structure**
```sh
/env/
├── .env.all # Global default variables
├── development/
│ ├── .env.backend # Backend service config for development
│ ├── .env.database # Database config for development
│ ├── .env.proxy # Proxy config for development
├── staging/
│ ├── .env.backend # Backend service config for staging
│ ├── .env.database # Database config for staging
├── production/
│ ├── .env.backend # Backend service config for production
│ ├── .env.database # Database config for production

View File

@@ -11,16 +11,21 @@ SERVER_IP=${SERVER_IP:-localhost}
# Laravel Backend
# ----------------------------------
BACKEND_NETWORK=backend
APP_ENV=${ENVIRONMENT-local}
APP_NAME="mindboost backend - Compose Deployment"
APP_URL=https://backend.local
LARAVEL_PORT=8000
LARAVEL_VITE_PORT=5173
DB_HOST=${MARIADB_HOST:-database}
DB_PORT=${MARIADB_PORT:-3306}
DB_PASSWORD=${MARIADB_PASSWORD:-default}
DB_USERNAME=${MARIADB_USER:-default}
DB_DATABASE=${MARIADB_DATABASE:-default}
JWT_SECRET=zMtO8sgsnc4UixWSsYWE1pK9EdpNLzxNSoIPlUpTe6dDlarM3bu4cwM80tH3jA0F
# ----------------------------------
# Datenbank Zugriff - ! MUSS MIT .env.database übereinstimmen
# ----------------------------------
DB_HOST=database
DB_PORT=3306
DB_PASSWORD=1stronges-mindboostdb-passwort
DB_USERNAME=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}
DB_DATABASE=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}

View File

@@ -3,12 +3,7 @@
# ----------------------------------
MARIADB_USER=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}
MARIADB_DATABASE=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}
MARIADB_ROOT_PASSWORD_FILE=/run/secrets/mariadb_root
MARIADB_PASSWORD=1stronges-mindboostdb-passwort
MARIADB_RANDOM_ROOT_PASSWORD=1
MARIADB_PORT=3306
MARIADB_HOST=database
# ----------------------------------
# Adminer
# ----------------------------------
ADMINER_PORT=8082

View File

@@ -1,5 +1,4 @@
# ----------------------------------
# VUE APP
# ----------------------------------
BACKEND_URL="backend.local"

View File

@@ -2,7 +2,7 @@
# TRAEFIK
# ----------------------------------
TRAEFIK_ENABLE=false
TRAEFIK_ENABLE=true
TRAEFIK_NETWORK=proxy
TRAEFIK_BASIC_AUTH_USERS=${ADMIN_USER}:${ADMIN_PASSWORD_HASH}
TRAEFIK_CERT_RESOLVER=
@@ -14,6 +14,7 @@ FRONTEND_DOMAIN=frontend.local
FRONTEND_DOMAIN_2=app.frontend.local
BACKEND_DOMAIN=backend.local
WEBSITE_DOMAIN=web.local
ADMINER_DOMAIN=adminer.local
GITEA_DOMAIN=gitea.local
LIMESURVEY_DOMAIN=survey.local
LINKSTACK_DOMAIN=linkstack.local

31
env/development/portainer/backend.env vendored Normal file
View File

@@ -0,0 +1,31 @@
# ----------------------------------
# Redis
# ----------------------------------
REDIS_PASSWORD=laravel-redis-passwort
REDIS_PORT=6379
SERVER_IP=${SERVER_IP:-localhost}
# ----------------------------------
# Laravel Backend
# ----------------------------------
BACKEND_NETWORK=backend
APP_ENV=${ENVIRONMENT-local}
APP_NAME="mindboost backend - Compose Deployment"
APP_URL=https://backend.local
LARAVEL_PORT=8000
LARAVEL_VITE_PORT=5173
JWT_SECRET=zMtO8sgsnc4UixWSsYWE1pK9EdpNLzxNSoIPlUpTe6dDlarM3bu4cwM80tH3jA0F
# ----------------------------------
# Datenbank Zugriff - ! MUSS MIT .env.database übereinstimmen
# ----------------------------------
DB_HOST=database
DB_PORT=3306
DB_PASSWORD=1stronges-mindboostdb-passwort
DB_USERNAME=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}
DB_DATABASE=${INFRASTRUCTURE_LABEL:-default}_${ENVIRONMENT:-development}

View File

@@ -0,0 +1,3 @@
source ./../setup/set-global-env.sh
chmod +x ./../../apps/backend/src/entrypoint.sh
docker compose -f ./../../apps/backend/docker-compose.overwrite.yml --env-file ./../../env/${ENVIRONMENT}/.env.database --env-file ./../../env/${ENVIRONMENT}/.env.backend --profile backend up

View File

@@ -0,0 +1,3 @@
source ./../setup/set-global-env.sh
source ./../setup/set-frontend-env.sh
docker compose -f ./../../apps/frontend/docker-compose.overwrite.yml --env-file ./../../env/${ENVIRONMENT}/.env.frontend --profile frontend up

View File

@@ -3,7 +3,13 @@
# 🚀 Script to Generate Secure Secrets for Deployment
# Define root directory relative to the script location
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# Stelle sicher, dass ROOT_DIR gesetzt ist
if [ -z "$ROOT_DIR" ]; then
echo "❌ WARN: ROOT_DIR ist nicht gesetzt! Setze ROOT_DIR..."
source ./set-project-root.sh
fi
SECRET_FILE="$ROOT_DIR/env/secrets.env"
GITIGNORE_FILE="$ROOT_DIR/.gitignore"

View File

@@ -0,0 +1,59 @@
#!/bin/bash
# Stelle sicher, dass ROOT_DIR gesetzt ist
if [ -z "$ROOT_DIR" ]; then
echo "❌ WARN: ROOT_DIR ist nicht gesetzt! Setze ROOT_DIR..."
# Bestimme das Root-Verzeichnis des Git-Repos
ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null)
# Falls das Repository nicht gefunden wurde, abbrechen
if [ -z "$ROOT_DIR" ]; then
echo "❌ Fehler: Kein Git-Repository gefunden!"
exit 1
fi
# Setze die Variable für die aktuelle Shell-Sitzung
export ROOT_DIR
echo "✅ ROOT_DIR gesetzt auf: $ROOT_DIR"
fi
# Setze den Pfad zur .env.all Datei relativ zum Projekt-Root
ENV_FILE="$ROOT_DIR/env/development/.env.frontend"
# Prüfen, ob die Datei existiert
if [ ! -f "$ENV_FILE" ]; then
echo "❌ Fehler: Die Datei $ENV_FILE existiert nicht!"
exit 1
fi
echo "✅ ENV-Datei vorhanden: $ENV_FILE"
# Funktion: Alle Variablen exportieren
export_env_vars() {
while IFS='=' read -r key value; do
# Entferne führende und nachfolgende Leerzeichen
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)
# Falls die Zeile ein Kommentar oder leer ist, überspringen
if [[ -z "$key" || "$key" =~ ^# || -z "$value" ]]; then
continue
fi
# Exportiere die Variable
export "$key=$value"
done < "$ENV_FILE"
}
# Alle Variablen exportieren
export_env_vars
echo "🔹 Geladene Variablen:"
grep -o '^[^#]*' "$ENV_FILE" | cut -d '=' -f1 | while read -r var; do
echo "$var=${!var}" # Gibt die gesetzten Variablen mit ihrem Wert aus
done

65
scripts/setup/set-global-env.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/bin/bash
# Stelle sicher, dass ROOT_DIR gesetzt ist
if [ -z "$ROOT_DIR" ]; then
echo "❌ WARN: ROOT_DIR ist nicht gesetzt! Setze ROOT_DIR..."
# Bestimme das Root-Verzeichnis des Git-Repos
ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null)
# Falls das Repository nicht gefunden wurde, abbrechen
if [ -z "$ROOT_DIR" ]; then
echo "❌ Fehler: Kein Git-Repository gefunden!"
exit 1
fi
# Setze die Variable für die aktuelle Shell-Sitzung
export ROOT_DIR
echo "✅ ROOT_DIR gesetzt auf: $ROOT_DIR"
fi
# Setze den Pfad zur .env.all Datei relativ zum Projekt-Root
ENV_FILE="$ROOT_DIR/env/.env.all"
# Prüfen, ob die Datei existiert
if [ ! -f "$ENV_FILE" ]; then
echo "❌ Fehler: Die Datei $ENV_FILE existiert nicht!"
exit 1
fi
echo "✅ ENV-Datei vorhanden: $ENV_FILE"
# Funktion: Alle Variablen exportieren
export_env_vars() {
while IFS='=' read -r key value; do
# Entferne führende und nachfolgende Leerzeichen
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)
# Falls die Zeile ein Kommentar oder leer ist, überspringen
if [[ -z "$key" || "$key" =~ ^# || -z "$value" ]]; then
continue
fi
# Entferne umschließende Anführungszeichen, falls vorhanden
value=$(echo "$value" | sed -E 's/^"(.*)"$/\1/')
# Exportiere die Variable
export "$key=$value"
done < "$ENV_FILE"
}
# Alle Variablen exportieren
export_env_vars
export SERVER_IP=$(curl -s https://api.ipify.org)
echo "🔹 Geladene Variablen:"
grep -o '^[^#]*' "$ENV_FILE" | cut -d '=' -f1 | while read -r var; do
echo "$var=${!var}" # Gibt die gesetzten Variablen mit ihrem Wert aus
done

View File

@@ -0,0 +1,14 @@
#!/bin/bash
# Bestimme das Root-Verzeichnis des Git-Repos
ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null)
# Falls das Repository nicht gefunden wurde, abbrechen
if [ -z "$ROOT_DIR" ]; then
echo "❌ Fehler: Kein Git-Repository gefunden!"
exit 1
fi
# Setze die Variable für die aktuelle Shell-Sitzung
export ROOT_DIR
echo "✅ ROOT_DIR gesetzt auf: $ROOT_DIR"

View File

@@ -0,0 +1,60 @@
#!/bin/bash
# Stelle sicher, dass ROOT_DIR gesetzt ist
if [ -z "$ROOT_DIR" ]; then
echo "❌ WARN: ROOT_DIR ist nicht gesetzt! Setze ROOT_DIR..."
source ./set-project-root.sh
fi
# Stelle sicher, dass ENVIRONMENT gesetzt ist
if [ -z "$ENVIRONMENT" ]; then
echo "❌ WARN: ENVIRONMENT ist nicht gesetzt! Setze ENVIRONMENT..."
source ./set-global-env.sh
fi
# Setze den Pfad zur .env.all Datei relativ zum Projekt-Root
ENV_FILE="$ROOT_DIR/env/${ENVIRONMENT}/.env.proxy"
# Prüfen, ob die Datei existiert
if [ ! -f "$ENV_FILE" ]; then
echo "❌ Fehler: Die Datei $ENV_FILE existiert nicht!"
exit 1
fi
echo "✅ ENV-Datei vorhanden: $ENV_FILE"
# Funktion: Alle Variablen exportieren
export_env_vars() {
while IFS='=' read -r key value; do
# Entferne führende und nachfolgende Leerzeichen
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)
# Falls die Zeile ein Kommentar oder leer ist, überspringen
if [[ -z "$key" || "$key" =~ ^# || -z "$value" ]]; then
continue
fi
# Entferne umschließende Anführungszeichen, falls vorhanden
value=$(echo "$value" | sed -E 's/^"(.*)"$/\1/')
# Exportiere die Variable
export "$key=$value"
done < "$ENV_FILE"
}
# Alle Variablen exportieren
export_env_vars
export SERVER_IP=$(curl -s https://api.ipify.org)
echo "🔹 Geladene Variablen:"
grep -o '^[^#]*' "$ENV_FILE" | cut -d '=' -f1 | while read -r var; do
echo "$var=${!var}" # Gibt die gesetzten Variablen mit ihrem Wert aus
done

View File

@@ -1,4 +1,9 @@
#!/bin/bash
source ../setup/set-project-root.sh
source ../setup/set-global-env.sh
source ../setup/set-proxy-env.sh
source ../setup/generate-secrets.sh
# Pfad zur .env.all Datei
ENV_FILE="../../env/.env.all"

View File

@@ -1,4 +1,8 @@
#!/bin/bash
source ../setup/set-project-root.sh
source ../setup/set-global-env.sh
source ../setup/set-proxy-env.sh
source ../setup/generate-secrets.sh
# Pfad zur .env.all Datei
ENV_FILE="../../env/.env.all"
@@ -13,7 +17,7 @@ ENVIRONMENT=$(get_env_var "ENVIRONMENT")
SERVER_IP=$(curl -s https://api.ipify.org)
# Liste aller Stacks
STACKS=("frontend" "database" "backend")
STACKS=("proxy" "frontend" "database" "backend")
# Liste aller Environments
ENVIRONMENTS=("development" "staging" "production")
@@ -44,7 +48,7 @@ else
fi
# Ausgabe der Variablen
echo "Deploying to:"
echo "Deploying to"
echo "INFRASTRUCTURE: ${INFRASTRUCTURE:-Not set}"
echo "ENVIRONMENT: ${ENVIRONMENT:-Not set}"
echo "-----------------------------------"
@@ -57,5 +61,5 @@ fi
# Ausführen des Docker Compose Befehls
docker compose -f ../../apps/docker-compose.all.yml --env-file ../../env/.env.all -p ${INFRASTRUCTURE:-my} --profile app up --remove-orphans $BUILD_OPTION
docker compose -f ../../apps/docker-compose.all.yml -p ${INFRASTRUCTURE:-my} --profile app up --remove-orphans $BUILD_OPTION

View File

@@ -0,0 +1,3 @@
source ./../setup/set-global-env.sh
chmod +x ./../../apps/backend/src/entrypoint.sh
docker compose -f ./../../apps/backend/docker-compose.yml --env-file ./../../env/${ENVIRONMENT}/.env.database --env-file ./../../env/${ENVIRONMENT}/.env.backend --profile backend up

View File

@@ -3,7 +3,7 @@ set -e
# Funktion zur Überprüfung der Produktivumgebung
is_production() {
local prod_ip="85.215.56.185" # IP-Adresse deines Produktivservers
local prod_ip=${SERVER_IP:-127.0.0.1} # IP-Adresse deines Produktivservers
local current_ip
# Überprüfe das Betriebssystem
@@ -69,30 +69,27 @@ if ! docker ps --format '{{.Names}}' | grep -q 'traefik'; then
echo "Wir befinden uns in der Produktivumgebung."
echo "Starte Traefik und CrowdSec Bouncer mit docker-compose.traefik.prod.yml..."
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/proxy/docker-compose.traefik.prod.yml up -d
docker compose -f ../../apps/proxy/docker-compose.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
else
echo "Wir befinden uns in der lokalen Entwicklungsumgebung."
echo "Starte Traefik und CrowdSec Bouncer mit docker-compose.traefik.local.yml..."
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/docker-compose.traefik.local.yml up -d
docker compose -f ../../apps/proxy/docker-compose.overwrite.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
fi
else
echo "Traefik läuft bereits. Aktualisiere die Konfiguration..."
if is_production; then
echo "Aktualisiere Traefik und CrowdSec Bouncer in der Produktivumgebung..."
docker compose -f ../apps/docker-compose.traefik.prod.yml up -d
docker compose -f ../../apps/proxy/docker-compose.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
else
echo "Aktualisiere Traefik und CrowdSec Bouncer in der lokalen Umgebung..."
docker compose -f ../apps/docker-compose.traefik.local.yml up -d
docker compose -f ../../apps/proxy/docker-compose.overwrite.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
fi
fi
echo "Traefik und CrowdSec Bouncer Deployment abgeschlossen."
=================
echo "Prüfe, ob Traefik läuft..."
set_environment_variables
@@ -106,14 +103,14 @@ fi
if is_production; then
echo "Wir befinden uns in der Produktivumgebung."
echo "Starte/Aktualisiere Deployment mit docker-compose.prod.yml..."
echo "Starte/Aktualisiere Deployment mit docker-compose.yml..."
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/docker-compose.prod.yml up -d
docker compose -f ../../apps/proxy/docker-compose.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
else
echo "Wir befinden uns in der lokalen Entwicklungsumgebung."
echo "Starte/Aktualisiere lokale Version mit docker-compose.overwrite.yml..."
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/docker-compose.overwrite.yml up -d
docker compose -f ../../apps/proxy/docker-compose.overwrite.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
fi
@@ -123,9 +120,9 @@ if ! docker ps --format '{{.Names}}' | grep -q 'traefik'; then
if is_production; then
echo "Wir befinden uns in der Produktivumgebung."
set_environment_variables
echo "Starte Deployment mit docker-compose.prod.yml..."
echo "Starte Deployment mit docker-compose.yml..."
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/docker-compose.prod.yml up -d
docker compose -f ../../apps/proxy/docker-compose.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
else
echo "Wir befinden uns in der lokalen Entwicklungsumgebung."
read -p "Möchtest du die lokale Version zum Debuggen (docker-compose.overwrite.yml) starten? (y/n): " answer
@@ -133,7 +130,7 @@ if ! docker ps --format '{{.Names}}' | grep -q 'traefik'; then
echo "Starte lokale Version..."
set_environment_variables
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/docker-compose.overwrite.yml up -d
docker compose -f ../../apps/proxy/docker-compose.overwrite.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
else
echo "Deployment abgebrochen."
exit 1
@@ -145,15 +142,15 @@ else
if is_production; then
echo "Wir befinden uns in der Produktivumgebung."
set_environment_variables
echo "Aktualisiere Deployment mit docker-compose.prod.yml..."
echo "Aktualisiere Deployment mit docker-compose.yml..."
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/docker-compose.prod.yml up -d
docker compose -f ../../apps/proxy/docker-compose.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
else
echo "Wir befinden uns in der lokalen Entwicklungsumgebung."
set_environment_variables
echo "Aktualisiere lokale Version mit docker-compose.overwrite.yml..."
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
docker compose -f ../apps/docker-compose.overwrite.yml up -d
docker compose -f ../../apps/proxy/docker-compose.overwrite.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
fi
fi

37
scripts/start/deploy.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
#!/bin/bash
# Bestimme das Root-Verzeichnis des Git-Repos
ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null)
# Falls das Repository nicht gefunden wurde, abbrechen
if [ -z "$ROOT_DIR" ]; then
echo "❌ Fehler: Kein Git-Repository gefunden!"
exit 1
fi
# Setze die Variable für die aktuelle Shell-Sitzung
echo "✅ ROOT_DIR gesetzt auf: $ROOT_DIR"
# Pfad zur .env.all Datei
ENV_FILE="${ROOT_DIR}/env/.env.all"
echo $ENV_FILE
# Funktion zum Auslesen von Variablen aus der .env.all Datei
get_env_var() {
grep "^$1=" "$ENV_FILE" | cut -d '=' -f2
}
# Auslesen der INFRASTRUCTURE und ENVIRONMENT Variablen
INFRASTRUCTURE=$(get_env_var "INFRASTRUCTURE_LABEL")
ENVIRONMENT=$(get_env_var "ENVIRONMENT")
SERVER_IP=$(curl -s https://api.ipify.org)
# Ausgabe der Variablen
echo "Deploying to:"
echo "INFRASTRUCTURE: ${INFRASTRUCTURE:-Not set}"
echo "ENVIRONMENT: ${ENVIRONMENT:-Not set}"
echo "-----------------------------------"
# Ausführen des Docker Compose Befehls
docker compose -f ../../apps/docker-compose.all.yml -p ${INFRASTRUCTURE:-my} --env-file ${ENV_FILE} --env-file ${ROOT_DIR}/env/${ENVIRONMENT:-development}/.env.proxy --profile app up --remove-orphans