8 Commits

45 changed files with 692 additions and 1004 deletions

2
.idea/alpina.iml generated
View File

@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" /> <excludeFolder url="file://$MODULE_DIR$/venv" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="jdk" jdkName="Poetry (alpina)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="PyDocumentationSettings"> <component name="PyDocumentationSettings">

10
.idea/jsonSchemas.xml generated
View File

@@ -106,6 +106,16 @@
<option name="applicationDefined" value="true" /> <option name="applicationDefined" value="true" />
<option name="patterns"> <option name="patterns">
<list> <list>
<Item>
<option name="pattern" value="true" />
<option name="path" value="*/compose.yml" />
<option name="mappingKind" value="Pattern" />
</Item>
<Item>
<option name="pattern" value="true" />
<option name="path" value="*/compose.yml.j2" />
<option name="mappingKind" value="Pattern" />
</Item>
<Item> <Item>
<option name="pattern" value="true" /> <option name="pattern" value="true" />
<option name="path" value="*/docker-compose.yml" /> <option name="path" value="*/docker-compose.yml" />

View File

@@ -1,19 +1,23 @@
.POSIX: .POSIX:
.PHONY: * .PHONY: *
.EXPORT_ALL_VARIABLES: .EXPORT_ALL_VARIABLES:
MAKEFLAGS += -r # no use of built-in rules
env ?= staging env ?= staging
vault_id ?= alpina@contrib/rbw-client.sh vault_id ?= alpina@contrib/rbw-client.sh
clean_desired ?= false playbook_cmd := poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env}
all: site all: site services
setup: setup:
poetry install --quiet poetry install --quiet
site: setup site: setup
poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} --extra-vars "clean_desired_arg=${clean_desired}" site.yml $(playbook_cmd) site.yml
services: setup services: setup
poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} services.yml $(playbook_cmd) services.yml
clean: setup
$(playbook_cmd) clean.yml

3
clean.yml Normal file
View File

@@ -0,0 +1,3 @@
- hosts: alpina
roles:
- clean

View File

