Compare commits
10 commits
338f2ae636
...
a8a2815c5f
| Author | SHA1 | Date | |
|---|---|---|---|
| a8a2815c5f | |||
| cea2523e15 | |||
| c4094b692f | |||
| 16cbd189b8 | |||
| 82fca48b08 | |||
| 4bee182978 | |||
| 39a1b43577 | |||
| cc9340b7cc | |||
| b07ed72a92 | |||
| 8a3fddbe49 |
33 changed files with 717 additions and 640 deletions
|
|
@ -162,6 +162,12 @@ Note that, by applying these playbooks, both the root user and the `counterweigh
|
||||||
```bash
|
```bash
|
||||||
cp ansible/infra_secrets.yml.example ansible/infra_secrets.yml
|
cp ansible/infra_secrets.yml.example ansible/infra_secrets.yml
|
||||||
```
|
```
|
||||||
|
> **DEPRECATED (2026-09-11).** Uptime Kuma has been decommissioned. The server
|
||||||
|
> deployment was removed from this repo; what it monitored and how it was set up is
|
||||||
|
> preserved in [`archive/uptime_kuma/`](archive/uptime_kuma/). The monitoring blocks in
|
||||||
|
> the playbooks are kept but inert (`uptime_kuma_enabled: false`) so the check logic
|
||||||
|
> survives for whatever replaces it. The credentials below no longer exist in the vault.
|
||||||
|
|
||||||
* Edit `ansible/infra_secrets.yml` and add your Uptime Kuma credentials:
|
* Edit `ansible/infra_secrets.yml` and add your Uptime Kuma credentials:
|
||||||
```yaml
|
```yaml
|
||||||
uptime_kuma_username: "admin"
|
uptime_kuma_username: "admin"
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ Checklist:
|
||||||
|
|
||||||
## Uptime Kuma
|
## Uptime Kuma
|
||||||
|
|
||||||
|
> **DEPRECATED (2026-09-11).** Uptime Kuma has been decommissioned. The server
|
||||||
|
> deployment was removed from this repo; what it monitored and how it was set up is
|
||||||
|
> preserved in [`archive/uptime_kuma/`](archive/uptime_kuma/). The monitoring blocks in
|
||||||
|
> the playbooks are kept but inert (`uptime_kuma_enabled: false`) so the check logic
|
||||||
|
> survives for whatever replaces it. The credentials below no longer exist in the vault.
|
||||||
|
|
||||||
Uptime Kuma gets used to monitor the availability of services, keep track of their uptime and notify issues.
|
Uptime Kuma gets used to monitor the availability of services, keep track of their uptime and notify issues.
|
||||||
|
|
||||||
### Deploy
|
### Deploy
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ Assumes that you've set `ansible/.vault_pass` with `chmod 600`.
|
||||||
+ Plan install
|
+ Plan install
|
||||||
+ File based config
|
+ File based config
|
||||||
+ Crossbackup to Desky via rsync
|
+ Crossbackup to Desky via rsync
|
||||||
* Uptime Kuma
|
* ~~Uptime Kuma~~ — decommissioned 2026-09-11, see `archive/uptime_kuma/`
|
||||||
+ Deployed on Vipy
|
+ Deployed on Vipy
|
||||||
+ Crossbackup to Desky via rsync
|
+ Crossbackup to Desky via rsync
|
||||||
* Vaultwarden
|
* Vaultwarden
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,60 @@
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
65343264303166346334396163363362326334626531336363363766326135393462373564313539
|
61356165613635386631393135656434646436303665313031346566323336313138353433316463
|
||||||
6633346163343664393232363965383334303563396236360a316265623239333431636133306663
|
3363323534613064643132663335623238366431393062340a346538396662306537663163623366
|
||||||
65623237393564323936303936633036343137646637633963396166313462626165616463616665
|
38626166383933616331623231373137306562623637313263333237633661663436666266616433
|
||||||
3235373562626238640a636163623535376565373835653831666361636563616230353639626131
|
3862346438643638650a306634333535653633613534646630386131333236366538333765323333
|
||||||
38393530363461346334356437613934306330666563326661343465653362313038346535386337
|
38656163303837303732663561373232393132343331663164656262393730326434373731333636
|
||||||
62623964633764343964653061373137366539326433396231396339313231633632353465323139
|
36613538646431396536363936336562616431656665653965373864633366663836353434626434
|
||||||
33333866383834376165303964353639386234646535626333363932333764646137663036303530
|
34383932373461333564303439623565383661646365386665393831383463663662356536356236
|
||||||
32326635343631623535323830333934376466323338353234323464666435383436633139343037
|
36373964666236626465366161636135393734356536633466383262326537343833636630343738
|
||||||
62666333383231356163383530353339336230373431616665333638633234656231393166303639
|
62353066316131613737373162643363653662656261363465386364323962656537373061373032
|
||||||
32386134386264613839313564316164336461373738646630636630363731643066633132336636
|
33343763353464383438363438343965653532393831343930393562633630383932653862623637
|
||||||
64663532663661653539653431353763303436323234383864353064333631643435633733366435
|
38386239353237356631646436356166373961333464396639383538383662326534343339313330
|
||||||
32656332626633313134623361343965643962663134613363626265353865643738363738316232
|
65373339356364636634616532363832386631323062363530313861336238353261353334306235
|
||||||
62356136623166303038653830393138646637636335366362323239316333616331383765663861
|
62616338396431316537346638656365356564346666366366343638356261623664393263323937
|
||||||
33643331323766646463663862396232306233343134326436326235336165616662383636616539
|
30343261363562383332323462336435376664386134646562643836363834313237373631353731
|
||||||
39373962336264636363303734343666646534343733666632626338393936393032626130643233
|
35653535663864643266313332356635363262363533663232656531373130336539633066376139
|
||||||
30633963656166343834396431323233363036353165623934336532333662323932336630636235
|
32316665393831663035623962656364363831333563366135636164346335383738363336663566
|
||||||
63326631366234383732316464383364316337393034303433646365343763633135336336376161
|
63356532643563393939383635386462663561386434323939303431653438653131363538383034
|
||||||
33326436303863326666616234396438623864333538313363623261353962336430316132343830
|
33623933333464363032656636643033326162626163353633343062633966343332383138363963
|
||||||
36353761326133666166393930343233643861366138363930623362336566386230316236353365
|
36383831663562616533316436366566323061386535343538393861383462333166343562316633
|
||||||
65663632383436333536636161393133316334376262653330303238636431353966646666663665
|
30623665623035393537393965626363323132656433313339396233356666346634316332616336
|
||||||
30386137623066343135616534323336313162643066636330323934646162303362373838313532
|
37363635363330323230373332326565343530653335383437373230366563366237633665626331
|
||||||
61386163356537613334616537656134373835326265393765303436396233383239393365336136
|
66623336626230663361636439316337393865383035326136653264666438666566646132353036
|
||||||
64623130383538306331323939386634316663663263306362363830383930346232313965613035
|
38616264313833316536623238633339373466613866626366383835656638623863323838653030
|
||||||
33353235663230663635316136666335343233646539613832643431393134303865616232636435
|
63303938376164653966356435386333363731656666313234663535666165646233313137343563
|
||||||
66366437353863336235646438353431616465396365373562636461623938303663326461656134
|
36386437393139656438333262383437656666343831313239323961373637653163643664356565
|
||||||
66353735343237363164326236663363376333316163353462626234393861663535323463623233
|
62346431393133656530316262303763646165643336396661666431383436323562336137653031
|
||||||
66623934336662323830616362653035353563343564636431383837643961303637366131633132
|
62626538373839613734396366653065306534636630346338316237616161613037616364356431
|
||||||
33376133376465623030643935643737636339333236316566636663323934626265633863343963
|
38643965376133616161336633383664326230383435363334353137303162663738313331346238
|
||||||
38626563323166343264643465626264393838643330393739386330656461656561306539653232
|
39356161616533616134356231323530306338333162343363353531303263636632613036386638
|
||||||
63393838626233386531353063366131366237633162393537363963633361386238643232336230
|
63633136386232306234323936303563646466313935326631396565383432386130656638616266
|
||||||
36363062386262303364303736373061316265373730366437326166336163386335623665323234
|
32383334363237336539396665336366643764633131643663643137376438323666326435626461
|
||||||
35383865646466363534383833653764303833323230613863313735393264336132303934633465
|
64346633636431393137633537306431646564386565303933636434386462346630626537346438
|
||||||
65616138636134613361316539343739353735666538653438333264623034306633663634306438
|
32623333666133303061646564366366326665363163396262633164323631636337346130303239
|
||||||
33643165353534623039626536636433373963383866303535333931633633393138663464336562
|
38373936663337356134666132303165393365663763396362623434633737373538653566646134
|
||||||
36643432366233323235613139626236346135633237613265343933646434373939396265626366
|
62316164396438303532616266313062326666633130656338653139376634306664633031333037
|
||||||
34313835346463303132326537323166363032306133623662343736393435383330356433306138
|
31636166306565353334633435656233336233363664306264626237623366336161303134353433
|
||||||
65653931613832313832323936353638303937613863646430633266306330656135386533306462
|
63383739666462623336386537346662633666626466393039653439346436653937633537396436
|
||||||
30663366396566393134653663356531316639303635343236666333363637636433336533356663
|
35393339383066326630353066623132333034656539363561346462626265363263303535343961
|
||||||
35346261363134326165316463626439306130653165636134616434663736616666643963336464
|
39316461616630326539613731303039613736393633373338646266323938326162373831346336
|
||||||
61643834613164336234386237393333636234306162306563363430646262363963366666653666
|
30656130343463366534323030646238313465306266383034623065636665623366333063383736
|
||||||
64323036323731626236343361613566643565666138386631633462613836613766626562353934
|
38373063393837306462303564643962373334343139626338623935336435643730646532633630
|
||||||
32363936626466346464356131653232326330386239666638626333346238623964383666393961
|
66363730386636633639346463363365343239373265303738353732653633653437636130636664
|
||||||
38393264663636353161663636393733396332333838333962393439346533353332653362356230
|
39386365353334653765343335303263363461313965383664326563333734626533376436626530
|
||||||
62613039376539636363
|
63353163323637303730353564383733653365613635353764333266393532653663326533646132
|
||||||
|
39313763373735323835626437306435373238653432393936643165663663656665316132653330
|
||||||
|
35383038353532656434366336346235363563636264303734633138323963396562306232646236
|
||||||
|
38366536306561653937336333373434336164663336613839353439356435333833396363636437
|
||||||
|
38323934613735643363656233333037336465336564313966623063376566663030303230323262
|
||||||
|
65643564666534326234306164343365383632333061316238623565353538313538396364313337
|
||||||
|
35336230313339643736653238386231343661623337306236383665356632366236356335323530
|
||||||
|
66373831616239376231636361333430343433303233393066323865663434643433303832373262
|
||||||
|
36366534646161323130393931626362626139663139643263366639656531613436313533363130
|
||||||
|
65643736363833333939613566663339623964333262643863333030623138633464386238613934
|
||||||
|
31323639333234336264313663376465323737353766643839303665313737336534386665363034
|
||||||
|
30326439666433373232306136306365343764643434306561343339353132346430646436343362
|
||||||
|
32333765616262363930353435616563333736313533653339656231316230346166363335356638
|
||||||
|
37333561366339613136306438306130343230663732333862663838396463623661303961336433
|
||||||
|
65646332373139303462303633346432366530643130366133363937653739653036366136373434
|
||||||
|
343864373734666431326239373866313734
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,60 @@
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
65343264303166346334396163363362326334626531336363363766326135393462373564313539
|
34616531626537376463326332306434383163393761363536633133363161373631376437653234
|
||||||
6633346163343664393232363965383334303563396236360a316265623239333431636133306663
|
3831656536313531343433376264643261396634633965370a303931336236323766313065636535
|
||||||
65623237393564323936303936633036343137646637633963396166313462626165616463616665
|
31343338616364386132623232373266663665353563666535383232666262663062323864303932
|
||||||
3235373562626238640a636163623535376565373835653831666361636563616230353639626131
|
3439373734316639650a633732333064633335383833663261326464336538636666323063646331
|
||||||
38393530363461346334356437613934306330666563326661343465653362313038346535386337
|
66653464636534663935616461636132613162303530663237376661343338396133323431623561
|
||||||
62623964633764343964653061373137366539326433396231396339313231633632353465323139
|
30303563303465633231306339326561313533333536376433393130376634303932643339656336
|
||||||
33333866383834376165303964353639386234646535626333363932333764646137663036303530
|
30616130343733626162366561393939393766623138616537393032376665396139333561623830
|
||||||
32326635343631623535323830333934376466323338353234323464666435383436633139343037
|
33623130336235633034666561383165616439316334323664623661343438663733373833306335
|
||||||
62666333383231356163383530353339336230373431616665333638633234656231393166303639
|
30396165313731636435636263353133326135346236323030653734353831626238666663656364
|
||||||
32386134386264613839313564316164336461373738646630636630363731643066633132336636
|
62386164363361373464383730333733626333333736306535336635613634646535383237326332
|
||||||
64663532663661653539653431353763303436323234383864353064333631643435633733366435
|
37636532663933663739303634333235343137333363316430643263326231613635643633636437
|
||||||
32656332626633313134623361343965643962663134613363626265353865643738363738316232
|
30336462633233396430633939616661643261666136656363363461343230653738613166346434
|
||||||
62356136623166303038653830393138646637636335366362323239316333616331383765663861
|
63376363666462346539343063343562623962303130616535306439653134633630353963373337
|
||||||
33643331323766646463663862396232306233343134326436326235336165616662383636616539
|
64313239353162363862643432666438383330636638333464323731643163643236313535313030
|
||||||
39373962336264636363303734343666646534343733666632626338393936393032626130643233
|
65656231383738356537326661663163376634613031396436646633376139313237343534653065
|
||||||
30633963656166343834396431323233363036353165623934336532333662323932336630636235
|
64323532346133313265346334353530393633396339316330366536646565353836396662303866
|
||||||
63326631366234383732316464383364316337393034303433646365343763633135336336376161
|
65373030393463306664623235626437613965303837313365373632643935656630303936373837
|
||||||
33326436303863326666616234396438623864333538313363623261353962336430316132343830
|
64663539623764656636613263346638376665626262663430333231633735653563643864343835
|
||||||
36353761326133666166393930343233643861366138363930623362336566386230316236353365
|
62303637383332653366383066326536316336306539623230353066343739316430356437313365
|
||||||
65663632383436333536636161393133316334376262653330303238636431353966646666663665
|
33323031613130643832636133636263303565623330306135333762363036633737343933623437
|
||||||
30386137623066343135616534323336313162643066636330323934646162303362373838313532
|
33633436363062643436376632336235666330656265316333323361316430656631383734343238
|
||||||
61386163356537613334616537656134373835326265393765303436396233383239393365336136
|
65616366666536363866343361666563643336306532666332643230656264303565353032393932
|
||||||
64623130383538306331323939386634316663663263306362363830383930346232313965613035
|
36613738326239376161383064646634623639356439663965323237303361343838373737636235
|
||||||
33353235663230663635316136666335343233646539613832643431393134303865616232636435
|
39656465333063633136643463356564636537326339653033633063366265636138656466646264
|
||||||
66366437353863336235646438353431616465396365373562636461623938303663326461656134
|
32643961343863656464353439346531633036613138353333353631626665396239326465303632
|
||||||
66353735343237363164326236663363376333316163353462626234393861663535323463623233
|
39336664333038636435366333623336353963323535316436646136313739373537376537353735
|
||||||
66623934336662323830616362653035353563343564636431383837643961303637366131633132
|
66333265633232346536313933333836643439656666636236626266323333383935383565616139
|
||||||
33376133376465623030643935643737636339333236316566636663323934626265633863343963
|
38626133356364613562393664643563346539366364636332613162663337356232333735393431
|
||||||
38626563323166343264643465626264393838643330393739386330656461656561306539653232
|
30343635393462356431646336636663333735343164616261343836363366616162613563613066
|
||||||
63393838626233386531353063366131366237633162393537363963633361386238643232336230
|
66333034613234626431356536323832393466363135653231336238356334353638613838626430
|
||||||
36363062386262303364303736373061316265373730366437326166336163386335623665323234
|
63636630313533363563376161663637353362383431663130646666646433353864373736613662
|
||||||
35383865646466363534383833653764303833323230613863313735393264336132303934633465
|
62343666633862643839666532656132653939663437373164393536653739376265303130353636
|
||||||
65616138636134613361316539343739353735666538653438333264623034306633663634306438
|
62616538326330333136626238306133363634326365366637363961333635356133613564373131
|
||||||
33643165353534623039626536636433373963383866303535333931633633393138663464336562
|
64626139656633663065353862343135393233333231386166346532656534623361623061336434
|
||||||
36643432366233323235613139626236346135633237613265343933646434373939396265626366
|
37616565626134333863376532393861376132323434656433613731613834633963386635353336
|
||||||
34313835346463303132326537323166363032306133623662343736393435383330356433306138
|
39653263346637303836663763653264396139383363616461393333333362616332663863363834
|
||||||
65653931613832313832323936353638303937613863646430633266306330656135386533306462
|
61613832326466646133626337663364333566326633313664613236346135653332373035313034
|
||||||
30663366396566393134653663356531316639303635343236666333363637636433336533356663
|
62356530313065393737393634313166313039616635363365633031336434396463326462316236
|
||||||
35346261363134326165316463626439306130653165636134616434663736616666643963336464
|
62353838636533303664663132353838636632353733316639643964666139383539333761663531
|
||||||
61643834613164336234386237393333636234306162306563363430646262363963366666653666
|
37366530373165653063303032383461326535613336343635626538373635356266396666346133
|
||||||
64323036323731626236343361613566643565666138386631633462613836613766626562353934
|
61383434323565306438356634646338666232363238393932353365363461376130323363363236
|
||||||
32363936626466346464356131653232326330386239666638626333346238623964383666393961
|
34643862653937353461383265663933646264373365623465313666643662633334366437646434
|
||||||
38393264663636353161663636393733396332333838333962393439346533353332653362356230
|
34343332613832366235663563353435323738356339383338333361383561336366376238393237
|
||||||
62613039376539636363
|
38656265663164376666616366623062393530366261623361383365376235643035353838313235
|
||||||
|
32396430376139313430316439333539343266393965353030636638656661316137313437663832
|
||||||
|
64366661323865383262323036613230316233666566386133363633303931323464663238323861
|
||||||
|
62333132346165353830653062353763306232366563323430383933653163373562326536393362
|
||||||
|
66353931376262383931613931303034356537363137366235643430323465623162363031373034
|
||||||
|
64653563666533363062333831336463376530306639616631303266386136666233653638653732
|
||||||
|
31313537393838333730303235363661326333646531653935633935373362303732653565656438
|
||||||
|
36626330623063373832333739643666396135653838643164376264393863646433353036643731
|
||||||
|
34623636623366353466333237373265323936643134613230326565303663306431373634356334
|
||||||
|
37613732393262626135306632623336613364323632316636623037656538313236666562633438
|
||||||
|
37306361333130376538366232393637646263656239303431623963626265386634313735373162
|
||||||
|
64393733303132383464386330626135336237303563326238633437346164333738646431333730
|
||||||
|
62616533363638643261306565373835303832313539656564386132393863373039653938616261
|
||||||
|
36343031356361336563316230343433633033353130373933313361326164633765316433616162
|
||||||
|
62356338393634653330623933313433343630386264396337373532376335316362333164363963
|
||||||
|
363663666365336564663232363462613162
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,20 @@
|
||||||
vipy ansible_host=167.172.107.33 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
vipy ansible_host=167.172.107.33 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
watchtower ansible_host=164.92.239.72 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
watchtower ansible_host=164.92.239.72 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
spacey ansible_host=64.227.112.128 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
spacey ansible_host=64.227.112.128 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
|
|
||||||
[nodito_host]
|
[nodito_host]
|
||||||
nodito ansible_host=192.168.1.139 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
nodito ansible_host=192.168.1.139 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
|
|
||||||
|
# Requires the tailnet to be up on the control node.
|
||||||
[nodito_vms]
|
[nodito_vms]
|
||||||
knots_box_local ansible_host=192.168.1.135 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
knots_box_local ansible_host=knots-box lan_ip=192.168.1.135 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
fulcrum_box_local ansible_host=192.168.1.142 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
fulcrum_box_local ansible_host=fulcrum-box lan_ip=192.168.1.140 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
mempool_box_local ansible_host=192.168.1.140 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
mempool_box_local ansible_host=mempool-box lan_ip=192.168.1.142 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
memos_box_local ansible_host=192.168.1.130 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
memos_box_local ansible_host=memos-box lan_ip=192.168.1.145 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
forgejo_runner_local ansible_host=192.168.1.147 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
forgejo_runner_local ansible_host=forgejo-runner-box lan_ip=192.168.1.132 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
arbret_staging_local ansible_host=192.168.1.142 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
arbret_staging_local ansible_host=arbret-staging-box lan_ip=192.168.1.147 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
small_backups_local ansible_host=192.168.1.148 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
small_backups_local ansible_host=small-backups-box lan_ip=192.168.1.131 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
nonkeiwaisi_local ansible_host=192.168.1.151 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
nonkeiwaisi_local ansible_host=nonkeiwaisi-box lan_ip=192.168.1.151 ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/counterganzua
|
||||||
|
|
||||||
# Local connection to laptop: this assumes you're running ansible commands from your personal laptop
|
# Local connection to laptop: this assumes you're running ansible commands from your personal laptop
|
||||||
[lapy]
|
[lapy]
|
||||||
|
|
@ -58,4 +59,13 @@ localhost
|
||||||
[managed:children]
|
[managed:children]
|
||||||
vps
|
vps
|
||||||
nodito_host
|
nodito_host
|
||||||
nodito_vms
|
nodito_vms
|
||||||
|
|
||||||
|
# Hosts that run Caddy and therefore have /etc/caddy/sites-enabled.
|
||||||
|
[caddy:children]
|
||||||
|
edge
|
||||||
|
monitoring
|
||||||
|
vpn_control
|
||||||
|
|
||||||
|
[backup_store]
|
||||||
|
small_backups_local
|
||||||
|
|
|
||||||
118
ansible/roles/caddy_site/README.md
Normal file
118
ansible/roles/caddy_site/README.md
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
# `caddy_site`
|
||||||
|
|
||||||
|
Writes one Caddy site file into `{{ caddy_sites_dir }}`, makes sure the main
|
||||||
|
Caddyfile imports that directory, validates the result, and reloads Caddy once.
|
||||||
|
|
||||||
|
Replaces the four-task block that was copy-pasted into 10 playbooks.
|
||||||
|
|
||||||
|
Runs on any host in the `[caddy]` group — `edge` (vipy), `monitoring`
|
||||||
|
(watchtower) and `vpn_control` (spacey).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- ansible.builtin.include_role:
|
||||||
|
name: caddy_site
|
||||||
|
vars:
|
||||||
|
caddy_site_name: forgejo # -> forgejo.conf
|
||||||
|
caddy_site_domain: "{{ forgejo_domain }}"
|
||||||
|
caddy_site_upstream: "localhost:{{ forgejo_port }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `include_role`, not a `roles:` block, so the call stays in task order next
|
||||||
|
to the tasks it depends on. Variables passed this way are scoped to the include
|
||||||
|
and do not leak into later calls — so **every call must pass everything it
|
||||||
|
needs**; nothing carries over.
|
||||||
|
|
||||||
|
## Shapes
|
||||||
|
|
||||||
|
Pick exactly one of `caddy_site_upstream`, `caddy_site_root`, `caddy_site_body`.
|
||||||
|
|
||||||
|
| Want | Set |
|
||||||
|
|---|---|
|
||||||
|
| `reverse_proxy host:port` | `caddy_site_upstream` |
|
||||||
|
| static `root *` + `file_server` | `caddy_site_root` |
|
||||||
|
| anything else | `caddy_site_body` (raw, indented 4 for you) |
|
||||||
|
|
||||||
|
`caddy_site_upstream` accepts two modifiers, which add a block to the
|
||||||
|
`reverse_proxy`:
|
||||||
|
|
||||||
|
- `caddy_site_headers_up: {"X-Forwarded-Host": "..."}`
|
||||||
|
- `caddy_site_resolvers: "100.100.100.100"` — Tailscale MagicDNS
|
||||||
|
|
||||||
|
and `caddy_site_basic_auth` wraps the site in a `basic_auth` block.
|
||||||
|
|
||||||
|
## `caddy_site_basic_auth` is a LIST, not a dict
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
caddy_site_basic_auth:
|
||||||
|
- user: "{{ datum_dashboard_username }}"
|
||||||
|
hash: "{{ datum_dashboard_password_hash }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ansible does not template dictionary keys.** With `{ "{{ user }}": "hash" }`
|
||||||
|
the value is rendered and the key is not, so the literal string
|
||||||
|
`{{ datum_dashboard_username }}` lands in the config file. Found while building
|
||||||
|
this role; the `assert` refuses a mapping so it cannot happen again.
|
||||||
|
|
||||||
|
## Secrets and `--diff`
|
||||||
|
|
||||||
|
Rendered site files can carry credentials — `datum-gateway.conf` holds a bcrypt
|
||||||
|
hash — and `--diff` prints rendered content. The template task therefore sets
|
||||||
|
`diff: "{{ caddy_site_reveal | bool }}"`, default `false`, so `--diff` runs are
|
||||||
|
safe everywhere. Pass `-e caddy_site_reveal=true` to see what moved on a site
|
||||||
|
you know is not secret.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
`validate: "caddy validate --adapter caddyfile --config %s"` runs against the
|
||||||
|
rendered temp file before it is moved into place. Verified on vipy that a single
|
||||||
|
site fragment validates cleanly (rc=0, `Valid configuration`) and that a
|
||||||
|
malformed one is rejected (rc=1, with the syntax error and line number). A
|
||||||
|
failed validate leaves the live file untouched, so a broken config can no longer
|
||||||
|
reach a running Caddy.
|
||||||
|
|
||||||
|
What it cannot catch is a conflict with the global `/etc/caddy/Caddyfile`.
|
||||||
|
|
||||||
|
## The reload is a handler
|
||||||
|
|
||||||
|
`Reload caddy` fires **once, at the end of the play**, however many sites
|
||||||
|
notified it. The code this replaced ran `command: systemctl reload caddy`
|
||||||
|
immediately, mid-play. If a later task in the same play needs the new config to
|
||||||
|
be live, flush first:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- ansible.builtin.meta: flush_handlers
|
||||||
|
```
|
||||||
|
|
||||||
|
## Known intentional difference
|
||||||
|
|
||||||
|
The `resolvers` block is commented `# Use Tailscale MagicDNS to resolve the
|
||||||
|
upstream hostname` in every case. `datum-gateway` previously said `# Resolve via
|
||||||
|
Tailscale MagicDNS`. Migrating it therefore rewrites one comment line, which
|
||||||
|
Caddy ignores. Every other site renders byte-identical to what its playbook
|
||||||
|
produced.
|
||||||
|
|
||||||
|
## Sites on the hosts that this role does NOT manage
|
||||||
|
|
||||||
|
Four vhosts exist in `/etc/caddy/sites-enabled/` that no playbook writes. They
|
||||||
|
were made by hand. The role only ever writes the one file it is told to, so it
|
||||||
|
leaves them alone — but nothing in the repo records them, and that is why they
|
||||||
|
are listed here. Checked 2026-09-11:
|
||||||
|
|
||||||
|
| File | Host | Serves | State |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `uptime-kuma.conf` | watchtower | `localhost:3001` | **HTTP 302 — still live**, see below |
|
||||||
|
| `arbretstaging.conf` | vipy | `arbret-staging-box:80` via MagicDNS | HTTP 200 |
|
||||||
|
| `bitcoininfra.conf` | vipy | static `file_server` from `/var/www/bitcoin-services-home` | HTTP 200 |
|
||||||
|
| `scriberr.conf` | vipy | `scriberr-box:8080` via MagicDNS | HTTP 502 — upstream down |
|
||||||
|
|
||||||
|
**`uptime-kuma.conf` must not be deleted as dead config.** Uptime Kuma was
|
||||||
|
"decommissioned" in the repo — its playbooks archived and its credentials pulled
|
||||||
|
from the vault — but the container is **still running** on watchtower
|
||||||
|
(`louislam/uptime-kuma:latest`, created 2026-02-07, `restart=unless-stopped`)
|
||||||
|
and is still reachable at its public subdomain. Only the Ansible code was
|
||||||
|
retired; the service was not. See `archive/uptime_kuma/`.
|
||||||
|
|
||||||
|
`scriberr` returning 502 is the one that looks like genuine rot: it proxies to a
|
||||||
|
`scriberr-box` that is not answering, and `scriberr-box` is not in the inventory.
|
||||||
23
ansible/roles/caddy_site/defaults/main.yml
Normal file
23
ansible/roles/caddy_site/defaults/main.yml
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
# Required
|
||||||
|
caddy_site_name: "" # file basename -> <name>.conf
|
||||||
|
caddy_site_domain: "" # site address line; may hold several, comma separated
|
||||||
|
|
||||||
|
# Pick exactly one shape
|
||||||
|
caddy_site_upstream: "" # "localhost:3000" -> reverse_proxy
|
||||||
|
caddy_site_root: "" # filesystem path -> root * + file_server
|
||||||
|
caddy_site_body: "" # raw escape hatch for one-off sites; wins over both
|
||||||
|
|
||||||
|
# reverse_proxy modifiers
|
||||||
|
caddy_site_resolvers: "" # "100.100.100.100" for Tailscale MagicDNS
|
||||||
|
caddy_site_headers_up: {} # {"X-Forwarded-Host": "wallet.example.com"}
|
||||||
|
# A LIST, not a dict: Ansible does not template dict *keys*, so a Jinja
|
||||||
|
# expression for the username silently passes through as literal text.
|
||||||
|
caddy_site_basic_auth: [] # [{user: "{{ x_user }}", hash: "{{ x_hash }}"}]
|
||||||
|
|
||||||
|
# Placement. caddy_sites_dir comes from services_config.yml; this is the fallback.
|
||||||
|
caddy_sites_dir: /etc/caddy/sites-enabled
|
||||||
|
|
||||||
|
# Rendered site files can carry credentials (basic_auth hashes), so --diff is
|
||||||
|
# suppressed by default. Pass -e caddy_site_reveal=true to see what moved.
|
||||||
|
caddy_site_reveal: false
|
||||||
12
ansible/roles/caddy_site/handlers/main.yml
Normal file
12
ansible/roles/caddy_site/handlers/main.yml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
# Fires once at the end of the play, however many sites notified it.
|
||||||
|
# Anything later in the same play that needs the new config live must be
|
||||||
|
# preceded by `- ansible.builtin.meta: flush_handlers`.
|
||||||
|
# become is explicit because handlers do not inherit it from the task that
|
||||||
|
# notified them. headscale's play runs become: no and elevates per task, so
|
||||||
|
# without this the reload would run unprivileged and fail.
|
||||||
|
- name: Reload caddy
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: caddy
|
||||||
|
state: reloaded
|
||||||
46
ansible/roles/caddy_site/tasks/main.yml
Normal file
46
ansible/roles/caddy_site/tasks/main.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
- name: Assert caddy_site parameters are sane
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- caddy_site_name | length > 0
|
||||||
|
- caddy_site_domain | length > 0
|
||||||
|
- (caddy_site_upstream | length > 0) or (caddy_site_root | length > 0) or (caddy_site_body | length > 0)
|
||||||
|
- caddy_site_basic_auth is not mapping
|
||||||
|
fail_msg: >-
|
||||||
|
caddy_site: '{{ caddy_site_name | default("<unnamed>") }}' needs a name, a domain and
|
||||||
|
one of caddy_site_upstream / caddy_site_root / caddy_site_body.
|
||||||
|
caddy_site_basic_auth must be a LIST of {user, hash} — Ansible does not template dict keys.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Ensure Caddy sites-enabled directory exists
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ caddy_sites_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Ensure Caddyfile imports sites-enabled
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/caddy/Caddyfile
|
||||||
|
line: 'import sites-enabled/*'
|
||||||
|
insertafter: EOF
|
||||||
|
state: present
|
||||||
|
create: yes
|
||||||
|
mode: '0644'
|
||||||
|
backup: yes
|
||||||
|
|
||||||
|
# `validate` runs `caddy validate` against the rendered temp file before it is
|
||||||
|
# moved into place: verified on vipy that a single site fragment validates
|
||||||
|
# cleanly (rc=0, "Valid configuration") and that a malformed one is rejected
|
||||||
|
# (rc=1). A failed validate leaves the live file untouched.
|
||||||
|
- name: "Write Caddy site '{{ caddy_site_name }}'"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: site.conf.j2
|
||||||
|
dest: "{{ caddy_sites_dir }}/{{ caddy_site_name }}.conf"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
validate: "caddy validate --adapter caddyfile --config %s"
|
||||||
|
diff: "{{ caddy_site_reveal | bool }}"
|
||||||
|
notify: Reload caddy
|
||||||
34
ansible/roles/caddy_site/templates/site.conf.j2
Normal file
34
ansible/roles/caddy_site/templates/site.conf.j2
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{{ caddy_site_domain }} {
|
||||||
|
{% if caddy_site_body %}
|
||||||
|
{{ caddy_site_body | trim | indent(4, first=True) }}
|
||||||
|
{% else %}
|
||||||
|
{% if caddy_site_basic_auth %}
|
||||||
|
basic_auth {
|
||||||
|
{% for cred in caddy_site_basic_auth %}
|
||||||
|
{{ cred.user }} {{ cred.hash }}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% if caddy_site_root %}
|
||||||
|
root * {{ caddy_site_root }}
|
||||||
|
file_server
|
||||||
|
{% endif %}
|
||||||
|
{% if caddy_site_upstream %}
|
||||||
|
{% if caddy_site_headers_up or caddy_site_resolvers %}
|
||||||
|
reverse_proxy {{ caddy_site_upstream }} {
|
||||||
|
{% for key, value in caddy_site_headers_up.items() %}
|
||||||
|
header_up {{ key }} {{ value }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if caddy_site_resolvers %}
|
||||||
|
# Use Tailscale MagicDNS to resolve the upstream hostname
|
||||||
|
transport http {
|
||||||
|
resolvers {{ caddy_site_resolvers }}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
|
reverse_proxy {{ caddy_site_upstream }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
62
ansible/roles/socket_proxy/README.md
Normal file
62
ansible/roles/socket_proxy/README.md
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
# `socket_proxy`
|
||||||
|
|
||||||
|
Exposes a service running on a private Tailscale host through a public TCP port
|
||||||
|
on an edge machine, using `systemd-socket-proxyd`. Writes a `.socket` and a
|
||||||
|
`.service` unit, enables the socket, opens the UFW port, and checks the upstream
|
||||||
|
is reachable.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- ansible.builtin.include_role:
|
||||||
|
name: socket_proxy
|
||||||
|
vars:
|
||||||
|
socket_proxy_name: fulcrum-ssl # -> fulcrum-ssl-proxy.{socket,service}
|
||||||
|
socket_proxy_description: "Fulcrum SSL" # -> "Fulcrum SSL Proxy Socket"
|
||||||
|
socket_proxy_listen_port: "{{ fulcrum_ssl_port }}"
|
||||||
|
socket_proxy_upstream_host: "{{ fulcrum_tailscale_hostname }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
`socket_proxy_upstream_port` defaults to `socket_proxy_listen_port`, which is
|
||||||
|
what all three current callers want.
|
||||||
|
|
||||||
|
## Optional unit settings
|
||||||
|
|
||||||
|
These exist because the **live** `bitcoin-p2p-proxy` units on vipy carried
|
||||||
|
settings the playbook never wrote. Somebody added them by hand, so running
|
||||||
|
`deploy_bitcoin_knots_playbook.yml` would have silently removed them:
|
||||||
|
|
||||||
|
| Variable | Emits | Why it matters |
|
||||||
|
|---|---|---|
|
||||||
|
| `socket_proxy_free_bind` | `FreeBind=true` in `[Socket]` | Lets the socket bind to an address that is not up yet. Without it the socket can fail to start on boot. |
|
||||||
|
| `socket_proxy_documentation` | `Documentation=` in both units | Cosmetic. |
|
||||||
|
| `socket_proxy_timeout_stop_sec` | `TimeoutStopSec=` | Bounds how long a stop can hang. |
|
||||||
|
| `socket_proxy_log_to_journal` | `StandardOutput=journal` + `StandardError=journal` | Cosmetic on modern systemd, which defaults to the journal anyway. |
|
||||||
|
|
||||||
|
Only `bitcoin-p2p` passes any of them.
|
||||||
|
|
||||||
|
## `socket_proxy_ufw_comment`
|
||||||
|
|
||||||
|
Defaults to `"<description> public access"`, which reproduces the live rule
|
||||||
|
comment for bitcoin-p2p and fulcrum-ssl. **datum-stratum must pass it
|
||||||
|
explicitly** — its live comment is `DATUM Gateway Stratum public access` while
|
||||||
|
the derived default would be `DATUM Stratum public access`, and UFW treats the
|
||||||
|
comment as part of the rule, so the mismatch rewrites the rule on every run.
|
||||||
|
|
||||||
|
## The upstream check never fails the play
|
||||||
|
|
||||||
|
`wait_for` on the upstream carries `failed_when: false`. The proxy is correctly
|
||||||
|
configured whether or not the backend happens to be up, and this is the one task
|
||||||
|
that depends on another machine. The original plays used `ignore_errors: yes`,
|
||||||
|
which prints a red "ignoring" line; `failed_when: false` is the quieter
|
||||||
|
equivalent.
|
||||||
|
|
||||||
|
## Restarts
|
||||||
|
|
||||||
|
The handler restarts the `.socket`, not the `.service` — that is what picks up a
|
||||||
|
changed unit; the service is started by the socket on the next connection.
|
||||||
|
|
||||||
|
**Restarting a socket drops connections that are currently open through it.**
|
||||||
|
For bitcoin-p2p that means peers reconnect; for datum-stratum it means a mining
|
||||||
|
client has to reconnect and may lose in-flight shares. The handler only fires
|
||||||
|
when a unit file actually changes.
|
||||||
17
ansible/roles/socket_proxy/defaults/main.yml
Normal file
17
ansible/roles/socket_proxy/defaults/main.yml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
# Required
|
||||||
|
socket_proxy_name: "" # "bitcoin-p2p" -> bitcoin-p2p-proxy.{socket,service}
|
||||||
|
socket_proxy_description: "" # "Bitcoin P2P" -> "Bitcoin P2P Proxy Socket"
|
||||||
|
socket_proxy_listen_port: 0 # public port on the edge host
|
||||||
|
socket_proxy_upstream_host: "" # Tailscale hostname, e.g. "knots-box"
|
||||||
|
|
||||||
|
# Optional
|
||||||
|
socket_proxy_upstream_port: "" # defaults to socket_proxy_listen_port
|
||||||
|
socket_proxy_documentation: "" # Documentation= in both units
|
||||||
|
socket_proxy_free_bind: false # FreeBind=true: bind before the address is up
|
||||||
|
socket_proxy_timeout_stop_sec: "" # TimeoutStopSec=
|
||||||
|
socket_proxy_log_to_journal: false # StandardOutput/StandardError=journal
|
||||||
|
|
||||||
|
# Firewall
|
||||||
|
socket_proxy_ufw_proto: tcp
|
||||||
|
socket_proxy_ufw_comment: "" # defaults to "<description> public access"
|
||||||
8
ansible/roles/socket_proxy/handlers/main.yml
Normal file
8
ansible/roles/socket_proxy/handlers/main.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# Restarting the .socket is what picks up a changed unit; the .service is
|
||||||
|
# started by the socket on the next connection.
|
||||||
|
- name: Restart socket proxy
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ socket_proxy_name }}-proxy.socket"
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: yes
|
||||||
54
ansible/roles/socket_proxy/tasks/main.yml
Normal file
54
ansible/roles/socket_proxy/tasks/main.yml
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
- name: Assert socket_proxy parameters are sane
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- socket_proxy_name | length > 0
|
||||||
|
- socket_proxy_description | length > 0
|
||||||
|
- socket_proxy_listen_port | int > 0
|
||||||
|
- socket_proxy_upstream_host | length > 0
|
||||||
|
fail_msg: >-
|
||||||
|
socket_proxy: '{{ socket_proxy_name | default("<unnamed>") }}' needs a name,
|
||||||
|
a description, a listen port and an upstream host.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: "Create the {{ socket_proxy_name }}-proxy socket unit"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: proxy.socket.j2
|
||||||
|
dest: "/etc/systemd/system/{{ socket_proxy_name }}-proxy.socket"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
notify: Restart socket proxy
|
||||||
|
|
||||||
|
- name: "Create the {{ socket_proxy_name }}-proxy service unit"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: proxy.service.j2
|
||||||
|
dest: "/etc/systemd/system/{{ socket_proxy_name }}-proxy.service"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
notify: Restart socket proxy
|
||||||
|
|
||||||
|
- name: "Enable and start the {{ socket_proxy_name }}-proxy socket"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ socket_proxy_name }}-proxy.socket"
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
daemon_reload: yes
|
||||||
|
|
||||||
|
- name: "Allow the {{ socket_proxy_name }} port through UFW"
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
port: "{{ socket_proxy_listen_port | string }}"
|
||||||
|
proto: "{{ socket_proxy_ufw_proto }}"
|
||||||
|
comment: "{{ socket_proxy_ufw_comment | default(socket_proxy_description ~ ' public access', true) }}"
|
||||||
|
|
||||||
|
# Reachability of the upstream over Tailscale. Deliberately non-fatal: the proxy
|
||||||
|
# is still correctly configured if the backend happens to be down, and this is
|
||||||
|
# the one check that depends on another machine being up.
|
||||||
|
- name: "Verify {{ socket_proxy_upstream_host }} is reachable over Tailscale"
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
host: "{{ socket_proxy_upstream_host }}"
|
||||||
|
port: "{{ socket_proxy_upstream_port | default(socket_proxy_listen_port, true) }}"
|
||||||
|
timeout: 10
|
||||||
|
failed_when: false
|
||||||
18
ansible/roles/socket_proxy/templates/proxy.service.j2
Normal file
18
ansible/roles/socket_proxy/templates/proxy.service.j2
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
[Unit]
|
||||||
|
Description={{ socket_proxy_description }} Proxy to {{ socket_proxy_upstream_host }}
|
||||||
|
{% if socket_proxy_documentation %}
|
||||||
|
Documentation={{ socket_proxy_documentation }}
|
||||||
|
{% endif %}
|
||||||
|
Requires={{ socket_proxy_name }}-proxy.socket
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
ExecStart=/lib/systemd/systemd-socket-proxyd {{ socket_proxy_upstream_host }}:{{ socket_proxy_upstream_port | default(socket_proxy_listen_port, true) }}
|
||||||
|
{% if socket_proxy_timeout_stop_sec %}
|
||||||
|
TimeoutStopSec={{ socket_proxy_timeout_stop_sec }}
|
||||||
|
{% endif %}
|
||||||
|
{% if socket_proxy_log_to_journal %}
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
{% endif %}
|
||||||
14
ansible/roles/socket_proxy/templates/proxy.socket.j2
Normal file
14
ansible/roles/socket_proxy/templates/proxy.socket.j2
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[Unit]
|
||||||
|
Description={{ socket_proxy_description }} Proxy Socket
|
||||||
|
{% if socket_proxy_documentation %}
|
||||||
|
Documentation={{ socket_proxy_documentation }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream={{ socket_proxy_listen_port }}
|
||||||
|
{% if socket_proxy_free_bind %}
|
||||||
|
FreeBind=true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sockets.target
|
||||||
|
|
@ -740,7 +740,7 @@
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
|
|
||||||
- name: Setup public Bitcoin P2P forwarding on vipy via systemd-socket-proxyd
|
- name: Setup public Bitcoin P2P forwarding on the edge host
|
||||||
hosts: edge
|
hosts: edge
|
||||||
become: yes
|
become: yes
|
||||||
vars_files:
|
vars_files:
|
||||||
|
|
@ -753,62 +753,21 @@
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Create Bitcoin P2P proxy socket unit
|
- name: Expose Bitcoin P2P through a socket proxy
|
||||||
copy:
|
ansible.builtin.include_role:
|
||||||
dest: /etc/systemd/system/bitcoin-p2p-proxy.socket
|
name: socket_proxy
|
||||||
content: |
|
vars:
|
||||||
[Unit]
|
socket_proxy_name: bitcoin-p2p
|
||||||
Description=Bitcoin P2P Proxy Socket
|
socket_proxy_description: "Bitcoin P2P"
|
||||||
|
socket_proxy_listen_port: "{{ bitcoin_p2p_port }}"
|
||||||
[Socket]
|
socket_proxy_upstream_host: "{{ bitcoin_tailscale_hostname }}"
|
||||||
ListenStream={{ bitcoin_p2p_port }}
|
# These four were added by hand on vipy and were NOT in this playbook;
|
||||||
|
# writing the unit without them would have dropped FreeBind, which lets
|
||||||
[Install]
|
# the socket bind before the address is up.
|
||||||
WantedBy=sockets.target
|
socket_proxy_documentation: "https://github.com/bitcoin/bitcoin"
|
||||||
owner: root
|
socket_proxy_free_bind: true
|
||||||
group: root
|
socket_proxy_timeout_stop_sec: 5
|
||||||
mode: '0644'
|
socket_proxy_log_to_journal: true
|
||||||
notify: Restart bitcoin-p2p-proxy socket
|
|
||||||
|
|
||||||
- name: Create Bitcoin P2P proxy service unit
|
|
||||||
copy:
|
|
||||||
dest: /etc/systemd/system/bitcoin-p2p-proxy.service
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Bitcoin P2P Proxy to {{ bitcoin_tailscale_hostname }}
|
|
||||||
Requires=bitcoin-p2p-proxy.socket
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=notify
|
|
||||||
ExecStart=/lib/systemd/systemd-socket-proxyd {{ bitcoin_tailscale_hostname }}:{{ bitcoin_p2p_port }}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload systemd daemon
|
|
||||||
systemd:
|
|
||||||
daemon_reload: yes
|
|
||||||
|
|
||||||
- name: Enable and start Bitcoin P2P proxy socket
|
|
||||||
systemd:
|
|
||||||
name: bitcoin-p2p-proxy.socket
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
||||||
- name: Allow Bitcoin P2P port through UFW
|
|
||||||
ufw:
|
|
||||||
rule: allow
|
|
||||||
port: "{{ bitcoin_p2p_port | string }}"
|
|
||||||
proto: tcp
|
|
||||||
comment: "Bitcoin P2P public access"
|
|
||||||
|
|
||||||
- name: Verify connectivity to knots-box via Tailscale
|
|
||||||
wait_for:
|
|
||||||
host: "{{ bitcoin_tailscale_hostname }}"
|
|
||||||
port: "{{ bitcoin_p2p_port }}"
|
|
||||||
timeout: 10
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Display public endpoint
|
- name: Display public endpoint
|
||||||
when: uptime_kuma_enabled | default(false)
|
when: uptime_kuma_enabled | default(false)
|
||||||
|
|
@ -931,8 +890,3 @@
|
||||||
- /tmp/setup_bitcoin_p2p_tcp_monitor.py
|
- /tmp/setup_bitcoin_p2p_tcp_monitor.py
|
||||||
- /tmp/ansible_bitcoin_p2p_config.yml
|
- /tmp/ansible_bitcoin_p2p_config.yml
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: Restart bitcoin-p2p-proxy socket
|
|
||||||
systemd:
|
|
||||||
name: bitcoin-p2p-proxy.socket
|
|
||||||
state: restarted
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
- name: Install and configure Caddy on Debian 12
|
- name: Install and configure Caddy on Debian 12
|
||||||
hosts: vps
|
hosts: caddy
|
||||||
become: yes
|
become: yes
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
|
||||||
|
|
@ -487,7 +487,7 @@
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# Caddy Reverse Proxy for DATUM Dashboard (on vipy)
|
# Caddy Reverse Proxy for DATUM Dashboard (on vipy)
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: Configure Caddy reverse proxy for DATUM Gateway dashboard on vipy
|
- name: Configure Caddy reverse proxy for DATUM Gateway dashboard on the edge host
|
||||||
hosts: edge
|
hosts: edge
|
||||||
become: yes
|
become: yes
|
||||||
vars_files:
|
vars_files:
|
||||||
|
|
@ -498,64 +498,29 @@
|
||||||
vars:
|
vars:
|
||||||
datum_gateway_subdomain: "{{ subdomains.datum_gateway }}"
|
datum_gateway_subdomain: "{{ subdomains.datum_gateway }}"
|
||||||
datum_gateway_domain: "{{ datum_gateway_subdomain }}.{{ root_domain }}"
|
datum_gateway_domain: "{{ datum_gateway_subdomain }}.{{ root_domain }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish the DATUM Gateway dashboard through Caddy
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: datum-gateway
|
||||||
group: root
|
caddy_site_domain: "{{ datum_gateway_domain }}"
|
||||||
mode: "0755"
|
caddy_site_upstream: "knots-box:{{ datum_gateway_api_port }}"
|
||||||
|
caddy_site_resolvers: "100.100.100.100"
|
||||||
|
caddy_site_basic_auth:
|
||||||
|
- user: "{{ datum_dashboard_username }}"
|
||||||
|
hash: "{{ datum_dashboard_password_hash }}"
|
||||||
|
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
# The role validates the site fragment on its own. This re-validates the
|
||||||
lineinfile:
|
# whole assembled Caddyfile, which is the only thing that catches a
|
||||||
path: /etc/caddy/Caddyfile
|
# conflict between this site and another. Kept from the hand-rolled
|
||||||
line: "import sites-enabled/*"
|
# version; the other nine services never had it.
|
||||||
insertafter: EOF
|
- name: Validate the assembled Caddyfile
|
||||||
state: present
|
ansible.builtin.command: caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||||
backup: yes
|
|
||||||
create: yes
|
|
||||||
mode: "0644"
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy config for DATUM Gateway dashboard
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/datum-gateway.conf"
|
|
||||||
content: |
|
|
||||||
{{ datum_gateway_domain }} {
|
|
||||||
basic_auth {
|
|
||||||
{{ datum_dashboard_username }} {{ datum_dashboard_password_hash }}
|
|
||||||
}
|
|
||||||
reverse_proxy knots-box:{{ datum_gateway_api_port }} {
|
|
||||||
# Resolve via Tailscale MagicDNS
|
|
||||||
transport http {
|
|
||||||
resolvers 100.100.100.100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
|
||||||
|
|
||||||
- name: Validate Caddy config
|
|
||||||
command: caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
|
||||||
register: caddy_validate
|
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Display Caddy validation output
|
|
||||||
debug:
|
|
||||||
msg: "{{ caddy_validate.stdout_lines + caddy_validate.stderr_lines }}"
|
|
||||||
|
|
||||||
- name: Reload Caddy
|
|
||||||
command: systemctl reload caddy
|
|
||||||
register: caddy_reload
|
|
||||||
|
|
||||||
- name: Display Caddy reload output
|
|
||||||
debug:
|
|
||||||
msg: "{{ caddy_reload.stdout_lines + caddy_reload.stderr_lines }}"
|
|
||||||
|
|
||||||
- name: Display DATUM Gateway dashboard URL
|
- name: Display DATUM Gateway dashboard URL
|
||||||
when: uptime_kuma_enabled | default(false)
|
when: uptime_kuma_enabled | default(false)
|
||||||
debug:
|
debug:
|
||||||
|
|
@ -685,7 +650,7 @@
|
||||||
# Miners connect to vipy:23334; traffic is forwarded to knots-box:23334
|
# Miners connect to vipy:23334; traffic is forwarded to knots-box:23334
|
||||||
# over the Tailscale network, matching the Bitcoin P2P proxy pattern.
|
# over the Tailscale network, matching the Bitcoin P2P proxy pattern.
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: Setup public Stratum port forwarding on vipy via systemd-socket-proxyd
|
- name: Setup public Stratum port forwarding on the edge host
|
||||||
hosts: edge
|
hosts: edge
|
||||||
become: yes
|
become: yes
|
||||||
vars_files:
|
vars_files:
|
||||||
|
|
@ -698,62 +663,17 @@
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Create Stratum proxy socket unit
|
- name: Expose the DATUM Stratum port through a socket proxy
|
||||||
copy:
|
ansible.builtin.include_role:
|
||||||
dest: /etc/systemd/system/datum-stratum-proxy.socket
|
name: socket_proxy
|
||||||
content: |
|
vars:
|
||||||
[Unit]
|
socket_proxy_name: datum-stratum
|
||||||
Description=DATUM Stratum Proxy Socket
|
socket_proxy_description: "DATUM Stratum"
|
||||||
|
socket_proxy_listen_port: "{{ datum_gateway_stratum_port }}"
|
||||||
[Socket]
|
socket_proxy_upstream_host: "{{ datum_tailscale_hostname }}"
|
||||||
ListenStream={{ datum_gateway_stratum_port }}
|
# Matches the UFW comment already on vipy; the derived default would
|
||||||
|
# have said "DATUM Stratum" and rewritten the rule.
|
||||||
[Install]
|
socket_proxy_ufw_comment: "DATUM Gateway Stratum public access"
|
||||||
WantedBy=sockets.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
|
||||||
notify: Restart datum-stratum-proxy socket
|
|
||||||
|
|
||||||
- name: Create Stratum proxy service unit
|
|
||||||
copy:
|
|
||||||
dest: /etc/systemd/system/datum-stratum-proxy.service
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=DATUM Stratum Proxy to {{ datum_tailscale_hostname }}
|
|
||||||
Requires=datum-stratum-proxy.socket
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=notify
|
|
||||||
ExecStart=/lib/systemd/systemd-socket-proxyd {{ datum_tailscale_hostname }}:{{ datum_gateway_stratum_port }}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
|
||||||
|
|
||||||
- name: Reload systemd daemon
|
|
||||||
systemd:
|
|
||||||
daemon_reload: yes
|
|
||||||
|
|
||||||
- name: Enable and start Stratum proxy socket
|
|
||||||
systemd:
|
|
||||||
name: datum-stratum-proxy.socket
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
||||||
- name: Allow Stratum port through UFW
|
|
||||||
ufw:
|
|
||||||
rule: allow
|
|
||||||
port: "{{ datum_gateway_stratum_port | string }}"
|
|
||||||
proto: tcp
|
|
||||||
comment: "DATUM Gateway Stratum public access"
|
|
||||||
|
|
||||||
- name: Verify connectivity to knots-box Stratum via Tailscale
|
|
||||||
wait_for:
|
|
||||||
host: "{{ datum_tailscale_hostname }}"
|
|
||||||
port: "{{ datum_gateway_stratum_port }}"
|
|
||||||
timeout: 10
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Display public Stratum endpoint
|
- name: Display public Stratum endpoint
|
||||||
when: uptime_kuma_enabled | default(false)
|
when: uptime_kuma_enabled | default(false)
|
||||||
|
|
@ -880,8 +800,3 @@
|
||||||
- /tmp/setup_datum_stratum_tcp_monitor.py
|
- /tmp/setup_datum_stratum_tcp_monitor.py
|
||||||
- /tmp/ansible_datum_stratum_config.yml
|
- /tmp/ansible_datum_stratum_config.yml
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: Restart datum-stratum-proxy socket
|
|
||||||
systemd:
|
|
||||||
name: datum-stratum-proxy.socket
|
|
||||||
state: restarted
|
|
||||||
|
|
|
||||||
|
|
@ -25,4 +25,6 @@ ansible-playbook ansible/services/forgejo-runner/deploy_forgejo_runner_playbook.
|
||||||
|
|
||||||
1. On the VM: `systemctl status forgejo-runner` should show active
|
1. On the VM: `systemctl status forgejo-runner` should show active
|
||||||
2. In Forgejo: **Site Administration** > **Actions** > **Runners** should show the runner as online
|
2. In Forgejo: **Site Administration** > **Actions** > **Runners** should show the runner as online
|
||||||
3. In Uptime Kuma: the `forgejo-runner-healthcheck` push monitor should be receiving pings
|
3. ~~In Uptime Kuma: the `forgejo-runner-healthcheck` push monitor should be receiving pings~~
|
||||||
|
*(Uptime Kuma was decommissioned 2026-09-11 — this check no longer applies. The
|
||||||
|
healthcheck timer still runs on the host but pushes nowhere. See `archive/uptime_kuma/`.)*
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
- ./forgejo_vars.yml
|
- ./forgejo_vars.yml
|
||||||
vars:
|
vars:
|
||||||
forgejo_subdomain: "{{ subdomains.forgejo }}"
|
forgejo_subdomain: "{{ subdomains.forgejo }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
forgejo_domain: "{{ forgejo_subdomain }}.{{ root_domain }}"
|
forgejo_domain: "{{ forgejo_subdomain }}.{{ root_domain }}"
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
|
|
@ -88,35 +87,13 @@
|
||||||
enabled: yes
|
enabled: yes
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish Forgejo through Caddy
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: forgejo
|
||||||
group: root
|
caddy_site_domain: "{{ forgejo_domain }}"
|
||||||
mode: '0755'
|
caddy_site_upstream: "localhost:{{ forgejo_port }}"
|
||||||
|
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/caddy/Caddyfile
|
|
||||||
line: 'import sites-enabled/*'
|
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy configuration for forgejo
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/forgejo.conf"
|
|
||||||
content: |
|
|
||||||
{{ forgejo_domain }} {
|
|
||||||
reverse_proxy localhost:{{ forgejo_port }}
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
command: systemctl reload caddy
|
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||||
|
|
|
||||||
|
|
@ -540,7 +540,7 @@
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
|
|
||||||
- name: Setup public Fulcrum SSL forwarding on vipy via systemd-socket-proxyd
|
- name: Setup public Fulcrum SSL forwarding on the edge host
|
||||||
hosts: edge
|
hosts: edge
|
||||||
become: yes
|
become: yes
|
||||||
vars_files:
|
vars_files:
|
||||||
|
|
@ -552,62 +552,14 @@
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Create Fulcrum SSL proxy socket unit
|
- name: Expose Fulcrum SSL through a socket proxy
|
||||||
copy:
|
ansible.builtin.include_role:
|
||||||
dest: /etc/systemd/system/fulcrum-ssl-proxy.socket
|
name: socket_proxy
|
||||||
content: |
|
vars:
|
||||||
[Unit]
|
socket_proxy_name: fulcrum-ssl
|
||||||
Description=Fulcrum SSL Proxy Socket
|
socket_proxy_description: "Fulcrum SSL"
|
||||||
|
socket_proxy_listen_port: "{{ fulcrum_ssl_port }}"
|
||||||
[Socket]
|
socket_proxy_upstream_host: "{{ fulcrum_tailscale_hostname }}"
|
||||||
ListenStream={{ fulcrum_ssl_port }}
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=sockets.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
notify: Restart fulcrum-ssl-proxy socket
|
|
||||||
|
|
||||||
- name: Create Fulcrum SSL proxy service unit
|
|
||||||
copy:
|
|
||||||
dest: /etc/systemd/system/fulcrum-ssl-proxy.service
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Fulcrum SSL Proxy to {{ fulcrum_tailscale_hostname }}
|
|
||||||
Requires=fulcrum-ssl-proxy.socket
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=notify
|
|
||||||
ExecStart=/lib/systemd/systemd-socket-proxyd {{ fulcrum_tailscale_hostname }}:{{ fulcrum_ssl_port }}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload systemd daemon
|
|
||||||
systemd:
|
|
||||||
daemon_reload: yes
|
|
||||||
|
|
||||||
- name: Enable and start Fulcrum SSL proxy socket
|
|
||||||
systemd:
|
|
||||||
name: fulcrum-ssl-proxy.socket
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
||||||
- name: Allow Fulcrum SSL port through UFW
|
|
||||||
ufw:
|
|
||||||
rule: allow
|
|
||||||
port: "{{ fulcrum_ssl_port | string }}"
|
|
||||||
proto: tcp
|
|
||||||
comment: "Fulcrum SSL public access"
|
|
||||||
|
|
||||||
- name: Verify connectivity to fulcrum-box via Tailscale
|
|
||||||
wait_for:
|
|
||||||
host: "{{ fulcrum_tailscale_hostname }}"
|
|
||||||
port: "{{ fulcrum_ssl_port }}"
|
|
||||||
timeout: 10
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Display public endpoint
|
- name: Display public endpoint
|
||||||
when: uptime_kuma_enabled | default(false)
|
when: uptime_kuma_enabled | default(false)
|
||||||
|
|
@ -730,9 +682,4 @@
|
||||||
- /tmp/setup_fulcrum_ssl_tcp_monitor.py
|
- /tmp/setup_fulcrum_ssl_tcp_monitor.py
|
||||||
- /tmp/ansible_fulcrum_ssl_config.yml
|
- /tmp/ansible_fulcrum_ssl_config.yml
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: Restart fulcrum-ssl-proxy socket
|
|
||||||
systemd:
|
|
||||||
name: fulcrum-ssl-proxy.socket
|
|
||||||
state: restarted
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
- ./headscale_vars.yml
|
- ./headscale_vars.yml
|
||||||
vars:
|
vars:
|
||||||
headscale_subdomain: "{{ subdomains.headscale }}"
|
headscale_subdomain: "{{ subdomains.headscale }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
headscale_domain: "{{ headscale_subdomain }}.{{ root_domain }}"
|
headscale_domain: "{{ headscale_subdomain }}.{{ root_domain }}"
|
||||||
headscale_base_domain: "tailnet.{{ root_domain }}"
|
headscale_base_domain: "tailnet.{{ root_domain }}"
|
||||||
headscale_namespace: "{{ service_settings.headscale.namespace }}"
|
headscale_namespace: "{{ service_settings.headscale.namespace }}"
|
||||||
|
|
@ -230,39 +229,34 @@
|
||||||
port: '3478'
|
port: '3478'
|
||||||
proto: udp
|
proto: udp
|
||||||
|
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish headscale through Caddy
|
||||||
become: yes
|
ansible.builtin.include_role:
|
||||||
file:
|
name: caddy_site
|
||||||
path: "{{ caddy_sites_dir }}"
|
# This play is become: no and elevates per task. `apply` is how an
|
||||||
state: directory
|
# include_role passes become down to the role's tasks - `become:` on
|
||||||
owner: root
|
# the include itself is rejected. The role's handler sets its own.
|
||||||
group: root
|
apply:
|
||||||
mode: '0755'
|
become: yes
|
||||||
|
vars:
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
caddy_site_name: headscale
|
||||||
become: yes
|
caddy_site_domain: "{{ headscale_domain }}"
|
||||||
lineinfile:
|
# Raw body, and it must stay raw: the /admin* route in front of
|
||||||
path: /etc/caddy/Caddyfile
|
# Headplane is not expressible as a plain reverse_proxy. The previous
|
||||||
line: 'import sites-enabled/*'
|
# version of this task wrote only `reverse_proxy localhost:8080`, which
|
||||||
insertafter: EOF
|
# would have deleted the admin route and its auth on the next run.
|
||||||
state: present
|
caddy_site_body: |
|
||||||
backup: yes
|
@headplane {
|
||||||
|
path /admin*
|
||||||
- name: Create Caddy reverse proxy configuration for headscale
|
|
||||||
become: yes
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/headscale.conf"
|
|
||||||
content: |
|
|
||||||
{{ headscale_domain }} {
|
|
||||||
reverse_proxy localhost:{{ headscale_port }}
|
|
||||||
}
|
}
|
||||||
owner: root
|
handle @headplane {
|
||||||
group: root
|
basicauth {
|
||||||
mode: '0644'
|
{{ headscale_ui_username }} {{ headscale_ui_password_hash }}
|
||||||
|
}
|
||||||
- name: Reload Caddy to apply new config
|
reverse_proxy http://localhost:{{ headplane_port }}
|
||||||
become: yes
|
}
|
||||||
command: systemctl reload caddy
|
# Headscale API is protected by its own API key authentication
|
||||||
|
# All API operations require a valid Bearer token in the Authorization header
|
||||||
|
reverse_proxy * http://localhost:{{ headscale_port }}
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||||
|
|
|
||||||
|
|
@ -22,3 +22,6 @@ remote_port: "{{ hostvars.get(remote_host_name, {}).get('ansible_port', 22) }}"
|
||||||
# Local backup
|
# Local backup
|
||||||
local_backup_dir: "{{ lookup('env', 'HOME') }}/headscale-backups"
|
local_backup_dir: "{{ lookup('env', 'HOME') }}/headscale-backups"
|
||||||
backup_script_path: "{{ lookup('env', 'HOME') }}/.local/bin/headscale_backup.sh"
|
backup_script_path: "{{ lookup('env', 'HOME') }}/.local/bin/headscale_backup.sh"
|
||||||
|
|
||||||
|
# Headplane (headscale admin UI), proxied at /admin* behind Caddy basic auth
|
||||||
|
headplane_port: 3000
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
- ./lnbits_vars.yml
|
- ./lnbits_vars.yml
|
||||||
vars:
|
vars:
|
||||||
lnbits_subdomain: "{{ subdomains.lnbits }}"
|
lnbits_subdomain: "{{ subdomains.lnbits }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
lnbits_domain: "{{ lnbits_subdomain }}.{{ root_domain }}"
|
lnbits_domain: "{{ lnbits_subdomain }}.{{ root_domain }}"
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
|
|
@ -147,39 +146,15 @@
|
||||||
enabled: yes
|
enabled: yes
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish LNBits through Caddy
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: lnbits
|
||||||
group: root
|
caddy_site_domain: "{{ lnbits_domain }}"
|
||||||
mode: '0755'
|
caddy_site_upstream: "localhost:{{ lnbits_port }}"
|
||||||
|
caddy_site_headers_up:
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
X-Forwarded-Host: "{{ lnbits_domain }}"
|
||||||
lineinfile:
|
|
||||||
path: /etc/caddy/Caddyfile
|
|
||||||
line: 'import sites-enabled/*'
|
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
create: yes
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy configuration for lnbits
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/lnbits.conf"
|
|
||||||
content: |
|
|
||||||
{{ lnbits_domain }} {
|
|
||||||
reverse_proxy localhost:{{ lnbits_port }} {
|
|
||||||
header_up X-Forwarded-Host {{ lnbits_domain }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
command: systemctl reload caddy
|
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
|
|
||||||
- name: Configure Caddy reverse proxy for Memos on vipy (proxying via Tailscale)
|
- name: Configure Caddy reverse proxy for Memos on the edge host (via Tailscale)
|
||||||
hosts: edge
|
hosts: edge
|
||||||
become: yes
|
become: yes
|
||||||
vars_files:
|
vars_files:
|
||||||
|
|
@ -166,45 +166,18 @@
|
||||||
- ./memos_vars.yml
|
- ./memos_vars.yml
|
||||||
vars:
|
vars:
|
||||||
memos_subdomain: "{{ subdomains.memos }}"
|
memos_subdomain: "{{ subdomains.memos }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
memos_domain: "{{ memos_subdomain }}.{{ root_domain }}"
|
memos_domain: "{{ memos_subdomain }}.{{ root_domain }}"
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish Memos through Caddy (via Tailscale)
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: memos
|
||||||
group: root
|
caddy_site_domain: "{{ memos_domain }}"
|
||||||
mode: '0755'
|
caddy_site_upstream: "{{ memos_tailscale_hostname }}:{{ memos_port }}"
|
||||||
|
caddy_site_resolvers: "100.100.100.100"
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/caddy/Caddyfile
|
|
||||||
line: 'import sites-enabled/*'
|
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy configuration for memos (via Tailscale)
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/memos.conf"
|
|
||||||
content: |
|
|
||||||
{{ memos_domain }} {
|
|
||||||
reverse_proxy {{ memos_tailscale_hostname }}:{{ memos_port }} {
|
|
||||||
# Use Tailscale MagicDNS to resolve the upstream hostname
|
|
||||||
transport http {
|
|
||||||
resolvers 100.100.100.100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
command: systemctl reload caddy
|
|
||||||
|
|
||||||
- name: Create Uptime Kuma monitor setup script for Memos
|
- name: Create Uptime Kuma monitor setup script for Memos
|
||||||
when: uptime_kuma_enabled | default(false)
|
when: uptime_kuma_enabled | default(false)
|
||||||
|
|
|
||||||
|
|
@ -603,7 +603,7 @@
|
||||||
- /tmp/ansible_mempool_config.yml
|
- /tmp/ansible_mempool_config.yml
|
||||||
- /tmp/mempool_push_urls.yml
|
- /tmp/mempool_push_urls.yml
|
||||||
|
|
||||||
- name: Configure Caddy reverse proxy for Mempool on vipy
|
- name: Configure Caddy reverse proxy for Mempool on the edge host
|
||||||
hosts: edge
|
hosts: edge
|
||||||
become: yes
|
become: yes
|
||||||
vars_files:
|
vars_files:
|
||||||
|
|
@ -614,47 +614,16 @@
|
||||||
vars:
|
vars:
|
||||||
mempool_subdomain: "{{ subdomains.mempool }}"
|
mempool_subdomain: "{{ subdomains.mempool }}"
|
||||||
mempool_domain: "{{ mempool_subdomain }}.{{ root_domain }}"
|
mempool_domain: "{{ mempool_subdomain }}.{{ root_domain }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish Mempool through Caddy (via Tailscale)
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: mempool
|
||||||
group: root
|
caddy_site_domain: "{{ mempool_domain }}"
|
||||||
mode: '0755'
|
caddy_site_upstream: "mempool-box:{{ mempool_frontend_port }}"
|
||||||
|
caddy_site_resolvers: "100.100.100.100"
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/caddy/Caddyfile
|
|
||||||
line: 'import sites-enabled/*'
|
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
create: yes
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy configuration for Mempool
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/mempool.conf"
|
|
||||||
content: |
|
|
||||||
{{ mempool_domain }} {
|
|
||||||
reverse_proxy mempool-box:{{ mempool_frontend_port }} {
|
|
||||||
# Use Tailscale MagicDNS to resolve the upstream hostname
|
|
||||||
transport http {
|
|
||||||
resolvers 100.100.100.100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
systemd:
|
|
||||||
name: caddy
|
|
||||||
state: reloaded
|
|
||||||
|
|
||||||
- name: Display Mempool URL
|
- name: Display Mempool URL
|
||||||
when: uptime_kuma_enabled | default(false)
|
when: uptime_kuma_enabled | default(false)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
- ./ntfy_emergency_app_vars.yml
|
- ./ntfy_emergency_app_vars.yml
|
||||||
vars:
|
vars:
|
||||||
ntfy_emergency_app_subdomain: "{{ subdomains.ntfy_emergency_app }}"
|
ntfy_emergency_app_subdomain: "{{ subdomains.ntfy_emergency_app }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
ntfy_emergency_app_domain: "{{ ntfy_emergency_app_subdomain }}.{{ root_domain }}"
|
ntfy_emergency_app_domain: "{{ ntfy_emergency_app_subdomain }}.{{ root_domain }}"
|
||||||
ntfy_service_domain: "{{ subdomains.ntfy }}.{{ root_domain }}"
|
ntfy_service_domain: "{{ subdomains.ntfy }}.{{ root_domain }}"
|
||||||
ntfy_emergency_app_ntfy_url: "https://{{ ntfy_service_domain }}"
|
ntfy_emergency_app_ntfy_url: "https://{{ ntfy_service_domain }}"
|
||||||
|
|
@ -49,35 +48,13 @@
|
||||||
args:
|
args:
|
||||||
chdir: "{{ ntfy_emergency_app_dir }}"
|
chdir: "{{ ntfy_emergency_app_dir }}"
|
||||||
|
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish ntfy-emergency-app through Caddy
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: ntfy-emergency-app
|
||||||
group: root
|
caddy_site_domain: "{{ ntfy_emergency_app_domain }}"
|
||||||
mode: '0755'
|
caddy_site_upstream: "localhost:{{ ntfy_emergency_app_port }}"
|
||||||
|
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/caddy/Caddyfile
|
|
||||||
line: 'import sites-enabled/*'
|
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy configuration for ntfy-emergency-app
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/ntfy-emergency-app.conf"
|
|
||||||
content: |
|
|
||||||
{{ ntfy_emergency_app_domain }} {
|
|
||||||
reverse_proxy localhost:{{ ntfy_emergency_app_port }}
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
command: systemctl reload caddy
|
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
- ./ntfy_vars.yml
|
- ./ntfy_vars.yml
|
||||||
vars:
|
vars:
|
||||||
ntfy_subdomain: "{{ subdomains.ntfy }}"
|
ntfy_subdomain: "{{ subdomains.ntfy }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
ntfy_domain: "{{ ntfy_subdomain }}.{{ root_domain }}"
|
ntfy_domain: "{{ ntfy_subdomain }}.{{ root_domain }}"
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
@ -76,42 +75,23 @@
|
||||||
shell: |
|
shell: |
|
||||||
(echo "{{ ntfy_password }}"; echo "{{ ntfy_password }}") | ntfy user add --role=admin "{{ ntfy_username }}"
|
(echo "{{ ntfy_password }}"; echo "{{ ntfy_password }}") | ntfy user add --role=admin "{{ ntfy_username }}"
|
||||||
|
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish ntfy through Caddy
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: ntfy
|
||||||
group: root
|
caddy_site_domain: "{{ ntfy_domain }}, http://{{ ntfy_domain }}"
|
||||||
mode: '0755'
|
# Raw body: ntfy needs a plain-HTTP listener for its CLI/app clients,
|
||||||
|
# with only GETs to the docs and topic paths redirected to HTTPS.
|
||||||
|
caddy_site_body: |
|
||||||
|
reverse_proxy 127.0.0.1:{{ ntfy_port }}
|
||||||
|
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
@httpget {
|
||||||
lineinfile:
|
protocol http
|
||||||
path: /etc/caddy/Caddyfile
|
method GET
|
||||||
line: 'import sites-enabled/*'
|
path_regexp ^/([-_a-z0-9]{0,64}$|docs/|static/)
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy configuration for ntfy
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/ntfy.conf"
|
|
||||||
content: |
|
|
||||||
{{ ntfy_domain }}, http://{{ ntfy_domain }} {
|
|
||||||
reverse_proxy 127.0.0.1:{{ ntfy_port }}
|
|
||||||
|
|
||||||
@httpget {
|
|
||||||
protocol http
|
|
||||||
method GET
|
|
||||||
path_regexp ^/([-_a-z0-9]{0,64}$|docs/|static/)
|
|
||||||
}
|
|
||||||
redir @httpget https://{host}{uri}
|
|
||||||
}
|
}
|
||||||
owner: root
|
redir @httpget https://{host}{uri}
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
command: systemctl reload caddy
|
|
||||||
|
|
||||||
handlers:
|
handlers:
|
||||||
- name: Restart ntfy
|
- name: Restart ntfy
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
- ./personal_blog_vars.yml
|
- ./personal_blog_vars.yml
|
||||||
vars:
|
vars:
|
||||||
personal_blog_subdomain: "{{ subdomains.personal_blog }}"
|
personal_blog_subdomain: "{{ subdomains.personal_blog }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
personal_blog_domain: "{{ personal_blog_subdomain }}.{{ root_domain }}"
|
personal_blog_domain: "{{ personal_blog_subdomain }}.{{ root_domain }}"
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
|
|
@ -51,36 +50,13 @@
|
||||||
group: www-data
|
group: www-data
|
||||||
mode: '0664'
|
mode: '0664'
|
||||||
|
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish the blog through Caddy
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: personal-blog
|
||||||
group: root
|
caddy_site_domain: "{{ personal_blog_domain }}"
|
||||||
mode: '0755'
|
caddy_site_root: "{{ personal_blog_web_root }}"
|
||||||
|
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/caddy/Caddyfile
|
|
||||||
line: 'import sites-enabled/*'
|
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
|
|
||||||
- name: Create Caddy file server configuration for personal blog
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/personal-blog.conf"
|
|
||||||
content: |
|
|
||||||
{{ personal_blog_domain }} {
|
|
||||||
root * {{ personal_blog_web_root }}
|
|
||||||
file_server
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
command: systemctl reload caddy
|
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
# ⚠️ After the first run, back up {{ phoenixd_data_dir }}/seed.dat. Losing it
|
# ⚠️ After the first run, back up {{ phoenixd_data_dir }}/seed.dat. Losing it
|
||||||
# means losing the funds. See setup_backup_phoenixd_to_lapy.yml.
|
# means losing the funds. See setup_backup_phoenixd_to_lapy.yml.
|
||||||
|
|
||||||
- name: Deploy phoenixd on vipy
|
- name: Deploy phoenixd on the edge host
|
||||||
hosts: edge
|
hosts: edge
|
||||||
become: yes
|
become: yes
|
||||||
vars_files:
|
vars_files:
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
- ./vaultwarden_vars.yml
|
- ./vaultwarden_vars.yml
|
||||||
vars:
|
vars:
|
||||||
vaultwarden_subdomain: "{{ subdomains.vaultwarden }}"
|
vaultwarden_subdomain: "{{ subdomains.vaultwarden }}"
|
||||||
caddy_sites_dir: "{{ caddy_sites_dir }}"
|
|
||||||
vaultwarden_domain: "{{ vaultwarden_subdomain }}.{{ root_domain }}"
|
vaultwarden_domain: "{{ vaultwarden_subdomain }}.{{ root_domain }}"
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||||
|
|
||||||
|
|
@ -81,35 +80,13 @@
|
||||||
name: fail2ban
|
name: fail2ban
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: Ensure Caddy sites-enabled directory exists
|
- name: Publish Vaultwarden through Caddy
|
||||||
file:
|
ansible.builtin.include_role:
|
||||||
path: "{{ caddy_sites_dir }}"
|
name: caddy_site
|
||||||
state: directory
|
vars:
|
||||||
owner: root
|
caddy_site_name: vaultwarden
|
||||||
group: root
|
caddy_site_domain: "{{ vaultwarden_domain }}"
|
||||||
mode: '0755'
|
caddy_site_upstream: "localhost:{{ vaultwarden_port }}"
|
||||||
|
|
||||||
- name: Ensure Caddyfile includes import directive for sites-enabled
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/caddy/Caddyfile
|
|
||||||
line: 'import sites-enabled/*'
|
|
||||||
insertafter: EOF
|
|
||||||
state: present
|
|
||||||
backup: yes
|
|
||||||
|
|
||||||
- name: Create Caddy reverse proxy configuration for vaultwarden
|
|
||||||
copy:
|
|
||||||
dest: "{{ caddy_sites_dir }}/vaultwarden.conf"
|
|
||||||
content: |
|
|
||||||
{{ vaultwarden_domain }} {
|
|
||||||
reverse_proxy localhost:{{ vaultwarden_port }}
|
|
||||||
}
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload Caddy to apply new config
|
|
||||||
command: systemctl reload caddy
|
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue