grundstruktur der dockerverzeichnisse mit richtegen funktionsfähigen docker files
This commit is contained in:
parent
034aedef72
commit
464b87a74b
50
docker/bookstack/docker-compose.yml
Normal file
50
docker/bookstack/docker-compose.yml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
bookstack:
|
||||||
|
image: lscr.io/linuxserver/bookstack:latest
|
||||||
|
container_name: bookstack
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- APP_URL=https://bookstack.hessenkamp-server.de
|
||||||
|
- DB_HOST=bookstack_db
|
||||||
|
- DB_PORT=3306
|
||||||
|
- DB_USER=bookstack
|
||||||
|
- DB_PASS=ObV2rbC9MgBKGCZjTLI2 # Ändern Sie dies!
|
||||||
|
- DB_DATABASE=bookstackapp
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/bookstack/config:/config
|
||||||
|
ports:
|
||||||
|
- 6875:80
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- bookstack_db
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.bookstack.rule=Host(`bookstack.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.bookstack.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.bookstack.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.bookstack.loadbalancer.server.port=80"
|
||||||
|
|
||||||
|
bookstack_db:
|
||||||
|
image: lscr.io/linuxserver/mariadb:latest
|
||||||
|
container_name: bookstack_db
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- MYSQL_ROOT_PASSWORD=ObV2rbC9MgBKGCZjTLI2 # Ändern Sie dies!
|
||||||
|
- TZ=Europe/Berlin
|
||||||
|
- MYSQL_DATABASE=bookstackapp
|
||||||
|
- MYSQL_USER=bookstack
|
||||||
|
- MYSQL_PASSWORD=ObV2rbC9MgBKGCZjTLI2 # Muss mit DB_PASS übereinstimmen
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/bookstack/db:/config
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
21
docker/duplicati/docker-compose.yml
Normal file
21
docker/duplicati/docker-compose.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
|
services:
|
||||||
|
duplicati:
|
||||||
|
container_name: duplicati
|
||||||
|
image: lscr.io/linuxserver/duplicati:latest
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.duplicati.rule=Host(`duplicati.hessenkamp-server.de`)
|
||||||
|
- traefik.http.routers.duplicati.entrypoints=websecure
|
||||||
|
- traefik.http.routers.duplicati.tls.certresolver=letsencrypt
|
||||||
|
- traefik.http.services.duplicati.loadbalancer.server.port=8200
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- /home/andiamolino/backups:/backups
|
||||||
|
- ../containerdaten/duplicati/config:/config
|
||||||
|
- /:/source:ro
|
||||||
|
version: '3'
|
||||||
26
docker/elasticsearch/docker-compose.yml
Normal file
26
docker/elasticsearch/docker-compose.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
elasticsearch:
|
||||||
|
container_name: elasticsearch
|
||||||
|
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.10
|
||||||
|
environment:
|
||||||
|
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||||
|
- "discovery.type=single-node"
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.elasticsearch.rule=Host(`elasticsearch.hessenkamp-server.de`)
|
||||||
|
- traefik.http.routers.elasticsearch.entrypoints=websecure
|
||||||
|
- traefik.http.routers.elasticsearch.tls.certresolver=letsencrypt
|
||||||
|
- traefik.http.services.elasticsearch.loadbalancer.server.port=9200
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/elasticsearch/data:/usr/share/elasticsearch/data
|
||||||
|
ports:
|
||||||
|
- "9200:9200"
|
||||||
27
docker/gitea/docker-compose.yml
Normal file
27
docker/gitea/docker-compose.yml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
environment:
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- GITEA__database__DB_TYPE=sqlite3
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/gitea/data:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.gitea.rule=Host(`gitea.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.gitea.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.gitea.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
21
docker/grafana/docker-compose.yml
Normal file
21
docker/grafana/docker-compose.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:latest
|
||||||
|
container_name: grafana
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/grafana/data:/var/lib/grafana
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.grafana.rule=Host(`grafana.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.grafana.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.grafana.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
53
docker/invoiceNinja/docker-compose.yml
Normal file
53
docker/invoiceNinja/docker-compose.yml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
container_name: invoiceninja-server
|
||||||
|
image: nginx
|
||||||
|
restart: always
|
||||||
|
env_file: env
|
||||||
|
volumes:
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
|
||||||
|
- ./docker/app/public:/var/www/app/public:ro
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.invoiceninja.rule=Host(`invoice.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.invoiceninja.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.invoiceninja.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.invoiceninja.loadbalancer.server.port=80"
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
|
||||||
|
app:
|
||||||
|
container_name: invoiceninja-app
|
||||||
|
image: invoiceninja/invoiceninja:5
|
||||||
|
env_file: env
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- ./config/hosts:/etc/hosts:ro
|
||||||
|
- ./docker/app/public:/var/www/app/public:rw,delegated
|
||||||
|
- ./docker/app/storage:/var/www/app/storage:rw,delegated
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
|
||||||
|
db:
|
||||||
|
container_name: invoiceninja-db
|
||||||
|
image: mariadb:10.4
|
||||||
|
restart: always
|
||||||
|
env_file: env
|
||||||
|
volumes:
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- ./docker/mysql/data:/var/lib/mysql:rw,delegated
|
||||||
|
- ./docker/mysql/bak:/backups:rw
|
||||||
|
- ./config/mysql/backup-script:/etc/cron.weekly/weekly:ro
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
20
docker/logstash/docker-compose.yml
Normal file
20
docker/logstash/docker-compose.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
|
services:
|
||||||
|
logstash:
|
||||||
|
container_name: logstash
|
||||||
|
image: docker.elastic.co/logstash/logstash:7.17.10
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.logstash.rule=Host(`logstash.hessenkamp-server.de`)
|
||||||
|
- traefik.http.routers.logstash.entrypoints=websecure
|
||||||
|
- traefik.http.routers.logstash.tls.certresolver=letsencrypt
|
||||||
|
- traefik.http.services.logstash.loadbalancer.server.port=5044
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/logstash/config:/usr/share/logstash/config
|
||||||
|
- ../containerdaten/logstash/pipeline:/usr/share/logstash/pipeline
|
||||||
|
version: '3'
|
||||||
28
docker/portainer/docker-compose.yml
Normal file
28
docker/portainer/docker-compose.yml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
portainer:
|
||||||
|
image: portainer/portainer-ce:latest
|
||||||
|
container_name: portainer
|
||||||
|
restart: always
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- portainer_data:/data
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.portainer.rule=Host(`portainer.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.portainer.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.portainer.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
portainer_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
|
|
||||||
19
docker/prometheus/docker-compose.yml
Normal file
19
docker/prometheus/docker-compose.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
|
services:
|
||||||
|
prometheus:
|
||||||
|
container_name: prometheus
|
||||||
|
image: prom/prometheus:latest
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.prometheus.rule=Host(`prometheus.hessenkamp-server.de`)
|
||||||
|
- traefik.http.routers.prometheus.entrypoints=websecure
|
||||||
|
- traefik.http.routers.prometheus.tls.certresolver=letsencrypt
|
||||||
|
- traefik.http.services.prometheus.loadbalancer.server.port=9090
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/prometheus/data:/data
|
||||||
|
version: '3'
|
||||||
37
docker/traefik/docker-compose.yml
Normal file
37
docker/traefik/docker-compose.yml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
reverse-proxy:
|
||||||
|
image: traefik:v3.1
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./traefik.yml:/etc/traefik/traefik.yml
|
||||||
|
- ./acme.json:/acme.json
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.dashboard.rule=Host(`traefik.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.dashboard.service=api@internal"
|
||||||
|
- "traefik.http.routers.dashboard.middlewares=auth"
|
||||||
|
- "traefik.http.middlewares.auth.basicauth.users=admino:$$apr1$$RaHHY28p$$EMckBAfuRv1BF2Qvy40d20"
|
||||||
|
- "traefik.http.routers.dashboard.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.dashboard.tls=true"
|
||||||
|
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
|
||||||
|
- "traefik.http.routers.http-catchall.entrypoints=web"
|
||||||
|
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
|
||||||
|
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
name: traefik_network
|
||||||
|
|
||||||
20
docker/traefik/traefik.yml
Normal file
20
docker/traefik/traefik.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
api:
|
||||||
|
dashboard: true
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: ":80"
|
||||||
|
websecure:
|
||||||
|
address: ":443"
|
||||||
|
|
||||||
|
providers:
|
||||||
|
docker:
|
||||||
|
exposedByDefault: false
|
||||||
|
|
||||||
|
certificatesResolvers:
|
||||||
|
letsencrypt:
|
||||||
|
acme:
|
||||||
|
email: alexander@hessenkamp.de
|
||||||
|
storage: acme.json
|
||||||
|
httpChallenge:
|
||||||
|
entryPoint: web
|
||||||
37
docker/wg-easy/docker-compose.yml
Normal file
37
docker/wg-easy/docker-compose.yml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
wg-easy:
|
||||||
|
image: weejewel/wg-easy
|
||||||
|
container_name: wg-easy
|
||||||
|
environment:
|
||||||
|
- WG_HOST=wgeasy.hessenkamp-server.de
|
||||||
|
- PASSWORD=!(hB1nDerAdn1n
|
||||||
|
- WG_PORT=51820
|
||||||
|
- WG_DEFAULT_ADDRESS=10.8.0.x
|
||||||
|
- WG_DEFAULT_DNS=1.1.1.1
|
||||||
|
volumes:
|
||||||
|
- ../containerdaten/wg-easy:/etc/wireguard
|
||||||
|
ports:
|
||||||
|
- "51820:51820/udp"
|
||||||
|
- "51821:51821/tcp"
|
||||||
|
restart: unless-stopped
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_MODULE
|
||||||
|
sysctls:
|
||||||
|
- net.ipv4.conf.all.src_valid_mark=1
|
||||||
|
- net.ipv4.ip_forward=1
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.wg-easy.rule=Host(`wgeasy.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.wg-easy.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.wg-easy.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.wg-easy.loadbalancer.server.port=51821"
|
||||||
|
- "traefik.http.routers.wg-easy.middlewares=wg-easy-auth"
|
||||||
|
- "traefik.http.middlewares.wg-easy-auth.basicauth.users=admino:$$apr1$$ffntQ3Qe$$WPCeUgCF7jgWYuJ6FyrC9."
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik_network:
|
||||||
|
external: true
|
||||||
54
docker/wireguard-ui/docker-compose.yml
Normal file
54
docker/wireguard-ui/docker-compose.yml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
wireguard:
|
||||||
|
image: linuxserver/wireguard
|
||||||
|
container_name: wireguard
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_MODULE
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- SERVERURL=wgcool.hessenkamp-server.de
|
||||||
|
- SERVERPORT=51820
|
||||||
|
- PEERS=1
|
||||||
|
- PEERDNS=auto
|
||||||
|
- INTERNAL_SUBNET=10.13.13.0
|
||||||
|
volumes:
|
||||||
|
- ./config:/config
|
||||||
|
- /lib/modules:/lib/modules
|
||||||
|
ports:
|
||||||
|
- 51820:51820/udp
|
||||||
|
sysctls:
|
||||||
|
- net.ipv4.conf.all.src_valid_mark=1
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
wireguard-ui:
|
||||||
|
image: ngoduykhanh/wireguard-ui:latest
|
||||||
|
container_name: wireguard-ui
|
||||||
|
depends_on:
|
||||||
|
- wireguard
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
environment:
|
||||||
|
- WGUI_USERNAME=admino
|
||||||
|
- WGUI_PASSWORD=!(hB1nDerAdn1n
|
||||||
|
- WGUI_MANAGE_START=true
|
||||||
|
- WGUI_MANAGE_RESTART=true
|
||||||
|
volumes:
|
||||||
|
- ./config:/etc/wireguard
|
||||||
|
- ./db:/app/db
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.wireguard-ui.rule=Host(`wgcool.hessenkamp-server.de`)"
|
||||||
|
- "traefik.http.routers.wireguard-ui.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.wireguard-ui.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.wireguard-ui.loadbalancer.server.port=5000"
|
||||||
|
- "traefik.http.routers.wireguard-ui.middlewares=wireguard-auth"
|
||||||
|
- "traefik.http.middlewares.wireguard-auth.basicauth.users=admino:$$apr1$$ffntQ3Qe$$WPCeUgCF7jgWYuJ6FyrC9."
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
external: true
|
||||||
|
name: traefik_network
|
||||||
40
scripts/docker_compose_creator/compose_utils.py
Normal file
40
scripts/docker_compose_creator/compose_utils.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
def load_existing_compose(file_path):
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
return yaml.safe_load(f)
|
||||||
|
except FileNotFoundError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def create_compose_config(service_name):
|
||||||
|
# Beispieldaten basierend auf dem Service
|
||||||
|
image_name = input("Enter image name: ")
|
||||||
|
image_tag = input("Enter image tag [latest]: ") or "latest"
|
||||||
|
subdomain = input("Enter subdomain for Traefik: ")
|
||||||
|
container_port = input("Enter container port [80]: ") or "80"
|
||||||
|
|
||||||
|
return {
|
||||||
|
'version': '3',
|
||||||
|
'services': {
|
||||||
|
service_name: {
|
||||||
|
'image': f"{image_name}:{image_tag}",
|
||||||
|
'container_name': service_name,
|
||||||
|
'restart': 'always',
|
||||||
|
'networks': ['traefik_network'],
|
||||||
|
'labels': [
|
||||||
|
"traefik.enable=true",
|
||||||
|
f"traefik.http.routers.{service_name}.rule=Host(`{subdomain}.hessenkamp-server.de`)",
|
||||||
|
f"traefik.http.routers.{service_name}.entrypoints=websecure",
|
||||||
|
f"traefik.http.routers.{service_name}.tls.certresolver=letsencrypt",
|
||||||
|
f"traefik.http.services.{service_name}.loadbalancer.server.port={container_port}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'networks': {
|
||||||
|
'traefik_network': {
|
||||||
|
'external': True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
scripts/docker_compose_creator/create_docker_compose.py
Normal file
52
scripts/docker_compose_creator/create_docker_compose.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
from volume_utils import setup_volume_paths, check_existing_volumes
|
||||||
|
from compose_utils import create_compose_config, load_existing_compose
|
||||||
|
from permission_utils import check_permissions
|
||||||
|
from input_utils import get_input
|
||||||
|
from escape_handler import start_exit_handler
|
||||||
|
|
||||||
|
DOCKER_DIR = os.path.expanduser("~/docker")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
start_exit_handler()
|
||||||
|
service_name = get_input("Enter service name (e.g., gitea, bookstack)")
|
||||||
|
service_dir = os.path.join(DOCKER_DIR, service_name)
|
||||||
|
|
||||||
|
if os.path.exists(service_dir):
|
||||||
|
compose_file = os.path.join(service_dir, 'docker-compose.yml')
|
||||||
|
if os.path.exists(compose_file):
|
||||||
|
existing_compose = load_existing_compose(compose_file)
|
||||||
|
if existing_compose:
|
||||||
|
print("Existing configuration:")
|
||||||
|
print(yaml.dump(existing_compose, default_flow_style=False))
|
||||||
|
print("\nChecking existing volumes:")
|
||||||
|
check_existing_volumes(existing_compose)
|
||||||
|
if get_input("Do you want to overwrite this file? (y/n)", "n").lower() != 'y':
|
||||||
|
print("Operation cancelled.")
|
||||||
|
return
|
||||||
|
|
||||||
|
compose = create_compose_config(service_name)
|
||||||
|
|
||||||
|
volumes = []
|
||||||
|
while True:
|
||||||
|
volume = get_input("Enter volume mapping (host:container) or press Enter to finish")
|
||||||
|
if not volume:
|
||||||
|
break
|
||||||
|
volumes.append(volume)
|
||||||
|
|
||||||
|
if volumes:
|
||||||
|
compose['services'][service_name]['volumes'] = volumes
|
||||||
|
setup_volume_paths(service_name, volumes)
|
||||||
|
|
||||||
|
os.makedirs(service_dir, exist_ok=True)
|
||||||
|
compose_file = os.path.join(service_dir, 'docker-compose.yml')
|
||||||
|
with open(compose_file, 'w') as f:
|
||||||
|
yaml.dump(compose, f, default_flow_style=False)
|
||||||
|
|
||||||
|
print(f"docker-compose.yml has been created successfully in {service_dir}!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
10
scripts/docker_compose_creator/escape_handler.py
Normal file
10
scripts/docker_compose_creator/escape_handler.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def signal_handler(sig, frame):
|
||||||
|
print("\nStrg+C wurde gedrückt. Beende das Programm...")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def start_exit_handler():
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
print("Drücken Sie Strg+C, um das Programm zu beenden.")
|
||||||
3
scripts/docker_compose_creator/escape_handler.py.save
Normal file
3
scripts/docker_compose_creator/escape_handler.py.save
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
3
scripts/docker_compose_creator/input_utils.py
Normal file
3
scripts/docker_compose_creator/input_utils.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
def get_input(prompt, default=None):
|
||||||
|
value = input(f"{prompt} {f'[{default}]' if default else ''}: ").strip()
|
||||||
|
return value if value else default
|
||||||
84
scripts/docker_compose_creator/permission_utils.py
Normal file
84
scripts/docker_compose_creator/permission_utils.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import os
|
||||||
|
import stat
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# Standardwerte für Berechtigungen
|
||||||
|
DEFAULT_DIR_PERMS = 0o755
|
||||||
|
DEFAULT_FILE_PERMS = 0o644
|
||||||
|
DEFAULT_OWNER = "65534:65534" # nobody:nogroup
|
||||||
|
|
||||||
|
def check_permissions(path):
|
||||||
|
try:
|
||||||
|
stat_info = os.stat(path)
|
||||||
|
uid = stat_info.st_uid
|
||||||
|
gid = stat_info.st_gid
|
||||||
|
mode = stat_info.st_mode
|
||||||
|
if uid == 65534 and gid == 65534 and (mode & 0o777) == 0o755:
|
||||||
|
print(f"Permissions are correct for: {path}")
|
||||||
|
else:
|
||||||
|
print(f"Warning: Permissions may not be correct for: {path}")
|
||||||
|
print(f"Current: UID={uid}, GID={gid}, Mode={mode:o}")
|
||||||
|
print(f"Expected: UID=65534, GID=65534, Mode=755")
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Error checking permissions: {e}")
|
||||||
|
|
||||||
|
def set_permissions(path, is_directory=True):
|
||||||
|
if is_directory:
|
||||||
|
perms = input(f"Enter directory permissions [{DEFAULT_DIR_PERMS:o}]: ") or DEFAULT_DIR_PERMS
|
||||||
|
else:
|
||||||
|
perms = input(f"Enter file permissions [{DEFAULT_FILE_PERMS:o}]: ") or DEFAULT_FILE_PERMS
|
||||||
|
|
||||||
|
owner = input(f"Enter owner [{DEFAULT_OWNER}]: ") or DEFAULT_OWNER
|
||||||
|
|
||||||
|
if isinstance(perms, str):
|
||||||
|
perms = int(perms, 8)
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(['sudo', 'chmod', f'{perms:o}', path], check=True)
|
||||||
|
subprocess.run(['sudo', 'chown', owner, path], check=True)
|
||||||
|
print(f"Set permissions for {path}: {perms:o}, owner: {owner}")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error setting permissions: {e}")
|
||||||
|
|
||||||
|
def set_permissions_recursive(path):
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
set_permissions(root, is_directory=True)
|
||||||
|
for file in files:
|
||||||
|
set_permissions(os.path.join(root, file), is_directory=False)
|
||||||
|
|
||||||
|
def ensure_correct_permissions(path, is_directory=True):
|
||||||
|
stat_info = os.stat(path)
|
||||||
|
uid = stat_info.st_uid
|
||||||
|
gid = stat_info.st_gid
|
||||||
|
mode = stat_info.st_mode
|
||||||
|
|
||||||
|
expected_mode = DEFAULT_DIR_PERMS if is_directory else DEFAULT_FILE_PERMS
|
||||||
|
|
||||||
|
if uid != 65534 or gid != 65534 or (mode & 0o777) != expected_mode:
|
||||||
|
print(f"Correcting permissions for: {path}")
|
||||||
|
set_permissions(path, is_directory)
|
||||||
|
else:
|
||||||
|
print(f"Permissions are already correct for: {path}")
|
||||||
|
|
||||||
|
def ensure_correct_permissions_recursive(path):
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
ensure_correct_permissions(root, is_directory=True)
|
||||||
|
for file in files:
|
||||||
|
ensure_correct_permissions(os.path.join(root, file), is_directory=False)
|
||||||
|
|
||||||
|
def create_files_in_directory(directory):
|
||||||
|
while True:
|
||||||
|
create_file = input(f"Do you want to create a file in {directory}? (y/n): ").lower()
|
||||||
|
if create_file != 'y':
|
||||||
|
break
|
||||||
|
|
||||||
|
filename = input("Enter the file name: ")
|
||||||
|
full_path = os.path.join(directory, filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(full_path, 'w') as f:
|
||||||
|
pass # Create an empty file
|
||||||
|
print(f"Created file: {full_path}")
|
||||||
|
set_permissions(full_path, is_directory=False)
|
||||||
|
except IOError as e:
|
||||||
|
print(f"Error creating file: {e}")
|
||||||
64
scripts/docker_compose_creator/volume_utils.py
Normal file
64
scripts/docker_compose_creator/volume_utils.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import os
|
||||||
|
from permission_utils import set_permissions, check_permissions, set_permissions_recursive
|
||||||
|
|
||||||
|
def setup_volume_paths(service_name, volumes):
|
||||||
|
created_paths = []
|
||||||
|
for volume in volumes:
|
||||||
|
if ':' in volume:
|
||||||
|
host_path, _ = volume.split(':', 1)
|
||||||
|
if host_path.startswith('../containerdaten'):
|
||||||
|
_, path = host_path.split('../containerdaten/', 1)
|
||||||
|
full_path = os.path.expanduser(f"~/docker/containerdaten/{path}")
|
||||||
|
created_paths.extend(setup_volume_path(service_name, full_path))
|
||||||
|
|
||||||
|
# Setze Berechtigungen für alle erstellten Pfade am Ende
|
||||||
|
for path in created_paths:
|
||||||
|
set_permissions_recursive(path)
|
||||||
|
|
||||||
|
def setup_volume_path(service_name, full_path):
|
||||||
|
created_paths = []
|
||||||
|
if not os.path.exists(full_path):
|
||||||
|
os.makedirs(full_path, exist_ok=True)
|
||||||
|
print(f"Created directory: {full_path}")
|
||||||
|
else:
|
||||||
|
print(f"Directory already exists: {full_path}")
|
||||||
|
|
||||||
|
created_paths.append(full_path)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
create_file_choice = input(f"Do you want to create a file in {full_path}? (y/n): ").lower()
|
||||||
|
if create_file_choice != 'y':
|
||||||
|
break
|
||||||
|
file_name = input("Enter the file name: ")
|
||||||
|
file_path = create_file(full_path, file_name)
|
||||||
|
if file_path:
|
||||||
|
created_paths.append(file_path)
|
||||||
|
|
||||||
|
return created_paths
|
||||||
|
|
||||||
|
def create_file(path, filename):
|
||||||
|
full_path = os.path.join(path, filename)
|
||||||
|
try:
|
||||||
|
with open(full_path, 'w') as f:
|
||||||
|
pass # Create an empty file
|
||||||
|
print(f"Created file: {full_path}")
|
||||||
|
return full_path
|
||||||
|
except IOError as e:
|
||||||
|
print(f"Error creating file: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def check_existing_volumes(compose_data):
|
||||||
|
if 'services' in compose_data:
|
||||||
|
for service in compose_data['services'].values():
|
||||||
|
if 'volumes' in service:
|
||||||
|
for volume in service['volumes']:
|
||||||
|
if ':' in volume:
|
||||||
|
host_path, _ = volume.split(':', 1)
|
||||||
|
if host_path.startswith('../containerdaten'):
|
||||||
|
_, path = host_path.split('../containerdaten/', 1)
|
||||||
|
full_path = os.path.expanduser(f"~/docker/containerdaten/{path}")
|
||||||
|
if os.path.exists(full_path):
|
||||||
|
print(f"Directory exists: {full_path}")
|
||||||
|
check_permissions(full_path)
|
||||||
|
else:
|
||||||
|
print(f"Directory does not exist: {full_path}")
|
||||||
10
scripts/escape_handler.py
Normal file
10
scripts/escape_handler.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def signal_handler(sig, frame):
|
||||||
|
print("\nStrg+C wurde gedrückt. Beende das Programm...")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def start_exit_handler():
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
print("Drücken Sie Strg+C, um das Programm zu beenden.")
|
||||||
86
scripts/start_docker_services.py
Normal file
86
scripts/start_docker_services.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from escape_handler import start_exit_handler
|
||||||
|
|
||||||
|
DOCKER_DIR = "/home/andiamolino/docker"
|
||||||
|
|
||||||
|
def get_running_containers():
|
||||||
|
"""Gibt eine Liste der laufenden Container zurück."""
|
||||||
|
result = subprocess.run(["docker", "ps", "--format", "{{.Names}}"], capture_output=True, text=True)
|
||||||
|
return result.stdout.strip().split('\n') if result.stdout else []
|
||||||
|
|
||||||
|
def stop_container(container_name):
|
||||||
|
"""Stoppt einen spezifischen Container."""
|
||||||
|
subprocess.run(["docker", "stop", container_name], check=True)
|
||||||
|
|
||||||
|
def start_docker_compose(dir_path):
|
||||||
|
"""Startet Docker-Compose in einem bestimmten Verzeichnis."""
|
||||||
|
print(f"Starte Docker-Compose in {dir_path}")
|
||||||
|
subprocess.run(["docker-compose", "up", "-d"], cwd=dir_path, check=True)
|
||||||
|
|
||||||
|
def get_docker_compose_dirs():
|
||||||
|
"""Findet alle Verzeichnisse mit einer docker-compose.yml Datei."""
|
||||||
|
dirs = []
|
||||||
|
for dir_name in os.listdir(DOCKER_DIR):
|
||||||
|
dir_path = os.path.join(DOCKER_DIR, dir_name)
|
||||||
|
if os.path.isdir(dir_path) and dir_name != "containerdaten":
|
||||||
|
if os.path.exists(os.path.join(dir_path, "docker-compose.yml")):
|
||||||
|
dirs.append(dir_path)
|
||||||
|
return dirs
|
||||||
|
|
||||||
|
def main():
|
||||||
|
start_exit_handler
|
||||||
|
running_containers = get_running_containers()
|
||||||
|
|
||||||
|
if running_containers:
|
||||||
|
print("Laufende Container:")
|
||||||
|
for container in running_containers:
|
||||||
|
print(f"- {container}")
|
||||||
|
|
||||||
|
choice = input("Möchten Sie laufende Container stoppen? (j/n): ").strip().lower()
|
||||||
|
if choice == 'j':
|
||||||
|
for container in running_containers:
|
||||||
|
stop_container(container)
|
||||||
|
print("Alle laufenden Container wurden gestoppt.")
|
||||||
|
|
||||||
|
start_new = input("Möchten Sie neue Container starten? (j/n): ").strip().lower()
|
||||||
|
if start_new != 'j':
|
||||||
|
print("Keine neuen Container werden gestartet. Programm wird beendet.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
docker_dirs = get_docker_compose_dirs()
|
||||||
|
|
||||||
|
print("\nGefundene Docker-Compose-Projekte:")
|
||||||
|
for i, dir_path in enumerate(docker_dirs, 1):
|
||||||
|
print(f"{i}. {os.path.basename(dir_path)}")
|
||||||
|
|
||||||
|
print("\nWählen Sie die zu startenden Projekte (durch Kommas getrennte Nummern, oder 'alle'):")
|
||||||
|
choice = input().strip().lower()
|
||||||
|
|
||||||
|
if choice == 'alle':
|
||||||
|
to_start = docker_dirs
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
indices = [int(x.strip()) - 1 for x in choice.split(',')]
|
||||||
|
to_start = [docker_dirs[i] for i in indices if 0 <= i < len(docker_dirs)]
|
||||||
|
except ValueError:
|
||||||
|
print("Ungültige Eingabe. Beende Programm.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Stelle sicher, dass Traefik zuerst gestartet wird
|
||||||
|
traefik_dir = next((d for d in to_start if os.path.basename(d) == "traefik"), None)
|
||||||
|
if traefik_dir:
|
||||||
|
to_start.remove(traefik_dir)
|
||||||
|
to_start.insert(0, traefik_dir)
|
||||||
|
|
||||||
|
for dir_path in to_start:
|
||||||
|
try:
|
||||||
|
start_docker_compose(dir_path)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Fehler beim Starten von {os.path.basename(dir_path)}: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue
Block a user