Compare commits
50 Commits
a96ddd3ddf
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a11a4ce8e | |||
| 844cef4bef | |||
| 3ed21badb3 | |||
| bab98a020c | |||
| 3148136c22 | |||
| fe618ac8e4 | |||
| d04a68b4df | |||
| 6ed68a36be | |||
| 0eb4e4483c | |||
| 3032dd0882 | |||
| 0ee5f37b54 | |||
| 24bd4ec162 | |||
| cec78f8229 | |||
| 234d9edc68 | |||
| 59c003f619 | |||
| 98c88759be | |||
| 8173b7cbc1 | |||
| 886c6f559b | |||
| a05b2ea9ea | |||
| ce197c3299 | |||
| 94984f0635 | |||
| e1500967cf | |||
| 9e4a1f7836 | |||
| a286b755fe | |||
| e7bb6eadb8 | |||
| c5421a4af4 | |||
| fb7e101d6f | |||
| 9ffae8989a | |||
| e44dafb0e2 | |||
| 68d5178ab4 | |||
| 714f2449f6 | |||
| 5030362ba4 | |||
| 8fb291704e | |||
| f0b7351f64 | |||
| f111fdfcb7 | |||
| 07ac4dfec4 | |||
| 0cc349765e | |||
| 7ad7b26385 | |||
| 48ef6eda37 | |||
| 0c90b7a155 | |||
| ea9ad9eb30 | |||
| 13022f4c34 | |||
| 57847ca4fe | |||
| 7a211b2d4b | |||
| c3ecd9449e | |||
| 82b8bb2e2a | |||
| a00d3d6ee3 | |||
| c3ad0b889d | |||
| df602c0832 | |||
| 13539eebc6 |
@@ -11,30 +11,21 @@ app_data_disks:
|
|||||||
disk_id: scsi1
|
disk_id: scsi1
|
||||||
mount_point: /data/pocket-id
|
mount_point: /data/pocket-id
|
||||||
device: /dev/sdb
|
device: /dev/sdb
|
||||||
komodo:
|
trek:
|
||||||
vm: infra-core-1
|
|
||||||
vmid: 410
|
|
||||||
node: purah
|
|
||||||
size: "20"
|
|
||||||
storage: purah-mirror-860gb
|
|
||||||
disk_id: scsi2
|
|
||||||
mount_point: /data/komodo
|
|
||||||
device: /dev/sdc
|
|
||||||
komodo-periphery-media:
|
|
||||||
vm: media-1
|
|
||||||
vmid: 420
|
|
||||||
node: purah
|
|
||||||
size: "20"
|
|
||||||
storage: purah-mirror-860gb
|
|
||||||
disk_id: scsi1
|
|
||||||
mount_point: /data/komodo-periphery
|
|
||||||
device: /dev/sdb
|
|
||||||
komodo-periphery-apps:
|
|
||||||
vm: apps-1
|
vm: apps-1
|
||||||
vmid: 430
|
vmid: 430
|
||||||
node: yunobo
|
node: yunobo
|
||||||
size: "20"
|
size: "10"
|
||||||
storage: nvme-2tb
|
storage: nvme-2tb
|
||||||
disk_id: scsi1
|
disk_id: scsi1
|
||||||
mount_point: /data/komodo-periphery
|
mount_point: /data/trek
|
||||||
device: /dev/sdb
|
device: /dev/sdb
|
||||||
|
forgejo:
|
||||||
|
vm: apps-1
|
||||||
|
vmid: 430
|
||||||
|
node: yunobo
|
||||||
|
size: "50"
|
||||||
|
storage: nvme-2tb
|
||||||
|
disk_id: scsi2
|
||||||
|
mount_point: /data/forgejo
|
||||||
|
device: /dev/sdc
|
||||||
|
|||||||
@@ -26,200 +26,231 @@ auto_configure_traefik:
|
|||||||
subdomain: "sonarr"
|
subdomain: "sonarr"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 8989
|
port: 8989
|
||||||
auth_required: true
|
internal: true
|
||||||
radarr:
|
radarr:
|
||||||
subdomain: "radarr"
|
subdomain: "radarr"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 7878
|
port: 7878
|
||||||
auth_required: true
|
internal: true
|
||||||
lidarr:
|
lidarr:
|
||||||
subdomain: "lidarr"
|
subdomain: "lidarr"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 8686
|
port: 8686
|
||||||
auth_required: true
|
internal: true
|
||||||
transmission:
|
transmission:
|
||||||
subdomain: "transmission"
|
subdomain: "transmission"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 9091
|
port: 9091
|
||||||
auth_required: true
|
internal: true
|
||||||
tdarr:
|
unmanic:
|
||||||
subdomain: "tdarr"
|
subdomain: "unmanic"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 8265
|
port: 8888
|
||||||
auth_required: true
|
internal: true
|
||||||
bazarr:
|
bazarr:
|
||||||
subdomain: "bazarr"
|
subdomain: "bazarr"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 6767
|
port: 6767
|
||||||
auth_required: true
|
internal: true
|
||||||
seerr:
|
seerr:
|
||||||
subdomain: "overseerr"
|
subdomain: "overseerr"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 5055
|
port: 5055
|
||||||
auth_required: false
|
internal: false
|
||||||
prowlarr:
|
prowlarr:
|
||||||
subdomain: "prowlarr"
|
subdomain: "prowlarr"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 9696
|
port: 9696
|
||||||
auth_required: true
|
internal: true
|
||||||
unpackerr:
|
unpackerr:
|
||||||
subdomain: "unpackerr"
|
subdomain: "unpackerr"
|
||||||
host: "10.0.2.25"
|
host: "10.0.2.25"
|
||||||
port: 5656
|
port: 5656
|
||||||
auth_required: true
|
internal: true
|
||||||
|
questarr:
|
||||||
|
subdomain: "questarr"
|
||||||
|
host: "10.0.2.25"
|
||||||
|
port: 5000
|
||||||
|
internal: true
|
||||||
|
|
||||||
# infra
|
# infra
|
||||||
komodo:
|
komodo:
|
||||||
subdomain: "komodo"
|
subdomain: "komodo"
|
||||||
host: "10.0.4.10"
|
host: "10.0.4.10"
|
||||||
port: 9120
|
port: 9120
|
||||||
auth_required: true
|
internal: true
|
||||||
|
|
||||||
homeassistant:
|
homeassistant:
|
||||||
subdomain: "homeassistant"
|
subdomain: "homeassistant"
|
||||||
host: "10.0.2.100"
|
host: "10.0.2.100"
|
||||||
port: 8123
|
port: 8123
|
||||||
auth_required: false
|
internal: false
|
||||||
|
|
||||||
# media
|
# media
|
||||||
plex:
|
plex:
|
||||||
subdomain: "plex"
|
subdomain: "plex"
|
||||||
host: "10.0.2.10"
|
host: "10.0.2.10"
|
||||||
port: 32400
|
port: 32400
|
||||||
auth_required: false
|
internal: false
|
||||||
tracearr:
|
tracearr:
|
||||||
subdomain: "tracearr"
|
subdomain: "tracearr"
|
||||||
host: "10.0.2.21"
|
host: "10.0.2.21"
|
||||||
port: 3000
|
port: 3000
|
||||||
auth_required: true
|
internal: true
|
||||||
|
jellyfin:
|
||||||
|
subdomain: "jellyfin"
|
||||||
|
host: "10.0.2.11"
|
||||||
|
port: 8096
|
||||||
|
internal: true
|
||||||
|
|
||||||
vaultwarden:
|
vaultwarden:
|
||||||
subdomain: "pwds"
|
subdomain: "pwds"
|
||||||
host: "10.0.2.27"
|
host: "10.0.2.27"
|
||||||
port: 8004
|
port: 8004
|
||||||
auth_required: false
|
internal: false
|
||||||
changedetection:
|
changedetection:
|
||||||
subdomain: "changedetection"
|
subdomain: "changedetection"
|
||||||
host: "10.0.2.24"
|
host: "10.0.2.24"
|
||||||
port: 5000
|
port: 5000
|
||||||
auth_required: true
|
internal: true
|
||||||
nextcloud:
|
nextcloud:
|
||||||
subdomain: "cloud"
|
subdomain: "cloud"
|
||||||
host: "10.0.2.30"
|
host: "10.0.2.30"
|
||||||
port: 8001
|
port: 8001
|
||||||
auth_required: false
|
internal: false
|
||||||
convertx:
|
convertx:
|
||||||
subdomain: "convertx"
|
subdomain: "convertx"
|
||||||
host: "10.0.2.43"
|
host: "10.0.2.43"
|
||||||
port: 3000
|
port: 3000
|
||||||
auth_required: true
|
internal: true
|
||||||
dawarich:
|
dawarich:
|
||||||
subdomain: "places"
|
subdomain: "places"
|
||||||
host: "10.0.2.48"
|
host: "10.0.2.48"
|
||||||
port: 3000
|
port: 3000
|
||||||
auth_required: false
|
internal: false
|
||||||
frigate:
|
frigate:
|
||||||
subdomain: "frigate"
|
subdomain: "frigate"
|
||||||
host: "10.0.2.14"
|
host: "10.0.2.14"
|
||||||
port: 5000
|
port: 5000
|
||||||
auth_required: true
|
internal: true
|
||||||
droposs:
|
droposs:
|
||||||
subdomain: "games"
|
subdomain: "games"
|
||||||
host: "10.0.2.46"
|
host: "10.0.2.46"
|
||||||
port: 3000
|
port: 3000
|
||||||
auth_required: false
|
internal: false
|
||||||
# geoguessr:
|
|
||||||
# subdomain: "geoguessr"
|
|
||||||
# host: "10.0.2.39"
|
|
||||||
# port: 8080
|
|
||||||
# auth_required: true
|
|
||||||
gitea:
|
gitea:
|
||||||
subdomain: "gitea"
|
subdomain: "gitea"
|
||||||
host: "10.0.2.28"
|
host: "10.0.2.28"
|
||||||
port: 3000
|
port: 3000
|
||||||
auth_required: true
|
internal: false
|
||||||
|
forgejo:
|
||||||
|
subdomain: "git"
|
||||||
|
host: "10.0.4.30"
|
||||||
|
port: 8086
|
||||||
|
internal: false
|
||||||
immich:
|
immich:
|
||||||
subdomain: "immich"
|
subdomain: "immich"
|
||||||
host: "10.0.2.18"
|
host: "10.0.2.18"
|
||||||
port: 2283
|
port: 2283
|
||||||
auth_required: false
|
internal: false
|
||||||
mastodon:
|
mastodon:
|
||||||
subdomain: "social"
|
subdomain: "social"
|
||||||
host: "10.0.2.20"
|
host: "10.0.2.20"
|
||||||
port: 80
|
port: 80
|
||||||
auth_required: false
|
internal: false
|
||||||
forward_https: true
|
forward_https: true
|
||||||
matrix:
|
matrix:
|
||||||
subdomain: "chat"
|
subdomain: "chat"
|
||||||
host: "10.0.2.20"
|
host: "10.0.2.20"
|
||||||
port: 8008
|
port: 8008
|
||||||
auth_required: false
|
internal: false
|
||||||
mealie:
|
mealie:
|
||||||
subdomain: "recipes"
|
subdomain: "recipes"
|
||||||
host: "10.0.2.26"
|
host: "10.0.2.26"
|
||||||
port: 9000
|
port: 9000
|
||||||
auth_required: false
|
internal: false
|
||||||
truenas:
|
truenas:
|
||||||
subdomain: "nas"
|
subdomain: "nas"
|
||||||
host: "10.0.2.200"
|
host: "10.0.2.200"
|
||||||
port: 80
|
port: 80
|
||||||
auth_required: true
|
internal: true
|
||||||
paperless:
|
paperless:
|
||||||
subdomain: "paperless"
|
subdomain: "paperless"
|
||||||
host: "10.0.2.29"
|
host: "10.0.2.29"
|
||||||
port: 8003
|
port: 8003
|
||||||
auth_required: true
|
internal: true
|
||||||
pbs:
|
pbs:
|
||||||
subdomain: "pbs"
|
subdomain: "pbs"
|
||||||
host: "10.0.2.104"
|
host: "10.0.2.104"
|
||||||
port: 8007
|
port: 8007
|
||||||
https: true
|
https: true
|
||||||
auth_required: true
|
internal: true
|
||||||
# pinchflat:
|
# pinchflat:
|
||||||
# subdomain: "youtube"
|
# subdomain: "youtube"
|
||||||
# host: "10.0.2.23"
|
# host: "10.0.2.23"
|
||||||
# port: 8081
|
# port: 8081
|
||||||
# auth_required: true
|
# internal: true
|
||||||
proxmox:
|
proxmox:
|
||||||
subdomain: "proxmox"
|
subdomain: "proxmox"
|
||||||
host: "10.0.2.2"
|
host: "10.0.2.2"
|
||||||
port: 8006
|
port: 8006
|
||||||
https: true
|
https: true
|
||||||
auth_required: true
|
internal: true
|
||||||
resume:
|
resume:
|
||||||
subdomain: "resume"
|
subdomain: "resume"
|
||||||
host: "10.0.2.53"
|
host: "10.0.2.53"
|
||||||
port: 3000
|
port: 3000
|
||||||
auth_required: true
|
internal: true
|
||||||
auth_bypass_paths:
|
auth_bypass_paths:
|
||||||
- /lino
|
- /lino
|
||||||
- /assets
|
- /assets
|
||||||
- /api
|
- /api
|
||||||
speedtest-tracker:
|
speedtest-tracker:
|
||||||
subdomain: "fast"
|
subdomain: "fast"
|
||||||
host: "10.0.2.15"
|
host: "10.0.4.30"
|
||||||
port: 8765
|
port: 8085
|
||||||
auth_required: true
|
internal: true
|
||||||
stocks:
|
stocks:
|
||||||
subdomain: "stocks"
|
subdomain: "stocks"
|
||||||
host: "10.0.2.40"
|
host: "10.0.2.40"
|
||||||
port: 3333
|
port: 3333
|
||||||
auth_required: false
|
internal: false
|
||||||
super-productivity:
|
super-productivity:
|
||||||
subdomain: "tasks"
|
subdomain: "tasks"
|
||||||
host: "10.0.2.45"
|
host: "10.0.2.45"
|
||||||
port: 80
|
port: 80
|
||||||
auth_required: true
|
internal: true
|
||||||
uptime-kuma:
|
uptime-kuma:
|
||||||
subdomain: "uptime"
|
subdomain: "uptime"
|
||||||
host: "10.0.2.203"
|
host: "10.0.2.203"
|
||||||
port: 3001
|
port: 3001
|
||||||
auth_required: true
|
internal: true
|
||||||
wealthfolio:
|
wealthfolio:
|
||||||
subdomain: "wealth"
|
subdomain: "wealth"
|
||||||
host: "10.0.2.40"
|
host: "10.0.2.40"
|
||||||
port: 8088
|
port: 8088
|
||||||
auth_required: true
|
internal: false
|
||||||
|
trek:
|
||||||
|
subdomain: "trips"
|
||||||
|
host: "10.0.4.30"
|
||||||
|
port: 8083
|
||||||
|
internal: true
|
||||||
|
homelable:
|
||||||
|
subdomain: "infra"
|
||||||
|
host: "10.0.4.30"
|
||||||
|
port: 8084
|
||||||
|
internal: true
|
||||||
|
price-tracker:
|
||||||
|
subdomain: "prices"
|
||||||
|
host: "10.0.4.30"
|
||||||
|
port: 3000
|
||||||
|
internal: true
|
||||||
|
kvm:
|
||||||
|
subdomain: "kvm"
|
||||||
|
host: "10.0.3.1"
|
||||||
|
port: 80
|
||||||
|
internal: true
|
||||||
|
forward_https: true
|
||||||
|
|
||||||
# Auth services configuration
|
# Auth services configuration
|
||||||
pocketid_host: 10.0.4.10
|
pocketid_host: 10.0.4.10
|
||||||
@@ -242,4 +273,4 @@ komodo_db_password: "{{ vault_komodo_db_password }}"
|
|||||||
komodo_webhook_secret: "{{ vault_komodo_webhook_secret }}"
|
komodo_webhook_secret: "{{ vault_komodo_webhook_secret }}"
|
||||||
komodo_jwt_secret: "{{ vault_komodo_jwt_secret }}"
|
komodo_jwt_secret: "{{ vault_komodo_jwt_secret }}"
|
||||||
komodo_onboarding_key: "{{ vault_komodo_onboarding_key }}"
|
komodo_onboarding_key: "{{ vault_komodo_onboarding_key }}"
|
||||||
komodo_core_address: "komodo.lino.cooking"
|
komodo_core_host: "10.0.4.10:9120"
|
||||||
|
|||||||
@@ -1,46 +1,53 @@
|
|||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
34633839643463656436373363623239343634393834353863336665613863663464316636343564
|
63666330376531356135326331306565336237626132383934313666636134366436383831393730
|
||||||
6561613766613735303865363339326563363961343739370a626535346366366261666131653565
|
3330643462346434663536383231646364613963373833360a386237306230636131313464363636
|
||||||
39653832326235353662656466626132383531613338653138363039633563313536313765333166
|
66383366616436633538363430383530613635333462383431643438643962633833363632366438
|
||||||
6265343938386332340a313230353564653739633939363031623130316265373538333237343133
|
3063323965363031360a353662366435323263356235333633306161363664373738313830333562
|
||||||
39303831303230323738383565303335363763353462353966643832626131646436336434323138
|
36383637363465396161313332316262383132313061356461626331623134653136353566333539
|
||||||
66636635326634383137376431323736613434656533633664383161393338326565336130303930
|
39626662663539303337306662666131653738633666393434336338616561353061316132653666
|
||||||
31303232393332623839323162373239616634356434643364323933613335363861343738313661
|
39313537636561396466646366653366663134386564643036613465623061323261343532373037
|
||||||
63306435303962323566346564383066636634663536646264383961343461623236386362336239
|
39663931326339636533323631333661643736663066643262383766623163333234336364626165
|
||||||
36316536346533626438366430363664383135346337303239643335656261626639323433313765
|
36333536313332613966303838393262616335343563643965363664653334613330356134353362
|
||||||
33613564626235323337343164346235336663613238323966346331623266613832633234393232
|
30643636323661666463393564393434383436346636616333626464306261346337623063306136
|
||||||
39393565383235373365353538373764333433386439333132643064373839643963376333373032
|
33353034386566323366343739626533323735333638313261336666663964633665313962383364
|
||||||
34613361663630323937333162373534356263373861363163303062363232663731316164653966
|
65326536333462303637376265366532623435336363346230366631313663366234616436363161
|
||||||
39346163353635663738316262363465643639313766346339333963333964336265303666643064
|
65663932303138623865306163656464613039643936313532396135393966333632333235636461
|
||||||
62643366613034663838326436313739363863316666393238306564306539623162636266393033
|
65656636666339303365663766323434633032376561333939306336643563653832306362313134
|
||||||
39653438663938346233656630366130316161373363393561663631663737373131383736666136
|
64616438393235623964356132626231646539333065663334346139353232663263323331643064
|
||||||
66346231663338643735313739343361643431396638613837303833616539373261346163306132
|
35636563613836376666643664636265626530363235373265306163386331633631313161346133
|
||||||
39656436626635633733396138303963343135343437313637346565643835613739653839343938
|
64633038306335373236646632356238343763636433623938373064383834346361316232643830
|
||||||
61623561303930306335383963393561393735316331323639373536616236383532366136653134
|
64316663653638386466313336666164343036373231623066663033336365303934626236633238
|
||||||
63366661363332366338656234386139363066363239656136383634623430303262626465356536
|
62643032303863366436313934316563346364383536636236633232656164643032653530376665
|
||||||
34303862303763613761616134323236316232373931386336653034633230396633363965313331
|
30326639646632346638636232626431396536346165656539343535313266666665336366373333
|
||||||
31666234363064323331666535316134623461663433366538613133396633353161323766363437
|
31333930656330653031656236316261663366396434353063663831643464663134623063386333
|
||||||
66396439303235313137393135383837323737663731386331376362613964323737366633623733
|
37386431393336396362373834303135663631343366666333613331333136303134656231343530
|
||||||
31353261306163356333303333393466643338343765323637656565333762386133363031396638
|
64316562663362656662613932393136383837666666316438393235316666323063373732666334
|
||||||
34386639393133303134383034316439363262386461346534326236326135623964363461646430
|
38356162396630363430633166306566626131643734636536633264336632323734333163306535
|
||||||
33623433306130393232353135623332396136653230383439333665303737343137383864356433
|
36633965376362373733616635656565636164636562386566643231363835656634343235373838
|
||||||
37313262383961656133393731656162316433356336336530333862363561353238663433343131
|
34333730353935643935626366656133353330316165633835626333663539623665653662353138
|
||||||
32353862363863343666383766363135663736613332313438356366303332326632653961313762
|
61363230303634653131356563376263363339613265373534383561313932616635643038363266
|
||||||
34363230633461616461373536366239313962616565396566316139393466303332643265353835
|
31663835643830666363646635346538656665363730396366643439326537386264663666363332
|
||||||
35356364343734663963303839363733393730633262643438336562643733623966663130353635
|
64363561623031626531663934636634313536653435663431666463386362306331353137396362
|
||||||
38363833633936363164313239323265623332643539356532623636383232323538386431653165
|
65653039623636316338326335613164376366613266316134386163626436383539393932666436
|
||||||
31353138666537616565646239303165376439373063356663316664356564323961613039663061
|
33633264653230663065393632653935633833313233373933326464316331646363613832633330
|
||||||
62336261306532386136616465383265613262363936633164373236353238633463303939623133
|
30353263343433366362323365386536313535396430373966323337623830373465356437643734
|
||||||
65313335653935346364383232373261666334663634373938353861383561613936393339366530
|
32313038323664376566656666633364363634613033376636326635343233666134363864343634
|
||||||
34303961373561303031323834663466346436383966373530633430333536373833383166313938
|
65386538663835663539353533633931323837373738393463336337353865616439336537353933
|
||||||
31376531366166333762623233646433323134663366323730613932393333333737623463653634
|
32353162363166353265316534643764616132656534666463363439643237396166303833303038
|
||||||
31356466646465333666363034343730313164353039646236393564326536323330363639343664
|
66383236363738336363643832666130633464333536623134616265316663333237383739336537
|
||||||
39363836663332333234396239336339356532626430653861373137333562623830653936323432
|
37376331326139633764353166656634323339656435663531313934376565393639316531663237
|
||||||
34306238623137313232333033356266303564376163333065653137616661643537373831666136
|
64303931386461346632646161393061376534393539663966373562646432386134616435363261
|
||||||
39303037383661313064396364363639346564643564303638623661356235336162633633616531
|
37356466303165356336626134313135353830316536323165323233613235643733643333613636
|
||||||
34626331393564363564613937346165333936366231333462633561356362616434306165343130
|
63666139323931616166346566396162373637336331393034623631346437643632643938323834
|
||||||
62346665653532663434396238366562336264656130643566666466313964303066373462373034
|
35383862653464643533663333616263633465663939633064653666353363363830393565666236
|
||||||
32613434363832626265636234343535313438313532643631363633363335653364393564356632
|
31333663663332363533336132346666643734623131643339643865633565393262643966393734
|
||||||
37613135343632613433616630333163323230333235363531343966333232646664393163386238
|
36663533313638386166653334623832323363636262373931356664323766666538343838313039
|
||||||
36613731656666663236316133353237636363663336656162316163393230346565366536376236
|
39393765343430633336373966346161393130386539393366363366366163316363613038613962
|
||||||
6336
|
36646336396333333863326565303666373963326163393434313534333533323739623035323137
|
||||||
|
32346535383263316332653239306633343935383166653139323036616133656638643532646634
|
||||||
|
64333466666533363932323366353762653461336538303166626330333336616437613037363139
|
||||||
|
63303764313330656366363630636463303461383565346262656136326362623839366531326663
|
||||||
|
34663534343564313030613366626337336331343637343564386638653530663631613234636237
|
||||||
|
37373064303137666263666133363865386135333038653231346562333131313233643062376265
|
||||||
|
34646635663961393837396637383834376136323864646166656436383338623364613861663537
|
||||||
|
39313230306465626630
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ vms:
|
|||||||
network_bridge: "vmbr2"
|
network_bridge: "vmbr2"
|
||||||
storage: nvme-2tb
|
storage: nvme-2tb
|
||||||
|
|
||||||
|
apps-2:
|
||||||
|
vmid: 431
|
||||||
|
node: yuga
|
||||||
|
template_vmid: 9004
|
||||||
|
cores: 5
|
||||||
|
memory: 12288
|
||||||
|
disk: 30G
|
||||||
|
ip: 10.0.4.31
|
||||||
|
network_bridge: "vmbr0"
|
||||||
|
storage: media
|
||||||
|
|
||||||
edge-1:
|
edge-1:
|
||||||
vmid: 401
|
vmid: 401
|
||||||
node: mipha
|
node: mipha
|
||||||
|
|||||||
@@ -6,5 +6,3 @@ keepalived_interface: eth0
|
|||||||
keepalived_router_id: 51
|
keepalived_router_id: 51
|
||||||
keepalived_vip: 10.0.4.254
|
keepalived_vip: 10.0.4.254
|
||||||
keepalived_password: "{{ vault_keepalived_password | default('changeme') }}"
|
keepalived_password: "{{ vault_keepalived_password | default('changeme') }}"
|
||||||
|
|
||||||
komodo_core_address: "10.0.4.10:9120"
|
|
||||||
|
|||||||
@@ -6,5 +6,3 @@ keepalived_interface: eth0
|
|||||||
keepalived_router_id: 51
|
keepalived_router_id: 51
|
||||||
keepalived_vip: 10.0.4.254
|
keepalived_vip: 10.0.4.254
|
||||||
keepalived_password: "{{ vault_keepalived_password | default('changeme') }}"
|
keepalived_password: "{{ vault_keepalived_password | default('changeme') }}"
|
||||||
|
|
||||||
komodo_core_address: "10.0.4.10:9120"
|
|
||||||
|
|||||||
@@ -22,3 +22,5 @@ all:
|
|||||||
hosts:
|
hosts:
|
||||||
apps-1:
|
apps-1:
|
||||||
ansible_host: 10.0.4.30
|
ansible_host: 10.0.4.30
|
||||||
|
apps-2:
|
||||||
|
ansible_host: 10.0.4.31
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
---
|
---
|
||||||
|
# NOTE: Adding a komodo-periphery role to an edge means you need to
|
||||||
|
# create an onboarding key on Komodo and change its value on
|
||||||
|
# the vault
|
||||||
|
|
||||||
- hosts: infra
|
- hosts: infra
|
||||||
become: yes
|
become: yes
|
||||||
roles:
|
roles:
|
||||||
@@ -25,7 +29,16 @@
|
|||||||
- docker
|
- docker
|
||||||
- komodo-periphery
|
- komodo-periphery
|
||||||
|
|
||||||
- hosts: apps
|
- hosts: apps-1
|
||||||
|
become: yes
|
||||||
|
roles:
|
||||||
|
- base
|
||||||
|
- docker
|
||||||
|
- komodo-periphery
|
||||||
|
- trek
|
||||||
|
- forgejo
|
||||||
|
|
||||||
|
- hosts: apps-2
|
||||||
become: yes
|
become: yes
|
||||||
roles:
|
roles:
|
||||||
- base
|
- base
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
# Playbook to provision Komodo stacks from git repository
|
||||||
|
# Automatically discovers stacks from docker-compose folder structure
|
||||||
|
# Structure: docker-compose/{server}/{app}/compose.yaml
|
||||||
|
# Usage: ansible-playbook -i inventories/production.yml playbooks/provision_komodo_stacks.yml
|
||||||
|
|
||||||
|
- name: Provision Komodo stacks
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
docker_compose_root: "{{ playbook_dir }}/../../docker-compose"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Find all compose.yaml files in docker-compose directory
|
||||||
|
find:
|
||||||
|
paths: "{{ docker_compose_root }}"
|
||||||
|
patterns: "compose.yaml"
|
||||||
|
recurse: true
|
||||||
|
register: compose_files
|
||||||
|
|
||||||
|
- name: Build stack list from discovered compose files
|
||||||
|
set_fact:
|
||||||
|
komodo_stacks: "{{ komodo_stacks | default([]) + [{'server': path_parts[0], 'app': path_parts[1]}] }}"
|
||||||
|
loop: "{{ compose_files.files }}"
|
||||||
|
vars:
|
||||||
|
path_parts: "{{ item.path | regex_replace('^.*/docker-compose/', '') | split('/') }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ path_parts[0] }}/{{ path_parts[1] }}"
|
||||||
|
|
||||||
|
- name: Display discovered stacks
|
||||||
|
debug:
|
||||||
|
msg: "Found {{ komodo_stacks | length }} stacks: {{ komodo_stacks | map(attribute='app') | list | join(', ') }}"
|
||||||
|
|
||||||
|
- name: Create Komodo stacks
|
||||||
|
include_role:
|
||||||
|
name: komodo_stack
|
||||||
|
vars:
|
||||||
|
komodo_stack_name: "{{ item.app }}"
|
||||||
|
komodo_server_name: "{{ item.server }}"
|
||||||
|
komodo_run_directory: "docker-compose/{{ item.server }}/{{ item.app }}"
|
||||||
|
loop: "{{ komodo_stacks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.app }} (on {{ item.server }})"
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
- name: Add data disk to VM for forgejo
|
||||||
|
community.proxmox.proxmox_disk:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
vmid: "{{ app_data_disks.forgejo.vmid }}"
|
||||||
|
disk: "{{ app_data_disks.forgejo.disk_id }}"
|
||||||
|
storage: "{{ app_data_disks.forgejo.storage }}"
|
||||||
|
size: "{{ app_data_disks.forgejo.size }}"
|
||||||
|
state: present
|
||||||
|
delegate_to: localhost
|
||||||
|
become: no
|
||||||
|
run_once: true
|
||||||
|
ignore_errors: yes
|
||||||
|
register: disk_result
|
||||||
|
|
||||||
|
- name: Display disk creation result
|
||||||
|
debug:
|
||||||
|
var: disk_result
|
||||||
|
|
||||||
|
- name: Wait for data disk to be available
|
||||||
|
wait_for:
|
||||||
|
path: "{{ app_data_disks.forgejo.device }}"
|
||||||
|
state: present
|
||||||
|
timeout: 30
|
||||||
|
|
||||||
|
- name: Check if data disk is formatted
|
||||||
|
command: "blkid {{ app_data_disks.forgejo.device }}"
|
||||||
|
register: disk_formatted
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Format data disk with ext4
|
||||||
|
filesystem:
|
||||||
|
fstype: ext4
|
||||||
|
dev: "{{ app_data_disks.forgejo.device }}"
|
||||||
|
when: disk_formatted.rc != 0
|
||||||
|
|
||||||
|
- name: Create forgejo data mount point
|
||||||
|
file:
|
||||||
|
path: "{{ app_data_disks.forgejo.mount_point }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Mount data disk
|
||||||
|
mount:
|
||||||
|
path: "{{ app_data_disks.forgejo.mount_point }}"
|
||||||
|
src: "{{ app_data_disks.forgejo.device }}"
|
||||||
|
fstype: ext4
|
||||||
|
state: mounted
|
||||||
|
opts: defaults
|
||||||
@@ -5,7 +5,7 @@ services:
|
|||||||
container_name: komodo-periphery
|
container_name: komodo-periphery
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
PERIPHERY_CORE_ADDRESS: {{ komodo_core_address }}
|
PERIPHERY_CORE_ADDRESS: {{ komodo_core_host }}
|
||||||
PERIPHERY_CONNECT_AS: {{ inventory_hostname }}
|
PERIPHERY_CONNECT_AS: {{ inventory_hostname }}
|
||||||
PERIPHERY_CORE_PUBLIC_KEYS: file:/config/keys/core.pub
|
PERIPHERY_CORE_PUBLIC_KEYS: file:/config/keys/core.pub
|
||||||
PERIPHERY_ROOT_DIRECTORY: /etc/komodo
|
PERIPHERY_ROOT_DIRECTORY: /etc/komodo
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# Komodo Stack Role
|
||||||
|
|
||||||
|
This role automates the creation of stacks in Komodo via its REST API.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
The included `provision_komodo_stacks.yml` playbook automatically discovers all stacks from your `docker-compose/` folder structure and creates them in Komodo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventories/production.yml playbooks/provision_komodo_stacks.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This will scan for all `compose.yaml` files in the structure: `docker-compose/{server}/{app}/compose.yaml` and create corresponding stacks in Komodo.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- A running Komodo instance with API access
|
||||||
|
- Valid Komodo API token stored in `vault_komodo_api_token`
|
||||||
|
- Existing server and repository configured in Komodo
|
||||||
|
|
||||||
|
## Role Variables
|
||||||
|
|
||||||
|
### Required Variables
|
||||||
|
|
||||||
|
- `komodo_stack_name`: Name for the stack (typically the app name, e.g., "changedetection")
|
||||||
|
- `komodo_server_name`: Name of the server in Komodo where the stack should deploy
|
||||||
|
- `komodo_repo_name`: Name of the repository in Komodo containing the stack definition
|
||||||
|
- `komodo_run_directory`: Path within the repository to the compose.yaml file (e.g., `docker-compose/apps-1/changedetection`)
|
||||||
|
|
||||||
|
### Optional Variables
|
||||||
|
|
||||||
|
- `komodo_host`: Komodo instance URL (default: `https://komodo.{{ domain }}`)
|
||||||
|
- `komodo_api_token`: API token for authentication (default: `{{ vault_komodo_api_token }}`)
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
### Automatic Discovery (Recommended)
|
||||||
|
|
||||||
|
Use the provided playbook to automatically discover and create all stacks from your repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventories/production.yml playbooks/provision_komodo_stacks.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This scans the `docker-compose/` directory and creates stacks for each app found in the structure:
|
||||||
|
|
||||||
|
- `docker-compose/{server}/{app}/compose.yaml`
|
||||||
|
|
||||||
|
Example structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker-compose/
|
||||||
|
apps-1/
|
||||||
|
changedetection/
|
||||||
|
compose.yaml
|
||||||
|
turn/
|
||||||
|
compose.yaml
|
||||||
|
media-1/
|
||||||
|
arr/
|
||||||
|
compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
1. Validates all required variables are provided
|
||||||
|
2. Fetches list of servers from Komodo API and finds the server ID by name
|
||||||
|
3. Fetches list of repositories from Komodo API and finds the repo ID by name
|
||||||
|
4. Checks if a stack with the same name already exists
|
||||||
|
5. Creates the stack if it doesn't exist (skips if it does)
|
||||||
|
|
||||||
|
## API Token Setup
|
||||||
|
|
||||||
|
Store your Komodo API token in an Ansible vault file:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# inventories/group_vars/all/vault.yml
|
||||||
|
vault_komodo_api_token: 'your-api-token-here'
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate an API token in Komodo: Settings → API Keys → Create New Token
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The role is idempotent - it won't create duplicate stacks
|
||||||
|
- Server and repo must already exist in Komodo before running this role
|
||||||
|
- Uses retry logic for API calls to handle temporary network issues
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
# Komodo API configuration
|
||||||
|
komodo_core_address: "http://{{ komodo_core_host }}"
|
||||||
|
|
||||||
|
komodo_api_key: "{{ vault_komodo_api_key }}"
|
||||||
|
komodo_api_secret: "{{ vault_komodo_api_secret }}"
|
||||||
|
|
||||||
|
# Stack configuration
|
||||||
|
komodo_repo_name: "homelab"
|
||||||
|
|
||||||
|
# Optional stack configuration
|
||||||
|
komodo_stack_environment: []
|
||||||
|
komodo_stack_labels: {}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
---
|
||||||
|
- name: Validate required variables
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- komodo_stack_name is defined and komodo_stack_name | length > 0
|
||||||
|
- komodo_server_name is defined and komodo_server_name | length > 0
|
||||||
|
- komodo_repo_name is defined and komodo_repo_name | length > 0
|
||||||
|
- komodo_run_directory is defined and komodo_run_directory | length > 0
|
||||||
|
- komodo_api_key is defined and komodo_api_key | length > 0
|
||||||
|
- komodo_api_secret is defined and komodo_api_secret | length > 0
|
||||||
|
fail_msg: "Missing required variables: komodo_stack_name, komodo_server_name, komodo_repo_name, komodo_run_directory, komodo_api_key, or komodo_api_secret"
|
||||||
|
|
||||||
|
- name: Get Komodo server by name
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/read/GetServer"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
server: "{{ komodo_server_name }}"
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
|
register: komodo_server
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
|
||||||
|
- name: Extract server ID
|
||||||
|
set_fact:
|
||||||
|
komodo_server_id: "{{ komodo_server.json._id['$oid'] }}"
|
||||||
|
|
||||||
|
- name: Debug server response
|
||||||
|
debug:
|
||||||
|
msg: "Server ID: {{ komodo_server_id }}"
|
||||||
|
|
||||||
|
- name: Get Komodo repo by name
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/read/GetRepo"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
repo: "{{ komodo_repo_name }}"
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
|
register: komodo_repo
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
|
||||||
|
- name: Extract repo ID
|
||||||
|
set_fact:
|
||||||
|
komodo_repo_id: "{{ komodo_repo.json._id['$oid'] }}"
|
||||||
|
|
||||||
|
- name: Debug repo response
|
||||||
|
debug:
|
||||||
|
msg: "Repo ID: {{ komodo_repo_id }}"
|
||||||
|
|
||||||
|
- name: Check if stack already exists
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/read/GetStack"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
stack: "{{ komodo_stack_name }}"
|
||||||
|
status_code: [200, 500]
|
||||||
|
validate_certs: false
|
||||||
|
register: existing_stack
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Create Komodo stack
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/write/CreateStack"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
name: "{{ komodo_stack_name }}"
|
||||||
|
config:
|
||||||
|
server_id: "{{ komodo_server_id }}"
|
||||||
|
linked_repo: "{{ komodo_repo_id }}"
|
||||||
|
run_directory: "{{ komodo_run_directory }}"
|
||||||
|
status_code: [200, 201]
|
||||||
|
validate_certs: false
|
||||||
|
register: stack_result
|
||||||
|
when: existing_stack.status == 500
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
|
||||||
|
- name: Display stack creation result
|
||||||
|
debug:
|
||||||
|
msg: "Stack '{{ komodo_stack_name }}' created successfully with ID: {{ stack_result.json._id }}"
|
||||||
|
when: existing_stack.status == 500 and stack_result is succeeded
|
||||||
|
|
||||||
|
- name: Display stack already exists message
|
||||||
|
debug:
|
||||||
|
msg: "Stack '{{ komodo_stack_name }}' already exists with ID: {{ existing_stack.json._id }}"
|
||||||
|
when: existing_stack.status == 200
|
||||||
|
|
||||||
|
- name: Deploy stack
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/execute/DeployStack"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
stack: "{{ komodo_stack_name }}"
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
|
register: start_result
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
when: existing_stack.status == 500 and stack_result is succeeded
|
||||||
@@ -36,6 +36,16 @@ http:
|
|||||||
insecureSkipVerify: true
|
insecureSkipVerify: true
|
||||||
|
|
||||||
routers:
|
routers:
|
||||||
|
# Local IP bypass - HTTPS (higher priority, no auth)
|
||||||
|
traefik-secure-local:
|
||||||
|
rule: "Host(`traefik.{{ domain }}`) && (ClientIP(`192.168.0.0/16`) || ClientIP(`10.0.0.0/8`) || ClientIP(`172.16.0.0/12`))"
|
||||||
|
entryPoints:
|
||||||
|
- https
|
||||||
|
priority: 200
|
||||||
|
service: api@internal
|
||||||
|
tls:
|
||||||
|
certResolver: cloudflare
|
||||||
|
|
||||||
# Static services - HTTPS
|
# Static services - HTTPS
|
||||||
traefik-secure:
|
traefik-secure:
|
||||||
rule: "Host(`traefik.{{ domain }}`)"
|
rule: "Host(`traefik.{{ domain }}`)"
|
||||||
@@ -106,6 +116,21 @@ http:
|
|||||||
|
|
||||||
# Auto-configured services - HTTPS
|
# Auto-configured services - HTTPS
|
||||||
{% for service_name, config in auto_configure_traefik.items() %}
|
{% for service_name, config in auto_configure_traefik.items() %}
|
||||||
|
{% if config.internal | default(true) %}
|
||||||
|
# {{ service_name }} - local IP bypass (no auth)
|
||||||
|
{{ service_name }}-local:
|
||||||
|
rule: "Host(`{{ config.subdomain }}.{{ domain }}`) && (ClientIP(`192.168.0.0/16`) || ClientIP(`10.0.0.0/8`) || ClientIP(`172.16.0.0/12`))"
|
||||||
|
entryPoints:
|
||||||
|
- https
|
||||||
|
priority: 200
|
||||||
|
{% if config.forward_https | default(false) %}
|
||||||
|
middlewares:
|
||||||
|
- {{ service_name }}-https-headers
|
||||||
|
{% endif %}
|
||||||
|
service: {{ service_name }}
|
||||||
|
tls:
|
||||||
|
certResolver: cloudflare
|
||||||
|
{% endif %}
|
||||||
{% if config.auth_bypass_paths is defined %}
|
{% if config.auth_bypass_paths is defined %}
|
||||||
# {{ service_name }} - bypass paths (no auth)
|
# {{ service_name }} - bypass paths (no auth)
|
||||||
{% for path in config.auth_bypass_paths %}
|
{% for path in config.auth_bypass_paths %}
|
||||||
@@ -128,9 +153,9 @@ http:
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- https
|
- https
|
||||||
priority: 1
|
priority: 1
|
||||||
{% if config.auth_required | default(true) or config.forward_https | default(false) %}
|
{% if config.internal | default(true) or config.forward_https | default(false) %}
|
||||||
middlewares:
|
middlewares:
|
||||||
{% if config.auth_required | default(true) %}
|
{% if config.internal | default(true) %}
|
||||||
- pocketid-auth
|
- pocketid-auth
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if config.forward_https | default(false) %}
|
{% if config.forward_https | default(false) %}
|
||||||
@@ -145,9 +170,9 @@ http:
|
|||||||
rule: "Host(`{{ config.subdomain }}.{{ domain }}`)"
|
rule: "Host(`{{ config.subdomain }}.{{ domain }}`)"
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- https
|
- https
|
||||||
{% if config.auth_required | default(true) or config.forward_https | default(false) %}
|
{% if config.internal | default(true) or config.forward_https | default(false) %}
|
||||||
middlewares:
|
middlewares:
|
||||||
{% if config.auth_required | default(true) %}
|
{% if config.internal | default(true) %}
|
||||||
- pocketid-auth
|
- pocketid-auth
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if config.forward_https | default(false) %}
|
{% if config.forward_https | default(false) %}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
- name: Add data disk to VM for trek
|
||||||
|
community.proxmox.proxmox_disk:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
vmid: "{{ app_data_disks.trek.vmid }}"
|
||||||
|
disk: "{{ app_data_disks.trek.disk_id }}"
|
||||||
|
storage: "{{ app_data_disks.trek.storage }}"
|
||||||
|
size: "{{ app_data_disks.trek.size }}"
|
||||||
|
state: present
|
||||||
|
delegate_to: localhost
|
||||||
|
become: no
|
||||||
|
run_once: true
|
||||||
|
ignore_errors: yes
|
||||||
|
register: disk_result
|
||||||
|
|
||||||
|
- name: Display disk creation result
|
||||||
|
debug:
|
||||||
|
var: disk_result
|
||||||
|
|
||||||
|
- name: Wait for data disk to be available
|
||||||
|
wait_for:
|
||||||
|
path: "{{ app_data_disks.trek.device }}"
|
||||||
|
state: present
|
||||||
|
timeout: 30
|
||||||
|
|
||||||
|
- name: Check if data disk is formatted
|
||||||
|
command: "blkid {{ app_data_disks.trek.device }}"
|
||||||
|
register: disk_formatted
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Format data disk with ext4
|
||||||
|
filesystem:
|
||||||
|
fstype: ext4
|
||||||
|
dev: "{{ app_data_disks.trek.device }}"
|
||||||
|
when: disk_formatted.rc != 0
|
||||||
|
|
||||||
|
- name: Create trek data mount point
|
||||||
|
file:
|
||||||
|
path: "{{ app_data_disks.trek.mount_point }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Mount data disk
|
||||||
|
mount:
|
||||||
|
path: "{{ app_data_disks.trek.mount_point }}"
|
||||||
|
src: "{{ app_data_disks.trek.device }}"
|
||||||
|
fstype: ext4
|
||||||
|
state: mounted
|
||||||
|
opts: defaults
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
services:
|
||||||
|
dahuavto2mqtt:
|
||||||
|
image: "registry.gitlab.com/elad.bar/dahuavto2mqtt:latest"
|
||||||
|
container_name: "dahua2mqtt"
|
||||||
|
hostname: "dahua2mqtt"
|
||||||
|
restart: "unless-stopped"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
services:
|
||||||
|
server:
|
||||||
|
image: codeberg.org/forgejo/forgejo:15
|
||||||
|
container_name: forgejo
|
||||||
|
environment:
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- /data/forgejo:/data
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- "8086:3000"
|
||||||
|
- "222:22"
|
||||||
|
|
||||||
|
docker-in-docker:
|
||||||
|
image: docker:dind
|
||||||
|
container_name: "docker_dind"
|
||||||
|
privileged: "true"
|
||||||
|
command: ["dockerd", "-H", "tcp://0.0.0.0:2375", "--tls=false"]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
|
||||||
|
runner:
|
||||||
|
image: "data.forgejo.org/forgejo/runner:12"
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
depends_on:
|
||||||
|
docker-in-docker:
|
||||||
|
condition: service_started
|
||||||
|
container_name: "runner"
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: tcp://docker-in-docker:2375
|
||||||
|
# User without root privileges, but with access to `./data`.
|
||||||
|
user: 1001:1001
|
||||||
|
volumes:
|
||||||
|
- /data/forgejo/runner:/data
|
||||||
|
restart: "unless-stopped"
|
||||||
|
command: "forgejo-runner daemon --config /data/runner-config.yml"
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
services:
|
||||||
|
backend:
|
||||||
|
image: ghcr.io/pouzor/homelable-backend:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
# Override env_file: SQLite path must point inside the container volume
|
||||||
|
SQLITE_PATH: /app/data/homelab.db
|
||||||
|
volumes:
|
||||||
|
- /data/homelable:/app/data
|
||||||
|
networks:
|
||||||
|
- homelable
|
||||||
|
# Required for ping-based status checks
|
||||||
|
cap_add:
|
||||||
|
- NET_RAW
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 6
|
||||||
|
start_period: 15s
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: ghcr.io/pouzor/homelable-frontend:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8084:80"
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
networks:
|
||||||
|
- homelable
|
||||||
|
|
||||||
|
networks:
|
||||||
|
homelable:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
webserver:
|
||||||
|
image: git.lino.cooking/lino/bpi-stock-price-scraper:latest
|
||||||
|
container_name: price-tracker
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
# SparkyFitness Environment Variables
|
||||||
|
# Copy this file to .env in the root directory and fill in your own values before running 'docker-compose up'.
|
||||||
|
|
||||||
|
# --- PostgreSQL Database Settings ---
|
||||||
|
# These values should match the ones used by your PostgreSQL container.
|
||||||
|
# For local development (running Node.js directly), use 'localhost' or '127.0.0.1' if PostgreSQL is on your host.
|
||||||
|
SPARKY_FITNESS_DB_NAME=sparkyfitness_db
|
||||||
|
#SPARKY_FITNESS_DB_USER is super user for DB initialization and migrations.
|
||||||
|
SPARKY_FITNESS_DB_USER=sparky
|
||||||
|
SPARKY_FITNESS_DB_PASSWORD=changeme_db_password
|
||||||
|
# Application database user with limited privileges. it can be changed any time after initialization.
|
||||||
|
SPARKY_FITNESS_APP_DB_USER=sparky_app
|
||||||
|
SPARKY_FITNESS_APP_DB_PASSWORD=password
|
||||||
|
|
||||||
|
# For Docker Compose deployments, SPARKY_FITNESS_DB_HOST will be the service name (e.g., 'sparkyfitness-db').
|
||||||
|
#SPARKY_FITNESS_DB_HOST=sparkyfitness-db
|
||||||
|
|
||||||
|
# SPARKY_FITNESS_DB_PORT controls the HOST port for external database access (e.g., pgAdmin, DBeaver).
|
||||||
|
# To use this, you must also uncomment the 'ports' section under sparkyfitness-db in docker-compose.prod.yml.
|
||||||
|
# Inside Docker, containers always communicate on port 5432 (the internal PostgreSQL port).
|
||||||
|
# Changing this value will NOT affect container-to-container communication.
|
||||||
|
#SPARKY_FITNESS_DB_PORT=5432
|
||||||
|
|
||||||
|
# --- Backend Server Settings ---
|
||||||
|
# The hostname or IP address of the backend server.
|
||||||
|
# For Docker Compose, this is typically the service name (e.g., 'sparkyfitness-server').
|
||||||
|
# For local development or other deployments, this might be 'localhost' or a specific IP.
|
||||||
|
SPARKY_FITNESS_SERVER_HOST=sparkyfitness-server
|
||||||
|
# The external port the server will be exposed on.
|
||||||
|
SPARKY_FITNESS_SERVER_PORT=3010
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The public URL of your frontend (e.g., https://fitness.example.com). This is crucial for CORS security.
|
||||||
|
# For local development, use http://localhost:8080. For production, use your domain with https.
|
||||||
|
SPARKY_FITNESS_FRONTEND_URL=http://localhost:3004
|
||||||
|
|
||||||
|
|
||||||
|
# Allow CORS requests from private network addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, localhost, etc.)
|
||||||
|
# SECURITY WARNING: Only enable this if you are running on a private/self-hosted network.
|
||||||
|
# Do NOT enable on shared hosting or cloud environments where other users might access your network.
|
||||||
|
# Default: false (secure default - only the configured SPARKY_FITNESS_FRONTEND_URL is allowed)
|
||||||
|
#ALLOW_PRIVATE_NETWORK_CORS=false
|
||||||
|
|
||||||
|
# A comma-separated list of additional URLs that Better Auth should trust.
|
||||||
|
# This is useful when accessing the app from a specific local IP on your network.
|
||||||
|
# Example: SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS=http://192.168.1.175:8080,http://10.0.0.5:8080
|
||||||
|
# SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS=
|
||||||
|
|
||||||
|
# Logging level for the server (e.g., INFO, DEBUG, WARN, ERROR)
|
||||||
|
SPARKY_FITNESS_LOG_LEVEL=ERROR
|
||||||
|
|
||||||
|
# Node.js environment mode (e.g., development, production, test)
|
||||||
|
# Set to 'production' for deployment to ensure optimal performance and security.
|
||||||
|
NODE_ENV=production
|
||||||
|
|
||||||
|
# Server timezone. Use a TZ database name (e.g., 'America/New_York', 'Etc/UTC').
|
||||||
|
# This affects how dates/times are handled by the server if not explicitly managed in code.
|
||||||
|
TZ=Europe/Lisbon
|
||||||
|
|
||||||
|
# --- Security Settings ---
|
||||||
|
# A 64-character hex string for data encryption.
|
||||||
|
# You can generate a secure key with the following command:
|
||||||
|
# openssl rand -hex 32
|
||||||
|
# or
|
||||||
|
# node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
||||||
|
# Changing this will invalidate existing encrypted data. You will need to delete and add External Data sources again.
|
||||||
|
SPARKY_FITNESS_API_ENCRYPTION_KEY=b65743a2f9946be8b7f14083f59183f26bc07c9d2d352a96b2d186a06907e111
|
||||||
|
# For Docker Swarm/Kubernetes secrets, you can use a file-based secret:
|
||||||
|
# SPARKY_FITNESS_API_ENCRYPTION_KEY_FILE=/run/secrets/sparkyfitness_api_key
|
||||||
|
|
||||||
|
# BETTER_AUTH_SECRET is used to sign sessions and encrypt 2FA/TOTP data.
|
||||||
|
# CRITICAL: If you change this after users have enabled 2FA, they will be LOCKED OUT of their accounts.
|
||||||
|
# Ensure this is set to a strong, persistent value during initial setup and is never changed.
|
||||||
|
# If you MUST change it, all users must disable Two-Factor Authentication (TOTP) first.
|
||||||
|
BETTER_AUTH_SECRET=297f9b19e4f13b3ce45af8f1fcc8234264223b6c2052e1f51ea6869583325ecc
|
||||||
|
# For Docker Swarm/Kubernetes secrets, you can use a file-based secret:
|
||||||
|
# BETTER_AUTH_SECRET_FILE=/run/secrets/sparkyfitness_better_auth_secret
|
||||||
|
|
||||||
|
# --- Signup Settings ---
|
||||||
|
# Set to 'true' to disable new user registrations.
|
||||||
|
SPARKY_FITNESS_DISABLE_SIGNUP=false
|
||||||
|
|
||||||
|
# --- Admin Settings ---
|
||||||
|
# Set the email of a user to automatically grant admin privileges on server startup.
|
||||||
|
# This is useful for development or initial setup.
|
||||||
|
# Example: SPARKY_FITNESS_ADMIN_EMAIL=admin@example.com
|
||||||
|
# Optional. If not set, no admin user will be created automatically.
|
||||||
|
SPARKY_FITNESS_ADMIN_EMAIL=sparkyfitness@lino.cooking
|
||||||
|
|
||||||
|
# --- OIDC Authentication Configuration ---
|
||||||
|
# Set to 'true' to disable email/password login on the login page (overridden by SPARKY_FITNESS_FORCE_EMAIL_LOGIN).
|
||||||
|
SPARKY_FITNESS_DISABLE_EMAIL_LOGIN=true
|
||||||
|
|
||||||
|
# Set to 'true' to enable OIDC login. When set, overrides the database value from Admin > Authentication Settings.
|
||||||
|
SPARKY_FITNESS_OIDC_AUTH_ENABLED=true
|
||||||
|
|
||||||
|
# Display name and provider slug (URL-safe id) for the ENV-configured OIDC provider.
|
||||||
|
SPARKY_FITNESS_OIDC_PROVIDER_SLUG=pocket-id
|
||||||
|
SPARKY_FITNESS_OIDC_PROVIDER_NAME=Pocket ID
|
||||||
|
|
||||||
|
SPARKY_FITNESS_OIDC_AUTO_REGISTER=true
|
||||||
|
SPARKY_FITNESS_OIDC_LOGO_URL=https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/pocket-id.svg
|
||||||
|
|
||||||
|
# OIDC issuer URL (e.g. https://example.com). Discovery URL is derived as issuer + /.well-known/openid-configuration.
|
||||||
|
# When set with CLIENT_ID, CLIENT_SECRET and PROVIDER_SLUG, an ENV-configured OIDC provider is upserted at startup.
|
||||||
|
SPARKY_FITNESS_OIDC_ISSUER_URL=https://auth.lino.cooking/application/o/{{slug}}/
|
||||||
|
|
||||||
|
# SPARKY_FITNESS_OIDC_DOMAIN=example.com
|
||||||
|
|
||||||
|
# OIDC client credentials from your IdP.
|
||||||
|
# SPARKY_FITNESS_OIDC_CLIENT_ID=
|
||||||
|
# SPARKY_FITNESS_OIDC_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# SPARKY_FITNESS_OIDC_SCOPE=openid email profile
|
||||||
|
|
||||||
|
# Set to 'true' to allow auto-redirect to the single OIDC provider when email login is disabled.
|
||||||
|
SPARKY_FITNESS_OIDC_AUTO_REDIRECT=true
|
||||||
|
|
||||||
|
# Group/claim values from your IdP for role mapping (admin vs user). Configure your IdP to send these in token claims.
|
||||||
|
# SPARKY_FITNESS_OIDC_ADMIN_GROUP=Admin
|
||||||
|
# --- Advanced OIDC Settings ---
|
||||||
|
# SPARKY_FITNESS_OIDC_TOKEN_AUTH_METHOD=client_secret_post
|
||||||
|
# SPARKY_FITNESS_OIDC_ID_TOKEN_SIGNED_ALG=RS256
|
||||||
|
# SPARKY_FITNESS_OIDC_USERINFO_SIGNED_ALG=none
|
||||||
|
# SPARKY_FITNESS_OIDC_TIMEOUT=30000
|
||||||
|
|
||||||
|
# Set custom uploads and backups directory. Only needed for standalone installation
|
||||||
|
# SPARKY_FITNESS_CUSTOM_UPLOADS_DIRECTORY=
|
||||||
|
# SPARKY_FITNESS_CUSTOM_BACKUP_DIRECTORY=
|
||||||
|
#
|
||||||
|
# --- Login Management Fail-Safe ---
|
||||||
|
# Set to 'true' to force email/password login to be enabled, overriding any in-app settings.
|
||||||
|
# This is a fail-safe to prevent being locked out if OIDC is misconfigured.
|
||||||
|
# SPARKY_FITNESS_FORCE_EMAIL_LOGIN=true
|
||||||
|
|
||||||
|
# --- Email Settings (Optional) ---
|
||||||
|
# Configure these variables if you want to enable email notifications (e.g., for password resets).
|
||||||
|
# If not configured, email functionality will be disabled.
|
||||||
|
# SPARKY_FITNESS_EMAIL_HOST=smtp.example.com
|
||||||
|
# SPARKY_FITNESS_EMAIL_PORT=587
|
||||||
|
# SPARKY_FITNESS_EMAIL_SECURE=true # Use 'true' for TLS/SSL, 'false' for plain text
|
||||||
|
# SPARKY_FITNESS_EMAIL_USER=your_email@example.com
|
||||||
|
# SPARKY_FITNESS_EMAIL_PASS=your_email_password
|
||||||
|
# SPARKY_FITNESS_EMAIL_FROM=no-reply@example.com
|
||||||
|
|
||||||
|
# --- Volume Paths (Optional) ---
|
||||||
|
# These paths define where Docker volumes will store persistent data on your host.
|
||||||
|
# If not set, Docker will manage volumes automatically in its default location.
|
||||||
|
DB_PATH=/data/sparky-fitness/postgresql # Path for PostgreSQL database data
|
||||||
|
SERVER_BACKUP_PATH=/data/sparky-fitness/backup # Path for server backups
|
||||||
|
SERVER_UPLOADS_PATH=/data/sparky-fitness/uploads # Path for profile pictures and exercise images
|
||||||
|
|
||||||
|
|
||||||
|
# --- API Key Rate Limiting (Optional) ---
|
||||||
|
# Override the default rate limit for API key authentication (used by automation tools like n8n).
|
||||||
|
# Defaults to 100 requests per 60-second window if not set.
|
||||||
|
#SPARKY_FITNESS_API_KEY_RATELIMIT_WINDOW_MS=60000
|
||||||
|
#SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS=100
|
||||||
|
|
||||||
|
# --- Start of Garmin Integration Settings ---
|
||||||
|
#Below variables are needed only for Garmin integration. If you don't use Garmin integration, you can remove them in your .env file.
|
||||||
|
|
||||||
|
|
||||||
|
# The URL for the Garmin microservice.
|
||||||
|
# For Docker Compose, this would typically be the service name and port (e.g., 'http://sparkyfitness-garmin:8000').
|
||||||
|
# For local development, use 'http://localhost:8000' or the port you've configured.
|
||||||
|
|
||||||
|
# GARMIN_MICROSERVICE_URL=http://sparkyfitness-garmin:8000
|
||||||
|
|
||||||
|
|
||||||
|
# This is used for Garmin Connect synchronization.
|
||||||
|
# If you are not using Garmin integration, you don't need this. Make sure this matches with GARMIN_MICROSERVICE_URL.
|
||||||
|
# GARMIN_SERVICE_PORT=8000
|
||||||
|
|
||||||
|
# set to true for China region. Everything else should be false. Optional - defaults to false
|
||||||
|
# GARMIN_SERVICE_IS_CN=false
|
||||||
|
|
||||||
|
# --- End of Garmin Integration Settings ---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# --- MCP Server Settings ---
|
||||||
|
# The port the MCP server will listen on.
|
||||||
|
# SPARKY_FITNESS_MCP_PORT=3001
|
||||||
|
|
||||||
|
# Vision API Settings (for sparky_analyze_food_image and sparky_scan_label)
|
||||||
|
# Supported providers: gemini, openai, anthropic
|
||||||
|
# VISION_API_PROVIDER=gemini
|
||||||
|
# VISION_API_KEY=
|
||||||
|
|
||||||
|
# Set to 'true' to enable developer tools (e.g., sparky_inspect_schema)
|
||||||
|
# Requires the authenticated user to have the 'admin' role.
|
||||||
|
# DEV_TOOLS_ENABLED=false
|
||||||
|
|
||||||
|
# ----- Developers Section -----
|
||||||
|
# Data source for external integrations (fitbit, garmin, withings).
|
||||||
|
# By default, these use live APIs. Set to 'local' to use mock data from the mock_data directory.
|
||||||
|
# To use these variables, you will also need to pass to Server container. For Garmin, pass to Garmin container.
|
||||||
|
|
||||||
|
#SPARKY_FITNESS_FITBIT_DATA_SOURCE=local
|
||||||
|
#SPARKY_FITNESS_WITHINGS_DATA_SOURCE=local
|
||||||
|
#SPARKY_FITNESS_GARMIN_DATA_SOURCE=local
|
||||||
|
#SPARKY_FITNESS_POLAR_DATA_SOURCE=local
|
||||||
|
#SPARKY_FITNESS_HEVY_DATA_SOURCE=local
|
||||||
|
|
||||||
|
# Set to 'true' to capture live API responses into mock data JSON files. Defaults to false.
|
||||||
|
#SPARKY_FITNESS_SAVE_MOCK_DATA=false
|
||||||
|
|
||||||
|
#-----------------------------
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
services:
|
||||||
|
sparkyfitness-db:
|
||||||
|
image: postgres:18.3-alpine
|
||||||
|
container_name: sparkyfitness-db
|
||||||
|
restart: always
|
||||||
|
# Uncomment below to expose PostgreSQL to the host (e.g., for pgAdmin, DBeaver).
|
||||||
|
# ports:
|
||||||
|
# - "${SPARKY_FITNESS_DB_PORT:-5432}:5432"
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${SPARKY_FITNESS_DB_NAME:?Variable is required and must be set}
|
||||||
|
POSTGRES_USER: ${SPARKY_FITNESS_DB_USER:?Variable is required and must be set}
|
||||||
|
POSTGRES_PASSWORD: ${SPARKY_FITNESS_DB_PASSWORD:?Variable is required and must be set}
|
||||||
|
PUID: 1000
|
||||||
|
GUID: 1000
|
||||||
|
volumes:
|
||||||
|
- ${DB_PATH:-./postgresql}:/var/lib/postgresql
|
||||||
|
|
||||||
|
sparkyfitness-server:
|
||||||
|
image: codewithcj/sparkyfitness_server:latest # Use pre-built image
|
||||||
|
environment:
|
||||||
|
SPARKY_FITNESS_LOG_LEVEL: ${SPARKY_FITNESS_LOG_LEVEL}
|
||||||
|
ALLOW_PRIVATE_NETWORK_CORS: ${ALLOW_PRIVATE_NETWORK_CORS:-false}
|
||||||
|
SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS: ${SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS:-}
|
||||||
|
SPARKY_FITNESS_DB_USER: ${SPARKY_FITNESS_DB_USER:-sparky}
|
||||||
|
SPARKY_FITNESS_DB_HOST: ${SPARKY_FITNESS_DB_HOST:-sparkyfitness-db} # Use the service name 'sparkyfitness-db' for inter-container communication
|
||||||
|
SPARKY_FITNESS_DB_NAME: ${SPARKY_FITNESS_DB_NAME}
|
||||||
|
SPARKY_FITNESS_DB_PASSWORD: ${SPARKY_FITNESS_DB_PASSWORD:?Variable is required and must be set}
|
||||||
|
SPARKY_FITNESS_APP_DB_USER: ${SPARKY_FITNESS_APP_DB_USER:-sparkyapp}
|
||||||
|
SPARKY_FITNESS_APP_DB_PASSWORD: ${SPARKY_FITNESS_APP_DB_PASSWORD:?Variable is required and must be set}
|
||||||
|
SPARKY_FITNESS_DB_PORT: 5432 # Uses internal container port. Do NOT change this if SPARKY_FITNESS_DB_HOST is using container name.
|
||||||
|
SPARKY_FITNESS_API_ENCRYPTION_KEY: ${SPARKY_FITNESS_API_ENCRYPTION_KEY:?Variable is required and must be set}
|
||||||
|
# Uncomment the line below and comment the line above to use a file-based secret
|
||||||
|
# SPARKY_FITNESS_API_ENCRYPTION_KEY_FILE: /run/secrets/sparkyfitness_api_key
|
||||||
|
|
||||||
|
BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET:?Variable is required and must be set}
|
||||||
|
# Uncomment the line below and comment the line above to use a file-based secret
|
||||||
|
# BETTER_AUTH_SECRET_FILE: /run/secrets/sparkyfitness_better_auth_secret
|
||||||
|
SPARKY_FITNESS_FRONTEND_URL: ${SPARKY_FITNESS_FRONTEND_URL:-http://0.0.0.0:3004}
|
||||||
|
SPARKY_FITNESS_DISABLE_SIGNUP: ${SPARKY_FITNESS_DISABLE_SIGNUP}
|
||||||
|
SPARKY_FITNESS_ADMIN_EMAIL: ${SPARKY_FITNESS_ADMIN_EMAIL} #User with this email can access the admin panel
|
||||||
|
SPARKY_FITNESS_EMAIL_HOST: ${SPARKY_FITNESS_EMAIL_HOST}
|
||||||
|
SPARKY_FITNESS_EMAIL_PORT: ${SPARKY_FITNESS_EMAIL_PORT}
|
||||||
|
SPARKY_FITNESS_EMAIL_SECURE: ${SPARKY_FITNESS_EMAIL_SECURE}
|
||||||
|
SPARKY_FITNESS_EMAIL_USER: ${SPARKY_FITNESS_EMAIL_USER}
|
||||||
|
SPARKY_FITNESS_EMAIL_PASS: ${SPARKY_FITNESS_EMAIL_PASS}
|
||||||
|
SPARKY_FITNESS_EMAIL_FROM: ${SPARKY_FITNESS_EMAIL_FROM}
|
||||||
|
GARMIN_MICROSERVICE_URL: http://sparkyfitness-garmin:8000 # Add Garmin microservice URL
|
||||||
|
PUID: 1000
|
||||||
|
GUID: 1000
|
||||||
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
- sparkyfitness-db # Backend depends on the database being available
|
||||||
|
volumes:
|
||||||
|
- ${SERVER_BACKUP_PATH:-./backup}:/app/SparkyFitnessServer/backup # Mount volume for backups
|
||||||
|
- ${SERVER_UPLOADS_PATH:-./uploads}:/app/SparkyFitnessServer/uploads # Mount volume for Profile pictures and excercise images
|
||||||
|
|
||||||
|
sparkyfitness-frontend:
|
||||||
|
image: codewithcj/sparkyfitness:latest # Use pre-built image
|
||||||
|
ports:
|
||||||
|
- "8087:80" # Map host port 8087 to container port 80 (Nginx)
|
||||||
|
environment:
|
||||||
|
SPARKY_FITNESS_FRONTEND_URL: ${SPARKY_FITNESS_FRONTEND_URL}
|
||||||
|
SPARKY_FITNESS_SERVER_HOST: sparkyfitness-server # Internal Docker service name for the backend
|
||||||
|
SPARKY_FITNESS_SERVER_PORT: 3010 # Port the backend server listens on
|
||||||
|
PUID: 1000
|
||||||
|
GUID: 1000
|
||||||
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
- sparkyfitness-server # Frontend depends on the server
|
||||||
|
#- sparkyfitness-garmin # Frontend depends on Garmin microservice. Enable if you are using Garmin Connect features.
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
services:
|
||||||
|
speedtest:
|
||||||
|
container_name: speedtest
|
||||||
|
image: henrywhitaker3/speedtest-tracker
|
||||||
|
ports:
|
||||||
|
- 8085:80
|
||||||
|
volumes:
|
||||||
|
- /data/speedtest:/config
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Lisbon
|
||||||
|
- PGID=1000
|
||||||
|
- PUID=1000
|
||||||
|
- OOKLA_EULA_GDPR=true
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-file: "10"
|
||||||
|
max-size: "200k"
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: mauriceboe/trek:latest
|
||||||
|
container_name: trek
|
||||||
|
read_only: true
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- CHOWN
|
||||||
|
- SETUID
|
||||||
|
- SETGID
|
||||||
|
tmpfs:
|
||||||
|
- /tmp:noexec,nosuid,size=64m
|
||||||
|
ports:
|
||||||
|
- "8083:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3000
|
||||||
|
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||||
|
- TZ=Europe/Lisbon
|
||||||
|
- LOG_LEVEL=info
|
||||||
|
- ALLOWED_ORIGINS=https://trips.lino.cooking
|
||||||
|
- FORCE_HTTPS=true
|
||||||
|
- TRUST_PROXY=1
|
||||||
|
- ALLOW_INTERNAL_NETWORK=true
|
||||||
|
- APP_URL=https://trips.lino.cooking
|
||||||
|
- OIDC_ISSUER=https://auth.lino.cooking
|
||||||
|
- OIDC_CLIENT_ID=652278a5-b695-4589-9d51-d23cfb2e15dd
|
||||||
|
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
|
||||||
|
- OIDC_DISPLAY_NAME=PocketID
|
||||||
|
- OIDC_ONLY=true
|
||||||
|
- OIDC_DISCOVERY_URL=https://auth.lino.cooking/.well-known/openid-configuration
|
||||||
|
volumes:
|
||||||
|
- /data/trek/app:/app/data
|
||||||
|
- /data/trek/uploads:/app/uploads
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 15s
|
||||||
|
retries: 3
|
||||||
|
start_period: 15s
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
webserver:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: hello-webserver
|
||||||
|
ports:
|
||||||
|
- "8082:80"
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
webserver:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: hello-webserver
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
webserver:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: hello-webserver
|
||||||
|
ports:
|
||||||
|
- "8081:80"
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
webserver:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: hello-webserver
|
||||||
|
ports:
|
||||||
|
- "8082:80"
|
||||||
|
restart: unless-stopped
|
||||||
Reference in New Issue
Block a user