Compare commits
40 Commits
eb7b1cf7dd
...
4b39cd884b
Author | SHA1 | Date |
---|---|---|
|
4b39cd884b | |
|
f682150557 | |
|
da67cbd46e | |
|
d4f202f204 | |
|
49badb74a7 | |
|
71d080a87e | |
|
138525835d | |
|
f6e3793193 | |
|
c9b55aa0ed | |
|
b8a6abe100 | |
|
2930854814 | |
|
d4abe64b0b | |
|
1d04638be8 | |
|
02f20a277c | |
|
0f08168947 | |
|
c976fea1c3 | |
|
e981a365cc | |
|
42b71394df | |
|
a9143ae8f8 | |
|
dff86e0486 | |
|
f14186deca | |
|
9afa8808db | |
|
69323be965 | |
|
76e3b3938f | |
|
97b28e9540 | |
|
b886adf877 | |
|
c45823ee91 | |
|
2cb9a141b2 | |
|
fd36d17e12 | |
|
ba5d253c19 | |
|
a5b26ebde1 | |
|
ac27973330 | |
|
ebe6da4fbb | |
|
3686959644 | |
|
c0a3fc7a10 | |
|
83e78eb652 | |
|
388475fafc | |
|
302f9be36c | |
|
2dbc359bd2 | |
|
1c5d9359ff |
|
@ -0,0 +1,6 @@
|
|||
volumes
|
||||
apps/proxy
|
||||
.DS_Store
|
||||
apps/administration/*
|
||||
apps/tools/app/*
|
||||
env/secrets.env
|
|
@ -0,0 +1,6 @@
|
|||
[submodule "apps/backend/src"]
|
||||
path = apps/backend/src
|
||||
url = https://gitea.mindboost.team/Mindboost/mindboost-backend.git
|
||||
[submodule "apps/frontend/src"]
|
||||
path = apps/frontend/src
|
||||
url = https://gitea.mindboost.team/Mindboost/mindboost-webapp.git
|
189
README.md
189
README.md
|
@ -1,3 +1,190 @@
|
|||
# mindboost-infrastructure
|
||||
|
||||
All the software used and hosted by mindboost organized in containers.
|
||||
All the software used and hosted by mindboost organized in containers.
|
||||
|
||||
## Project Structure
|
||||
|
||||
./apps/
|
||||
├── docker-compose.all.yml # Orchestriert alle Docker Compose Stacks
|
||||
│
|
||||
├── frontend/
|
||||
│ ├── docker-compose.yml
|
||||
│ └── src/ # Vue.js frontend source code
|
||||
│
|
||||
├── backend/
|
||||
│ ├── docker-compose.yml
|
||||
│ └── src/ # Laravel backend source code
|
||||
│
|
||||
├── database/
|
||||
│ └── docker-compose.yml # MariaDB stack
|
||||
│
|
||||
├── website/
|
||||
│ └── docker-compose.yml # KirbyCMS public site stack
|
||||
│
|
||||
├── administration/
|
||||
│ └── docker-compose.yml # Portainer stack
|
||||
│
|
||||
├── proxy/
|
||||
│ └── docker-compose.yml # Traefik, Crowdsec, and Bouncer stack
|
||||
│
|
||||
├── develop/
|
||||
│ └── docker-compose.yml # Gitea, Jenkins, and Adminer stack
|
||||
│
|
||||
└── tools/
|
||||
└── docker-compose.yml # Nextcloud, LimeSurvey, and LinkStack stack
|
||||
|
||||
## Current Services
|
||||
|
||||
1. Frontend (Vue.js)
|
||||
2. Backend (Laravel)
|
||||
3. Database (MariaDB)
|
||||
4. Proxy (Traefik, Crowdsec, Bouncer)
|
||||
|
||||
## Upcoming Services
|
||||
|
||||
1. Website (KirbyCMS)
|
||||
2. Administration (Portainer)
|
||||
3. Development Tools (Gitea, Jenkins, Adminer)
|
||||
4. Utility Tools (Nextcloud, LimeSurvey, LinkStack)
|
||||
|
||||
## Service Descriptions
|
||||
|
||||
### Current Services
|
||||
|
||||
- **Frontend**: Vue.js based user interface for the mindboost application.
|
||||
- **Backend**: Laravel based API and server-side logic for the mindboost application.
|
||||
- **Database**: MariaDB for data storage and management.
|
||||
- **Proxy**: Traefik for reverse proxy, Crowdsec and Bouncer for security.
|
||||
|
||||
### Upcoming Services
|
||||
|
||||
- **Website**: KirbyCMS for the public-facing website.
|
||||
- **Administration**: Portainer for container management and monitoring.
|
||||
- **Development Tools**:
|
||||
- Gitea: Self-hosted Git service
|
||||
- Jenkins: Continuous Integration/Continuous Deployment (CI/CD) tool
|
||||
- Adminer: Database management tool
|
||||
- **Utility Tools**:
|
||||
- Nextcloud: File hosting and collaboration platform
|
||||
- LimeSurvey: Online survey tool
|
||||
- LinkStack: Link management tool
|
||||
|
||||
## Deployment
|
||||
|
||||
Each service or group of related services has its own `docker-compose.yml` file in its respective folder under `./apps/`. This structure allows for modular deployment and easier management of individual services.
|
||||
|
||||
To deploy a service, navigate to its directory and run:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
For the entire infrastructure, a root `docker-compose.yml` file can be created to orchestrate all services together.
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
Environment variables are managed in a centralized `env` folder at the root of the project. This structure allows for easy management of different environments and services.
|
||||
|
||||
./env/
|
||||
│
|
||||
├── development/
|
||||
│ ├── frontend.env
|
||||
│ ├── backend.env
|
||||
│ ├── database.env
|
||||
│ └── ...
|
||||
│
|
||||
├── staging/
|
||||
│ ├── frontend.env
|
||||
│ ├── backend.env
|
||||
│ ├── database.env
|
||||
│ └── ...
|
||||
│
|
||||
└── production/
|
||||
├── frontend.env
|
||||
├── backend.env
|
||||
├── database.env
|
||||
└── ...
|
||||
|
||||
Each service's `docker-compose.yml` file references the appropriate `.env` file based on the current environment. For example:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
backend:
|
||||
env_file:
|
||||
- ../../env/${ENVIRONMENT:-development}/backend.env
|
||||
```
|
||||
|
||||
## Networking
|
||||
|
||||
Our infrastructure uses a two-tier network model to enhance security and isolate services:
|
||||
|
||||
1. Proxy Network (proxy_network):
|
||||
- Exposed to the internet and contains the Traefik reverse proxy.
|
||||
- Only services that need to be publicly accessible should be connected to this network.
|
||||
- Example services: Traefik, frontend application.
|
||||
|
||||
2. Internal Networks:
|
||||
- Separate internal networks are created for each public service that needs to communicate with internal services.
|
||||
- These networks are not directly accessible from the internet and provide secure communication between public and internal services.
|
||||
- Examples: backend_network, database_network, etc.
|
||||
|
||||
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.
|
||||
- Each connection between a public and an internal service has its own isolated network.
|
||||
|
||||
This configuration minimizes the attack surface by isolating networks and ensuring that services only have access to the networks they absolutely need. Each connection between a public and an internal service is protected by a dedicated internal network, further enhancing security.
|
||||
|
||||
## Volumes
|
||||
|
||||
Persistent data should be managed using named volumes or bind mounts, depending on the requirements of each service. This ensures data persistence across container restarts and updates.
|
||||
|
||||
The `volumes/` folder contains subdirectories for different volumes used by various applications in the infrastructure. This centralized structure allows for easier management and backup of persistent data.
|
||||
|
||||
./volumes/
|
||||
│
|
||||
├── backend/ # Volume for backend-specific data
|
||||
├── database/ # Volume for MariaDB data
|
||||
├── website/ # Volume for KirbyCMS data
|
||||
├── administration/ # Volume for Portainer data
|
||||
├── develop/
|
||||
│ ├── gitea/ # Volume for Gitea repositories and data
|
||||
│ └── jenkins/ # Volume for Jenkins data and job configurations
|
||||
└── tools/
|
||||
├── nextcloud/ # Volume for Nextcloud files and data
|
||||
├── limesurvey/ # Volume for LimeSurvey data
|
||||
└── linkstack/ # Volume for LinkStack data
|
||||
|
||||
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.
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- ./volumes/database:/var/lib/mysql
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
The `scripts/` folder contains a collection of utility scripts for deployment, backup, and maintenance tasks. These scripts are designed to automate common operations and ensure consistency across different environments.
|
||||
|
||||
./scripts/
|
||||
│
|
||||
├── deployment/
|
||||
│ ├── deploy-app.sh # Script for deploying the main application
|
||||
│ └── deploy-traefik.sh # Script for deploying Traefik
|
||||
│
|
||||
├── backup/
|
||||
│ ├── backup-database.sh # Script for backing up the database
|
||||
│ └── backup-files.sh # Script for backing up file storage
|
||||
│
|
||||
└── maintenance/
|
||||
├── update-services.sh # Script for updating all services
|
||||
└── health-check.sh # Script for performing health checks on services
|
||||
|
||||
These scripts can be run from the command line to perform various tasks related to the infrastructure. Always review and test scripts in a safe environment before using them in production.
|
||||
|
||||
To use a script, navigate to the scripts directory and run:
|
||||
|
||||
```bash
|
||||
./script-name.sh
|
|
@ -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}
|
|
@ -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
|
|
@ -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!"
|
|
@ -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}_backend_redis_data"
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
### 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"]
|
||||
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}_backend_redis_data"
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 9ec88bb4faddc8474d660269bc80efcefa18e183
|
|
@ -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}"
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
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"]
|
||||
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}"
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 03a625f7acc74adf10270ba1abe1cf6c33a5063b
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/bash
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Konfiguration #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
# Verzeichnis, das gesichert werden soll
|
||||
source_dir="../volumes"
|
||||
# Verzeichnis, in dem die Backups gespeichert werden sollen
|
||||
backup_dir="/opt/docker_backups"
|
||||
# Anzahl der zu behaltenden Backups
|
||||
keep_backups=10
|
||||
# Aktuelles Datum und Uhrzeit
|
||||
current_datetime=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
# Name für das Backup-Archiv
|
||||
backup_filename="${current_datetime}-backup.tar"
|
||||
# Zielserver-Informationen
|
||||
remote_user="root"
|
||||
remote_server="TARGET NOT YET DEVICED"
|
||||
remote_dir="/opt/docker_backups"
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Ende der Konfiguration #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
remote_target="${remote_user}@${remote_server}"
|
||||
backup_fullpath="${backup_dir}/${backup_filename}"
|
||||
|
||||
# Docker-Container herunterfahren
|
||||
docker stop $(docker ps -q)
|
||||
# Erstelle das Backup-Archiv
|
||||
tar -cpf "${backup_fullpath}" "${source_dir}"
|
||||
# Docker-Container wieder starten
|
||||
docker start $(docker ps -a -q)
|
||||
# Komprimiere das Backup-Archiv
|
||||
gzip "${backup_fullpath}"
|
||||
backup_fullpath="${backup_fullpath}.gz"
|
||||
# Kopiere das Backup auf den Zielserver mit SCP ohne Passwort
|
||||
scp "${backup_fullpath}" "${remote_target}:$remote_dir/"
|
||||
# Lösche ältere lokale Backups mit `find`
|
||||
find "$backup_dir" -type f -name "*-backup.tar.gz" -mtime +$keep_backups -exec rm {} \;
|
||||
# Lösche ältere remote Backups mit `find`
|
||||
ssh "${remote_target}" "find ${remote_dir} -type f -name '*-backup.tar.gz' -mtime +$keep_backups -exec rm {} \;"
|
||||
|
||||
echo "Backup wurde erstellt: ${backup_fullpath} und auf ${remote_target} kopiert."
|
|
@ -0,0 +1,87 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 🚀 Script to Generate Secure Secrets for Deployment
|
||||
|
||||
# Define root directory relative to the script location
|
||||
|
||||
# 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"
|
||||
|
||||
# ✅ Function to check if a command is installed
|
||||
check_dependency() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# 🔍 Check for OpenSSL, and prompt user to install if missing
|
||||
if ! check_dependency "openssl"; then
|
||||
echo "⚠️ OpenSSL is not installed. It is required to generate secure secrets."
|
||||
echo "Would you like to install OpenSSL now? (yes/no)"
|
||||
read -r install_choice
|
||||
if [[ "$install_choice" == "yes" ]]; then
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
sudo apt update && sudo apt install -y openssl
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
brew install openssl
|
||||
else
|
||||
echo "❌ Unsupported OS. Please install OpenSSL manually."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "❌ OpenSSL is required but was not installed. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ✅ Securely generate random values
|
||||
generate_secret() {
|
||||
openssl rand -base64 32
|
||||
}
|
||||
|
||||
# 🔄 Check if the secret file already exists
|
||||
if [ -f "$SECRET_FILE" ]; then
|
||||
echo "⚠️ $SECRET_FILE already exists. Overwrite? (yes/no)"
|
||||
read -r response
|
||||
if [[ "$response" != "yes" ]]; then
|
||||
echo "❌ Secret file creation canceled."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ✏️ Write secrets to file
|
||||
echo "🔐 Generating $SECRET_FILE ..."
|
||||
mkdir -p "$(dirname "$SECRET_FILE")" # Ensure the env directory exists
|
||||
> "$SECRET_FILE" # Clear file if it exists
|
||||
|
||||
# 🔑 Define and write secrets
|
||||
echo "ADMIN_PASSWORD_HASH=$(openssl passwd -6 admin)" >> "$SECRET_FILE"
|
||||
echo "JWT_SECRET=$(generate_secret)" >> "$SECRET_FILE"
|
||||
echo "MARIADB_PASSWORD=$(generate_secret)" >> "$SECRET_FILE"
|
||||
echo "MARIADB_ROOT_PASSWORD=$(generate_secret)" >> "$SECRET_FILE"
|
||||
echo "REDIS_HOST_PASSWORD=$(generate_secret)" >> "$SECRET_FILE"
|
||||
echo "TRAEFIK_BASIC_AUTH_USERS=admin:$(openssl passwd -6 traefikpass)" >> "$SECRET_FILE"
|
||||
echo "GITEA_MYSQL_PASSWORD=$(generate_secret)" >> "$SECRET_FILE"
|
||||
echo "NEXTCLOUD_ADMIN_PASSWORD=$(generate_secret)" >> "$SECRET_FILE"
|
||||
echo "MAIL_PASSWORD=$(generate_secret)" >> "$SECRET_FILE"
|
||||
|
||||
# 🛑 Ensure secrets.env is ignored by Git **without overwriting last line**
|
||||
if [ -f "$SECRET_FILE" ]; then
|
||||
# Check if the last line is missing a newline and fix it
|
||||
if [ -s "$GITIGNORE_FILE" ] && [ "$(tail -c1 "$GITIGNORE_FILE")" != "" ]; then
|
||||
echo "" >> "$GITIGNORE_FILE"
|
||||
fi
|
||||
|
||||
# Append 'env/secrets.env' only if it's not already in .gitignore
|
||||
if ! grep -q "^env/secrets.env$" "$GITIGNORE_FILE"; then
|
||||
echo "env/secrets.env" >> "$GITIGNORE_FILE"
|
||||
echo "✅ Added 'env/secrets.env' to .gitignore"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ Secrets have been generated and stored in $SECRET_FILE."
|
||||
echo "⚠️ Keep this file secure and do NOT commit it to Git!"
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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"
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Pfad zur .env.all Datei
|
||||
ENV_FILE="../../env/.env.all"
|
||||
|
||||
# Funktion zum Überprüfen der Existenz einer Datei
|
||||
check_file_exists() {
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "Fehler: Die Datei $1 existiert nicht."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Überprüfe die Existenz von .env.all
|
||||
check_file_exists "../../env/.env.all"
|
||||
|
||||
# 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")
|
||||
|
||||
# Load environment variables from the .env files
|
||||
set -o allexport
|
||||
source ../../env/.env.all
|
||||
source ../../env/${ENVIRONMENT:-development}/.env.administration
|
||||
set +o allexport
|
||||
|
||||
# Liste Stacks
|
||||
STACKS=("administration")
|
||||
|
||||
# Liste aller Environments
|
||||
ENVIRONMENTS=("development" "staging" "production")
|
||||
|
||||
|
||||
# Überprüfe die Existenz aller Stack-spezifischen .env Dateien
|
||||
missing_files=0
|
||||
for stack in "${STACKS[@]}"; do
|
||||
env_file="../../env/${ENVIRONMENT:-development}/.env.${stack}"
|
||||
if ! check_file_exists "$env_file"; then
|
||||
missing_files=$((missing_files + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $missing_files -eq 0 ]; then
|
||||
echo "Alle erforderlichen .env Dateien für das ${ENVIRONMENT:-development}-Environment sind vorhanden."
|
||||
else
|
||||
echo "Warnung: $missing_files .env Datei(en) fehlen. Einige Stacks könnten nicht korrekt funktionieren."
|
||||
fi
|
||||
|
||||
# Überprüfe die Existenz aller Stack-spezifischen .env Dateien für alle Environments
|
||||
for env in "${ENVIRONMENTS[@]}"; do
|
||||
if [ "$env" != "$ENVIRONMENT" ]; then
|
||||
for stack in "${STACKS[@]}"; do
|
||||
env_file="../../env/${env}/.env.${stack}"
|
||||
if ! check_file_exists "$env_file"; then
|
||||
echo "Warnung: Die Datei $env_file fehlt für das Environment $env."
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
# Ausgabe der Variablen
|
||||
echo " "
|
||||
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 --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile administration up --remove-orphans
|
|
@ -0,0 +1,109 @@
|
|||
#!/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"
|
||||
# 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)
|
||||
|
||||
# Liste aller Stacks
|
||||
STACKS=("administration" "frontend" "develop" "database" "proxy" "tools" "website" "backend")
|
||||
|
||||
# Liste aller Environments
|
||||
ENVIRONMENTS=("development" "staging" "production")
|
||||
|
||||
# Funktion zum Überprüfen der Existenz einer Datei
|
||||
check_file_exists() {
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "Fehler: Die Datei $1 existiert nicht."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Prüfe, ob das Skript nur in der Entwicklungsumgebung ausgeführt wird
|
||||
if [ "$ENVIRONMENT" == "development" ]; then
|
||||
# Sicherstellen, dass acme_letsencrypt.json existiert und korrekte Berechtigungen hat
|
||||
ACME_FILE="../apps/proxy/traefik/acme_letsencrypt.json"
|
||||
|
||||
if [ ! -f "$ACME_FILE" ]; then
|
||||
echo "🔹 Erstelle $ACME_FILE..."
|
||||
touch "$ACME_FILE"
|
||||
fi
|
||||
|
||||
echo "🔹 Setze Berechtigungen für $ACME_FILE auf 600..."
|
||||
chmod 600 "$ACME_FILE"
|
||||
|
||||
echo "🔹 ENVIRONMENT ist 'development' – Hosts aus .env.proxy werden hinzugefügt und Container gestartet."
|
||||
|
||||
# Pfad zur Proxy-Env-Datei
|
||||
ENV_PROXY_FILE="../../env/development/.env.proxy"
|
||||
|
||||
# Hosts-Datei Pfad (Linux/macOS)
|
||||
HOSTS_FILE="/etc/hosts"
|
||||
|
||||
# Prüfe, ob die Env-Datei existiert
|
||||
if [ ! -f "$ENV_PROXY_FILE" ]; then
|
||||
echo "❌ Fehler: Die Datei $ENV_PROXY_FILE existiert nicht!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Lese alle Zeilen, die auf *_DOMAIN= enden und extrahiere die Werte
|
||||
DOMAINS=($(grep -E '^[A-Z_]+_DOMAIN=' "$ENV_PROXY_FILE" | cut -d '=' -f2))
|
||||
|
||||
# Füge jede Domain zur /etc/hosts Datei hinzu, falls sie fehlt
|
||||
for DOMAIN in "${DOMAINS[@]}"; do
|
||||
if ! grep -q "$DOMAIN" "$HOSTS_FILE"; then
|
||||
echo "127.0.0.1 $DOMAIN" | sudo tee -a "$HOSTS_FILE" > /dev/null
|
||||
echo "✅ $DOMAIN zu /etc/hosts hinzugefügt"
|
||||
else
|
||||
echo "✅ $DOMAIN ist bereits in /etc/hosts vorhanden"
|
||||
fi
|
||||
done
|
||||
|
||||
else
|
||||
echo "❌ ENVIRONMENT ist nicht 'development' – Routing über externen DNS erwartet"
|
||||
fi
|
||||
|
||||
# Überprüfe die Existenz von .env.all
|
||||
check_file_exists "../../env/.env.all"
|
||||
|
||||
# Überprüfe die Existenz aller Stack-spezifischen .env Dateien
|
||||
missing_files=0
|
||||
for stack in "${STACKS[@]}"; do
|
||||
env_file="../../env/${ENVIRONMENT:-development}/.env.${stack}"
|
||||
if ! check_file_exists "$env_file"; then
|
||||
missing_files=$((missing_files + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $missing_files -eq 0 ]; then
|
||||
echo "Alle erforderlichen .env Dateien sind vorhanden."
|
||||
else
|
||||
echo "WARNUNG: $missing_files .env Datei(en) fehlen. Einige Stacks könnten nicht korrekt funktionieren."
|
||||
fi
|
||||
|
||||
# Ausgabe der Variablen
|
||||
echo "Deploying to:"
|
||||
echo "INFRASTRUCTURE: ${INFRASTRUCTURE:-Not set}"
|
||||
echo "ENVIRONMENT: ${ENVIRONMENT:-Not set}"
|
||||
echo "-----------------------------------"
|
||||
|
||||
# Check for the --build argument
|
||||
BUILD_OPTION=""
|
||||
if [[ "$1" == "--build" ]]; then
|
||||
BUILD_OPTION="--build"
|
||||
fi
|
||||
|
||||
# Ausführen des Docker Compose Befehls
|
||||
docker compose -f ../../apps/docker-compose.all.yml -p ${INFRASTRUCTURE:-my} --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile backend up --remove-orphans $BUILD_OPTION
|
|
@ -0,0 +1,65 @@
|
|||
#!/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"
|
||||
# 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)
|
||||
|
||||
# Liste aller Stacks
|
||||
STACKS=("proxy" "frontend" "database" "backend")
|
||||
|
||||
# Liste aller Environments
|
||||
ENVIRONMENTS=("development" "staging" "production")
|
||||
|
||||
# Funktion zum Überprüfen der Existenz einer Datei
|
||||
check_file_exists() {
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "Fehler: Die Datei $1 existiert nicht."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
# Überprüfe die Existenz von .env.all
|
||||
check_file_exists "../../env/.env.all"
|
||||
|
||||
# Überprüfe die Existenz aller Stack-spezifischen .env Dateien
|
||||
missing_files=0
|
||||
for stack in "${STACKS[@]}"; do
|
||||
env_file="../../env/${ENVIRONMENT:-development}/.env.${stack}"
|
||||
if ! check_file_exists "$env_file"; then
|
||||
missing_files=$((missing_files + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $missing_files -eq 0 ]; then
|
||||
echo "Alle erforderlichen .env Dateien sind vorhanden."
|
||||
else
|
||||
echo "WARNUNG: $missing_files .env Datei(en) fehlen. Einige Stacks könnten nicht korrekt funktionieren."
|
||||
fi
|
||||
|
||||
# Ausgabe der Variablen
|
||||
echo "Deploying to"
|
||||
echo "INFRASTRUCTURE: ${INFRASTRUCTURE:-Not set}"
|
||||
echo "ENVIRONMENT: ${ENVIRONMENT:-Not set}"
|
||||
echo "-----------------------------------"
|
||||
|
||||
# Check for the --build argument
|
||||
BUILD_OPTION=""
|
||||
if [[ "$1" == "--build" ]]; then
|
||||
BUILD_OPTION="--build"
|
||||
fi
|
||||
|
||||
|
||||
# Ausführen des Docker Compose Befehls
|
||||
docker compose -f ../../apps/docker-compose.all.yml -p ${INFRASTRUCTURE:-my} --profile app up --remove-orphans $BUILD_OPTION
|
||||
|
|
@ -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
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Prüfe, ob Traefik läuft..."
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q 'traefik'; then
|
||||
echo "Traefik läuft nicht."
|
||||
read -p "Möchtest du die lokale Version zum Debuggen (docker-compose.overwrite.yml) starten? (y/n): " answer
|
||||
if [[ "$answer" =~ ^[Yy]$ ]]; then
|
||||
echo "Starte lokale Version..."
|
||||
docker compose -f ../apps/docker-compose.overwrite.yml up -d
|
||||
else
|
||||
echo "Deployment abgebrochen."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Traefik läuft."
|
||||
echo "Starte Deployment mit docker-compose.prod.yml..."
|
||||
docker compose -f ../apps/docker-compose.prod.yml up -d
|
||||
fi
|
||||
|
||||
echo "Deployment abgeschlossen."
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Pfad zur .env.all Datei
|
||||
ENV_FILE="../../env/.env.all"
|
||||
|
||||
# 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")
|
||||
|
||||
# Liste aller Stacks
|
||||
STACKS=("proxy")
|
||||
|
||||
# Liste aller Environments
|
||||
ENVIRONMENTS=("development" "staging" "production")
|
||||
|
||||
# Funktion zum Überprüfen der Existenz einer Datei
|
||||
check_file_exists() {
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "Fehler: Die Datei $1 existiert nicht."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Überprüfe die Existenz von .env.all
|
||||
check_file_exists "../../env/.env.all"
|
||||
|
||||
# Überprüfe die Existenz aller Stack-spezifischen .env Dateien
|
||||
missing_files=0
|
||||
for stack in "${STACKS[@]}"; do
|
||||
env_file="../../env/${ENVIRONMENT:-development}/.env.${stack}"
|
||||
if ! check_file_exists "$env_file"; then
|
||||
missing_files=$((missing_files + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $missing_files -eq 0 ]; then
|
||||
echo "Alle erforderlichen .env Dateien sind vorhanden."
|
||||
else
|
||||
echo "WARNUNG: $missing_files .env Datei(en) fehlen. Einige Stacks könnten nicht korrekt funktionieren."
|
||||
fi
|
||||
|
||||
# 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 --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans
|
|
@ -0,0 +1,157 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Funktion zur Überprüfung der Produktivumgebung
|
||||
is_production() {
|
||||
local prod_ip=${SERVER_IP:-127.0.0.1} # IP-Adresse deines Produktivservers
|
||||
local current_ip
|
||||
|
||||
# Überprüfe das Betriebssystem
|
||||
case "$OSTYPE" in
|
||||
msys*|cygwin*|mingw*)
|
||||
# Windows
|
||||
current_ip=$(ipconfig | grep -i "IPv4 Address" | head -n 1 | awk '{print $NF}')
|
||||
;;
|
||||
darwin*)
|
||||
# macOS
|
||||
current_ip=$(ipconfig getifaddr en0) # Für Wi-Fi
|
||||
if [ -z "$current_ip" ]; then
|
||||
current_ip=$(ipconfig getifaddr en1) # Für Ethernet
|
||||
fi
|
||||
;;
|
||||
linux*|bsd*|solaris*)
|
||||
# Linux und andere Unix-ähnliche Systeme
|
||||
current_ip=$(hostname -I | awk '{print $1}')
|
||||
;;
|
||||
*)
|
||||
echo "Unbekanntes Betriebssystem: $OSTYPE"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Erkannte IP-Adresse: $current_ip"
|
||||
|
||||
if [ "$current_ip" == "$prod_ip" ]; then
|
||||
echo "Produktivumgebung erkannt."
|
||||
return 0 # True, wir sind in der Produktivumgebung
|
||||
else
|
||||
echo "Lokale Entwicklungsumgebung erkannt."
|
||||
return 1 # False, wir sind in der lokalen Umgebung
|
||||
fi
|
||||
}
|
||||
|
||||
# Funktion zum Setzen der Umgebungsvariablen
|
||||
set_environment_variables() {
|
||||
if is_production; then
|
||||
export DOMAIN_SUFFIX=".mindboost.team"
|
||||
export TRAEFIK_DASHBOARD_DOMAIN="traefik${DOMAIN_SUFFIX}"
|
||||
export PORTAINER_DOMAIN="portainer${DOMAIN_SUFFIX}"
|
||||
export FRONTEND_DOMAIN="app${DOMAIN_SUFFIX}"
|
||||
export BACKEND_DOMAIN="b${DOMAIN_SUFFIX}"
|
||||
else
|
||||
export DOMAIN_SUFFIX=".local"
|
||||
export TRAEFIK_DASHBOARD_DOMAIN="traefik${DOMAIN_SUFFIX}"
|
||||
export PORTAINER_DOMAIN="portainer${DOMAIN_SUFFIX}"
|
||||
export FRONTEND_DOMAIN="frontend${DOMAIN_SUFFIX}"
|
||||
export BACKEND_DOMAIN="backend${DOMAIN_SUFFIX}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
echo "Prüfe, ob Traefik läuft..."
|
||||
|
||||
set_environment_variables
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q 'traefik'; then
|
||||
echo "Traefik läuft nicht. Starte Traefik mit CrowdSec Bouncer..."
|
||||
|
||||
if is_production; 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.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/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/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/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
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q 'traefik'; then
|
||||
echo "Traefik läuft nicht. Starte Traefik und Portainer..."
|
||||
else
|
||||
echo "Traefik läuft bereits. Aktualisiere die Konfiguration..."
|
||||
fi
|
||||
|
||||
|
||||
if is_production; then
|
||||
echo "Wir befinden uns in der Produktivumgebung."
|
||||
echo "Starte/Aktualisiere Deployment mit docker-compose.yml..."
|
||||
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
|
||||
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/proxy/docker-compose.overwrite.yml --env-file ../../env/.env.all --env-file ../../env/${ENVIRONMENT:-development}/.env.proxy --profile proxy up --remove-orphans -d
|
||||
fi
|
||||
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q 'traefik'; then
|
||||
echo "Traefik läuft nicht."
|
||||
|
||||
if is_production; then
|
||||
echo "Wir befinden uns in der Produktivumgebung."
|
||||
set_environment_variables
|
||||
echo "Starte Deployment mit docker-compose.yml..."
|
||||
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
|
||||
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
|
||||
if [[ "$answer" =~ ^[Yy]$ ]]; then
|
||||
echo "Starte lokale Version..."
|
||||
set_environment_variables
|
||||
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
|
||||
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
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Traefik läuft bereits."
|
||||
|
||||
if is_production; then
|
||||
echo "Wir befinden uns in der Produktivumgebung."
|
||||
set_environment_variables
|
||||
echo "Aktualisiere Deployment mit docker-compose.yml..."
|
||||
env | grep DOMAIN # Debug: Zeige die gesetzten Umgebungsvariablen an
|
||||
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/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 "Deployment abgeschlossen."
|
|
@ -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
|
Loading…
Reference in New Issue