@@ -6,23 +6,38 @@ default:
- subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, subnet_index) }} - subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, subnet_index) }}
{% endmacro %} {% endmacro %}
{% macro traefik_labels(host, service="", port="", auth=false) %} {% macro traefik_labels(host, port='', path_prefix='', auth=false, wildcard=false) %}
{% set name = host ~ (wildcard * '-*') ~ path_prefix -%}
{% set tls_base = domain %}
{% if wildcard -%}
{% set tls_base = host ~ '.' ~ domain %}
{%- endif -%}
traefik.enable=true traefik.enable=true
- traefik.http.routers.{{ host }}.rule=Host(`{{ host }}.{{ domain }}`) - traefik.http.routers.r-{{ name }}.rule={{ host_rule(host, path_prefix, wildcard) }}
- traefik.http.routers.{{ host }}.entrypoints=web - traefik.http.routers.r-{{ name }}.entrypoints=websecure
- traefik.http.routers.{{ host }}-tls.rule=Host(`{{ host }}.{{ domain }}`) - traefik.http.routers.r-{{ name }}.tls=true
- traefik.http.routers.{{ host }}-tls.entrypoints=websecure - traefik.http.routers.r-{{ name }}.tls.certresolver=letsencrypt
- traefik.http.routers.{{ host }}-tls.tls=true - traefik.http.routers.r-{{ name }}.tls.domains.0.main={{ tls_base }}
- traefik.http.routers.{{ host }}-tls.tls.certresolver=letsencrypt - traefik.http.routers.r-{{ name }}.tls.domains.0.sans=*.{{ tls_base }}
- traefik.http.routers.{{ host }}-tls.tls.domains.0.main={{ domain }}
- traefik.http.routers.{{ host }}-tls.tls.domains.0.sans=*.{{ domain }}
{% if service -%}
- traefik.http.routers.{{ host }}.service={{ service }}
{% endif %}
{% if port -%} {% if port -%}
- traefik.http.services.{{ host }}.loadbalancer.server.port={{ port }} - traefik.http.routers.r-{{ name }}.service=svc-{{ name }}
- traefik.http.services.svc-{{ name }}.loadbalancer.server.port={{ port }}
{% endif %} {% endif %}
{% if auth -%} {% if auth -%}
- traefik.http.routers.{{ host }}-tls.middlewares=authentik@docker - traefik.http.routers.r-{{ name }}.middlewares=authentik@docker
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
{% macro host_rule(host, path_prefix="", wildcard=false) %}
{% if wildcard %}
{# regular a.host prevents warnings from 'No domain found in rule HostRegexp' #}
{# TODO: figure out this stupidity properly #}
Host(`a.{{ host }}.{{ domain }}`) || HostRegexp(`^.+\.{{ host }}\.{{ domain | replace('.', '\.') }}$`)
{%- else %}
Host(`{{ host }}.{{ domain }}`)
{%- endif %}
{% if path_prefix -%}
&& PathPrefix(`{{ path_prefix }}`)
{%- endif %}
{% endmacro %}

View File

@@ -5,12 +5,15 @@ alpina_svc_path: ~/alpina
base_volume_path: /mnt/dock base_volume_path: /mnt/dock
media_volume_path: /mnt/media media_volume_path: /mnt/media
traefik_subnet: 172.16.122.0 docker_ipv6_subnet: "{{ \
ansible_default_ipv6.address \
| ansible.utils.ipsubnet(64) \
| ansible.utils.ipsubnet(72, docker_ipv6_index) \
}}"
# Authentik # Authentik
authentik_db_password: "{{ vault_authentik_db_password }}" authentik_db_password: "{{ vault_authentik_db_password }}"
authentik_secret_key: "{{ vault_authentik_secret_key }}" authentik_secret_key: "{{ vault_authentik_secret_key }}"
authentik_sendgrid_api_key: "{{ vault_authentik_sendgrid_api_key }}" authentik_sendgrid_api_key: "{{ vault_authentik_sendgrid_api_key }}"
auth_grafana_client_secret: "{{ vault_auth_grafana_client_secret }}" auth_grafana_client_secret: "{{ vault_auth_grafana_client_secret }}"
@@ -19,6 +22,9 @@ auth_gitea_client_secret: "{{ vault_auth_gitea_client_secret }}"
auth_nextcloud_client_secret: "{{ vault_auth_nextcloud_client_secret }}" auth_nextcloud_client_secret: "{{ vault_auth_nextcloud_client_secret }}"
arrstack_password: "{{ vault_arrstack_password }}" arrstack_password: "{{ vault_arrstack_password }}"
auth_vpgen_client_secret: "{{ vault_auth_vpgen_client_secret }}" auth_vpgen_client_secret: "{{ vault_auth_vpgen_client_secret }}"
auth_pgrok_client_secret: "{{ vault_auth_pgrok_client_secret }}"
auth_default_enrollment_group: vpgen
# Minio # Minio
minio_password: "{{ vault_minio_password }}" minio_password: "{{ vault_minio_password }}"
@@ -61,3 +67,9 @@ vpgen_ip_max_index: 100
vpgen_vpn_endpoint: "{{ vault_vpgen_vpn_endpoint }}" vpgen_vpn_endpoint: "{{ vault_vpgen_vpn_endpoint }}"
vpgen_vpn_dns: "{{ vault_vpgen_vpn_dns }}" vpgen_vpn_dns: "{{ vault_vpgen_vpn_dns }}"
vpgen_max_clients_per_user: 20 vpgen_max_clients_per_user: 20
# Woodpecker
woodpecker_agent_secret: "{{ vault_woopecker_agent_secret }}"
# Pgrok
pgrok_db_password: "{{ vault_pgrok_db_password }}"

View File

@@ -1,138 +1,154 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
38376439643766303237356563616337663731366435613930393135383962666435313530663632 64326366396663613133333430356565636565363066383339646533623964613638613932633865
3432326162343632613565393737363335306263653032300a643539393562376162333761376631 3435613234306336376565623861303864323735323533360a656533303734646630343964666666
62343731316430316638363338343966326635383930623339383339653936343765316439393233 65396638373733353833333736626465336663323934373461303564376531623066303062646630
6562323634383363300a323233346338393764623363346139313661386433656337363332656230 6362633163653936390a626138656361663635336533376563373139663538663037306336333865
31306233643735333033316139363165373062363334363933396563366234316330646230353261 63393263646665663664333162656532373064336361346133383064383035333831653563393337
62326539663337323036346533303031333730373061656563613535376162633138306634626462 39306138623764366131303332653839653061393530353235613563376430666337656336386262
37313038356466336138643834643863393333373939616362636365366231383762633030313831 64363731656230323832616437633735343662376637303334343161343165636137623434613636
33393139313336623437396161623437323163633362363137626262653462633737373062643735 35666439383036633761353062613464363264633231306138636362643434333338303238616364
63353561313639393166306466346134623933323532636438656263663338376337376434356163 35636430626536633264616233303462363839653436323138613836633336383438393364373338
64343239616632313566656664393136363337386464613932383961343134363233653039336137 37623539306635636462363239396231663264613034646165393031343763643265363235623736
65656566306463313264646163646130323533666464323464643433313030346535346535323264 37383439313066386139373736396465323962663131383664393939373862336231306266653832
34356433343739343166383034313935666139663239653662663734343139343035616134303730 61663037613535663138333565613066663938616432356434323531383837363931393837323634
39643136623735666333646234346239303337333961343261383834393963386633633030633962 66353436303065323266386264353436393266363136326531646438326130613865663132353164
61376132313532643730633865326130666565303631386262396366306565613665363934383335 30366434373164623037613931393634613065383737643863343939373063376530633938346434
37376139616165396436663135373932653064656136356662363137653036383537613665393634 62633432636430366361616636313337366238303566303566616363653336643736333636663737
38313063656637353630373634316564383362663335356364626161663163323362333937316461 38316330646266636633323162346231353337626133663939306131653434326533326162663963
64336636386234623438613766316430353261346339313863306462393335636131363966363038 34666262313232663564356633393162653639653739323639396562613362313663383736393438
66393561323335393063663838393466656331323433376461653838313638303564666662636438 31373930393465356535303236343934663238373764303333663634666338643666646665326563
38663735616261656338626437336433613730353236636266316536656165303534353538316232 34376164303538336133613630623466656466663266326432343439613235376463326661663131
62363063376464323932383261663537393263333266633461326536656533653661303335646431 38373533313661333431343638346334303736306237653336633366313831626466633430373865
36616436396137343634373563386439653833306537373735353764346430616231313538636362 32646536643862646135653434343337373563666532333561316232393063306365363631623262
30363430613839373761363032316137636432643339383561313637376339323836353161343639 31313538306264623030353230326330666234303138646237613435633637373837656565623538
36316665656164396236383538346561306432333637393431393566333566633434393961663330 33616233623366346237376563613430663835653432653834353835376338643236663266646462
32383833396238633966393837336564626135653733383863346161663364353062303931303931 62316438356233383965616434393737306132306538396564396431376661323135353137316534
39653662373734643037393832643439653437353935666430373337643532346161376661633738 63353663343338353339373163343737333835363363316563393538353266653033383136646437
61643431633431666535333463636461613166363238373138306565643533623039353031646634 37626661383531363233656663616630316361373438616232313131316234386665653262313937
62383662663435346635373865633731393362623761313834393964623930646364366534333236 61366536613731663231616663393735303535326636383066333330386233306534656237653561
35393138346433366435313066633436393561643263343534393034373161343834633261363933 33336639356331313636363865313836306137333439613365636132356631653437316161346230
65376636393263663566653436633762643331336139653565663334373561353130653065653935 64643736323437396663653937633634633230386164333239616261616332323137643764383335
31616337313764313532303934376236623833363433336335303262643135643339613839623231 64613966653764623031323961386530383731316464386131393264346261356331666165623738
37343730616166323239653537313137373136626337333665633134363830626131353030393662 62643564323134393630336566343834356265316264393530356633356466313831623262363730
31643366386365353336326133636434303636343637643539653131316133306132643133643364 66373232353439616539643433653435643931623430633338623737643039306532343234646333
64636464373564383938663838613031626563613362626435383832346661306562343165643539 34393536333730626136313039646364626235616233323137386137383565326461393635353838
66353431393032313262393566353833343632366139656234306561366139633431653133356165 35616530383765373431626130386165663538663861653064646363633465326364353533646137
32363332636433626132666462626137653337646234646565303831646330333133353964626461 62326435353239363164383236333236643430396561396231323130376264646139666264356138
37333265623865376562663365336339353036346135363062663534643537353331623630356264 35353466396335336532363566323738373932643634363763633832353462663836636465626434
66386665333633383534313062623533383239383231333163663565633531666236306465633135 38656332626236626335386166333835306666643438376330373936656639313933373635333436
36363164636165343863363866343437636630353863316633623761373232643262623762316162 30633731376166376232363834346632633261353361323563376162343063343065643439306231
32613665306535626139366564616362393536336364666663333761383362393631316134373138 30666131373361633862363833373366313733626161643932306332613230393636636138363337
32616665363164363639303538373539346239663261373731613464333734326436666433666539 61666565633931376639613262666332363037373337663430343939333431303732636434633934
31656264326535626134323231646535656563363231633434636337323538343038303233363765 35386130386363333431636363336130336430633839653231363935313930393037306536336563
61393164316237323533313336316530316431653731343261636265393361616464323536333130 36653462383432366337646266313139346536666230386565333364383330653333353765326136
65346538306664663566666435393738323832396365363764333637613331356661306535376332 33626236333765333863363265346561643835373235393361643234386336656134353731393033
62313533306365373737643835396364363737306631346161353031633531383364636563383237 34316430383933626434343839333065333166386233316132373138666534653434653033356135
64633432386565356137333730313736393737303665326531356265376333663636393430386233 31366539346538336639626363396636646135386266386138356362616464316630313437386265
33666532616632373061633063656136646533363034363330366231653936396166663134396139 30353361626338633961366633333631383366316331333635613738366139633863376331333435
66393131653963386365656364666263666362316136333561326566626562616138383739346139 39376239336532343937346563646331366136666130646336366537366534323961363930663438
62343035646435393136656434646138376331346164663562306166646132363230333538323536 65333663613030336131663665343234616231306130663761643163646233353265333030396333
38643934613633373734653337666261356639353235326539356264633232343834633062336539 30326436396163343732313430373135323332326161623566633932303537666564633834623863
31616536663730656163626437653932313564633938643163313765393731386533323465303831 66353039626565646539313763373864623638323765313065646133646430666162616533323036
34353663363862363761643565633635373834623665653131613531373637386361636661376532 64313238633264623465313961656563643536313435313162376339353532363232613637343463
64386435643966343034643763393461373961626134346539653865636161333962333463393734 33343066303465643930613364356635333234363563653731663137306337346630653637656566
62343838363432396133326235323636613239326139376365353930373835313531326433326234 30323537356264356137643637646265643537303263373964346165656266623263636331323130
66396537636162363865663433626230316362343334653735646637613130636436633132663538 31396433346561666331616639306131623261353763343638663931623161343133616639633561
64623230303266373965616533346464373661363233613837613765343463306136623063313139 36646266643636613564346663666633313665386137323266633330333862313637386330643937
31383039343462363536646636653736316362356565326538636331646235373162663332313961 33393561376331316235323961636462363661383466663635323464366238386531393466316361
64623061636638666234623336656365383165626461323561343930316432313632316332306334 30396434666335346232643738396638633239323935636637343838353364656662663666303366
61376430303835383934396266303564363230313735366464386134393265326334663633663632 37663666373839613837313335366635363634623133653463626466316435303538303632633762
38643034393737303963643733656333316137646435653666353239373738373632383561646333 66366538303630336630663365663831313562383334666435383831376564333438633364343861
65363865353362383832643238363332613931343038366563316163303764323936316466666364 35343462653233636265336266386637636261666331316666663966313666383965303163656238
31373439383661656336653431666164393833643266656133383137376133636134643137663532 66343932323939363339323664366334386166373139363866353161396235366466306466636439
33353531663336346562653339616430333133363232336461353937303435346337363932306133 36313039313263643739353230313362353263626236393239656164656334653363623965653936
37623164343462363830323263323664303334633563313439376232303031633633316636383164 65386165663361313066646532393939383165316239653335623965346363613335396639653134
66306238333432333635653435383138383339343837346134613630353335656335663062326132 36346164383439636237306233333166383233376462633136383933666161643734303032313530
65323638343963623062663638366538363162343230323262616138373239653163623832313366 62343866316162393766626261393635643564366431383164626236653062336466343634323432
65323834383631646164316363383636643437346435313030656362653332653635343066666232 38343663623261343535616536613961636564376563303064623537303233373366326136353665
39346235383265326262306434383861653138393835663863383032363664323565316165646566 33336532633161623638303761383034306265613230323433326133653035303661626234353931
61646238393062373131346536343533663839313831383335316363343465663130633133393436 31646530383637626231313965343138303565303030316132613930306137313465616664646230
66333465633636353639663836376561353839613533346164366238353833636534633338313262 30353163626562396566653261643336653832663635333963343539396366346132353465386463
30656433376362346333303630643639353262323532666238633764363132303161326638643761 33666365363639343066653330326233373035313433316264373236366565643931616335643762
36616131636538613539383935613337643930333334613566393031646630383330656164363361 63306165393166396437646366303837316235643562366464326530373230633664653235363136
37306536356164633831626362653364313164356235653464333633313263383032333439626434 31333938616139653261656132663439323066636135303430383662333639306265633436326666
65376531396661636661303831393062666362623966353739303330393631323963373564353265 62353936663463343864383432636465373737666239613033383538396338303533636663393339
61343862323737336238356231626561396333386264666563356235333339653538626130623936 63633561343135343339393063636163373936323461303734613766626539343363363365643632
63326431316538346534313764356333396565666431633833613337323136643137306166623238 66306630303634353230393933353333346166303436333038303637313162626464373334373063
66393561333137373964353935323930636237366433613038383761643665363330323865386133 38313438633365316562363564316138393531633661323139343938633636373534386465643631
37623339613733353366656637383030623663313639363334656361623035643232626633313864 35396261643865393531366432343265663363336562643366623062343331306431663461393066
36346564653766646333613763616163363462613937656534363461376235613064373039326165 32633732333634383462383061623334306332326466306666626131363461343436393966633233
32666265383065636232613632333830633439653066653666663261646536663434393535613131 31656538633733303264663239643639326235316561386564613563383930383336386664363135
30373062313765663038313534623165653833623330383032363063393239373234636630646561 39616263313036646630373233636534376361386230386235363636643835636538663930633630
38633962363530666638666630316434613462656335613236363831313863613030636539356133 38656664383138373138626639666230623635613137666533353233333636323062666432313434
66386133383433663964306661636131633236633935633236623530373864646363383534383735 37666132303233353438346439653965626434663136386631313337633636653464396566323532
63633165626464333332303331333338313838393832626637626137316338643136336333633930 39366434373830343764346138613665373536656164363637663037663534633963336230663439
61346436336635656639616261383666336330333862303139633137373362303033653432613039 38373138336666633934643537383131333034316135343738623435643630653661633432363161
35623663353538323761623839623438646363313164356631386364356533346133333334326565 37373837303838343566626662656231306438613538333733323632616132343563376533663539
32303837663261386463313535373765356166376165386535623838326431616564346632363732 64653262646463613739313737356139666666623963636261336433396363636632333933393463
62373231356530346632373134343865303532326136653731633038353066623435336462303138 63653366666536323536666264343931373961356361646434623461316630626133376639613362
37363039343433613939363663623135396636396433653362666164323237393664623564393532 38333836653332346134616134313164313965613531343630383764636161653730656332616238
61376463336564396537366365373936333666373432376566323864343735636264643139643063 31393132363064663431316165346135343861653462383162353063653837393566356161333535
66396230303336633438666234336434353866323637316334313162363734623763666338336234 35343133646632343164336364623337393138343630643737643531346566636633646438396162
39303330343035333864396631323231363134646238323065356138633131323135613133356237 31393632303661323363346164636331626638326437383035363930656635316236366434623236
34373562633430613062313261363939373632313838333934303165336562663839663833383763 33633136303533636239666434323962333134366461363037343463623437363961353962346236
39316632656561653033613933373861366361353761346539306234366538373461373930306535 66313838643238323136356135346564363732656666363431653061663863616537663035373631
66623430343336333033306135303639646566393336663538313430616364653933663536386535 34613262363065333162353039613762386130353930316161613061633164383539623263323865
64323962353734356134656361663131376564626461386233643731393664353038626464313763 30313566613365656563353236386334636335366663643034316435376532333438643166663536
64396265373737313134613962376334373965353338303363303935353538643561336461393032 38363363373330326132336363363039396563396435366131353933393434373336363033343265
37356434343837376534663938366434343063643966643965346465636166363235643635333466 30613539366436643631303933376137386635366166663930303331623238633034326631656366
38323664366366663363616664336165653264633437393636363866316262303432356461386330 31356337303834356334633636333832363837343735396632356365613439383061366232383462
63326539626363333331366162363230626462656633653866383331333164663734633630353265 62613934373535626639363230366266343762643232623933613265356436656364363835323062
63303832376230646136346261383965626633613739616330666232376366613332663839336531 32393062386432323562313734346133393465316135316135366331653161636261316364643632
32343031336363663865643165666435623462376130326433316562363530343662366432313031 36326161653937336562643034636638666265386264623133626335616633353239333965656632
63626538656633346563663735323030363231643933326337613634376531636235333339373633 31323134393230303733623732313836373465383535626434383638666135313237633731613763
66353362333265343964353966383363613336636536393734363363623363316532653533633434 64343066336662643264663130363962626435626332626464396137386538333731373238616636
39333162303834353362323362656630343733653336613065333462626637303264653361393462 66313931666466306133643666363862626438343634353336376566333533393936363866626233
32336238326535383662636465383832346438333230666662633430303964343236626331623536 63616633373536633138393563323636343035343564626236383064376135656638616534353431
65383666316431646538396661386332323037383666336138666135613763363633343934663836 31643063346631636666333065386339663363623431653532643065363636303764666333393761
32656362323631303732613235663135633939643165626231373162643963613637626235613365 36313439303765356532393832633637636336643036306333663935393734663662346435396466
32326266323431636434633234333730373836373039666137663232323539396364373061393232 37376537323262653033356336363835666231363661653133666361383065343063643061376164
30646432666365333336333836313333363537363163383034656136383164663331373632313564 32333530376530326662373738333363373631663536373961373965373263346635643762396666
34353731363338323438366464663938393632626530323537306233613866356234323364373766 61396632343464343735623531653831393735666331316162353430353134383430393865383662
34326662656263383864613538326536626133386532303932326362376632363631356535393937 66656264376564343636386263333934313364373564616134623863613439636537613764376434
33346462336636656165316166363364343330383337636361656438383661333366633532616131 65313964303539376131396339356238363735363766616365306133393464613131643166646437
37313033623430663039626131303933316561666233613666636433363537373264653331323136 39353961393036646164663865633633373465653766386230333762643735363734633633363461
66663532653233373735326333333738663931343735306262353831303330633136623966316431 62613332346336633833663862333230363161663636646232343761356338393639613035646438
39316462313066336536623438626163383139343532313932316435356431323865373035343465 32663465303138613731303961633565616239633033333361613861623161353032353661363062
30346237393531353833616136323431376530333635633632666431313938643539363831313539 39316262363738383163366332373438636539623365353232316536363130333438613031653665
38396338336136363165323135663836336139623865666631663237616664636233653663383965 62366334653036353566333663353862303335656266613134633731633535313730303539306334
39623665656563316334323738323730306631636565393662313536353565383033653365663461 63393431306265373234313939373133363961626265626633343631613931636132653635376634
38326432353166376438356238386161396638666131636536356333393563613461373263346538 61366262336239656638343438646231653030666638383239313834363334663661316235366162
36656138353762323662363061613764633466303566353338626666646533616137393336333333 34346438386461633366353838346664663832323436333737306566333164323066313931643630
30393733316636353266653039346237363830333831383535646531616130353534633062643135 33363733356231326636646133366136663431343038643265633136626363343131656463373264
64373533646462313035383236333866313866366130663863363162613234393762646662666233 65363833353831656638303439623636373062383235363966356332343163616336643735306466
30653666353333366365343036643462346361303536363935396133343166303339623461376563 65663366643030626437326439633665333564623065633431636232393465623365636565363230
39333163636466646534356337656431376663623833303235303534633634386665636162346634 38393664653432383539376363366462386438663137363562323231663661353635383866373761
34646665633639663763316339663539663261333436363935316334656330313835616138626237 66303165323861626538353236366533336533333939376232313038343331663833303864356235
35623363393532633937653132303635396536646635633062393661616538303631663136363038 64383664376237346465626339336536393537323665653766363464393133323637646264643830
35623539303963383063343338653130643233636537356264323238633839303337383665393333 32376435623666383633383636323862376166623938346239363339336333373531376433383032
36303330393638643464646535653833626531343634626531396261363139326336623765623039 39656466363761376565653936366430363638623332636532383431373334386436373737323163
32613237636366376463343766303964336661363432646436373963626537373137396661633766 61616230396135353831343139346464623261303231633035353264626232393933393732393634
63633830663035663764303634643662333464353234646232343066306131336533396435313239 35353531626532626334613836623633636265613963613064626334363436336664363633653636
66366630643564313665306130656463633065646430373334336664633264353336376439666137 64366262336134653932386236663161623639626562303135386532366261396134613664653037
65366537366462623136353539373961333238373733663837373430663865643334393565333861 63656665393835653831366464386236303239363338623338653833653430323135333063616266
35363035343561633164613631633532623164376339633630393633396437333034376339656538 61383539613066623563616139666261373066316662636633613561366466623032386434366137
32653030626434326632386635383739663932393331333062656565303939373566653031613839 63643030653538623039353934373531633034386665303866623835356433353666653831326464
31363162666330393232646562333833633266643165316464623533623539356339333365623966 32323134323333386563316230656362396635656461643061393562393766633736613361373637
65323638396531346261303835373138333262323466656263643737343734303237303638353036 65663763373139343162643431353039613565333639336530666164343239653461623734303538
3733 30613432363233353335373539653439313333353537343733616432316338343836336539613832
63353363373536333731636431336433333061336537353231656430343434613836383264663634
38346165373533663330373964303161373331316666633865333538656136656637346266313237
30376135656230353464643262633837336465376434323166663731346130626338613138656161
34623765316239363863626139333536376534396563623631643231616266656238383763386137
30313162373338653131623464396362666163656638656164656131616631373833373936373539
37633861306362383762363733333233623134616565383037336539343937633663356262376133
38656630343136613337663164643338323261613033383564353330306465663932653566376465
63613933626164303466366539303863366263366638663830333861663734616439316463373537
66396433663764336630643038323964656131393731623733393133653432663763326662643137
38323130336137356263303961363562623235343765356366353964396636306235616435663932
39663732313066663834616664336631376639336536323230333462386636333234373063336535
66633238666639643632383666666136383834313162396265386466643130313736653239653231
64613637646539626432613532633231343634363263363331346434613833376532323366643063
61386565316132386162663539623164626234383665336234653534336461623632636461323934
66653966656230366166363535656261363534636136376566333566313564363361316563653638
61643361383263643833636639643362613134623464346537386237616464626265

View File

@@ -1 +0,0 @@
domain: cazzzer.com

View File

@@ -1,6 +1,8 @@
# Environment specific variables (prod) # Environment specific variables (prod)
--- ---
domain: cazzzer.com
docker_ipv6_index: 255 docker_ipv6_index: 255
# Arrstack VPN # Arrstack VPN
@@ -18,3 +20,7 @@ google_consumer_secret: "{{ vault_google_consumer_secret }}"
# VPGen # VPGen
vpgen_ipv4_starting_addr: 10.18.11.100 vpgen_ipv4_starting_addr: 10.18.11.100
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}" vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"
# Woodpecker
woodpecker_gitea_client_id: 3b7515f3-6005-4512-a2ee-5464dba315f8
woodpecker_gitea_client_secret: "{{ vault_woodpecker_gitea_client_secret }}"

View File

@@ -1,27 +1,32 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
64376262343730306465343137353235393430646535633031646432363631643061656336313962 36313835643238353932323631323439626432316436346533376365633332313963666433313333
6661643832613835353937313832393762613430616338360a356137373036343037316635666366 6134633133636133623130376237373462383164396338380a316463396139653161366536636336
62643132656233663933353239653438316238353363326539353038383436613038356137643836 64346664356538366538363239306631326464633635316161663963326635656430326637333963
6265373939326266640a376162333266313333653339383533303639393932373266356361313763 6462633236353132300a323062353639646238663737353461633733636530613036316364353864
65346235626430323232393161643932316161383564393663343039626431366130353066636265 34326534376639643734303137613866393464306334336566653134333765356361386436323939
63643639383162326235373636393435316338393431393166663835623739356562633435373438 35393535303635376162386266396431313739663961643061623037343463303637623130623131
30393630623261353134313038643464306637383738303163353937316261313263613264393939 31653761616639613964386432643561376637316435333064343837636463303033333432636234
37363037616230623732663866656665666664393835313836393237303234303866393437393833 39323735373161616133396566316266383165343033666530376333626264643531613334363634
34376335353133613938663861323062623763323463316563363439623030653033373538323436 35393766623361346461333764666139366632306362613362376133363239656562346263643066
38333863353333323364396431373030386636366330323562663831376531333661613337303835 65616538366532346537383432663766366161633234373562623531356339666661346164306563
35643464396332333436633036326563613863636238353837643965303862636665303362336162 35343339386631383462656466303563376237386137346437323634626163353464356462346364
34623430353061613364643436343736613734326332316465356333626534303166636638336236 35373061636237383335396231326563366230663566333665326338303564326263316630666233
36613362666337616635316330396635616165346666396465303861386162353836333332663931 65303930663862313137333630353837363265333532303133306466643462626662613166326132
64663838646332316363376339666632336238613365636666623137663564313665363461393163 66346439333739653965346236313766346532356233333164633538326135643662623533646561
35303735613734393439376339396466643065316432383236393633376461316534623535396464 65626530386333303362343830653430653866336261623566616362313739303939656364656363
62386464396534333561323539646336623464623033333835356439353632373033373736393134 37336331353766633534653936626139303061623531323362346564363665663438646533646166
30666435306632336433383562303238363361313735323439366638333033653761393061303130 62376534653562373138656465666133353235313935626534383537643436376665613865303363
36633536356264376366383335623534323436383361373037383931313766353534363663336462 62326562396361306131616363363866316232623635353663323537366563333239383636643763
39353064306439306135623863643163393762333366303665623432386462333466626535613464 35623366663463303831323730363036306363643364303532326339353633393739306366396331
65613031666530303163353534323032396264666464303639383038343537303839633831373039 33313230656431623462376135623438633164323064653866646165643263383832353138633931
61323437313737623530663532626530613935353431306138623239386136323334636163343432 66306463346361646561376334613837383762366365666638643434383034376339643239646463
65633933643630643634336639393866353739653638656366356163343132656666336232643731 66343461363233626635323535336462666339323032616136396239396534346434623238396330
65363639623262613132646366353235626237646532373233626162643434396362313033653637 37653665643366323362313136386231396532323035363963623738346564356435303263303832
36333035646634616138313863386637346466393262363833313135343964666630623736343666 37346532366432363638363330316464366361313461626535616165333433343835393565633766
64373638333066343666306334366332366530623138306636633166613739363635303138633434 32663162386562373035333335303332323136613233613431386265626337653939326435396262
3439326265613564666639363362643037653733393336363232 61303631633838613962346663326232636438393563396230306361333335383462653432383766
35376662353262303635316635363130383032366530396439613861653037383234363831333562
37343332646534353838626366623361636261393865363633303631613837323733626264643835
63376430613234386463336234623062656534643863656434386134616265333666613939393331
39333166393538306135313431303831623063363533326330633062653333313733653831383736
613864303461323739336563356161353234

View File

@@ -1 +0,0 @@
domain: lab.cazzzer.com

View File

@@ -1,6 +1,8 @@
# Environment specific variables (staging) # Environment specific variables (staging)
--- ---
domain: lab.cazzzer.com
docker_ipv6_index: 254 docker_ipv6_index: 254
# Arrstack VPN # Arrstack VPN
@@ -18,3 +20,7 @@ google_consumer_secret: "{{ vault_google_consumer_secret }}"
# VPGen # VPGen
vpgen_ipv4_starting_addr: 10.18.11.50 vpgen_ipv4_starting_addr: 10.18.11.50
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}" vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"
# Woodpecker
woodpecker_gitea_client_id: c7122416-b160-498b-8021-8f2837552588
woodpecker_gitea_client_secret: "{{ vault_woodpecker_gitea_client_secret }}"

