1
0

Base commit

This commit is contained in:
Adrien Bouvais 2025-05-29 08:17:44 +00:00
commit 0b58bd6e2d
27 changed files with 790 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
hdd0
hdd0_backups
cache
.env
letsencrypt
website-pro
config/gitea/conf

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# Self-Hosted Services
This repository contains my personal Docker Compose configuration for various self-hosted services, all exposed via Traefik. It serves primarily as a personal deployment configuration and a reference for others.
---
### Services Included:
- **Traefik:** Reverse proxy and load balancer with automatic HTTPS.
- **Prometheus:** Monitoring system.
- **Grafana:** Data visualization and dashboarding for Prometheus.
- **cAdvisor:** Container resource usage and performance analysis.
- **Node Exporter:** Exposes hardware and OS metrics for Prometheus.
- **Fail2Ban:** Intrusion prevention for various services.
- **Vaultwarden:** Unofficial Bitwarden server implementation.
- **Kopia:** Fast, secure, and incremental backups.
- **Memos:** A privacy-first, lightweight note-taking service.
- **Jellyfin:** Free software media system.
- **Filebrowser:** Web interface to browse and manage files.
- **Gitea:** Lightweight Git service (this repository is hosted on it!).
- **Gitea runner:** A runner for Gitea actions.
- **Actual Budget:** Local-first personal finance app.
---
### Usage
This repository is not intended for direct cloning and deployment as-is. It is highly tailored to my specific setup, including domain names (bouvais.lu), paths, and personal configurations.
However, you can use this repository as an example or reference.

89
compose-apps.yml Normal file
View File

@ -0,0 +1,89 @@
services:
memos:
image: neosmemo/memos:stable
container_name: memos
restart: unless-stopped
volumes:
- "./hdd0/memos:/var/opt/memos"
labels:
- "traefik.enable=true"
- "traefik.http.routers.memos.rule=Host(`notes.bouvais.lu`)"
- "traefik.http.routers.memos.entrypoints=websecure"
- "traefik.http.routers.memos.tls.certresolver=myresolver"
- "traefik.http.services.memos.loadbalancer.server.port=5230"
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
restart: unless-stopped
group_add:
- '107' #render
- '44' #video
volumes:
- "./cache/jellyfin:/cache"
- "./hdd0/jellyfin:/config"
- "./hdd0/media:/media"
- type: bind
source: /data/media
target: /media
labels:
- "traefik.enable=true"
- "traefik.http.routers.jellyfin.rule=Host(`jellyfin.bouvais.lu`)"
- "traefik.http.routers.jellyfin.entrypoints=websecure"
- "traefik.http.routers.jellyfin.tls.certresolver=myresolver"
- "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
filebrowser:
image: filebrowser/filebrowser:latest
container_name: filebrowser
restart: unless-stopped
environment:
TZ: Europe/Luxembourg
FB_BASEURL: /
volumes:
- "./config/filebrowser/filebrowser.json:/.filebrowser.json"
- "./hdd0/filebrowser/filebrowser.db:/database.db"
- "./hdd0/my_files:/srv"
labels:
- "traefik.enable=true"
- "traefik.http.routers.filebrowser.rule=Host(`files.bouvais.lu`)"
- "traefik.http.routers.filebrowser.entrypoints=websecure"
- "traefik.http.routers.filebrowser.tls.certresolver=myresolver"
- "traefik.http.services.filebrowser.loadbalancer.server.port=80"
actualbudget:
image: actualbudget/actual-server:latest
container_name: actualbudget
restart: unless-stopped
volumes:
- "./hdd0/actualbudget:/data"
environment:
- TZ=Europe/Luxembourg
labels:
- "traefik.enable=true"
- "traefik.http.routers.actualbudget.rule=Host(`budget.bouvais.lu`)"
- "traefik.http.routers.actualbudget.entrypoints=websecure"
- "traefik.http.routers.actualbudget.tls.certresolver=myresolver"
- "traefik.http.services.actualbudget.loadbalancer.server.port=5006"
vaultwarden:
image: vaultwarden/server:1.33.2
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.bouvais.lu"
SIGNUPS_ALLOWED: false
volumes:
- "./hdd0/vaultwarden:/data/"
labels:
- "traefik.enable=true"
- "traefik.http.services.my-vaultwarden-service.loadbalancer.server.port=80"
- "traefik.http.routers.vaultwarden.rule=Host(`vault.bouvais.lu`)"
- "traefik.http.routers.vaultwarden.entrypoints=websecure"
- "traefik.http.routers.vaultwarden.tls.certresolver=myresolver"
- "traefik.http.routers.vaultwarden.service=my-vaultwarden-service@docker"
- "traefik.http.routers.vaultwarden-admin.rule=Host(`vault.bouvais.lu`) && PathPrefix(`/admin`)"
- "traefik.http.routers.vaultwarden-admin.entrypoints=websecure"
- "traefik.http.routers.vaultwarden-admin.tls.certresolver=myresolver"
- "traefik.http.routers.vaultwarden-admin.middlewares=auth@docker"
- "traefik.http.routers.vaultwarden-admin.service=my-vaultwarden-service@docker"

47
compose-gitea.yml Normal file
View File