View File

@@ -1,27 +1,32 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
66646463303166643563376162636432643963336537343738383763653232316661383864373761 36343339366166383430383235626463376339653331333635623936653135633633353064613634
3539643230626437623736353630663865376630663765650a666266663366393833396461303665 3263306161376232356634363532653266366665333364650a636365393465383165306563346132
61663961623036383039323239333361396564343836363662326237666464363439643336613336 37653564633630653635353464333939353266396562316663653933373065353536333130383065
6562666639313461330a613831316232623963396136343638643133376430373634316133653432 3864353332303164320a316439313164663736636465366539643131303663343861333164613561
65633339623833303866343130386433633065326466333636353362306362663830333934393364 37383965373964313535313335643164376164323263613539643933333035323837373662303030
35613338316631333438623230623131626431633930313664616237396666326665633965373333 66636465303566313334386435326433653032383962353739643861346161323738636366396239
33636234666561656333623836633562363130346665623839353734616437303562623530613432 39623336336234376339343562656362323932383265313161396435346530663330353266323433
31313037366232613335613262336334393966326139633332613733326335383130316265613038 66396538313365653963323164306464663565303364386466666636346533633661333634313236
35366162623737666331636435643234383634663964666465666563396262336134306636343830 33623936616239613264613730363039366561646535633239633564656166343162303633373366
30373831393232373664666564316134316266376134323538366130383962396566386161303461 37656163333838656533363735383332626632353237613666396633363531666366336630613064
31336333633135323631373763346631656132346334356233303630643166323565393736336236 66626561663766376531313666663963643766393965653564333062653139336230356330383464
39343231313132316663613734323833303935333162643862623632316662653736303266336635 38343562383430303132663964303736623238386562323033623861303432363363373934643332
37316435633464343761656262326538633730616239366330363736323761653061306139623335 63363239323664333131306237336134613137653136633932356238343733393632616464366134
33363066383636633461353534396433653161393132313034373165653563646234653764306539 33623038363032653134626337663863366663383433633134326239616136656139366535613565
32653239613566653762613364653863313334653437646166643537633530613463653966383538 61646330356330396236303566363834613236653733643162666536303435643133346633353632
37343834326162393739333066623066613566313265626562333537366230393938613931366638 62386135303262353332643135636164303963616234626132356161663463366434323864626261
36316364383361366461396136353063363233353865373062643963646266643763363938376265 33356536626263626261343937386666396561306334346435316262333431353234303836356563
34623333316264383035373266313437353161666537376535333830616435383830366166316136 31343566373935396633636133616265346235396333396664333534336162323039623937656336
33643132316534383466343366303764633031353961363033663662636364613132343862653066 36656133383966613333646336613039626563353862646238376461373264633233313836333062
39376136323662383866666136656361396263666338623133346436353938316464346363303761 30343134363862626630393035643762376435346532306462363437646238333463396230666465
39656133653736646137396437396133373765376337623832653232383531663930663037323462 64386365393063613139313164366562643066323461313364393265393638643137386561633530
66373630633737356138333532333265393964313739336363663265613363636464623232316539 65643861386531323836306339386462656530383533363831323461303131396666626464303136
37353164393965616363346666303330613438306136363037313065666662656535356437663262 64343865616235616366633136393662623862383961323338366435396334653538303830616166
37306264626431396336326362653764316536396366393533336164663861366462653964656465 39636164613466313033643639366635323666666235653633333436613133343962353664313838
64366139333535383065643033343632323837633036323439376134373966613739626261376436 64356466393239666131363964643461346633313030643061643938643232343334313731636463
3133326138613735316230353965656239303263386638373339 37396637643232353539626239306463623237623534366666396164613135356136313534663231
36613662653237343061316463386231656136383636393034333666633063613731316162333464
64313866633062623530326233633166343434636639346565346337396461393637383333366435
62393030383963396638653230613431623837353461313630343333376131616239313164336234
62323739316536353835613032303438623230626563303934626466303934613566656232323663
643265386333313065333737613438316532

36
poetry.lock generated
View File

@@ -1,28 +1,28 @@
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
[[package]] [[package]]
name = "ansible" name = "ansible"
version = "10.7.0" version = "11.1.0"
description = "Radically simple IT automation" description = "Radically simple IT automation"
optional = false optional = false
python-versions = ">=3.10" python-versions = ">=3.11"
files = [ files = [
{file = "ansible-10.7.0-py3-none-any.whl", hash = "sha256:0089f08e047ceb70edd011be009f5c6273add613fbe491e9697c0556c989d8ea"}, {file = "ansible-11.1.0-py3-none-any.whl", hash = "sha256:bbaf7073993f019fc0293fc8b76c7b215081831957c28eb020f12c270a16e8f0"},
{file = "ansible-10.7.0.tar.gz", hash = "sha256:59d29e3de1080e740dfa974517d455217601b16d16880314d9be26145c68dc22"}, {file = "ansible-11.1.0.tar.gz", hash = "sha256:d01b425990d960d2a33fc378e1b73dbca1c0e28bc22f4056ab6b3c8e9ae74fba"},
] ]
[package.dependencies] [package.dependencies]
ansible-core = ">=2.17.7,<2.18.0" ansible-core = ">=2.18.1,<2.19.0"
[[package]] [[package]]
name = "ansible-core" name = "ansible-core"
version = "2.17.7" version = "2.18.1"
description = "Radically simple IT automation" description = "Radically simple IT automation"
optional = false optional = false
python-versions = ">=3.10" python-versions = ">=3.11"
files = [ files = [
{file = "ansible_core-2.17.7-py3-none-any.whl", hash = "sha256:64d4f0a006687a5621aa80dca54fd0c5ae75145b7aac8c1b8d7f07a1399c4705"}, {file = "ansible_core-2.18.1-py3-none-any.whl", hash = "sha256:4a312e416e09c7271188d6b8e2b1062fc6834fefd6a1814d0e02fb8aadb3e1ba"},
{file = "ansible_core-2.17.7.tar.gz", hash = "sha256:3aaab735d6c4e2d6239bc326800dc0ecda2a1490caa8455b41084ec0bc54dacf"}, {file = "ansible_core-2.18.1.tar.gz", hash = "sha256:14cac1f92bbdae881cb0616eddeb17925e8cb507e486087975e724533d9de74f"},
] ]
[package.dependencies] [package.dependencies]
@@ -418,25 +418,25 @@ test = ["commentjson", "packaging", "pytest"]
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "75.6.0" version = "75.7.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.9"
files = [ files = [
{file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, {file = "setuptools-75.7.0-py3-none-any.whl", hash = "sha256:84fb203f278ebcf5cd08f97d3fb96d3fbed4b629d500b29ad60d11e00769b183"},
{file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, {file = "setuptools-75.7.0.tar.gz", hash = "sha256:886ff7b16cd342f1d1defc16fc98c9ce3fde69e087a4e1983d7ab634e5f41f4f"},
] ]
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"]
core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
cover = ["pytest-cov"] cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
enabler = ["pytest-enabler (>=2.2)"] enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.11"
content-hash = "334448cb0c7d192f0e10987a995ecefca5e136733cce4dd15dcc2238f1c371c8" content-hash = "7c5b28e1b7fc5cf1c55fedf89a01f26e9246b9d1baa1441d51a8693697b6767a"

View File

@@ -6,8 +6,8 @@ authors = ["Iurii Tatishchev <itatishch@gmail.com>"]
readme = "README.md" readme = "README.md"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.10" python = "^3.11"
ansible = "^10.1.0" ansible = "^11.1.0"
ansible-vault = "^2.1.0" ansible-vault = "^2.1.0"
netaddr = "^1.3.0" netaddr = "^1.3.0"

View File

@@ -11,7 +11,7 @@
path: "{{ current_stack_dest }}/{{ item.path }}" path: "{{ current_stack_dest }}/{{ item.path }}"
state: directory state: directory
mode: "755" mode: "755"
loop: "{{ lookup('community.general.filetree', current_stack_source) }}" loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "directory" when: item.state == "directory"
- name: Generate {{ current_stack_name }} deployment from templates - name: Generate {{ current_stack_name }} deployment from templates
@@ -19,7 +19,7 @@
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ current_stack_dest }}/{{ item.path | regex_replace('\\.j2$', '') }}" dest: "{{ current_stack_dest }}/{{ item.path | regex_replace('\\.j2$', '') }}"
mode: "644" mode: "644"
loop: "{{ lookup('community.general.filetree', current_stack_source) }}" loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "file" and item.path | regex_search('\\.j2$') when: item.state == "file" and item.path | regex_search('\\.j2$')
- name: Generate {{ current_stack_name }} deployment from static files - name: Generate {{ current_stack_name }} deployment from static files
@@ -27,7 +27,7 @@
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ current_stack_dest }}/{{ item.path }}" dest: "{{ current_stack_dest }}/{{ item.path }}"
mode: "644" mode: "644"
loop: "{{ lookup('community.general.filetree', current_stack_source) }}" loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "file" and not item.path | regex_search('\\.j2$') when: item.state == "file" and not item.path | regex_search('\\.j2$')
- name: Deploy docker-compose for {{ current_stack_name }} - name: Deploy docker-compose for {{ current_stack_name }}