@ -0,0 +1,47 @@
services:
gitea:
image: "docker.gitea.com/gitea:1.23.8"
container_name: gitea
restart: unless-stopped
environment:
- GITEA_CUSTOM=/etc/gitea
volumes:
- "./hdd0/gitea:/data"
- "./config/gitea:/etc/gitea"
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
labels:
- "traefik.enable=true"
# HTTP/S
- "traefik.http.routers.gitea.rule=Host(`git.bouvais.lu`)"
- "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.tls.certresolver=myresolver"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
# SSH
- "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)"
- "traefik.tcp.routers.gitea-ssh.entrypoints=ssh"
- "traefik.tcp.services.gitea-ssh.loadbalancer.server.port=22"
gitea-runner:
image: docker.io/gitea/act_runner:latest
restart: unless-stopped
environment:
CONFIG_FILE: /config.yaml
GITEA_INSTANCE_URL: http://gitea:3000
GITEA_RUNNER_REGISTRATION_TOKEN: m03Cj8wJjujfRXenMoN0pVy1J34GmuwbZZ9Bghs1
volumes:
- ./config/gitea-runner/config.yaml:/config.yaml
- ./hdd0/gitea-runner:/data
- /var/run/docker.sock:/var/run/docker.sock
mkdocs:
image: squidfunk/mkdocs-material
restart: unless-stopped
volumes:
- ./:/docs
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`git.bouvais.lu`)"
- "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.tls.certresolver=myresolver"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"

81
compose-monitoring.yml Normal file
View File

@ -0,0 +1,81 @@
services:
prometheus:
image: prom/prometheus:v3.4.0
container_name: prometheus
privileged: true
user: root
restart: unless-stopped
volumes:
- ./config/prometheus:/etc/prometheus
- ./hdd0/prometheus:/prometheus # For Prometheus data persistence
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.enable-lifecycle' # Allows hot-reloading of config via API
labels:
- "traefik.enable=true"
- "traefik.http.routers.prometheus.rule=Host(`prometheus.bouvais.lu`)"
- "traefik.http.routers.prometheus.entrypoints=websecure"
- "traefik.http.routers.prometheus.tls.certresolver=myresolver"
- "traefik.http.routers.prometheus.service=prometheus"
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
- "traefik.http.routers.prometheus.middlewares=auth@docker"
depends_on:
- cadvisor
- node-exporter
grafana:
image: grafana/grafana:12.0.1
container_name: grafana
privileged: true
user: root
restart: unless-stopped
volumes:
- ./hdd0/grafana:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=adrien
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_MY_PASSWORD}
- GF_SERVER_ROOT_URL=https://grafana.bouvais.lu # Set this for correct links if behind a subpath
labels:
- "traefik.enable=true"
- "traefik.http.routers.grafana.rule=Host(`grafana.bouvais.lu`)"
- "traefik.http.routers.grafana.entrypoints=websecure"
- "traefik.http.routers.grafana.tls.certresolver=myresolver"
- "traefik.http.routers.grafana.service=grafana"
- "traefik.http.services.grafana.loadbalancer.server.port=3000" # Grafana's default port
- "traefik.http.routers.grafana.middlewares=auth@docker"
depends_on:
- prometheus
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.52.0
container_name: cadvisor
privileged: true
restart: unless-stopped
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg:/dev/kmsg
node-exporter:
image: prom/node-exporter:v1.9.1
container_name: node-exporter
privileged: true
restart: unless-stopped
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'

13
compose-website.yml Normal file
View File

@ -0,0 +1,13 @@
services:
website-pro:
build:
context: ./website-pro
dockerfile: Dockerfile
container_name: website-pro
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.www.rule=Host(`www.bouvais.lu`)"
- "traefik.http.routers.www.entrypoints=websecure"
- "traefik.http.routers.www.tls.certresolver=myresolver"
- "traefik.http.services.www.loadbalancer.server.port=8080"

View File

@ -0,0 +1,8 @@
{
"port": 80,
"baseURL": "files.bouvais.lu",
"address": "0.0.0.0",
"log": "stdout",
"database": "/database.db",
"root": "/srv"
}

View File

View File