View File

@@ -28,8 +28,11 @@
collection: apps collection: apps
stacks: stacks:
- gitea - gitea
- woodpecker
- nextcloud - nextcloud
- jellyfin - jellyfin
- arrstack - arrstack
- vpgen - vpgen
- pgrok
- obsidian-livesync
import_tasks: deploy_collection.yml import_tasks: deploy_collection.yml

View File

@@ -2,8 +2,6 @@
networks: networks:
{{ helpers.default_network(249) | indent(2) }} {{ helpers.default_network(249) | indent(2) }}
traefik_traefik:
external: true
services: services:
gluetun: gluetun:
@@ -11,14 +9,13 @@ services:
container_name: gluetun container_name: gluetun
cap_add: cap_add:
- NET_ADMIN - NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
sysctls: sysctls:
- net.ipv6.conf.all.disable_ipv6=0 - net.ipv6.conf.all.disable_ipv6=0
env_file: env_file:
- .env.gluetun - .env.gluetun
restart: unless-stopped restart: unless-stopped
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/arrstack/gluetun:/gluetun - {{ base_volume_path }}/arrstack/gluetun:/gluetun
@@ -49,9 +46,6 @@ services:
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- qbittorrent - qbittorrent
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/arrstack/config/prowlarr:/config - {{ base_volume_path }}/arrstack/config/prowlarr:/config
@@ -63,9 +57,6 @@ services:
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- qbittorrent - qbittorrent
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/arrstack/config/sonarr:/config - {{ base_volume_path }}/arrstack/config/sonarr:/config
- {{ base_volume_path }}/arrstack/downloads:/downloads - {{ base_volume_path }}/arrstack/downloads:/downloads
@@ -79,9 +70,6 @@ services:
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- qbittorrent - qbittorrent
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/arrstack/config/radarr:/config - {{ base_volume_path }}/arrstack/config/radarr:/config
- {{ base_volume_path }}/arrstack/downloads:/downloads - {{ base_volume_path }}/arrstack/downloads:/downloads

View File

@@ -2,8 +2,6 @@
networks: networks:
{{ helpers.default_network(199) | indent(2) }} {{ helpers.default_network(199) | indent(2) }}
traefik_traefik:
external: true
services: services:
server: server:
@@ -14,9 +12,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.gitea - .env.gitea
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/gitea/gitea:/data - {{ base_volume_path }}/gitea/gitea:/data
depends_on: depends_on:
@@ -27,7 +22,5 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.db - .env.db
networks:
- default
volumes: volumes:
- {{ base_volume_path }}/gitea/postgres:/var/lib/postgresql/data - {{ base_volume_path }}/gitea/postgres:/var/lib/postgresql/data

View File

@@ -2,8 +2,6 @@
networks: networks:
{{ helpers.default_network(197) | indent(2) }} {{ helpers.default_network(197) | indent(2) }}
traefik_traefik:
external: true
services: services:
jellyfin: jellyfin:
@@ -14,9 +12,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.jellyfin - .env.jellyfin
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/jellyfin/config:/config - {{ base_volume_path }}/jellyfin/config:/config
- {{ base_volume_path }}/jellyfin/cache:/cache - {{ base_volume_path }}/jellyfin/cache:/cache

View File

@@ -2,9 +2,6 @@
networks: networks:
{{ helpers.default_network(198) | indent(2) }} {{ helpers.default_network(198) | indent(2) }}
traefik_traefik:
external: true
services: services:
app: app:
@@ -18,8 +15,6 @@ services:
- redis - redis
env_file: env_file:
- .env.nextcloud - .env.nextcloud
networks:
- default
volumes: volumes:
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html - {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config - {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
@@ -32,8 +27,6 @@ services:
depends_on: depends_on:
- app - app
entrypoint: /cron.sh entrypoint: /cron.sh
networks:
- default
volumes: volumes:
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html - {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config - {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
@@ -42,16 +35,8 @@ services:
notify_push: notify_push:
image: nextcloud:${NEXTCLOUD_VERSION} image: nextcloud:${NEXTCLOUD_VERSION}
container_name: nextcloud_notify_push container_name: nextcloud_notify_push
{# TODO: Refactor this and minio -#}
labels: labels:
- traefik.enable=true - {{ helpers.traefik_labels('nc', port='7867', path_prefix='/push') | indent(6) }}
- traefik.http.routers.nc-notify.rule=Host(`nc.{{ domain }}`) && PathPrefix(`/push`)
- traefik.http.routers.nc-notify.entrypoints=websecure
- traefik.http.routers.nc-notify.tls=true
- traefik.http.routers.nc-notify.tls.certresolver=letsencrypt
- traefik.http.routers.nc-notify.tls.domains.0.main={{ domain }}
- traefik.http.routers.nc-notify.tls.domains.0.sans=*.{{ domain }}
- traefik.http.services.nc-notify.loadbalancer.server.port=7867
restart: unless-stopped restart: unless-stopped
user: www-data user: www-data
env_file: env_file:
@@ -68,8 +53,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.db - .env.db
networks:
- default
volumes: volumes:
- {{ base_volume_path }}/nextcloud/db:/var/lib/postgresql/data - {{ base_volume_path }}/nextcloud/db:/var/lib/postgresql/data
@@ -79,8 +62,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.redis - .env.redis
networks:
- default
command: command:
- sh - sh
- -c - -c

View File

@@ -0,0 +1,30 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(199) | indent(2) }}
services:
couchdb:
image: couchdb
container_name: obsidian-livesync
# user: 1000:1000
environment:
- COUCHDB_USER=hi
- COUCHDB_PASSWORD=3hCtyJ3bPFjxxGu4
volumes:
- {{ base_volume_path }}/obsidian-livesync:/opt/couchdb/data
# Ports not needed when already passed to Traefik
#ports:
# - 5984:5984
restart: unless-stopped
labels:
- {{ helpers.traefik_labels('obsidian-livesync', port='5984') | indent(6) }}
- traefik.http.routers.r-obsidian-livesync.middlewares=obsidiancors
- # https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/setup_own_server.md
# The part needed for CORS to work on Traefik 2.x starts here
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowmethods=GET,PUT,POST,HEAD,DELETE"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowheaders=accept,authorization,content-type,origin,referer"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolalloworiginlist=app://obsidian.md,capacitor://localhost,http://localhost"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolmaxage=3600"
- "traefik.http.middlewares.obsidiancors.headers.addvaryheader=true"
- "traefik.http.middlewares.obsidiancors.headers.accessControlAllowCredentials=true"

View File

@@ -0,0 +1,31 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(194) | indent(2) }}
# https://github.com/pgrok/pgrok/blob/main/docs/admin/docker.md#docker-compose
services:
server:
image: ghcr.io/pgrok/pgrokd:latest
container_name: pgrok_server
labels:
- {{ helpers.traefik_labels('pgrok', port='3320') | indent(6) }}
- {{ helpers.traefik_labels('pgrok', port='3000', wildcard=true) | indent(6) }}
restart: unless-stopped
volumes:
- ./pgrokd.yml:/var/opt/pgrokd/pgrokd.yml
ports:
- "2222:2222"
depends_on:
- db
db:
image: postgres:17-alpine
container_name: pgrok_db
restart: unless-stopped
volumes:
- {{ base_volume_path }}/pgrok/postgres:/var/lib/postgresql/data
environment:
POSTGRES_DB: pgrok
POSTGRES_USER: pgrok
POSTGRES_PASSWORD: "{{ pgrok_db_password }}"

View File

@@ -0,0 +1,29 @@
external_url: "https://pgrok.{{ domain }}"
web:
port: 3320
proxy:
port: 3000
scheme: https
domain: "pgrok.{{ domain }}"
sshd:
port: 2222
database:
host: db
port: 5432
user: pgrok
password: "{{ pgrok_db_password }}"
database: pgrok
identity_provider:
type: oidc
display_name: Authentik
issuer: "https://auth.{{ domain }}/application/o/pgrok/"
client_id: "pgrok"
client_secret: "{{ auth_pgrok_client_secret }}"
field_mapping:
identifier: "preferred_username"
display_name: "name"
email: "email"
# # The required domain name, "field_mapping.email" is required to set for this to work.
# required_domain: "example.com"

View File

@@ -0,0 +1,35 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(195) | indent(2) }}
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
container_name: woodpecker_server
labels:
- {{ helpers.traefik_labels('woodpecker', port='8000') | indent(6) }}
restart: unless-stopped
volumes:
- {{ base_volume_path }}/woodpecker/data:/var/lib/woodpecker
environment:
- WOODPECKER_OPEN=true
- WOODPECKER_HOST=https://woodpecker.{{ domain }}
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://gitea.{{ domain }}
- WOODPECKER_GITEA_CLIENT={{ woodpecker_gitea_client_id }}
- WOODPECKER_GITEA_SECRET={{ woodpecker_gitea_client_secret }}
- WOODPECKER_AGENT_SECRET={{ woodpecker_agent_secret }}
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
container_name: woodpecker_agent
restart: unless-stopped
depends_on:
- woodpecker-server
volumes:
- {{ base_volume_path }}/woodpecker/agent_config:/etc/woodpecker
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET={{ woodpecker_agent_secret }}