@ -0,0 +1 @@
@import "./theme-light.css"(prefers-color-scheme:light);@import "./theme-dark.css"(prefers-color-scheme:dark);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1080" height="1080" viewBox="0 0 1080 1080" xml:space="preserve">
<desc>Created with Fabric.js 5.2.4</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="transparent"></rect>
<g transform="matrix(1 0 0 1 540 540)" id="b1285610-dc32-45a8-9642-309fa9224800" >
</g>
<g transform="matrix(1 0 0 1 540 540)" id="50e8875c-2da2-4b35-a893-820abf496ce1" >
<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x="-540" y="-540" rx="0" ry="0" width="1080" height="1080" />
</g>
<g transform="matrix(1.05 0 0 1.05 521.54 520.51)" >
<g style="" >
<g transform="matrix(0.13 0 0 -0.13 16 19.46)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5240, -4974.05)" d="M 4830 7934 C 4287 7884 3837 7672 3364 7244 C 3031 6942 2707 6614 2600 6470 C 2469 6294 2448 6129 2534 5954 C 2577 5869 2620 5808 2763 5637 C 2883 5493 2900 5466 2900 5417 C 2900 5398 2875 5293 2845 5184 C 2655 4500 2380 3719 2213 3391 L 2160 3286 L 2203 3246 C 2319 3135 2648 2907 2909 2755 C 3094 2648 3452 2475 3650 2396 C 4174 2190 4722 2060 5244 2019 C 5434 2004 5904 2013 6055 2034 C 6280 2066 6360 2091 6360 2129 C 6360 2139 6311 2307 6251 2501 C 6130 2894 6085 3062 6041 3285 C 5924 3878 5944 4227 6104 4368 C 6156 4413 6206 4424 6340 4416 C 6745 4394 6899 4399 7126 4445 C 7595 4540 7921 4826 8130 5328 C 8254 5624 8320 5903 8320 6131 C 8320 6224 8317 6242 8295 6287 C 8238 6400 8159 6434 7589 6585 C 7103 6715 6952 6770 6851 6856 C 6808 6893 6732 7003 6710 7060 C 6651 7213 6432 7486 6266 7613 C 6022 7801 5830 7872 5450 7915 C 5319 7930 4922 7942 4830 7934 z M 5411 7620 C 5624 7598 5828 7543 5936 7479 C 6010 7435 6160 7292 6254 7176 C 6295 7126 6358 7031 6395 6965 C 6479 6814 6512 6769 6600 6687 C 6716 6577 6880 6508 7333 6376 C 7437 6346 7524 6319 7527 6316 C 7530 6313 7517 6269 7499 6218 C 7437 6049 7455 5924 7558 5810 C 7611 5750 7677 5715 7786 5690 C 7835 5679 7880 5663 7886 5654 C 7895 5643 7895 5624 7884 5577 C 7811 5263 7554 4954 7260 4829 C 7068 4748 6884 4724 6545 4736 C 6413 4741 6222 4744 6120 4743 C 5960 4742 5923 4738 5843 4717 C 5606 4655 5415 4459 5326 4188 C 5280 4047 5267 3928 5273 3721 C 5279 3514 5301 3387 5366 3180 C 5439 2945 5512 2788 5669 2526 C 5725 2433 5770 2355 5770 2352 C 5770 2342 5240 2359 5110 2374 C 4626 2430 4225 2531 3750 2717 C 3540 2799 3191 2971 2986 3094 C 2823 3192 2601 3346 2593 3366 C 2591 3372 2620 3456 2659 3552 C 2810 3931 3035 4602 3175 5093 C 3184 5124 3195 5150 3199 5150 C 3204 5150 3252 5109 3306 5058 C 3455 4921 3531 4857 3616 4799 C 3860 4634 4076 4590 4245 4668 C 4405 4743 4492 4901 4521 5169 C 4549 5427 4509 6177 4420 7070 C 4410 7177 4398 7318 4394 7382 L 4387 7500 L 4442 7525 C 4530 7565 4678 7592 4980 7623 C 5060 7631 5315 7629 5411 7620 z" stroke-linecap="round" />
</g>
<g transform="matrix(0.13 0 0 -0.13 92.12 -201.19)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5810.87, -6628.95)" d="M 5769 6889 C 5710 6880 5674 6861 5629 6813 C 5519 6698 5516 6537 5621 6432 C 5672 6380 5707 6366 5780 6366 C 5953 6366 6098 6526 6075 6692 C 6058 6814 5909 6910 5769 6889 z" stroke-linecap="round" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1080" height="1080" viewBox="0 0 1080 1080" xml:space="preserve">
<desc>Created with Fabric.js 5.2.4</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="transparent"></rect>
<g transform="matrix(1 0 0 1 540 540)" id="b1285610-dc32-45a8-9642-309fa9224800" >
</g>
<g transform="matrix(1 0 0 1 540 540)" id="50e8875c-2da2-4b35-a893-820abf496ce1" >
<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x="-540" y="-540" rx="0" ry="0" width="1080" height="1080" />
</g>
<g transform="matrix(1.05 0 0 1.05 521.54 520.51)" >
<g style="" >
<g transform="matrix(0.13 0 0 -0.13 16 19.46)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5240, -4974.05)" d="M 4830 7934 C 4287 7884 3837 7672 3364 7244 C 3031 6942 2707 6614 2600 6470 C 2469 6294 2448 6129 2534 5954 C 2577 5869 2620 5808 2763 5637 C 2883 5493 2900 5466 2900 5417 C 2900 5398 2875 5293 2845 5184 C 2655 4500 2380 3719 2213 3391 L 2160 3286 L 2203 3246 C 2319 3135 2648 2907 2909 2755 C 3094 2648 3452 2475 3650 2396 C 4174 2190 4722 2060 5244 2019 C 5434 2004 5904 2013 6055 2034 C 6280 2066 6360 2091 6360 2129 C 6360 2139 6311 2307 6251 2501 C 6130 2894 6085 3062 6041 3285 C 5924 3878 5944 4227 6104 4368 C 6156 4413 6206 4424 6340 4416 C 6745 4394 6899 4399 7126 4445 C 7595 4540 7921 4826 8130 5328 C 8254 5624 8320 5903 8320 6131 C 8320 6224 8317 6242 8295 6287 C 8238 6400 8159 6434 7589 6585 C 7103 6715 6952 6770 6851 6856 C 6808 6893 6732 7003 6710 7060 C 6651 7213 6432 7486 6266 7613 C 6022 7801 5830 7872 5450 7915 C 5319 7930 4922 7942 4830 7934 z M 5411 7620 C 5624 7598 5828 7543 5936 7479 C 6010 7435 6160 7292 6254 7176 C 6295 7126 6358 7031 6395 6965 C 6479 6814 6512 6769 6600 6687 C 6716 6577 6880 6508 7333 6376 C 7437 6346 7524 6319 7527 6316 C 7530 6313 7517 6269 7499 6218 C 7437 6049 7455 5924 7558 5810 C 7611 5750 7677 5715 7786 5690 C 7835 5679 7880 5663 7886 5654 C 7895 5643 7895 5624 7884 5577 C 7811 5263 7554 4954 7260 4829 C 7068 4748 6884 4724 6545 4736 C 6413 4741 6222 4744 6120 4743 C 5960 4742 5923 4738 5843 4717 C 5606 4655 5415 4459 5326 4188 C 5280 4047 5267 3928 5273 3721 C 5279 3514 5301 3387 5366 3180 C 5439 2945 5512 2788 5669 2526 C 5725 2433 5770 2355 5770 2352 C 5770 2342 5240 2359 5110 2374 C 4626 2430 4225 2531 3750 2717 C 3540 2799 3191 2971 2986 3094 C 2823 3192 2601 3346 2593 3366 C 2591 3372 2620 3456 2659 3552 C 2810 3931 3035 4602 3175 5093 C 3184 5124 3195 5150 3199 5150 C 3204 5150 3252 5109 3306 5058 C 3455 4921 3531 4857 3616 4799 C 3860 4634 4076 4590 4245 4668 C 4405 4743 4492 4901 4521 5169 C 4549 5427 4509 6177 4420 7070 C 4410 7177 4398 7318 4394 7382 L 4387 7500 L 4442 7525 C 4530 7565 4678 7592 4980 7623 C 5060 7631 5315 7629 5411 7620 z" stroke-linecap="round" />
</g>
<g transform="matrix(0.13 0 0 -0.13 92.12 -201.19)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5810.87, -6628.95)" d="M 5769 6889 C 5710 6880 5674 6861 5629 6813 C 5519 6698 5516 6537 5621 6432 C 5672 6380 5707 6366 5780 6366 C 5953 6366 6098 6526 6075 6692 C 6058 6814 5909 6910 5769 6889 z" stroke-linecap="round" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1080" height="1080" viewBox="0 0 1080 1080" xml:space="preserve">
<desc>Created with Fabric.js 5.2.4</desc>
<defs>
</defs>
<g transform="matrix(1 0 0 1 540 540)" id="b1285610-dc32-45a8-9642-309fa9224800" >
</g>
<g transform="matrix(1 0 0 1 540 540)" id="50e8875c-2da2-4b35-a893-820abf496ce1" >
<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x="-540" y="-540" rx="0" ry="0" width="1080" height="1080" />
</g>
<g transform="matrix(1.05 0 0 1.05 521.54 520.51)" >
<g style="" >
<g transform="matrix(0.13 0 0 -0.13 16 19.46)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5240, -4974.05)" d="M 4830 7934 C 4287 7884 3837 7672 3364 7244 C 3031 6942 2707 6614 2600 6470 C 2469 6294 2448 6129 2534 5954 C 2577 5869 2620 5808 2763 5637 C 2883 5493 2900 5466 2900 5417 C 2900 5398 2875 5293 2845 5184 C 2655 4500 2380 3719 2213 3391 L 2160 3286 L 2203 3246 C 2319 3135 2648 2907 2909 2755 C 3094 2648 3452 2475 3650 2396 C 4174 2190 4722 2060 5244 2019 C 5434 2004 5904 2013 6055 2034 C 6280 2066 6360 2091 6360 2129 C 6360 2139 6311 2307 6251 2501 C 6130 2894 6085 3062 6041 3285 C 5924 3878 5944 4227 6104 4368 C 6156 4413 6206 4424 6340 4416 C 6745 4394 6899 4399 7126 4445 C 7595 4540 7921 4826 8130 5328 C 8254 5624 8320 5903 8320 6131 C 8320 6224 8317 6242 8295 6287 C 8238 6400 8159 6434 7589 6585 C 7103 6715 6952 6770 6851 6856 C 6808 6893 6732 7003 6710 7060 C 6651 7213 6432 7486 6266 7613 C 6022 7801 5830 7872 5450 7915 C 5319 7930 4922 7942 4830 7934 z M 5411 7620 C 5624 7598 5828 7543 5936 7479 C 6010 7435 6160 7292 6254 7176 C 6295 7126 6358 7031 6395 6965 C 6479 6814 6512 6769 6600 6687 C 6716 6577 6880 6508 7333 6376 C 7437 6346 7524 6319 7527 6316 C 7530 6313 7517 6269 7499 6218 C 7437 6049 7455 5924 7558 5810 C 7611 5750 7677 5715 7786 5690 C 7835 5679 7880 5663 7886 5654 C 7895 5643 7895 5624 7884 5577 C 7811 5263 7554 4954 7260 4829 C 7068 4748 6884 4724 6545 4736 C 6413 4741 6222 4744 6120 4743 C 5960 4742 5923 4738 5843 4717 C 5606 4655 5415 4459 5326 4188 C 5280 4047 5267 3928 5273 3721 C 5279 3514 5301 3387 5366 3180 C 5439 2945 5512 2788 5669 2526 C 5725 2433 5770 2355 5770 2352 C 5770 2342 5240 2359 5110 2374 C 4626 2430 4225 2531 3750 2717 C 3540 2799 3191 2971 2986 3094 C 2823 3192 2601 3346 2593 3366 C 2591 3372 2620 3456 2659 3552 C 2810 3931 3035 4602 3175 5093 C 3184 5124 3195 5150 3199 5150 C 3204 5150 3252 5109 3306 5058 C 3455 4921 3531 4857 3616 4799 C 3860 4634 4076 4590 4245 4668 C 4405 4743 4492 4901 4521 5169 C 4549 5427 4509 6177 4420 7070 C 4410 7177 4398 7318 4394 7382 L 4387 7500 L 4442 7525 C 4530 7565 4678 7592 4980 7623 C 5060 7631 5315 7629 5411 7620 z" stroke-linecap="round" />
</g>
<g transform="matrix(0.13 0 0 -0.13 92.12 -201.19)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5810.87, -6628.95)" d="M 5769 6889 C 5710 6880 5674 6861 5629 6813 C 5519 6698 5516 6537 5621 6432 C 5672 6380 5707 6366 5780 6366 C 5953 6366 6098 6526 6075 6692 C 6058 6814 5909 6910 5769 6889 z" stroke-linecap="round" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1080" height="1080" viewBox="0 0 1080 1080" xml:space="preserve">
<desc>Created with Fabric.js 5.2.4</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="transparent"></rect>
<g transform="matrix(1 0 0 1 540 540)" id="b1285610-dc32-45a8-9642-309fa9224800" >
</g>
<g transform="matrix(1 0 0 1 540 540)" id="50e8875c-2da2-4b35-a893-820abf496ce1" >
<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x="-540" y="-540" rx="0" ry="0" width="1080" height="1080" />
</g>
<g transform="matrix(1.05 0 0 1.05 521.54 520.51)" >
<g style="" >
<g transform="matrix(0.13 0 0 -0.13 16 19.46)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5240, -4974.05)" d="M 4830 7934 C 4287 7884 3837 7672 3364 7244 C 3031 6942 2707 6614 2600 6470 C 2469 6294 2448 6129 2534 5954 C 2577 5869 2620 5808 2763 5637 C 2883 5493 2900 5466 2900 5417 C 2900 5398 2875 5293 2845 5184 C 2655 4500 2380 3719 2213 3391 L 2160 3286 L 2203 3246 C 2319 3135 2648 2907 2909 2755 C 3094 2648 3452 2475 3650 2396 C 4174 2190 4722 2060 5244 2019 C 5434 2004 5904 2013 6055 2034 C 6280 2066 6360 2091 6360 2129 C 6360 2139 6311 2307 6251 2501 C 6130 2894 6085 3062 6041 3285 C 5924 3878 5944 4227 6104 4368 C 6156 4413 6206 4424 6340 4416 C 6745 4394 6899 4399 7126 4445 C 7595 4540 7921 4826 8130 5328 C 8254 5624 8320 5903 8320 6131 C 8320 6224 8317 6242 8295 6287 C 8238 6400 8159 6434 7589 6585 C 7103 6715 6952 6770 6851 6856 C 6808 6893 6732 7003 6710 7060 C 6651 7213 6432 7486 6266 7613 C 6022 7801 5830 7872 5450 7915 C 5319 7930 4922 7942 4830 7934 z M 5411 7620 C 5624 7598 5828 7543 5936 7479 C 6010 7435 6160 7292 6254 7176 C 6295 7126 6358 7031 6395 6965 C 6479 6814 6512 6769 6600 6687 C 6716 6577 6880 6508 7333 6376 C 7437 6346 7524 6319 7527 6316 C 7530 6313 7517 6269 7499 6218 C 7437 6049 7455 5924 7558 5810 C 7611 5750 7677 5715 7786 5690 C 7835 5679 7880 5663 7886 5654 C 7895 5643 7895 5624 7884 5577 C 7811 5263 7554 4954 7260 4829 C 7068 4748 6884 4724 6545 4736 C 6413 4741 6222 4744 6120 4743 C 5960 4742 5923 4738 5843 4717 C 5606 4655 5415 4459 5326 4188 C 5280 4047 5267 3928 5273 3721 C 5279 3514 5301 3387 5366 3180 C 5439 2945 5512 2788 5669 2526 C 5725 2433 5770 2355 5770 2352 C 5770 2342 5240 2359 5110 2374 C 4626 2430 4225 2531 3750 2717 C 3540 2799 3191 2971 2986 3094 C 2823 3192 2601 3346 2593 3366 C 2591 3372 2620 3456 2659 3552 C 2810 3931 3035 4602 3175 5093 C 3184 5124 3195 5150 3199 5150 C 3204 5150 3252 5109 3306 5058 C 3455 4921 3531 4857 3616 4799 C 3860 4634 4076 4590 4245 4668 C 4405 4743 4492 4901 4521 5169 C 4549 5427 4509 6177 4420 7070 C 4410 7177 4398 7318 4394 7382 L 4387 7500 L 4442 7525 C 4530 7565 4678 7592 4980 7623 C 5060 7631 5315 7629 5411 7620 z" stroke-linecap="round" />
</g>
<g transform="matrix(0.13 0 0 -0.13 92.12 -201.19)" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-5810.87, -6628.95)" d="M 5769 6889 C 5710 6880 5674 6861 5629 6813 C 5519 6698 5516 6537 5621 6432 C 5672 6380 5707 6366 5780 6366 C 5953 6366 6098 6526 6075 6692 C 6058 6814 5909 6910 5769 6889 z" stroke-linecap="round" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,34 @@
{{if false}}
{{/* to make html structure "likely" complete to prevent IDE warnings */}}
<html>
<body>
<div>
{{end}}
<script src="{{AssetUrlPrefix}}/js/index.js?v={{AssetVersion}}" onerror="alert('Failed to load asset files from ' + this.src + '. Please make sure the asset files can be accessed.')"></script>
<script>
const dynamicLogo = document.getElementById('dynamic-logo');
const assetUrlPrefix = "{{AssetUrlPrefix}}"; // Get the asset URL prefix from your Go template
function setLogoBasedOnTheme() {
if (getComputedStyle(document.documentElement).getPropertyValue('--is-dark-theme').trim() == 'true') {
// Dark mode is active
dynamicLogo.src = `${assetUrlPrefix}/img/logo_light.svg`;
} else {
// Light mode or no preference (default to light)
dynamicLogo.src = `${assetUrlPrefix}/img/logo_dark.svg`;
}
}
// Set logo on initial load
setLogoBasedOnTheme();
// Listen for changes in the color scheme
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
setLogoBasedOnTheme();
});
</script>
</body>
</html>

View File

@ -0,0 +1,214 @@
{{$notificationUnreadCount := 0}}
{{if and .IsSigned .NotificationUnreadCount}}
{{$notificationUnreadCount = call .NotificationUnreadCount}}
{{end}}
<nav id="navbar" aria-label="{{ctx.Locale.Tr "aria.navbar"}}">
<div class="navbar-left">
<!-- the logo -->
<a class="item" id="navbar-logo" href="{{AppSubUrl}}/" aria-label="{{if .IsSigned}}{{ctx.Locale.Tr "dashboard"}}{{else}}{{ctx.Locale.Tr "home"}}{{end}}">
<img id="dynamic-logo" width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}" aria-hidden="true">
</a>
<!-- mobile right menu, it must be here because in mobile view, each item is a flex column, the first item is a full row column -->
<div class="ui secondary menu navbar-mobile-right only-mobile">
{{if and .IsSigned EnableTimetracking .ActiveStopwatch}}
<a id="mobile-stopwatch-icon" class="active-stopwatch item tw-mx-0" href="{{.ActiveStopwatch.IssueLink}}" title="{{ctx.Locale.Tr "active_stopwatch"}}" data-seconds="{{.ActiveStopwatch.Seconds}}">
<div class="tw-relative">
{{svg "octicon-stopwatch"}}
<span class="header-stopwatch-dot"></span>
</div>
</a>
{{end}}
{{if .IsSigned}}
<a id="mobile-notifications-icon" class="item tw-w-auto tw-p-2" href="{{AppSubUrl}}/notifications" data-tooltip-content="{{ctx.Locale.Tr "notifications"}}" aria-label="{{ctx.Locale.Tr "notifications"}}">
<div class="tw-relative">
{{svg "octicon-bell"}}
<span class="notification_count{{if not $notificationUnreadCount}} tw-hidden{{end}}">{{$notificationUnreadCount}}</span>
</div>
</a>
{{end}}
<button class="item tw-w-auto ui icon mini button tw-p-2 tw-m-0" id="navbar-expand-toggle" aria-label="{{ctx.Locale.Tr "home.nav_menu"}}">{{svg "octicon-three-bars"}}</button>
</div>
<!-- navbar links non-mobile -->
{{if and .IsSigned .MustChangePassword}}
{{/* No links */}}
{{else if .IsSigned}}
{{if not ctx.Consts.RepoUnitTypeIssues.UnitGlobalDisabled}}
<a class="item{{if .PageIsIssues}} active{{end}}" href="{{AppSubUrl}}/issues">{{ctx.Locale.Tr "issues"}}</a>
{{end}}
{{if not ctx.Consts.RepoUnitTypePullRequests.UnitGlobalDisabled}}
<a class="item{{if .PageIsPulls}} active{{end}}" href="{{AppSubUrl}}/pulls">{{ctx.Locale.Tr "pull_requests"}}</a>
{{end}}
{{if not (and ctx.Consts.RepoUnitTypeIssues.UnitGlobalDisabled ctx.Consts.RepoUnitTypePullRequests.UnitGlobalDisabled)}}
{{if .ShowMilestonesDashboardPage}}
<a class="item{{if .PageIsMilestonesDashboard}} active{{end}}" href="{{AppSubUrl}}/milestones">{{ctx.Locale.Tr "milestones"}}</a>
{{end}}
{{end}}
<a class="item{{if .PageIsExplore}} active{{end}}" href="{{AppSubUrl}}/explore/repos">{{ctx.Locale.Tr "explore"}}</a>
{{else if .IsLandingPageOrganizations}}
<a class="item{{if .PageIsExplore}} active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{ctx.Locale.Tr "explore"}}</a>
{{else}}
<a class="item{{if .PageIsExplore}} active{{end}}" href="{{AppSubUrl}}/explore/repos">{{ctx.Locale.Tr "explore"}}</a>
{{end}}
{{template "custom/extra_links" .}}
{{if not .IsSigned}}
<a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com">{{ctx.Locale.Tr "help"}}</a>
{{end}}
</div>
<!-- the full dropdown menus -->
<div class="navbar-right">
{{if and .IsSigned .MustChangePassword}}
<div class="ui dropdown jump item" data-tooltip-content="{{ctx.Locale.Tr "user_profile_and_more"}}">
<span class="text tw-flex tw-items-center">
{{ctx.AvatarUtils.Avatar .SignedUser 24 "tw-mr-1"}}
<span class="only-mobile tw-ml-2">{{.SignedUser.Name}}</span>
<span class="not-mobile">{{svg "octicon-triangle-down"}}</span>
</span>
<div class="menu user-menu">
<div class="header">
{{ctx.Locale.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong>
</div>
<div class="divider"></div>
<a class="item link-action" href data-url="{{AppSubUrl}}/user/logout">
{{svg "octicon-sign-out"}}
{{ctx.Locale.Tr "sign_out"}}
</a>
</div><!-- end content avatar menu -->
</div><!-- end dropdown avatar menu -->
{{else if .IsSigned}}
{{if and EnableTimetracking .ActiveStopwatch}}
<a class="item not-mobile active-stopwatch tw-mx-0" href="{{.ActiveStopwatch.IssueLink}}" title="{{ctx.Locale.Tr "active_stopwatch"}}" data-seconds="{{.ActiveStopwatch.Seconds}}">
<div class="tw-relative">
{{svg "octicon-stopwatch"}}
<span class="header-stopwatch-dot"></span>
</div>
</a>
{{end}}
<a class="item not-mobile tw-mx-0" href="{{AppSubUrl}}/notifications" data-tooltip-content="{{ctx.Locale.Tr "notifications"}}" aria-label="{{ctx.Locale.Tr "notifications"}}">
<div class="tw-relative">
{{svg "octicon-bell"}}
<span class="notification_count{{if not $notificationUnreadCount}} tw-hidden{{end}}">{{$notificationUnreadCount}}</span>
</div>
</a>
<div class="ui dropdown jump item tw-mx-0 tw-pr-2" data-tooltip-content="{{ctx.Locale.Tr "create_new"}}">
<span class="text">
{{svg "octicon-plus"}}
<span class="not-mobile">{{svg "octicon-triangle-down"}}</span>
<span class="only-mobile">{{ctx.Locale.Tr "create_new"}}</span>
</span>
<div class="menu">
<a class="item" href="{{AppSubUrl}}/repo/create">
{{svg "octicon-plus"}} {{ctx.Locale.Tr "new_repo"}}
</a>
{{if not .DisableMigrations}}
<a class="item" href="{{AppSubUrl}}/repo/migrate">
{{svg "octicon-repo-push"}} {{ctx.Locale.Tr "new_migrate"}}
</a>
{{end}}
{{if .SignedUser.CanCreateOrganization}}
<a class="item" href="{{AppSubUrl}}/org/create">
{{svg "octicon-organization"}} {{ctx.Locale.Tr "new_org"}}
</a>
{{end}}
</div><!-- end content create new menu -->
</div><!-- end dropdown menu create new -->
<div class="ui dropdown jump item tw-mx-0 tw-pr-2" data-tooltip-content="{{ctx.Locale.Tr "user_profile_and_more"}}">
<span class="text tw-flex tw-items-center">
{{ctx.AvatarUtils.Avatar .SignedUser 24 "tw-mr-1"}}
<span class="only-mobile tw-ml-2">{{.SignedUser.Name}}</span>
<span class="not-mobile">{{svg "octicon-triangle-down"}}</span>
</span>
<div class="menu user-menu">
<div class="header">
{{ctx.Locale.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong>
</div>
<div class="divider"></div>
<a class="item" href="{{.SignedUser.HomeLink}}">
{{svg "octicon-person"}}
{{ctx.Locale.Tr "your_profile"}}
</a>
{{if not .DisableStars}}
<a class="item" href="{{.SignedUser.HomeLink}}?tab=stars">
{{svg "octicon-star"}}
{{ctx.Locale.Tr "your_starred"}}
</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/notifications/subscriptions">
{{svg "octicon-bell"}}
{{ctx.Locale.Tr "notification.subscriptions"}}
</a>
<a class="{{if .PageIsUserSettings}}active {{end}}item" href="{{AppSubUrl}}/user/settings">
{{svg "octicon-tools"}}
{{ctx.Locale.Tr "your_settings"}}
</a>
<a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com">
{{svg "octicon-question"}}
{{ctx.Locale.Tr "help"}}
</a>
{{if .IsAdmin}}
<div class="divider"></div>
<a class="{{if .PageIsAdmin}}active {{end}}item" href="{{AppSubUrl}}/-/admin">
{{svg "octicon-server"}}
{{ctx.Locale.Tr "admin_panel"}}
</a>
{{end}}
<div class="divider"></div>
<a class="item link-action" href data-url="{{AppSubUrl}}/user/logout">
{{svg "octicon-sign-out"}}
{{ctx.Locale.Tr "sign_out"}}
</a>
</div><!-- end content avatar menu -->
</div><!-- end dropdown avatar menu -->
{{else}}
{{if .ShowRegistrationButton}}
<a class="item{{if .PageIsSignUp}} active{{end}}" href="{{AppSubUrl}}/user/sign_up">
{{svg "octicon-person"}} {{ctx.Locale.Tr "register"}}
</a>
{{end}}
<a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login{{if not .PageIsSignIn}}?redirect_to={{.CurrentURL}}{{end}}">
{{svg "octicon-sign-in"}} {{ctx.Locale.Tr "sign_in"}}
</a>
{{end}}
</div><!-- end full right menu -->
{{if and .IsSigned EnableTimetracking .ActiveStopwatch}}
<div class="active-stopwatch-popup tippy-target">
<div class="tw-flex tw-items-center tw-gap-2 tw-p-3">
<a class="stopwatch-link tw-flex tw-items-center tw-gap-2 muted" href="{{.ActiveStopwatch.IssueLink}}">
{{svg "octicon-issue-opened" 16}}
<span class="stopwatch-issue">{{.ActiveStopwatch.RepoSlug}}#{{.ActiveStopwatch.IssueIndex}}</span>
</a>
<div class="tw-flex tw-gap-1">
<form class="stopwatch-commit form-fetch-action" method="post" action="{{.ActiveStopwatch.IssueLink}}/times/stopwatch/toggle">
{{.CsrfTokenHtml}}
<button
type="submit"
class="ui button mini compact basic icon tw-mr-0"
data-tooltip-content="{{ctx.Locale.Tr "repo.issues.stop_tracking"}}"
>{{svg "octicon-square-fill"}}</button>
</form>
<form class="stopwatch-cancel form-fetch-action" method="post" action="{{.ActiveStopwatch.IssueLink}}/times/stopwatch/cancel">
{{.CsrfTokenHtml}}
<button
type="submit"
class="ui button mini compact basic icon tw-mr-0"
data-tooltip-content="{{ctx.Locale.Tr "repo.issues.cancel_tracking"}}"
>{{svg "octicon-trash"}}</button>
</form>
</div>
</div>
</div>
{{end}}
</nav>

View File

@ -0,0 +1,15 @@
{{template "base/head" .}}
<div role="main" aria-label="{{if .IsSigned}}{{ctx.Locale.Tr "dashboard"}}{{else}}{{ctx.Locale.Tr "home"}}{{end}}" class="page-content home">
<div class="tw-mb-8 tw-px-8">
<div class="center">
<img class="logo" width="220" height="220" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}">
<div class="hero">
<h1 class="ui icon header title">
{{AppName}}
</h1>
<h2>A simple place for my code.</h2>
</div>
</div>
</div>
</div>
{{template "base/footer" .}}

View File

@ -0,0 +1,20 @@
{
"storage": {
"type": "filesystem",
"config": {
"path": "/repository",
"dirShards": null
}
},
"caching": {
"cacheDirectory": "../cache",
"maxCacheSize": 5242880000,
"maxMetadataCacheSize": 5242880000,
"maxListCacheDuration": 30
},
"hostname": "b27568001edb",
"username": "root",
"description": "My Repository",
"enableActions": false,
"formatBlobCacheDuration": 900000000000
}

View File

View File

@ -0,0 +1 @@
{"bytesStringBase2":false,"defaultSnapshotViewAll":false,"theme":"dark","fontSize":"fs-6","pageSize":10,"language":""}

View File

@ -0,0 +1,26 @@
# ./prometheus/prometheus.yml
global:
scrape_interval: 15s # Default scrape interval
evaluation_interval: 15s # Default evaluation interval
scrape_configs:
- job_name: 'traefik'
static_configs:
- targets: ['traefik:8080'] # This should match the port you set for metrics in Traefik's command
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'cadvisor' # For Docker container metrics
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'node-exporter' # For host system metrics
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'gitea' # For host system metrics
static_configs:
- targets: ['gitea:3000']

1
config/users.cred Executable file
View File

@ -0,0 +1 @@
adrien:$apr1$jUYzh/ia$EBkIIA./9xR7gn0M3BsNs1

111
docker-compose.yml Normal file
View File

@ -0,0 +1,111 @@
include:
- compose-apps.yml
- compose-gitea.yml
- compose-monitoring.yml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
command:
# HTTPS TSL stuff
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entryPoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=adrien.bouvais.pro@gmail.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" # Relative path on SSD
# Enable Traefik API and Dashboard (securely)
- "--api.dashboard=true"
- "--metrics.prometheus=true"
- "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0"
- "--entryPoints.ssh.address=:2101"
# Logs - Traefik will write its logs to /logs within the container, which maps to /data/logs on host
- "--accesslog=true"
- "--accesslog.format=json"
- "--accesslog.filepath=/logs/access.log"
- "--accesslog.bufferingSize=0"
ports:
- target: 443
published: 443
protocol: tcp
mode: host
- target: 2101
published: 2101
protocol: tcp
mode: host
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./config/users.cred:/users.cred"
- "./hdd0/logs:/logs"
labels:
- "traefik.enable=true"
# Dashboard Router
- "traefik.http.routers.dashboard.rule=Host(`traefik.bouvais.lu`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=auth@docker"
- "traefik.http.routers.dashboard.tls.certresolver=myresolver"
# Traefik Middleware
- "traefik.http.middlewares.auth.basicauth.usersfile=/users.cred"
- "traefik.http.middlewares.ratelimit.ratelimit.average=20"
- "traefik.http.middlewares.ratelimit.ratelimit.burst=40"
# bouvais.lu redirection
- "traefik.http.routers.bouvais-redirect.rule=Host(`bouvais.lu`)"
- "traefik.http.routers.bouvais-redirect.entrypoints=websecure"
- "traefik.http.routers.bouvais-redirect.middlewares=redirect-to-gitea@docker"
- "traefik.http.routers.bouvais-redirect.tls.certresolver=myresolver"
- "traefik.http.middlewares.redirect-to-gitea.redirectregex.regex=^https?://(www\\.)?bouvais\\.lu(.*)"
- "traefik.http.middlewares.redirect-to-gitea.redirectregex.replacement=https://git.bouvais.lu$${2}"
- "traefik.http.middlewares.redirect-to-gitea.redirectregex.permanent=true"
fail2ban:
image: crazymax/fail2ban:1.1.0
container_name: fail2ban
restart: unless-stopped
cap_add:
- NET_ADMIN
- NET_RAW
network_mode: host
volumes:
- "./hdd0/fail2ban/data:/data"
- "./hdd0/fail2ban/log:/var/log"
- "./hdd0/logs:/logs:ro"
- "/etc/localtime:/etc/localtime:ro"
- "/etc/timezone:/etc/timezone:ro"
environment:
- F2B_IPTABLES_CHAIN=DOCKER-USER
kopia:
image: kopia/kopia:latest
container_name: kopia
restart: unless-stopped
ports:
- 51515:51515
command:
- server
- start
#- --disable-csrf-token-checks
- --insecure
- --address=0.0.0.0:51515
- --server-username=adrien
- --server-password=${MASTER_PASSWORD}
environment:
KOPIA_PASSWORD: ${MASTER_PASSWORD}
USER: "adrien"
volumes:
# Mount local folders needed by kopia
- ./config/kopia:/app/config
- ./cache/kopia:/app/cache
- ./hdd0/logs/:/app/logs
- ./hdd0:/hdd0 # Mount local folders to snapshot
- ./hdd0_backups/kopia/dir:/repository # Mount repository location
- ./hdd0_backups/kopia/shared:/tmp:shared # Mount path for browsing mounted snaphots
labels:
- "traefik.enable=true"
- "traefik.http.routers.kopia.rule=Host(`kopia.bouvais.lu`)"
- "traefik.http.routers.kopia.entrypoints=websecure"
- "traefik.http.routers.kopia.tls.certresolver=myresolver"
- "traefik.http.services.kopia.loadbalancer.server.port=51515"