View File

@@ -92,8 +92,8 @@ entries:
model: authentik_stages_user_write.userwritestage model: authentik_stages_user_write.userwritestage
id: enrollment-user-write id: enrollment-user-write
attrs: attrs:
user_creation_mode: always_create
user_type: internal user_type: internal
create_users_group: !Find [authentik_core.group, [name, {{ auth_default_enrollment_group }}]]
- identifiers: - identifiers:
name: alpina-enrollment-email-verify name: alpina-enrollment-email-verify
model: authentik_stages_email.emailstage model: authentik_stages_email.emailstage

View File

@@ -38,3 +38,8 @@ entries:
return { return {
"policy": policy, "policy": policy,
} }
- identifiers:
name: "vpgen"
model: authentik_core.group
id: "vpgen"

View File

@@ -76,4 +76,4 @@ entries:
model: authentik_stages_user_write.userwritestage model: authentik_stages_user_write.userwritestage
attrs: attrs:
user_type: internal user_type: internal
group: !Find [authentik_core.group, [name, users]] create_users_group: !Find [authentik_core.group, [name, {{ auth_default_enrollment_group }}]]

View File

@@ -38,6 +38,13 @@ entries:
"icon": "https://vpgen."~ domain ~"/favicon.png", "icon": "https://vpgen."~ domain ~"/favicon.png",
"client_secret": auth_vpgen_client_secret, "client_secret": auth_vpgen_client_secret,
"ui_group": "Apps", "ui_group": "Apps",
"allowed_for_groups": ["admins", "users", "vpgen"],
},
"Pgrok": {
"redirect_uri": "https://pgrok."~ domain ~"/-/oidc/callback",
"icon": "https://pgrok."~ domain ~"/pgrok.svg",
"client_secret": auth_pgrok_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users"], "allowed_for_groups": ["admins", "users"],
}, },
} -%} } -%}

View File

@@ -2,8 +2,6 @@
networks: networks:
{{ helpers.default_network(253) | indent(2) }} {{ helpers.default_network(253) | indent(2) }}
traefik_traefik:
external: true
services: services:
server: server:
@@ -17,13 +15,11 @@ services:
restart: unless-stopped restart: unless-stopped
# Port forward is needed because traefik can't resolve the container name from the host network # Port forward is needed because traefik can't resolve the container name from the host network
ports: ports:
- "9000:9000" - "127.0.0.1:9000:9000"
- "[::1]:9000:9000"
command: server command: server
env_file: env_file:
- .env.authentik - .env.authentik
networks:
- default
- traefik_traefik
worker: worker:
image: ghcr.io/goauthentik/server:latest image: ghcr.io/goauthentik/server:latest

View File

@@ -0,0 +1,19 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(252) | indent(2) }}
services:
minio:
image: minio/minio:latest
container_name: minio
labels:
- {{ helpers.traefik_labels('minio', port='9090') | indent(6) }}
- {{ helpers.traefik_labels('s3', port='9000') | indent(6) }}
- {{ helpers.traefik_labels('s3', port='9000', wildcard=true) | indent(6) }}
restart: unless-stopped
command: server --console-address ":9090" /data
env_file:
- .env.minio
volumes:
- {{ base_volume_path }}/minio/data:/data

View File

@@ -1,32 +0,0 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(252) | indent(2) }}
traefik_traefik:
external: true
services:
minio:
image: minio/minio:latest
container_name: minio
labels:
- {{ helpers.traefik_labels('minio', port='9090') | indent(6) }}
- traefik.http.routers.minio.service=minio
- traefik.http.routers.minio-tls.service=minio
- traefik.http.routers.minio-s3.rule=Host(`s3.{{ domain }}`) || HostRegexp(`^.+[.]s3[.]{{ domain }}`)
- traefik.http.routers.minio-s3.entrypoints=websecure
- traefik.http.routers.minio-s3.tls=true
- traefik.http.routers.minio-s3.tls.certresolver=letsencrypt
- traefik.http.routers.minio-s3.tls.domains.0.main=s3.{{ domain }}
- traefik.http.routers.minio-s3.tls.domains.0.sans=*.s3.{{ domain }}
- traefik.http.routers.minio-s3.service=minio-s3
- traefik.http.services.minio-s3.loadbalancer.server.port=9000
restart: unless-stopped
command: server --console-address ":9090" /data
env_file:
- .env.minio
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/minio/data:/data

View File

@@ -2,8 +2,6 @@
networks: networks:
{{ helpers.default_network(251) | indent(2) }} {{ helpers.default_network(251) | indent(2) }}
traefik_traefik:
external: true
services: services:
grafana: grafana:
@@ -17,9 +15,6 @@ services:
restart: unless-stopped restart: unless-stopped
# Needed to make config files readable (not anymore, TODO: remove) # Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}" user: "{{ remote_uid }}"
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/monitoring/grafana:/var/lib/grafana - {{ base_volume_path }}/monitoring/grafana:/var/lib/grafana
- ./grafana_config/grafana.ini:/etc/grafana/grafana.ini:ro - ./grafana_config/grafana.ini:/etc/grafana/grafana.ini:ro
@@ -36,7 +31,8 @@ services:
- -config.file=/etc/loki/loki-config.yaml - -config.file=/etc/loki/loki-config.yaml
# Port forward is needed because not possible to resolve the container name from the host network # Port forward is needed because not possible to resolve the container name from the host network
ports: ports:
- 3100:3100 - "127.0.0.1:3100:3100"
- "[::1]:3100:3100"
volumes: volumes:
- {{ base_volume_path }}/monitoring/loki:/loki - {{ base_volume_path }}/monitoring/loki:/loki
- ./loki_config:/etc/loki:ro - ./loki_config:/etc/loki:ro
@@ -103,9 +99,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.influxdb - .env.influxdb
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/monitoring/influxdb:/var/lib/influxdb2 - {{ base_volume_path }}/monitoring/influxdb:/var/lib/influxdb2

View File

@@ -1,27 +1,81 @@
from grafanalib.core import Template from attrs import define
from grafanalib.core import Template, TimeSeries, Dashboard, HIDE_VARIABLE, Target
# TODO: consider default params for common params like line width, show points, tooltip CONF_SUPPORT_LOKI = True
CONF_SUPPORT_ZFS = True
PrometheusTemplate = Template( CONF_DATASOURCE_VAR_PROM = 'prom_datasource'
name='datasource', CONF_DATASOURCE_VAR_LOKI = 'loki_datasource'
prom_datasource = f'${{{CONF_DATASOURCE_VAR_PROM}}}'
loki_datasource = f'${{{CONF_DATASOURCE_VAR_LOKI}}}'
prom_template = Template(
name=CONF_DATASOURCE_VAR_PROM,
type='datasource', type='datasource',
label='Prometheus', label='Prometheus',
query='prometheus', query='prometheus',
hide=HIDE_VARIABLE,
) )
# TODO: this slightly less (clown emoji), normal Target gave me errors in grafana loki_template = Template(
name=CONF_DATASOURCE_VAR_LOKI,
type='datasource',
label='Loki',
query='loki',
hide=HIDE_VARIABLE,
)
@define
class MyDashboard(Dashboard):
"""Wrapper class for Dashboard with some default values"""
timezone: str = 'browser'
sharedCrosshair: bool = True
@define
class MyTimeSeries(TimeSeries):
"""Wrapper class for TimeSeries with some default values and custom fields"""
fillOpacity: int = 10
lineWidth: int = 1
showPoints: str = 'never'
tooltipMode: str = 'multi'
maxDataPoints: int = None
# new fields
axisCenteredZero: bool = False
def to_json_data(self):
data = super().to_json_data()
data['fieldConfig']['defaults']['custom']['axisCenteredZero'] = self.axisCenteredZero
return data
@define
class PromTarget(Target):
"""Wrapper class for Target with default prometheus datasource"""
datasource: str = prom_datasource
@define
class LokiTarget(object): class LokiTarget(object):
def __init__(self, loki_datasource, expr, legendFormat, refId): """Custom class for Loki Target, because normal Target gave errors in grafana"""
self.loki_datasource = loki_datasource expr: str
self.expr = expr legendFormat: str
self.legendFormat = legendFormat datasource: str = loki_datasource
self.refId = refId refId: str = None
queryType: str = 'range'
def to_json_data(self): def to_json_data(self):
return { return {
'datasource': self.loki_datasource, 'datasource': self.datasource,
'expr': self.expr, 'expr': self.expr,
'legendFormat': self.legendFormat, 'legendFormat': self.legendFormat,
'refId': self.refId, 'refId': self.refId,
'queryType': 'range', 'queryType': self.queryType,
} }
def filter_none(l: list):
return [i for i in l if i is not None]

View File

@@ -1,16 +1,10 @@
from grafanalib.core import ( from grafanalib.core import GridPos, Templating, Template, Logs
Dashboard, TimeSeries,
Target, GridPos,
Templating, Template, REFRESH_ON_TIME_RANGE_CHANGE, Logs
)
from grafanalib.formatunits import BYTES_IEC, SECONDS, BYTES_SEC_IEC from grafanalib.formatunits import BYTES_IEC, SECONDS, BYTES_SEC_IEC
from common import LokiTarget, PrometheusTemplate from common import LokiTarget, prom_template, loki_template, MyTimeSeries, MyDashboard, CONF_SUPPORT_LOKI, filter_none, \
prom_datasource, PromTarget
prom_datasource='${datasource}' dashboard = MyDashboard(
loki_datasource='loki'
dashboard = Dashboard(
title='Containers', title='Containers',
uid='containers', uid='containers',
description='Data for compose projects from default Prometheus datasource collected by Cadvisor', description='Data for compose projects from default Prometheus datasource collected by Cadvisor',
@@ -18,8 +12,9 @@ dashboard = Dashboard(
'linux', 'linux',
'docker', 'docker',
], ],
templating=Templating(list=[ templating=Templating(list=filter_none([
PrometheusTemplate, prom_template,
loki_template if CONF_SUPPORT_LOKI else None,
Template( Template(
name='compose_project', name='compose_project',
label='Compose Project', label='Compose Project',
@@ -27,7 +22,6 @@ dashboard = Dashboard(
query='label_values({__name__=~"container.*"}, container_label_com_docker_compose_project)', query='label_values({__name__=~"container.*"}, container_label_com_docker_compose_project)',
includeAll=True, includeAll=True,
multi=True, multi=True,
refresh=REFRESH_ON_TIME_RANGE_CHANGE,
), ),
Template( Template(
name='container_name', name='container_name',
@@ -36,7 +30,6 @@ dashboard = Dashboard(
query='label_values({__name__=~"container.*", container_label_com_docker_compose_project=~"$compose_project"}, name)', query='label_values({__name__=~"container.*", container_label_com_docker_compose_project=~"$compose_project"}, name)',
includeAll=True, includeAll=True,
multi=True, multi=True,
refresh=REFRESH_ON_TIME_RANGE_CHANGE,
), ),
Template( Template(
name='logs_query', name='logs_query',
@@ -44,67 +37,48 @@ dashboard = Dashboard(
query='', query='',
type='textbox', type='textbox',
), ),
]), ])),
timezone='browser', panels=filter_none([
panels=[ MyTimeSeries(
TimeSeries(
title='Container Memory Usage', title='Container Memory Usage',
unit=BYTES_IEC, unit=BYTES_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=0), gridPos=GridPos(h=8, w=12, x=0, y=0),
lineWidth=2,
fillOpacity=10,
showPoints='never',
stacking={'mode': 'normal'},
tooltipMode='all',
tooltipSort='desc', tooltipSort='desc',
stacking={'mode': 'normal'},
targets=[ targets=[
Target( PromTarget(
datasource=prom_datasource,
expr='max by (name) (container_memory_usage_bytes{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"})', expr='max by (name) (container_memory_usage_bytes{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"})',
legendFormat='{{ name }}', legendFormat='{{ name }}',
refId='A',
), ),
], ],
), ),
TimeSeries( MyTimeSeries(
title='Container CPU Usage', title='Container CPU Usage',
unit=SECONDS, unit=SECONDS,
gridPos=GridPos(h=8, w=12, x=12, y=0), gridPos=GridPos(h=8, w=12, x=12, y=0),
lineWidth=2,
fillOpacity=10,
showPoints='never',
tooltipMode='all',
tooltipSort='desc', tooltipSort='desc',
stacking={'mode': 'normal'},
targets=[ targets=[
Target( PromTarget(
datasource=prom_datasource, expr='max by (name) (irate(container_cpu_usage_seconds_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
expr='max by (name) (rate(container_cpu_usage_seconds_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat='{{ name }}', legendFormat='{{ name }}',
refId='A',
), ),
], ],
), ),
TimeSeries( MyTimeSeries(
title='Container Network Traffic', title='Container Network Traffic',
unit=BYTES_SEC_IEC, unit=BYTES_SEC_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=8), gridPos=GridPos(h=8, w=12, x=0, y=8),
lineWidth=2,
fillOpacity=10,
showPoints='never',
tooltipMode='all',
tooltipSort='desc', tooltipSort='desc',
axisCenteredZero=True,
targets=[ targets=[
Target( PromTarget(
datasource=prom_datasource, expr='max by (name) (irate(container_network_receive_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
expr='max by (name) (rate(container_network_receive_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat="rx {{ name }}", legendFormat="rx {{ name }}",
refId='A',
), ),
Target( PromTarget(
datasource=prom_datasource, expr='-max by (name) (irate(container_network_transmit_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
expr='-max by (name) (rate(container_network_transmit_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat="tx {{ name }}", legendFormat="tx {{ name }}",
refId='B',
), ),
], ],
), ),
@@ -118,12 +92,10 @@ dashboard = Dashboard(
dedupStrategy='numbers', dedupStrategy='numbers',
targets=[ targets=[
LokiTarget( LokiTarget(
loki_datasource=loki_datasource,
expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`', expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
legendFormat='{{ container_name }}', legendFormat='{{ container_name }}',
refId='A',
),
],
), ),
], ],
) if CONF_SUPPORT_LOKI else None,
]),
).auto_panel_ids() ).auto_panel_ids()

View File

@@ -1,139 +1,159 @@
from grafanalib.core import Dashboard, Templating, Template, TimeSeries, PERCENT_UNIT_FORMAT, GridPos, Target from grafanalib.core import Templating, Template, GridPos
from grafanalib.formatunits import BYTES_IEC from grafanalib.formatunits import BYTES_IEC, BITS_SEC, PERCENT_UNIT
from common import PrometheusTemplate from common import prom_template, MyTimeSeries, MyDashboard, CONF_SUPPORT_ZFS, PromTarget, prom_datasource
from node_consts import CPU_BASIC_COLORS, MEMORY_BASIC_COLORS
dashboard = Dashboard( dashboard = MyDashboard(
title='Node Exporter', title='Node Exporter',
uid='node', uid='node',
description='Node Exporter (not quite full)', description='Node Exporter (not quite full)',
tags=[ tags=[
'linux', 'linux',
], ],
timezone='browser',
templating=Templating(list=[ templating=Templating(list=[
# Datasource # Datasource
PrometheusTemplate, prom_template,
# Job # Job
Template( Template(
name='job', name='job',
label='Job', label='Job',
dataSource='${datasource}', dataSource=prom_datasource,
query='label_values(node_uname_info, job)', query='label_values(node_uname_info, job)',
), ),
# Instance # Instance
Template( Template(
name='instance', name='instance',
label='Instance', label='Instance',
dataSource='${datasource}', dataSource=prom_datasource,
query='label_values(node_uname_info{job="$job"}, instance)', query='label_values(node_uname_info{job="$job"}, instance)',
), ),
]), ]),
panels=[ panels=[
# CPU Basic # CPU Basic
TimeSeries( MyTimeSeries(
title='CPU Basic', title='CPU Basic',
description='Basic CPU usage info', description='Basic CPU usage info',
unit=PERCENT_UNIT_FORMAT, unit=PERCENT_UNIT,
gridPos=GridPos(h=8, w=12, x=0, y=0), gridPos=GridPos(h=8, w=12, x=0, y=0),
lineWidth=1, stacking={'mode': 'percent'},
fillOpacity=30,
showPoints='never',
stacking={'mode': 'percent', 'group': 'A'},
tooltipMode='all',
tooltipSort='desc',
targets=[ targets=[
Target( PromTarget(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="system"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))', expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="system"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy System', legendFormat='Busy System',
refId='A',
), ),
Target( PromTarget(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="user"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))', expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="user"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy User', legendFormat='Busy User',
refId='B',
), ),
Target( PromTarget(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="iowait"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))', expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="iowait"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy Iowait', legendFormat='Busy Iowait',
refId='C',
), ),
Target( PromTarget(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode=~".*irq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))', expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode=~".*irq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy IRQs', legendFormat='Busy IRQs',
refId='D',
), ),
Target( PromTarget(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode!="idle",mode!="user",mode!="system",mode!="iowait",mode!="irq",mode!="softirq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))', expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode!="idle",mode!="user",mode!="system",mode!="iowait",mode!="irq",mode!="softirq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy Other', legendFormat='Busy Other',
refId='E',
), ),
Target( PromTarget(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="idle"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))', expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="idle"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Idle', legendFormat='Idle',
refId='F',
), ),
], ],
# Extra JSON for the colors
extraJson=CPU_BASIC_COLORS,
), ),
# Memory Basic # Memory Basic
TimeSeries( MyTimeSeries(
title='Memory Basic', title='Memory Basic',
description='Basic memory usage', description='Basic memory usage',
unit=BYTES_IEC, unit=BYTES_IEC,
gridPos=GridPos(h=8, w=12, x=12, y=0), gridPos=GridPos(h=8, w=12, x=12, y=0),
lineWidth=1, stacking={'mode': 'normal'},
fillOpacity=30, valueMin=0,
showPoints='never',
stacking={'mode': 'normal', 'group': 'A'},
tooltipMode='all',
tooltipSort='desc',
targets=[ targets=[
Target( PromTarget(
datasource='${datasource}',
expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"}', expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"}',
format='time_series', format='time_series',
legendFormat='RAM Total', legendFormat='RAM Total',
refId='A',
), ),
Target( PromTarget(
datasource='${datasource}',
expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"} - node_memory_MemFree_bytes{instance="$instance",job="$job"} - (node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"})', expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"} - node_memory_MemFree_bytes{instance="$instance",job="$job"} - (node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"})',
format='time_series', format='time_series',
legendFormat='RAM Used', legendFormat='RAM Used',
refId='B', hide=CONF_SUPPORT_ZFS,
), ),
Target( PromTarget(
datasource='${datasource}', expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"} - node_memory_MemFree_bytes{instance="$instance",job="$job"} - (node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"}) - node_zfs_arc_size{instance="$instance",job="$job"}',
format='time_series',
legendFormat='RAM Used',
hide=not CONF_SUPPORT_ZFS,
),
PromTarget(
expr='node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"}', expr='node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"}',
legendFormat='RAM Cache + Buffer', legendFormat='RAM Cache + Buffer',
refId='C',
), ),
Target( PromTarget(
datasource='${datasource}', expr='node_zfs_arc_size{instance="$instance",job="$job"}',
legendFormat='ZFS Arc',
hide=not CONF_SUPPORT_ZFS,
),
PromTarget(
expr='node_memory_MemFree_bytes{instance="$instance",job="$job"}', expr='node_memory_MemFree_bytes{instance="$instance",job="$job"}',
legendFormat='RAM Free', legendFormat='RAM Free',
refId='D',
), ),
Target( PromTarget(
datasource='${datasource}',
expr='(node_memory_SwapTotal_bytes{instance="$instance",job="$job"} - node_memory_SwapFree_bytes{instance="$instance",job="$job"})', expr='(node_memory_SwapTotal_bytes{instance="$instance",job="$job"} - node_memory_SwapFree_bytes{instance="$instance",job="$job"})',
legendFormat='SWAP Used', legendFormat='SWAP Used',
refId='E',
), ),
], ],
# Extra JSON for the colors overrides=[
extraJson=MEMORY_BASIC_COLORS, # Prevent total memory from being stacked
{
'matcher': {
'id': 'byName',
'options': 'RAM Total'
},
'properties': [
{
'id': 'custom.stacking',
'value': {'mode': 'none'}
}
]
},
],
),
# Network Traffic Basic
MyTimeSeries(
title='Network Traffic Basic',
description='Basic network usage info per interface',
unit=BITS_SEC,
gridPos=GridPos(h=8, w=12, x=0, y=8),
tooltipSort='desc',
axisCenteredZero=True,
targets=[
PromTarget(
expr='irate(node_network_receive_bytes_total{instance="$instance",job="$job"}[$__rate_interval]) * 8',
legendFormat='rx {{ device }}',
),
PromTarget(
expr='-irate(node_network_transmit_bytes_total{instance="$instance",job="$job"}[$__rate_interval]) * 8',
legendFormat='tx {{ device }}',
),
],
),
# Disk Space Basic
MyTimeSeries(
title='Disk Space Used Basic',
description='Disk space used of all filesystems mounted',
unit=PERCENT_UNIT,
gridPos=GridPos(h=8, w=12, x=12, y=8),
targets=[
PromTarget(
expr='1 - (node_filesystem_avail_bytes{instance="$instance",job="$job",device!~"rootfs"} / node_filesystem_size_bytes{instance="$instance",job="$job",device!~"rootfs"})',
legendFormat='{{ mountpoint }}',
),
],
), ),
# TODO: Network Basic
# TODO: Disk Basic
], ],
).auto_panel_ids() ).auto_panel_ids()

View File

@@ -1,487 +0,0 @@
# TODO: Question life decisions (I'm not sure if this is good)
CPU_BASIC_COLORS = {
"fieldConfig": {
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Busy Iowait"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#890F02",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Idle"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#052B51",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy Iowait"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#890F02",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Idle"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#7EB26D",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy System"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#EAB839",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy User"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A437C",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy Other"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#6D1F62",
"mode": "fixed"
}
}
]
}
]
},
}
MEMORY_BASIC_COLORS = {
"fieldConfig": {
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Apps"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#629E51",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Buffers"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#614D93",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Cache"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#6D1F62",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Cached"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#511749",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Committed"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#508642",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A437C",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#CFFAFF",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Inactive"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#584477",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "PageTables"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A50A1",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Page_Tables"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A50A1",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM_Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#E0F9D7",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "SWAP Used"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#BF1B00",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Slab"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#806EB7",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Slab_Cache"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#E0752D",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#BF1B00",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap Used"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#BF1B00",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap_Cache"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#C15C17",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap_Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#2F575E",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Unused"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#EAB839",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM Total"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#E0F9D7",
"mode": "fixed"
}
},
{
"id": "custom.fillOpacity",
"value": 0
},
{
"id": "custom.stacking",
"value": {
"group": False,
"mode": "normal"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM Cache + Buffer"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#052B51",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#7EB26D",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Available"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#DEDAF7",
"mode": "fixed"
}
},
{
"id": "custom.fillOpacity",
"value": 0
},
{
"id": "custom.stacking",
"value": {
"group": False,
"mode": "normal"
}
}
]
}
]
}
}

View File

@@ -1,14 +1,7 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %} {% import 'contrib/compose_helpers.j2' as helpers with context %}
networks: networks:
traefik: {{ helpers.default_network(254) | indent(2) }}
internal: true
enable_ipv6: true
ipam:
config:
# TODO: Consider removing traefik network, it shouldn't be needed with host networking
- subnet: {{ traefik_subnet }}/24
- subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, 255) }}
services: services:
traefik: traefik:
@@ -25,11 +18,8 @@ services:
- {{ base_volume_path }}/traefik/rules:/rules/extra:ro - {{ base_volume_path }}/traefik/rules:/rules/extra:ro
- {{ base_volume_path }}/traefik/acme:/acme - {{ base_volume_path }}/traefik/acme:/acme
# This is mostly just so that the traefik network gets created
whoami: whoami:
image: containous/whoami image: containous/whoami
container_name: whoami container_name: whoami
labels: labels:
- {{ helpers.traefik_labels('whoami', port=80) | indent(6) }} - {{ helpers.traefik_labels('whoami', port='80') | indent(6) }}
networks:
- traefik

View File

@@ -36,7 +36,6 @@ certificatesResolvers:
providers: providers:
docker: docker:
exposedByDefault: false exposedByDefault: false
network: traefik_traefik
file: file:
directory: /rules directory: /rules
watch: true watch: true

View File

@@ -0,0 +1,22 @@
- name: Get list of running Docker containers
docker_host_info:
containers: yes
register: docker_container_list
- name: Stop all running Docker containers
docker_container:
name: "{{ item }}"
state: stopped
loop: "{{ docker_container_list.containers | map(attribute='Id') | list }}"
async: 300
poll: 0
- name: Prune all Docker containers and networks
docker_prune:
containers: yes
networks: yes
- name: Clean alpina directory
file:
path: "{{ alpina_svc_path }}"
state: absent

View File

@@ -64,6 +64,14 @@
state: enabled state: enabled
immediate: yes immediate: yes
- name: Allow 2222 tcp for pgrok ssh tunnel
become: yes
firewalld:
port: 2222/tcp
permanent: yes
state: enabled
immediate: yes
- name: Reboot if needed - name: Reboot if needed
become: yes become: yes
ansible.builtin.reboot: ansible.builtin.reboot:

View File

@@ -1,12 +1,5 @@
- name: Get IPv6 subnet for Docker - name: IPv6 subnet for Docker
set_fact: debug:
docker_ipv6_subnet: "{{ \
ansible_default_ipv6.address \
| ansible.utils.ipsubnet(64) \
| ansible.utils.ipsubnet(72, docker_ipv6_index) \
}}"
- debug:
var: docker_ipv6_subnet var: docker_ipv6_subnet
- name: Configure Docker daemon - name: Configure Docker daemon
@@ -35,33 +28,6 @@
state: disabled state: disabled
register: docker0_firewalld register: docker0_firewalld
- name: Get list of running Docker containers
docker_host_info:
containers: yes
register: docker_container_list
when: clean_desired is true
- name: Stop all running Docker containers
docker_container:
name: "{{ item }}"
state: stopped
loop: "{{ docker_container_list.containers | map(attribute='Id') | list }}"
async: 300
poll: 0
when: clean_desired is true and docker_container_list.containers | length > 0
- name: Prune all Docker containers and networks
docker_prune:
containers: yes
networks: yes
when: clean_desired is true
- name: Clean alpina directory
file:
path: "{{ alpina_svc_path }}"
state: absent
when: clean_desired is true
- name: Restart Docker daemon - name: Restart Docker daemon
become: yes become: yes
service: service:

View File

@@ -1,6 +1,5 @@
- hosts: alpina - hosts: alpina
roles: roles:
- docker_host
- alpina - alpina
post_tasks: post_tasks:
- name: Docker prune objects - name: Docker prune objects

View File

@@ -1,12 +1,4 @@
- hosts: all - hosts: alpina
roles: roles:
- common - common
pre_tasks: - docker_host
- name: Set fact for clean desired of docker objects and compose files
set_fact:
# clean_desired_arg is an extra variable passed to the playbook
clean_desired: "{{ clean_desired_arg | bool }}"
- name: Install services
import_playbook: services.yml