Merge branch 'main' into diun

This commit is contained in:
Víðir Valberg Guðmundsson 2024-03-28 14:36:36 +01:00
commit f8e3823325
119 changed files with 2019 additions and 1909 deletions

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
playbook.retry *.retry
*.sw* *.sw*
.vagrant/ .vagrant/
*.log *.log

10
Vagrantfile vendored
View file

@ -13,7 +13,8 @@ Vagrant.configure(2) do |config|
config.vm.hostname = "datacoop" config.vm.hostname = "datacoop"
config.vm.provider :virtualbox do |v| config.vm.provider :virtualbox do |v|
v.memory = 8192 v.cpus = 8
v.memory = 16384
end end
config.vm.provision :ansible do |ansible| config.vm.provision :ansible do |ansible|
@ -26,7 +27,12 @@ Vagrant.configure(2) do |config|
if provisioned? if provisioned?
config.ssh.guest_port = PORT config.ssh.guest_port = PORT
ansible.extra_vars = { ansible.extra_vars = {
ansible_port: PORT ansible_port: PORT,
from_vagrant: true
}
else
ansible.extra_vars = {
from_vagrant: true
} }
end end
end end

View file

@ -1,4 +1,8 @@
[defaults] [defaults]
remote_user = root ask_vault_pass = True
inventory = datacoop_hosts inventory = datacoop_hosts
interpreter_python = /usr/bin/python3
remote_user = root
retry_files_enabled = True
use_persistent_connections = True use_persistent_connections = True
forks = 10

View file

@ -1,3 +1,5 @@
###################################### [production]
### All hosts hevonen.servers.data.coop ansible_port=19022
hevonen.servers.data.coop ansible_port=19022 ansible_python_interpreter=/usr/bin/python3
[monitoring]
uptime.data.coop

View file

@ -9,10 +9,11 @@ usage () {
} >&2 } >&2
} }
BASE_CMD="ansible-playbook playbook.yml --ask-vault-pass" BASE_CMD="ansible-playbook playbook.yml"
if [ "$1" = "--vagrant" ]; then if [ "$1" = "--vagrant" ]; then
BASE_CMD="$BASE_CMD --verbose --inventory=vagrant_host" BASE_CMD="$BASE_CMD --verbose --inventory=vagrant_host"
VAGRANT_VAR="from_vagrant"
shift shift
fi fi
@ -29,17 +30,17 @@ else
"services") "services")
if [ -z "$2" ]; then if [ -z "$2" ]; then
echo "Deploying all services!" echo "Deploying all services!"
$BASE_CMD --tags setup_services eval "$BASE_CMD --tags setup_services $(test -z "$VAGRANT_VAR" || printf '%s' "$VAGRANT_VAR=true")"
else else
echo "Deploying service: $2" echo "Deploying service: $2"
$BASE_CMD --tags setup_services --extra-vars "single_service=$2" $BASE_CMD --tags setup_services --extra-vars '{"single_service": "'"$2"'"'"$(test -z "$VAGRANT_VAR" || printf '%s' ', "'"$VAGRANT_VAR"'": true')"'}'
fi fi
;; ;;
"base") "base")
$BASE_CMD --tags base_only eval "$BASE_CMD --tags base_only $(test -z "$VAGRANT_VAR" || printf '%s' "$VAGRANT_VAR=true")"
;; ;;
"users") "users")
$BASE_CMD --tags setup-users eval "$BASE_CMD --tags setup-users $(test -z "$VAGRANT_VAR" || printf '%s' "$VAGRANT_VAR=true")"
;; ;;
*) *)
usage usage

View file

@ -1,165 +1,170 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
37303437623836623537343137326638663435303862366236656433656631353762383831393237 30613439636234396439623634656338666330643936373563656336323831353464353239353661
6165336434633034613838386563303963386163623932300a636663666130613636323836613338 6234316535383838653865643964353033623935313432630a666563316534343733363464396635
61313938373163656333656666386463643463633736666431613762663439346131613366363137 34396664643137643136633837656432623633383361633336343562333039326538393034616637
3731326163383337650a306561663939633939383437636662303138623064633264303463376536 6634613631636433610a663835343739376534356133323163343132323233643135613333313132
65336135623436383633383239663433353033353361613733643933636362373033393663613132 65373233666535366137343839363938303561653731633038376631386161653038613631396364
34643034633432356330653834393039623039653538316661356230366562666561356132376332 33636131636536306134346336636332393436303063306262333430613137376438626133353963
32323130663536363431366130366437666330313833656463356661356337346162373032323833 66396332363335333436623335613966323730616139353762656662386530356435623831656632
65306531663434303163613732376233633237376364373361383164313139383131376538656231 30333363376132653362323339386437346134323232363336363461323332613962613131386264
65343336353631626235346362316662363034646538376237343534356265626336643264343966 37383435653061653466613834346430656632626338316564656136666266353231363661666461
33623962353235396435613536383639383439363131373961393131373538306433386464363839 32646461313365626232376536376463313531613861363462643062326538326234613332646430
64656536643864363866396134353937626531373161323865663562626231313865666263653133 33383438613961623134343665383638346164653031363435656162306163653232353162343431
38336432353933383238636238656364383361383535386232633433363362663539323131386338 38333239393332613466663231383932316330376535383466643233326134623530306361393639
33316361663563363238626632303666396466326331363732326135643839373636636562653537 63386530643733393033646139613730313239313866343730643337393533366330373363353338
38373266636336383261363461623035396265613764663161643766363061306264306365323061 62313739613531636166663135646262396334373538636634393534616337363337323630666261
63346631366263326266303838393963353435643162306231633835336136666439393765643263 39643164363437653661633666376431303662396431633661663933343666613234326637636231
61613063343164633031393838636233636466383036353665303063653236623334376639346264 38383537333532326636343366343564646630363838323162373339323365666262303836636232
30343530653461336134383266633862373030376339656137356434383930396463363261663763 31343637616261636130656637393633383165353332346239323063646162306235313962363935
34353531303336343435303330623433326565616639353364366363616233323532323133393462 64633639653261363563646664393630666564646165393736363562623231626634326163306630
32386566353162656265373034663161313364666238363335373937646463626332396662373563 37613635306136643334616364303439323332666431386264623265323636623738303364396636
61656237353932353262333038633164623466663930623232666365653466613439383164383439 37626161363466646166633434333265623236633033666562643264303662333363396631646638
37313565383966633464646337323266666635613831356264656362353464616135306634623930 36626636363261313966393235313866353936323064343331626362306162323166323063656433
63663331316532316464623130386138636531353536313736313561393233613936383062323863 63303762346330323031353034356162373433356436663134373930633634366330653233613139
35303633666435376530646135366364376636653335663830363964323531356666366535346465 63363639343833616431633765613938623037323961623663336662666135313466303661316133
63386262386531666136383265623666633762346137633839306233343238303638663365643461 39353664633036323031373862393530653433373062623233313965653735353566306538393439
65616335353766653239356439346563636139653061663739616238376330633865656236666265 30366162663138326535346639393337393362366630343266643035353465663332333539613337
34653763643562396266313037663837386664633065643431303261303764353234393832653033 30666666363134313239306231356663343166363137366636643931313039333732383833313036
35613138663335363734316531636535616630636535323264633134393637383030613161633966 37393064396662623063613462336363386336393839313465323062646535373733326338353766
61326333623962613566666365376266383037653330386534343765623061303139653935346135 31666639303836316266343764336462343765363930326338313635336633323662366238356264
38386461613561316132666362323664623236333835323238346135616665306435663464313533 38613631313434383830333031643938393566633236383861633266326336653033663163336132
38316162356561353431656231643134613266663536633138316561613633643032373234656435 61313132643062666434346333653234393865656463343363313636613364616361353561343739
63626132356431353732386439396535353133623233336639373330623539643130303164376433 38313231333431303664323730626162613264343630356438336636373739653234336666646438
35333833653665653030613865323332656637633439346537623733303464643264396431373966 37636437623336323461613063396137396533353265333034333435306666636261353933613232
39366534343563313834303833303730373830633639363263373966663962323761363936323131 65363632383039666666323030323830333534376362326136313232393732613166303461383933
31646465323931396133333461383337396330323664353536313230393761333039663866373337 62303166396533616538666566356238393265663163343264333664393936613066313665616137
30383539343266333763316463393036363331333866343735666633353762613337303932363938 38613030623937633730646461666233333035323661363835313161613930336237396332623338
33383463613937363039336565303035626538326161616136353439303936336137356131623666 30666166636662613130363430333436613532326437393730376536353963356633393736303065
62363261636134306266636263646566323766376565366533303533376262646239356265663561 31393534646537323037316664313438643836386333613961663031383231663932633934656461
62356437336139613136386330393738326562646237346131383562346265646238376462626165 62313163616635626131663961326438396439383432346337386261313330343330353637376330
39666437336233393839653535313666323765666161396434653063316631386337356137373131 38346532396533326135303264613361663836646163623630323832653032396237353966663661
62313238633261666637356161393638326332663565623765616565393134663836346638633763 36353365313962663832393333336138346335363832396535346336643565366465643565616638
65653430636536623137373661363230636462366166376432613662323461653930653836643432 63616565356663623531323935393334326639626236353338643237343764366464666131393332
34353062363832663135613062663265653234326433393134663464366232313766636637363661 64396665343535323339383434366133613235313866653663313639633930323864646536346232
31633638323766346462626364323638323238663537653064303833383264333463333464343436 65316465643662376264373536393232326666663335316631376433343062646361376165363732
62396366613763646138616665656334643332626265623135303662613162376130333136353539 66326165643163333737313139386461363431353239626236366238343035386663363435366464
31343864656461346161363266663562326331333762366438333862653631613365316532306661 31633738336263633961306436613233303861633263343030336637373165663261316632663537
39333134343338363230386362336637306330386437376564363563616437626135326531663234 31613636663163323365303038373134306264343831326264326261633834393366623061616262
36353938633830636535633262336662366562373961343464653461383639323764643438313663 63393463333833393636666232626662643738653634306364326231343830633834643664353730
61366461356436393735336332376236306136636664333962613632353938393461323432316138 37346131346263356539363630363230626364663161643064323538396131636633623866383939
31626638313466663663313165376362396361356536363363643366313562393362646365663439 66346434323935353632633837363530663438636539616130633532346236343661633766383434
38326134646636333562386566373038643233366232323130376333626661623235313930366334 34343339646662393030323661623665643432376365633435666333316439356631386234303062
34383139353961623831343237643263376236313533363437303638396663653963336330663462 35346631656230346565323130333765663933373638303639363530373431343232393864656639
34613130333766653532323130663337383936613864376136316535376364643964353131386463 33666433366131396464323137393239653531376662646235343962613639343831636261326265
37653436663061333837386666616565356261663539363766336531326139356561616335343537 65663564613766313634653938316339306434663463623563316431633234323330623738646636
30623435646232626639323664626337633832313262333366333066363739643836333336616565 37643535623664323433626561383462393033343232303838333930653366376536353765613036
61323666323865366439363038316136343363383230386462366137653063616632333839346231 35663165623265616630373161336632646435613331373166303632373633313865386134636362
65663137396535353063653237663261333838373864636637643238373035643563663366633661 61636134343839643735636461626663626237613262316564646339323933363864303935353834
32323439636132666630646265636336343533646131366137373036333666653137396131373132 39396637646264633736366336616336643032313237653662646331383963366533373766356539
38336139666362373633386162376562626563656632396661383866353035393863393564626631 35306165306534393463663332336430336635666135643561303935386635393838323865623162
30316431613538396632373064646261373230376336616331303865373462336366376334626630 36323565616232353261303139623465646234313136383436376162376165303664613164356162
39333239653434323466383966633031313038346163366566613561393437633563323834393233 33373237333666616135636231653637396330663930663962636161326664333261343737343735
39353130643639636535623230663031303433313234333436343163616433346339653964636631 37313465396130653138613539376436373237343138636535626632326435383234326466363235
35303032633937353539386534323763623561616135396466353532333139363062376364653063 34646663653038396630353637636166346261346233333632363361326536383634663433613564
65343065316664323363643537373065343661383038363232323736636135633238383161363266 35633864343630333033613133626635313931333031643564396164393135346131343832363861
36346463616562356265336637306236336531376439313330393865303166333366663731356430 61366664363838653438653137383933386233633836323332643531303936353237623734666135
66356335326361393034386261393438363464666363623736633364383062666666323865323531 31356166613664636634336536343032646239643130346564303162356431346539646336323339
65393036333836303434386463336636383066353964383062303930383137356336616634323438 61626236346535336638353134353838333434663838303730613363393365633739383563613434
37306234343462376431393165343437643264333764613566636364313431613030666535643761 64336331306639323061386338656361653636353831346237373134346538623464343562393735
34633135636262356638306432356238376631353663356165313861366431663063343035666332 39333764343139333133393233626564643266373034623764633835383561366265636632633937
33323366656132366565646137353038326161353564366131633664316234383433616134653033 62343635343161363231653138613263313562366439316435633964396161343566316435303465
33316439313232336533646464653537626262376433313533623530656538353636383333346266 39666236316339653839313333396264623636663561653932386638366366663933353761353162
34376534383765383836333536346235386639643665313862323233386164376166616338653561 61343038383939396231346534336361306430373564353633653139306334623630343738636430
33363033663431316431343032616563373463343437643939333763613233623838343837376366 66376631366662313131646130363530323232383535333163363466636262363461633232343532
36343566323764343961636438623766616132363261353062623461303763346662383732303135 63626430336261353861633362396638643937623832386638626334663333363637393637373939
34343137316632373561623039623139643939326334323561666462613138303433346236653263 64303039666432303535636265613564376139333331653336666563663238366639393366363334
64383137383765646364363862613433356539613133396232363736633538323939663261666338 36303635633933333832396562373965653361303034653139643466656534326231383162336366
35656365396432636533323130646530376537386532376133643662363433343337613661616139 31656138656539383539396462326134333331653131306537643962653762373035343235333233
34343137616461626564396336323832303833386632353138306131376436383862353762343061 34373730623663346430303962653061623330653263393633383835663739663961326566323036
32653237353131633962393365326235383138363235653634356661383061306162636265346561 30336365616532303362396230616531386639333636336332366335613935623836616134393033
61663231626162353030343637393165343762373738373966333430616663373064643565666261 62653535396630383436393631396337336163323361663930323532633666663238333366383462
61396563666333623363353666376637616361386564386537643165366561353134663665363930 36393261376262643336643761613731643032626632646332366661626331333233363436613937
39623239656538333539656432396532623961356537623430626637333065383362663765353433 34653731666137313733653863396164323963383037353265373532303137623037343733616537
37383139613666313363636162316365353864376464333334353236303538353932616565666430 66336433343334626536323639636139653931383466633833326234633332613431353432343561
33363561393336623833373065616433363964353735353838326562383033663661313132303963 36626339656536383862623833633634356435393764316633353135326639623534366538313330
64623230626636303037396133636632333635643938626163636639386366613163343665346566 62633333303266613630326330333336353264343937393864393239623664323366373565383334
37343432656435646138353262323031396531353364646265663433353965613639346333396637 37383237376664643065383834633961366632643261343635336335353765353863323131653866
66396230663635303230656235643464633634323363353466653836323462623437393739626164 31326531303461323736303730623638663863353939636437636231636437323730656463633733
34363863613537353531633432336230303631663032353932346462656232363634373836613562 65383934343534383631363162363830386365313935663337366335326131393262353030663765
38613238356464386666363434623335313035646562356363663737623634323464306630316431 30643665383332613030336439346332363135366232303166623534333637366133656437643231
39623031393334383262613734663535643266666366616436666230346433616162313039643930 30306634636430643864363561316334383530613165326663326665613633636237353830393334
38303563363565306139373538646666383131383161353933663561356265626434326638616465 62653333623563626131666166646335663334393662336337333836376631303631666136376332
35306664386162316535643836373461313034653566653038626331363535613166396432393831 37316537356531346464623363653033306537636239633065646533643239653063613835363665
66643833636231656365326434363233346431656435306333376566343165373537336238623632 30383139326465613864316533643033333430326230646334353364633138666532353736313265
35623237393362346237353962626337356263323530616436303835333738646234663361303234 34623733613864646661353730666433613961643261346166303264386435643565373565323864
34376633313162373530326233323134323561653264303338646536376235623534616137623035 61346465336231613865363263303034396439346163393534666439666437353266323565653032
64383130306363393363386132373335616539653264613362396437366464346234646463633362 39386439646438313938356237643831643434666161383632316530356465616632313235643834
39616430373761653265613861353165623331316364396534396434656336356535383630316133 33303865653836303632656663366465333331616634313863656438393838636631313364633637
39643863313237303839663161303031393536626131346531636463333163323932303865326662 38646230643734393733663261326161376536643237626130353831363731306231313864613066
63636137613065383865306263396439396238626464323135396362303334363363333337326362 34623239396362336639363163313161323065653461363563353631613730373830643133336464
33303565396461663661613339623164383463353663313733643936323064376636633936366337 31336439636361363539383539323631303462633833353032373530333539336538363033383363
37323761373039653737623065623663393438313066393936643430616536653432646164346430 32613733623839623938326165356237313165383366646233393933393965613363666532646434
36653664383936383265666162343834653831393337343065363832356636663361313132306561 63316133613130313363303537366230646235663130313538333761633237383262316633366364
61373263643364363736623330363636653262333733356362383264313763663662306663323438 65373664616237316534613831313966623939396331626334313430386638653461386334363939
38626135613862663937346537333338303135346438613430653031636231366234323261336264 35333339643837666264356535643365353331393437313866643034663934336466336534343035
61633532626231663266643462383236396366333938663134623061616163356534313535643734 61313837666662343363613962623462333935353837333336363839623466303534303837396634
31666563323437643538613962366230623963346630303931663133613963366565663934323138 38656330666661356235626130303538666533666563323936633564383164633834353831306634
63363666653130323139636161343836613137313535303530333832666234373530663339613630 36343836353464623962333362353133386563343831336463646635646263383832666232323736
66636439636133376262653231636162643765333133633538303532376466643736393762386532 38613730316634373365343938623237356231643931303333366462373134383137366339613662
38363633623865633838393666663762613233376536353833306435613463626332613833393435 62643832323734363635643634373066303366306366663036623139393761636533326130313336
35656530306261306235643535396230373238336663333466316566316633376264666431336662 30316536396466383463393233363035393335343565323635333665346464366139626165636661
31323535663630386362313166373965353131326461376337363965613434643638346634366331 39363066643437613537653836636363376532643038363063383234353066313737663061363334
62313031373333343536376235323437346439346433393631346631616635323836393732363231 38306563613561663165623630366135303332636133343733343836383865613661393761333031
33636133393964333662343537616264306366643561386465383436313138396562663435613131 62653162626461616564643138613737623632313739393962396439306133646138303936636435
38643665613439623536343239613262623264326235306633623165613061386239636361626539 39393663653865363166316365376562353461633163353734343132343831386434653037323732
33393763616139656239646136656232656536636562363763336266303836346635336235663536 36356162356336616330636630376438636165653439376137313934663939376639396266323962
38393531323663663865303664323831623238643661653234383262303364646438303461386438 37383736333536653438363963316435326632393966383534326337303336386135616636363936
38353861386134333763333232386538353130303139353965343361613535363762313035353939 35393331313938653830646332376631623763383439623633396433633739663038313264323835
62636539366635383763643431356530643934623331396535616461633931393931336431643865 33373664313562366664363630316132643465363964383339363339656237323465626262306364
63373032353131616131663461393939646433626636393761663637313331336466663636373863 33306133373065303135613235623262396365363634316365356364373561363762666235666430
65346631656263653266646639663633613461363464646634336361323562376133393137373032 62336362643564313238363933623366396138646237336336623062326161326536323534326364
62313465326637646533666565626532643538363332623835626334613235616562653933353335 39316162643966616436343737313434616230346237346237363962653033613930623462386431
35363138663763653961356135373561633139663031306566316438633766646665316335633730 38343662356665383763633034393236613733643430313937326335356466376139653533333965
39613064333937646533306362333539653866363139353432313535656633343066386339326664 39386138623134666132663837616637376362303561393133656139653438386363613965393661
62366431666230613165613637356631386666306461353439333237303962386231373039393634 36343566643931393061373031343331336463643034383065383763663234373438383064303232
33613633323939666434636131336461393233303034363961366630396561336635643764373532 64666236313935346237666466333562613935646163653331303661386138313739326538353935
63643630636336386265616538613536373234613466356533323461633732363936343061326665 64323737323532663731353136336138633533386464616362333838396332323563353537613430
34633732353437343133613932623864333065623836303661643039643430343131343237396239 33633631326238366166346437316638363161386562383630623466386564323266333033313461
65626562646134343365333466383265343637373363626437363130666234356437643038313265 63666535363034613232346239636233623130393032353030363334333531646238373262323765
32313031313536656130326132396636326437663434303433383934356438383334363135323361 61373739396162643661353031613663353531653836323730326166383463613330333966336233
39613536343361316330653465613030343831643164636630383564623136613766383131323531 30386136346466336361303237303534373064353230653238363231633530613866663461643465
64376135326131393663613065366666393166326532396365396463373131643431346663323663 30396266356164353063323432663561396564636231346534366661663766613634376235356637
38616233313432383633306663363839636634613137353437363736356637323630336235383064 39313839616336666461313431326430333932623262333437386464636264373430653566386631
64343632613063353961343063313261333839383064363662666339313661653864656138613062 64653866623662363864376663613136306165393863346533303634623936373835633864313462
31326566316433336238383266613066383165616230646232666165303535633830623435323036 61333562646233303232623861366634383466633537383831626334356561353637663038643531
37396434396566353632383432636266656361313837633162326137353464623831613831323264 39386635326366646134333231653737653630356135396634326537633232333166616161653136
32656438373735653635393938353730356237646539663836383762393538636235343537393263 33393562383233656564356530386465623239386666313964343534343466616134373132636631
38323139333233623064613034336233333638316533323734643465633338326166626464313361 39666365393063323838343963366339373434353839383039383238613133636237316365323861
35616634643732353832353531353861353433356231383964383230643835353132396439663734 30626330643665626465666338353030653839383234393237623633646566376361646536353233
32346561663632643732623432376233656238346236653337366531353263613463323763656161 31393235623561323765633835313139313538343761393064353632316335656231353930656437
38633961326538333263373262323562303839393663363136373335393034613362623939336165 31313639313931636633333230653730666638373864326239333561393134356632623138366131
63393434656639393662323239306432633661656161316236653861323363343461666265353065 65356462373336383039316131626562633330666363386631383663343838393435663538343934
61376661383565356635333134616132646639383230363332326234326363316139663363353336 65386339626362623664393532386131303234633466363437383236616463343831353862323961
32316466373934393864663531316265313537646239313936353062353638366465366132633339 39663835313234326137303965663963663761656531653437343234643634316565333762663139
34656332636430643033326262636331616639356237393763326264393561393735333139643035 65393830633237623031303234636134633539316131396135616237316266333437633861303831
64346461353463633833653566666164616532336234346238346433306563326132643465343939 62656630373763343366636635653033666630613533363365636261323661383364343161343439
66343836663033613135383633303438626435353232393561323334373834633363653736623834 35626531346665656263643461306261376238353033343032353731373861333239333862653231
64353064333766376432326163613762653966653434653764373436623939363232346165643637 31336562653133623163353230633331346237356534333534613161323462636639636662623435
33643561653331336261636131623265646266663833623561373066666435333263353333646138 63633035336662376636623339326433393035646539626231363762643532323463316263393736
62653962333961613664383466383031646533616363303438363566383265653762613765336130 62613038333733636362356636373331313661663830633433643039653233626261613739663836
62343838323733653263633863313330336561613162643039656236363437393536336330323434 38643030313338383266323134326337323334343230623331386664333937316266623134336362
34633134316331323265363631363137353331383937623632643436323433373032376436393363 61373037353664623863393233376264616438656332386130316361663665323135386463383763
37363234313261343434323363316234663834396435386336666336636430653864353036386536 33303633356133353439393664363630336133306364363430393232326665393339323265383630
32316262373932626635383834336566333962356539313166626637663038343931353261646563 31656463343064383837333630366465396633393465666235626330343937313630623039383465
62303864346634343230353964323838316438656233306438656466396435643435396232636437 63326361663238653035613935343932623237396362643833313731323830313962616362613539
39346536306436333232316666626333653030373662613630323765646265666466386364336438 32346165303930323739313837643933363863643937346561643930653530393636383036613235
34633764303035356163653034376537393038303863353139373963616138663431666132383961 61376166386563643733333233343437623630323632643463353131386461663936313065313562
62653066343461323466633062663763613234616263376635393834393835346165653238663537 31393032646262386634353436643466323731366631393136393433616332613036666163336635
63353034633238343464616333656139343163313734643836303936373936386662396630663863 37303365633338613630656463663533653336666562653236336264303238383930383132346365
61323030343337636636623034353635613636366238383861313838376632323438343231623631 35386662636439653930343738633265363635626132343030653462306431363234633635643537
35613466303635313866353437373062616538626532306464613831383162616464313061356161 61666363346430653131623762666564313665653262386332396532646339383136383337353863
32343131636434653635366634343335616263653331646264643336623563336633313132343163 38386632316632373338653535323335363265653563376330663239343861346563646366313039
62616561376664313739643961353232343136356364653366353233333733363535656238616630 33306364623536346339393566326533633133393866303535326535306435626531346264616138
37396135383031396130623037343038643035373633626633343532383739643462666635386539 34356231373561633337653663643566633632393330386564393966666365306565316135646163
31316134383836373063386663303139393938383234383335346665373233373033643864356665 63366365383839343134303635376233343865663631633331333230616630366633396231333435
34616262343761653564 30366137383238393139336433353764633038616238326136663636656132626538393565393130
38653765326137393136386233383636383165613235373437353730306564643033306534386666
61623538663537653166313264303533623162356134393333373732383535386261333535383039
65613166666230336265366335323434636336663835323034373930393430363065376665666337
35363265666130653830333536326433316639613638613730666139623137333736663535633032
33363135376636636536623731323134343237393633333038393364376237386165

View file

@ -6,7 +6,6 @@ postgres_passwords:
passit: xxx passit: xxx
gitea: xxx gitea: xxx
matrix: xxx matrix: xxx
codimd: xxx
mailu: xxx mailu: xxx
keycloak: xxx keycloak: xxx
hedgedoc: xxx hedgedoc: xxx
@ -34,6 +33,7 @@ drone_secrets:
restic_secrets: restic_secrets:
repository_password: xxx repository_password: xxx
ssh_privkey: xxx ssh_privkey: xxx
uptime_kuma_url: xxx
matrix_secrets: matrix_secrets:
registration_shared_secret: xxx registration_shared_secret: xxx

View file

@ -1,12 +1,12 @@
# vim: ft=yaml.ansible # vim: ft=yaml.ansible
--- ---
- hosts: all - hosts: production
gather_facts: true gather_facts: true
become: true become: true
vars: vars:
ldap_dn: "dc=data,dc=coop" ldap_dn: "dc=data,dc=coop"
vagrant: "{{ ansible_virtualization_role == 'guest' }}" vagrant: "{{ from_vagrant is defined and from_vagrant }}"
letsencrypt_enabled: "{{ not vagrant }}" letsencrypt_enabled: "{{ not vagrant }}"
base_domain: "{{ 'datacoop.devel' if vagrant else 'data.coop' }}" base_domain: "{{ 'datacoop.devel' if vagrant else 'data.coop' }}"
@ -15,6 +15,9 @@
smtp_host: "postfix" smtp_host: "postfix"
smtp_port: "587" smtp_port: "587"
services_exclude:
- uptime_kuma
tasks: tasks:
- import_role: - import_role:
name: ubuntu_base name: ubuntu_base

View file

@ -1,90 +1,86 @@
# vim: ft=yaml.ansible # vim: ft=yaml.ansible
--- ---
volume_root_folder: "/docker-volumes" volume_root_folder: "/docker-volumes"
volume_website_folder: "{{ volume_root_folder }}/websites"
services: services:
### Internal services ### ### Internal services ###
postfix: postfix:
file: postfix.yml
domain: "smtp.{{ base_domain }}" domain: "smtp.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/postfix" volume_folder: "{{ volume_root_folder }}/postfix"
pre_deploy_tasks: true
version: "v3.6.1-alpine" version: "v3.6.1-alpine"
nginx_proxy: nginx_proxy:
file: nginx_proxy.yml
version: "1.0-alpine"
volume_folder: "{{ volume_root_folder }}/nginx" volume_folder: "{{ volume_root_folder }}/nginx"
pre_deploy_tasks: true
nginx_acme_companion: version: "1.3-alpine"
version: "2.2" acme_companion_version: "2.2"
openldap: openldap:
file: openldap.yml
domain: "ldap.{{ base_domain }}" domain: "ldap.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/openldap" volume_folder: "{{ volume_root_folder }}/openldap"
pre_deploy_tasks: true
version: "1.5.0" version: "1.5.0"
phpldapadmin_version: "0.9.0"
phpldapadmin:
version: "0.9.0"
netdata: netdata:
file: netdata.yml
domain: "netdata.{{ base_domain }}" domain: "netdata.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/netdata"
version: "v1" version: "v1"
portainer: portainer:
file: portainer.yml
domain: "portainer.{{ base_domain }}" domain: "portainer.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/portainer" volume_folder: "{{ volume_root_folder }}/portainer"
version: "2.19.0" version: "2.19.0"
keycloak: keycloak:
file: keycloak.yml
domain: sso.{{ base_domain }} domain: sso.{{ base_domain }}
volume_folder: "{{ volume_root_folder }}/keycloak" volume_folder: "{{ volume_root_folder }}/keycloak"
version: "20.0" version: "22.0"
postgres_version: "10" postgres_version: "10"
allowed_sender_domain: true allowed_sender_domain: true
restic: restic:
file: restic_backup.yml
user: dc-user
domain: rynkeby.skovgaard.tel
host_key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBLGol2G+a87ssy0nu/STKBZSiGyhZhZKx/ujfe9IeFo
volume_folder: "{{ volume_root_folder }}/restic" volume_folder: "{{ volume_root_folder }}/restic"
pre_deploy_tasks: true
remote_user: dc-user
remote_domain: rynkeby.skovgaard.tel
host_key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBLGol2G+a87ssy0nu/STKBZSiGyhZhZKx/ujfe9IeFo
repository: restic repository: restic
version: "1.7.0" version: "1.7.0"
disabled_in_vagrant: true disabled_in_vagrant: true
# mail dance
domain: "noreply.{{ base_domain }}"
allowed_sender_domain: true
mail_from: "backup@noreply.{{ base_domain }}"
docker_registry: docker_registry:
file: docker_registry.yml
domain: "docker.{{ base_domain }}" domain: "docker.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/docker-registry" volume_folder: "{{ volume_root_folder }}/docker-registry"
pre_deploy_tasks: true
post_deploy_tasks: true
username: "docker" username: "docker"
password: "{{ docker_password }}" password: "{{ docker_password }}"
version: "2" version: "2"
### External services ### ### External services ###
nextcloud: nextcloud:
file: nextcloud.yml
domain: "cloud.{{ base_domain }}" domain: "cloud.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/nextcloud" volume_folder: "{{ volume_root_folder }}/nextcloud"
version: 27-apache pre_deploy_tasks: true
version: 28-apache
postgres_version: "10" postgres_version: "10"
redis_version: 7-alpine redis_version: 7-alpine
allowed_sender_domain: true allowed_sender_domain: true
forgejo: forgejo:
file: forgejo.yml
domain: "git.{{ base_domain }}" domain: "git.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/forgejo" volume_folder: "{{ volume_root_folder }}/forgejo"
version: "1.20" version: "1.21.8-0"
allowed_sender_domain: true allowed_sender_domain: true
passit: passit:
file: passit.yml
domain: "passit.{{ base_domain }}" domain: "passit.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/passit" volume_folder: "{{ volume_root_folder }}/passit"
version: stable version: stable
@ -92,132 +88,141 @@ services:
allowed_sender_domain: true allowed_sender_domain: true
matrix: matrix:
file: matrix_element.yml
domain: "matrix.{{ base_domain }}" domain: "matrix.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/matrix" volume_folder: "{{ volume_root_folder }}/matrix"
version: v1.87.0 pre_deploy_tasks: true
version: v1.98.0
postgres_version: 15-alpine postgres_version: 15-alpine
allowed_sender_domain: true allowed_sender_domain: true
element: element:
domains: domain: "element.{{ base_domain }}"
- "riot.{{ base_domain }}"
- "element.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/element" volume_folder: "{{ volume_root_folder }}/element"
version: v1.11.28 pre_deploy_tasks: true
version: v1.11.51
privatebin: privatebin:
file: privatebin.yml
domain: "paste.{{ base_domain }}" domain: "paste.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/privatebin" volume_folder: "{{ volume_root_folder }}/privatebin"
pre_deploy_tasks: true
version: "20221009" version: "20221009"
codimd:
file: codimd.yml
domain: "oldpad.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/codimd"
hedgedoc: hedgedoc:
file: hedgedoc.yml
domain: "pad.{{ base_domain }}" domain: "pad.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/hedgedoc" volume_folder: "{{ volume_root_folder }}/hedgedoc"
version: 1.9.7-alpine pre_deploy_tasks: true
version: 1.9.9-alpine
postgres_version: 10-alpine postgres_version: 10-alpine
data_coop_website: data_coop_website:
file: websites/data.coop.yml
domain: "{{ base_domain }}" domain: "{{ base_domain }}"
www_domain: "www.{{ base_domain }}" www_domain: "www.{{ base_domain }}"
volume_folder: "{{ volume_website_folder }}/datacoop"
pre_deploy_tasks: true
version: stable version: stable
staging_domain: "staging.{{ base_domain }}" staging_domain: "staging.{{ base_domain }}"
staging_version: staging staging_version: staging
slides_2022_website: slides_2022_website:
file: websites/2022.slides.data.coop.yml
domain: "2022.slides.{{ base_domain }}" domain: "2022.slides.{{ base_domain }}"
volume_folder: "{{ volume_website_folder }}/slides-2022"
version: latest version: latest
fedi_dk_website: fedi_dk_website:
file: websites/fedi.dk.yaml
domain: fedi.dk domain: fedi.dk
volume_folder: "{{ volume_website_folder }}/fedidk"
version: latest version: latest
vhs_website: vhs_website:
file: websites/vhs.data.coop.yaml
domain: vhs.data.coop domain: vhs.data.coop
volume_folder: "{{ volume_website_folder }}/vhs"
version: latest version: latest
cryptohagen_website: cryptohagen_website:
file: websites/cryptohagen.dk.yml
domains: domains:
- "cryptohagen.dk" - "cryptohagen.dk"
- "www.cryptohagen.dk" - "www.cryptohagen.dk"
volume_folder: "{{ volume_website_folder }}/cryptohagen"
ulovliglogning_website: ulovliglogning_website:
file: websites/ulovliglogning.dk.yml
domains: domains:
- "ulovliglogning.dk" - "ulovliglogning.dk"
- "www.ulovliglogning.dk" - "www.ulovliglogning.dk"
- "ulovlig-logning.dk" - "ulovlig-logning.dk"
- "www.ulovlig-logning.dk" - "www.ulovlig-logning.dk"
volume_folder: "{{ volume_website_folder }}/ulovliglogning"
cryptoaarhus_website: cryptoaarhus_website:
file: websites/cryptoaarhus.dk.yml
domains: domains:
- "cryptoaarhus.dk" - "cryptoaarhus.dk"
- "www.cryptoaarhus.dk" - "www.cryptoaarhus.dk"
volume_folder: "{{ volume_website_folder }}/cryptoaarhus"
drone: drone:
file: drone.yml
domain: "drone.{{ base_domain }}" domain: "drone.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/drone" volume_folder: "{{ volume_root_folder }}/drone"
version: "1" version: "1"
mailu: mailu:
file: mailu.yml
version: "1.9"
domain: "mail.{{ base_domain }}" domain: "mail.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/mailu"
pre_deploy_tasks: true
dns: 192.168.203.254 dns: 192.168.203.254
subnet: 192.168.203.0/24 subnet: 192.168.203.0/24
volume_folder: "{{ volume_root_folder }}/mailu" version: "2.0"
postgres_version: 14-alpine
redis_version: alpine
mastodon: mastodon:
file: mastodon.yml
domain: "social.{{ base_domain }}" domain: "social.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/mastodon" volume_folder: "{{ volume_root_folder }}/mastodon"
version: v4.1.4 pre_deploy_tasks: true
post_deploy_tasks: true
version: v4.2.8
postgres_version: 14-alpine postgres_version: 14-alpine
redis_version: 6-alpine redis_version: 6-alpine
allowed_sender_domain: true allowed_sender_domain: true
rallly: rallly:
file: rallly.yml
domain: "when.{{ base_domain }}" domain: "when.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/rallly" volume_folder: "{{ volume_root_folder }}/rallly"
pre_deploy_tasks: true
version: "2" version: "2"
postgres_version: 14-alpine postgres_version: 14-alpine
allowed_sender_domain: true allowed_sender_domain: true
membersystem: membersystem:
file: membersystem.yml
domain: "member.{{ base_domain }}" domain: "member.{{ base_domain }}"
django_admins: "Vidir:valberg@orn.li" django_admins: "Vidir:valberg@orn.li"
volume_folder: "{{ volume_root_folder }}/membersystem"
version: latest version: latest
postgres_version: 13-alpine postgres_version: 13-alpine
allowed_sender_domain: true allowed_sender_domain: true
byro: writefreely:
file: byro.yml domain: "write.{{ base_domain }}"
domain: "byro.{{ base_domain }}" volume_folder: "{{ volume_root_folder }}/writefreely"
postgres_version: 14-alpine pre_deploy_tasks: true
volume_folder: "{{ volume_root_folder }}/byro-data" version: v0.15.0
mariadb_version: "11.2"
allowed_sender_domain: true allowed_sender_domain: true
watchtower: watchtower:
file: watchtower.yml volume_folder: "{{ volume_root_folder }}/watchtower"
version: "1.5.3" version: "1.5.3"
diun: diun:
file: diun.yml file: diun.yml
version: "4.25" version: "4.25"
volume_folder: "{{ volume_root_folder }}/diun" volume_folder: "{{ volume_root_folder }}/diun"
### Uptime monitoring ###
uptime_kuma:
domain: "uptime.{{ base_domain }}"
status_domain: "status.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/uptime_kuma"
pre_deploy_tasks: true
version: "latest"
services_exclude: []
services_include: "{{ services | dict2items | map(attribute='key') | list | difference(services_exclude) }}"

View file

@ -1,5 +0,0 @@
#!/bin/env bash
python /byro/manage.py migrate
python /byro/manage.py compress
python /byro/manage.py collectstatic --no-input

View file

@ -0,0 +1,4 @@
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;

View file

@ -1,8 +1,6 @@
# vim: ft=yaml.ansible # vim: ft=yaml.ansible
--- ---
- name: "restart nginx" - name: restart nginx
community.docker.docker_container: command: docker compose restart proxy
name: "nginx-proxy" args:
restart: "yes" chdir: "{{ services.nginx_proxy.volume_folder }}"
state: "started"

View file

@ -0,0 +1,26 @@
# vim: ft=yaml.ansible
---
- name: Create volume folder for service {{ service.name }}
file:
name: "{{ service.vars.volume_folder }}"
state: directory
- name: Upload Compose file for service {{ service.name }}
template:
src: compose-files/{{ service.name }}.yml.j2
dest: "{{ service.vars.volume_folder }}/docker-compose.yml"
owner: root
mode: u=rw,go=
- name: Run pre-deployment tasks for service {{ service.name }}
include_tasks: pre_deploy/{{ service.name }}.yml
when: service.vars.pre_deploy_tasks is defined and service.vars.pre_deploy_tasks
- name: Deploy Compose stack for service {{ service.name }}
command: docker compose up -d --remove-orphans --pull always
args:
chdir: "{{ service.vars.volume_folder }}"
- name: Run post-deployment tasks for service {{ service.name }}
include_tasks: post_deploy/{{ service.name }}.yml
when: service.vars.post_deploy_tasks is defined and service.vars.post_deploy_tasks

View file

@ -1,31 +1,25 @@
# vim: ft=yaml.ansible # vim: ft=yaml.ansible
--- ---
- name: add docker gpg key - name: Add Docker PGP key
apt_key: apt_key:
keyserver: pgp.mit.edu keyserver: pgp.mit.edu
id: 8D81803C0EBFCD88 id: 8D81803C0EBFCD88
state: present state: present
- name: add docker apt repository - name: Add Docker apt repository
apt_repository: apt_repository:
repo: deb https://download.docker.com/linux/ubuntu bionic stable repo: deb https://download.docker.com/linux/ubuntu bionic stable
state: present state: present
update_cache: yes update_cache: yes
- name: install docker-ce - name: Install Docker
apt: apt:
name: docker-ce name: "{{ pkgs }}"
state: present
- name: install docker python bindings
pip:
executable: pip3
name: "{{ packages }}"
state: present state: present
vars: vars:
packages: pkgs:
- docker - docker-ce
- docker-compose - docker-compose-plugin
- name: Configure cron job to prune unused Docker data weekly - name: Configure cron job to prune unused Docker data weekly
cron: cron:
@ -36,12 +30,15 @@
user: root user: root
state: present state: present
- name: create folder structure for bind mounts - name: Create folder structure for bind mounts
file: file:
name: "{{ volume_root_folder }}" name: "{{ item }}"
state: directory state: directory
loop:
- "{{ volume_root_folder }}"
- "{{ volume_website_folder }}"
- name: setup services - name: Set up services
import_tasks: services.yml import_tasks: services.yml
tags: tags:
- setup_services - setup_services

View file

@ -0,0 +1,13 @@
# vim: ft=yaml.ansible
---
- name: Generate htpasswd file
shell: docker compose exec registry htpasswd -Bbn docker {{ docker_password }} > auth/htpasswd
args:
chdir: "{{ services.docker_registry.volume_folder }}"
creates: "{{ services.docker_registry.volume_folder }}/auth/htpasswd"
- name: log in to registry
docker_login:
registry: "{{ 'docker.data.coop' if vagrant else services.docker_registry.domain }}"
username: docker
password: "{{ docker_password }}"

View file

@ -0,0 +1,19 @@
# vim: ft=yaml.ansible
---
- name: Configure cron job to remove old Mastodon media daily
cron:
name: Clean Mastodon media data older than a week
cron_file: ansible_mastodon_clean_media
job: docker exec mastodon-web-1 tootctl media remove --days 7
special_time: daily
user: root
state: present
- name: Configure cron job to remove old Mastodon preview cards daily
cron:
name: Clean Mastodon preview card data older than two weeks
cron_file: ansible_mastodon_clean_preview_cards
job: docker exec mastodon-web-1 tootctl preview_cards remove --days 14
special_time: daily
user: root
state: present

View file

@ -0,0 +1,11 @@
# vim: ft=yaml.ansible
---
- name: Upload vhost config for root domain
copy:
src: vhost/base_domain
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.data_coop_website.domain }}"
- name: Upload vhost config for WWW domain
copy:
src: vhost/www.base_domain
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.data_coop_website.www_domain }}"

View file

@ -0,0 +1,17 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
path: "{{ services.docker_registry.volume_folder }}/{{ volume }}"
state: directory
loop:
- auth
- registry
loop_control:
loop_var: volume
- name: Copy docker registry vhost configuration
copy:
src: vhost/docker_registry
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.docker_registry.domain }}"
mode: "0644"

View file

@ -0,0 +1,21 @@
# vim: ft=yaml.ansible
---
- name: Create subfolder
file:
name: "{{ services.element.volume_folder }}/data"
state: directory
- name: Upload config.json
template:
src: element/config.json.j2
dest: "{{ services.element.volume_folder }}/data/config.json"
- name: Upload riot.im.conf
copy:
src: element/riot.im.conf
dest: "{{ services.element.volume_folder }}/data/riot.im.conf"
- name: Upload vhost config for Element domain
copy:
src: vhost/element
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.element.domain }}"

View file

@ -0,0 +1,17 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
name: "{{ services.hedgedoc.volume_folder }}/{{ volume }}"
state: directory
loop:
- db
- hedgedoc/uploads
loop_control:
loop_var: volume
- name: Copy SSO certificate
copy:
src: sso/sso.data.coop.pem
dest: "{{ services.hedgedoc.volume_folder }}/sso.data.coop.pem"
mode: "0644"

View file

@ -0,0 +1,45 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
name: "{{ services.mailu.volume_folder }}/{{ volume }}"
state: directory
loop:
- redis
- certs
- data
- dkim
- mail
- mailqueue
- filter
- postgres
- webmail
- overrides
- overrides/nginx
- overrides/dovecot
- overrides/postfix
- overrides/rspamd
- overrides/snappymail
loop_control:
loop_var: volume
- name: Upload mailu.env file
template:
src: mailu/env.j2
dest: "{{ services.mailu.volume_folder }}/mailu.env"
- name: Hard link to Let's Encrypt TLS certificate
file:
src: "{{ services.nginx_proxy.volume_folder }}/certs/{{ services.mailu.domain }}/fullchain.pem"
dest: "{{ services.mailu.volume_folder }}/certs/cert.pem"
state: hard
force: true
when: letsencrypt_enabled
- name: Hard link to Let's Encrypt TLS key
file:
src: "{{ services.nginx_proxy.volume_folder }}/certs/{{ services.mailu.domain }}/key.pem"
dest: "{{ services.mailu.volume_folder }}/certs/key.pem"
state: hard
force: true
when: letsencrypt_enabled

View file

@ -0,0 +1,45 @@
# vim: ft=yaml.ansible
---
- name: Create subfolder for Mastodon data
file:
name: "{{ services.mastodon.volume_folder }}/mastodon_data"
state: directory
owner: "991"
mode: u=rwx,g=rx,o=rx
- name: Create subfolder for PostgreSQL data
file:
name: "{{ services.mastodon.volume_folder }}/postgres_data"
state: directory
owner: "70"
mode: u=rwx,go=
- name: Create subfolder for PostgreSQL config
file:
name: "{{ services.mastodon.volume_folder }}/postgres_config"
state: directory
owner: root
mode: u=rwx,g=rx,o=rx
- name: Create subfolder for Redis data
file:
name: "{{ services.mastodon.volume_folder }}/redis_data"
state: directory
owner: "999"
group: "1000"
mode: u=rwx,g=rx,o=rx
- name: Upload mastodon.env file
template:
src: mastodon/env.j2
dest: "{{ services.mastodon.volume_folder }}/mastodon.env"
- name: Upload vhost config for Mastodon domain
copy:
src: vhost/mastodon
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.mastodon.domain }}"
- name: Upload PostgreSQL config
copy:
src: mastodon/postgresql.conf
dest: "{{ services.mastodon.volume_folder }}/postgres_config/postgresql.conf"

View file

@ -0,0 +1,34 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
name: "{{ services.matrix.volume_folder }}/{{ volume }}"
state: directory
owner: "991"
group: "991"
loop:
- data
- data/uploads
- data/media
loop_control:
loop_var: volume
- name: Create Matrix DB subfolder
file:
name: "{{ services.matrix.volume_folder }}/db"
state: directory
- name: Upload vhost config for Matrix domain
copy:
src: vhost/matrix
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.matrix.domain }}"
- name: Upload homeserver.yaml
template:
src: matrix/homeserver.yaml.j2
dest: "{{ services.matrix.volume_folder }}/data/homeserver.yaml"
- name: Upload Matrix logging config
copy:
src: matrix/log.config
dest: "{{ services.matrix.volume_folder }}/data/matrix.data.coop.log.config"

View file

@ -0,0 +1,17 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
path: "{{ services.nextcloud.volume_folder }}/{{ volume }}"
state: directory
loop:
- app
- postgres
loop_control:
loop_var: volume
- name: Upload vhost config for Nextcloud domain
copy:
src: vhost/nextcloud
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.nextcloud.domain }}"
notify: "restart nginx"

View file

@ -0,0 +1,14 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
name: "{{ services.nginx_proxy.volume_folder }}/{{ volume }}"
state: directory
loop:
- conf
- vhost
- html
- dhparam
- certs
loop_control:
loop_var: volume

View file

@ -0,0 +1,12 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
name: "{{ services.openldap.volume_folder }}/{{ volume }}"
state: directory
loop:
- var/lib/ldap
- etc/slapd
- certs
loop_control:
loop_var: volume

View file

@ -0,0 +1,13 @@
# vim: ft=yaml.ansible
---
- name: Set up network for Postfix
docker_network:
name: postfix
ipam_config:
- subnet: '172.16.0.0/16'
gateway: 172.16.0.1
- name: Create subfolder
file:
name: "{{ services.postfix.volume_folder }}/dkim"
state: directory

View file

@ -0,0 +1,16 @@
# vim: ft=yaml.ansible
---
- name: Create subfolders
file:
name: "{{ services.privatebin.volume_folder }}/{{ volume }}"
state: directory
loop:
- cfg
- data
loop_control:
loop_var: volume
- name: Upload PrivateBin config
copy:
src: privatebin/conf.php
dest: "{{ services.privatebin.volume_folder }}/cfg/conf.php"

View file

@ -0,0 +1,11 @@
# vim: ft=yaml.ansible
---
- name: Create subfolder
file:
name: "{{ services.rallly.volume_folder }}/postgres"
state: directory
- name: Copy rallly.env file
template:
src: rallly/env.j2
dest: "{{ services.rallly.volume_folder }}/rallly.env"

View file

@ -0,0 +1,72 @@
# vim: ft=yaml.ansible
---
- name: Create SSH directory
file:
path: "{{ services.restic.volume_folder }}/ssh"
owner: root
group: root
mode: '0755'
state: directory
- name: Upload private SSH key
copy:
dest: "{{ services.restic.volume_folder }}/ssh/id_ed25519"
owner: root
group: root
mode: '0600'
content: "{{ restic_secrets.ssh_privkey }}"
- name: Derive public SSH key
shell: >-
ssh-keygen -f {{ services.restic.volume_folder }}/ssh/id_ed25519 -y
> {{ services.restic.volume_folder }}/ssh/id_ed25519.pub
args:
creates: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub"
- name: Set file permissions on public SSH key
file:
path: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub"
owner: root
group: root
mode: '0644'
state: touch
- name: Upload SSH config
template:
src: restic/ssh.config.j2
dest: "{{ services.restic.volume_folder }}/ssh/config"
owner: root
group: root
mode: '0600'
- name: Upload SSH known_hosts file
template:
src: restic/ssh.known_hosts.j2
dest: "{{ services.restic.volume_folder }}/ssh/known_hosts"
owner: root
group: root
mode: '0600'
- name: Create scripts directory
file:
path: "{{ services.restic.volume_folder }}/scripts"
owner: root
group: root
mode: '0755'
state: directory
- name: Upload failure.sh script
template:
src: restic/failure.sh.j2
dest: "{{ services.restic.volume_folder }}/scripts/failure.sh"
owner: root
group: root
mode: '0755'
- name: Upload success.sh script
template:
src: restic/success.sh.j2
dest: "{{ services.restic.volume_folder }}/scripts/success.sh"
owner: root
group: root
mode: '0755'

View file

@ -0,0 +1,9 @@
- name: Upload vhost config for uptime domain
copy:
src: vhost/uptime_kuma
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.uptime_kuma.domain }}_location"
- name: Upload vhost config for status domain
copy:
src: vhost/uptime_kuma
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.uptime_kuma.status_domain }}_location"

View file

@ -0,0 +1,20 @@
# vim: ft=yaml.ansible
---
- name: Create subfolder for MariaDB data
file:
name: "{{ services.writefreely.volume_folder }}/db"
owner: "999"
group: "999"
state: directory
- name: Create subfolder for encryption keys
file:
name: "{{ services.writefreely.volume_folder }}/keys"
owner: "2"
group: "2"
state: directory
- name: Upload config.ini
template:
src: "writefreely/config.ini.j2"
dest: "{{ services.writefreely.volume_folder }}/config.ini"

View file

@ -1,21 +1,28 @@
# vim: ft=yaml.ansible # vim: ft=yaml.ansible
--- ---
- name: setup external services network - name: Set up external services network
docker_network: docker_network:
name: external_services name: external_services
- name: setup services - name: Deploy all services
include_tasks: "services/{{ item.service.file }}" include_tasks:
loop: "{{ services | dict2items(value_name='service') }}" file: block.yml
vars:
service:
name: "{{ item }}"
vars: "{{ services[item] }}"
loop: "{{ services_include }}"
when: single_service is not defined and when: single_service is not defined and
item.service.file is defined and (item.vars.disabled_in_vagrant is not defined or
(item.service.disabled_in_vagrant is not defined or not (item.vars.disabled_in_vagrant and vagrant))
not (item.service.disabled_in_vagrant and vagrant))
- name: setup single service - name: Deploy single service
include_tasks: "services/{{ services[single_service].file }}" include_tasks:
when: single_service is defined and file: block.yml
single_service in services and vars:
services[single_service].file is defined and service:
name: "{{ single_service }}"
vars: "{{ services[single_service] }}"
when: single_service is defined and single_service in services and
(services[single_service].disabled_in_vagrant is not defined or (services[single_service].disabled_in_vagrant is not defined or
not (services[single_service].disabled_in_vagrant and vagrant)) not (services[single_service].disabled_in_vagrant and vagrant))

View file

@ -1,85 +0,0 @@
---
- name: ensure byro data folder exists
file:
path: "{{ services.byro.volume_folder }}"
state: directory
- name: create env file
template:
src: byro.env.j2
dest: "{{ services.byro.volume_folder }}/env"
- name: deploy entrypoint file
copy:
src: byro_deploy_entrypoint.sh
dest: "{{ services.byro.volume_folder}}/data/deploy_entrypoint.sh"
mode: "preserve"
- name: run byro
docker_compose:
project_name: "byro member system"
pull: yes
definition:
version: "3.8"
services:
manage:
image: ghcr.io/valberg/byro:add_missing_jquery_ui_images
entrypoint: "/var/byro/data/deploy_entrypoint.sh"
restart: "no"
volumes:
- "{{ services.byro.volume_folder }}/data:/var/byro/data"
- "{{ services.byro.volume_folder }}/static.dist:/byro/static.dist:rw"
networks:
- byro
- external_services
- postfix
env_file: "{{ services.byro.volume_folder }}/env"
gunicorn:
image: ghcr.io/byro/byro:master
restart: unless-stopped
working_dir: '/byro'
entrypoint:
- 'gunicorn'
command: >
byro.wsgi --name byro --workers 4
--max-requests 1200 --max-requests-jitter 50
--log-level=info
--bind=0.0.0.0:8345
links:
- postgres
depends_on:
postgres:
condition: service_healthy
volumes:
- "{{ services.byro.volume_folder }}/data:/var/byro/data"
- "{{ services.byro.volume_folder }}/static.dist:/byro/static.dist:rw"
networks:
- byro
- external_services
- postfix
env_file: "{{ services.byro.volume_folder }}/env"
postgres:
image: postgres:{{ services.byro.postgres_version }}
volumes:
- "{{ services.byro.volume_folder }}/postgres/:/var/lib/postgresql/data"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U byro"]
interval: 5s
timeout: 5s
retries: 5
environment:
POSTGRES_PASSWORD: "{{ postgres_passwords.byro }}"
networks:
- byro
networks:
byro:
external_services:
external: true
postfix:
external: true

View file

@ -1,55 +0,0 @@
# vim: ft=yaml.ansible
---
- name: codimd network
docker_network:
name: codimd
- name: create codimd volume folders
file:
name: "{{ services.codimd.volume_folder }}/{{ volume }}"
state: directory
loop:
- "db"
- "codimd/uploads"
loop_control:
loop_var: volume
- name: codimd database container
docker_container:
name: codimd_db
image: postgres:10
state: started
restart_policy: unless-stopped
networks:
- name: codimd
volumes:
- "{{ services.codimd.volume_folder }}/db:/var/lib/postgresql/data"
env:
POSTGRES_USER: "codimd"
POSTGRES_PASSWORD: "{{ postgres_passwords.codimd }}"
- name: codimd app container
docker_container:
name: codimd_app
image: hackmdio/hackmd:1.3.0
restart_policy: unless-stopped
networks:
- name: codimd
- name: ldap
- name: external_services
volumes:
- "{{ services.codimd.volume_folder }}/codimd/uploads:/codimd/public/uploads"
env:
CMD_DB_URL: "postgres://codimd:{{ postgres_passwords.codimd }}@codimd_db:5432/codimd"
CMD_ALLOW_EMAIL_REGISTER: "False"
CMD_IMAGE_UPLOAD_TYPE: "filesystem"
CMD_EMAIL: "False"
CMD_LDAP_URL: "ldap://openldap"
CMD_LDAP_BINDDN: "cn=admin,dc=data,dc=coop"
CMD_LDAP_BINDCREDENTIALS: "{{ ldap_admin_password }}"
CMD_LDAP_SEARCHBASE: "dc=data,dc=coop"
CMD_LDAP_SEARCHFILTER: "(&(uid={{ '{{username}}' }})(objectClass=inetOrgPerson))"
CMD_USECDN: "false"
VIRTUAL_HOST: "{{ services.codimd.domain }}"
LETSENCRYPT_HOST: "{{ services.codimd.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,36 +0,0 @@
# vim: ft=yaml.ansible
---
- name: copy docker registry nginx configuration
copy:
src: "files/configs/docker_registry/nginx.conf"
dest: "/docker-volumes/nginx/vhost/{{ services.docker_registry.domain }}"
mode: "0644"
- name: docker registry container
docker_container:
name: registry
image: registry:{{ services.docker_registry.version }}
restart_policy: always
volumes:
- "{{ services.docker_registry.volume_folder }}/registry:/var/lib/registry"
- "{{ services.docker_registry.volume_folder }}/auth:/auth"
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ services.docker_registry.domain }}"
LETSENCRYPT_HOST: "{{ services.docker_registry.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
REGISTRY_AUTH: "htpasswd"
REGISTRY_AUTH_HTPASSWD_PATH: "/auth/htpasswd"
REGISTRY_AUTH_HTPASSWD_REALM: "data.coop docker registry"
- name: generate htpasswd file
shell: "docker exec -it registry htpasswd -Bbn docker {{ docker_password }} > {{ services.docker_registry.volume_folder }}/auth/htpasswd"
args:
creates: "{{ services.docker_registry.volume_folder }}/auth/htpasswd"
- name: log in to registry
docker_login:
registry: "{{ 'docker.data.coop' if vagrant else services.docker_registry.domain }}"
username: "docker"
password: "{{ docker_password }}"

View file

@ -1,52 +0,0 @@
# vim: ft=yaml.ansible
---
- name: set up drone with docker runner
docker_compose:
project_name: drone
pull: yes
definition:
version: "3.6"
services:
drone:
container_name: "drone"
image: "drone/drone:{{ services.drone.version }}"
restart: unless-stopped
networks:
- external_services
- drone
volumes:
- "{{ services.drone.volume_folder }}:/data"
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
DRONE_GITEA_SERVER: "https://{{ services.forgejo.domain }}"
DRONE_GITEA_CLIENT_ID: "{{ drone_secrets.oauth_client_id }}"
DRONE_GITEA_CLIENT_SECRET: "{{ drone_secrets.oauth_client_secret }}"
DRONE_GIT_ALWAYS_AUTH: "true"
DRONE_SERVER_HOST: "{{ services.drone.domain }}"
DRONE_SERVER_PROTO: "https"
DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}"
PLUGIN_CUSTOM_DNS: "91.239.100.100"
VIRTUAL_HOST: "{{ services.drone.domain }}"
LETSENCRYPT_HOST: "{{ services.drone.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
drone-runner-docker:
container_name: "drone-runner-docker"
image: "drone/drone-runner-docker:{{ services.drone.version }}"
restart: unless-stopped
networks:
- drone
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
DRONE_RPC_HOST: "{{ services.drone.domain }}"
DRONE_RPC_PROTO: "https"
DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}"
DRONE_RUNNER_CAPACITY: 2
DRONE_RUNNER_NAME: "data.coop_drone_runner"
networks:
drone:
external_services:
external:
name: external_services

View file

@ -1,37 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Create Docker network for Forgejo
docker_network:
name: forgejo
# old DNS: 138.68.71.153
- name: Set up Forgejo container
docker_container:
name: forgejo
image: codeberg.org/forgejo/forgejo:{{ services.forgejo.version }}
restart_policy: unless-stopped
networks:
- name: forgejo
- name: postfix
- name: external_services
volumes:
- "{{ services.forgejo.volume_folder }}:/data"
published_ports:
- "22:22"
env:
VIRTUAL_HOST: "{{ services.forgejo.domain }}"
VIRTUAL_PORT: "3000"
LETSENCRYPT_HOST: "{{ services.forgejo.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
# Forgejo customization, see: https://docs.gitea.io/en-us/install-with-docker/#customization
# https://docs.gitea.io/en-us/config-cheat-sheet/#security-security
FORGEJO__mailer__ENABLED: "true"
FORGEJO__mailer__FROM: "noreply@{{ services.forgejo.domain }}"
FORGEJO__mailer__MAILER_TYPE: "smtp"
FORGEJO__mailer__HOST: "{{ smtp_host }}:{{ smtp_port }}"
FORGEJO__security__LOGIN_REMEMBER_DAYS: "60"
FORGEJO__security__PASSWORD_COMPLEXITY: "off"
FORGEJO__security__MIN_PASSWORD_LENGTH: "8"
FORGEJO__security__PASSWORD_CHECK_PWN: "true"
FORGEJO__service__ENABLE_NOTIFY_MAIL: "true"
FORGEJO__service__REGISTER_EMAIL_CONFIRM: "true"

View file

@ -1,67 +0,0 @@
# vim: ft=yaml.ansible
---
- name: create hedgedoc volume folders
file:
name: "{{ services.hedgedoc.volume_folder }}/{{ volume }}"
state: directory
loop:
- "db"
- "hedgedoc/uploads"
loop_control:
loop_var: volume
- name: copy sso public certificate
copy:
src: "files/sso/sso.data.coop.pem"
dest: "{{ services.hedgedoc.volume_folder }}/sso.data.coop.pem"
mode: "0644"
- name: setup hedgedoc
docker_compose:
project_name: "hedgedoc"
pull: "yes"
definition:
services:
database:
image: "postgres:{{ services.hedgedoc.postgres_version }}"
environment:
POSTGRES_USER: "codimd"
POSTGRES_PASSWORD: "{{ postgres_passwords.hedgedoc }}"
POSTGRES_DB: "codimd"
restart: "unless-stopped"
networks:
- "hedgedoc"
volumes:
- "{{ services.hedgedoc.volume_folder }}/db:/var/lib/postgresql/data"
app:
image: "quay.io/hedgedoc/hedgedoc:{{ services.hedgedoc.version }}"
environment:
CMD_DB_URL: "postgres://codimd:{{ postgres_passwords.hedgedoc }}@hedgedoc_database_1:5432/codimd"
CMD_DOMAIN: "{{ services.hedgedoc.domain }}"
CMD_ALLOW_EMAIL_REGISTER: "False"
CMD_IMAGE_UPLOAD_TYPE: "filesystem"
CMD_EMAIL: "False"
CMD_SAML_IDPCERT: "/sso.data.coop.pem"
CMD_SAML_IDPSSOURL: "https://sso.data.coop/auth/realms/datacoop/protocol/saml"
CMD_SAML_ISSUER: "hedgedoc"
CMD_SAML_IDENTIFIERFORMAT: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
CMD_USECDN: "false"
CMD_PROTOCOL_USESSL: "true"
VIRTUAL_HOST: "{{ services.hedgedoc.domain }}"
LETSENCRYPT_HOST: "{{ services.hedgedoc.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
volumes:
- "{{ services.hedgedoc.volume_folder }}/hedgedoc/uploads:/hedgedoc/public/uploads"
- "{{ services.hedgedoc.volume_folder }}/sso.data.coop.pem:/sso.data.coop.pem"
restart: "unless-stopped"
networks:
- "hedgedoc"
- "external_services"
depends_on:
- database
networks:
hedgedoc:
external_services:
external: true

View file

@ -1,50 +0,0 @@
# vim: ft=yaml.ansible
---
- name: setup keycloak containers for sso.data.coop
docker_compose:
project_name: "keycloak"
pull: "yes"
definition:
version: "3.6"
services:
postgres:
image: "postgres:{{ services.keycloak.postgres_version }}"
restart: "unless-stopped"
networks:
- "keycloak"
volumes:
- "{{ services.keycloak.volume_folder }}/data:/var/lib/postgresql/data"
environment:
POSTGRES_USER: "keycloak"
POSTGRES_PASSWORD: "{{ postgres_passwords.keycloak }}"
POSTGRES_DB: "keycloak"
app:
image: "quay.io/keycloak/keycloak:{{ services.keycloak.version }}"
restart: "unless-stopped"
networks:
- "keycloak"
- "postfix"
- "external_services"
command:
- "start"
- "--db=postgres"
- "--db-url=jdbc:postgresql://postgres:5432/keycloak"
- "--db-username=keycloak"
- "--db-password={{ postgres_passwords.keycloak }}"
- "--hostname={{ services.keycloak.domain }}"
- "--proxy=edge"
- "--https-port=8080"
- "--http-relative-path=/auth"
environment:
VIRTUAL_HOST: "{{ services.keycloak.domain }}"
VIRTUAL_PORT: "8080"
LETSENCRYPT_HOST: "{{ services.keycloak.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
keycloak:
postfix:
external: true
external_services:
external: true

View file

@ -1,181 +0,0 @@
# vim: ft=yaml.ansible
---
- name: create mailu volume folders
file:
name: "{{ services.mailu.volume_folder }}/{{ volume }}"
state: directory
loop:
- redis
- certs
- data
- dkim
- mail
- mailqueue
- filter
- postgres
- webmail
- overrides
- overrides/nginx
- overrides/dovecot
- overrides/postfix
- overrides/rspamd
- overrides/rainloop
loop_control:
loop_var: volume
- name: upload mailu.env file
template:
src: mailu.env.j2
dest: "{{ services.mailu.volume_folder }}/mailu.env"
- name: hard link to Let's Encrypt TLS certificate
file:
src: "{{ services.nginx_proxy.volume_folder }}/certs/{{ services.mailu.domain }}/fullchain.pem"
dest: "{{ services.mailu.volume_folder }}/certs/cert.pem"
state: hard
force: yes
when: letsencrypt_enabled
- name: hard link to Let's Encrypt TLS key
file:
src: "{{ services.nginx_proxy.volume_folder }}/certs/{{ services.mailu.domain }}/key.pem"
dest: "{{ services.mailu.volume_folder }}/certs/key.pem"
state: hard
force: yes
when: letsencrypt_enabled
- name: run mail server containers
docker_compose:
project_name: mail_server
pull: yes
definition:
version: '3.6'
services:
postgres:
image: postgres:14-alpine
restart: always
environment:
POSTGRES_DB: mailu
POSTGRES_USER: mailu
POSTGRES_PASSWORD: "{{ postgres_passwords.mailu }}"
volumes:
- "{{ services.mailu.volume_folder }}/postgres:/var/lib/postgresql/data"
dns:
- "{{ services.mailu.dns }}"
redis:
image: redis:alpine
restart: always
volumes:
- "{{ services.mailu.volume_folder }}/redis:/data"
depends_on:
- resolver
dns:
- "{{ services.mailu.dns }}"
front:
image: ghcr.io/mailu/nginx:{{ services.mailu.version }}
restart: always
env_file: "{{ services.mailu.volume_folder }}/mailu.env"
environment:
VIRTUAL_HOST: "{{ services.mailu.domain }}"
LETSENCRYPT_HOST: "{{ services.mailu.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
volumes:
- "{{ services.mailu.volume_folder }}/certs:/certs"
- "{{ services.mailu.volume_folder }}/overrides/nginx:/overrides:ro"
expose:
- "80"
ports:
- "993:993"
- "25:25"
- "587:587"
- "465:465"
networks:
- default
- external_services
resolver:
image: ghcr.io/mailu/unbound:{{ services.mailu.version }}
restart: always
env_file: "{{ services.mailu.volume_folder }}/mailu.env"
networks:
default:
ipv4_address: "{{ services.mailu.dns }}"
admin:
image: ghcr.io/mailu/admin:{{ services.mailu.version }}
restart: always
env_file: "{{ services.mailu.volume_folder}}/mailu.env"
volumes:
- "{{ services.mailu.volume_folder }}/data:/data"
- "{{ services.mailu.volume_folder }}/dkim:/dkim"
depends_on:
- redis
- resolver
dns:
- "{{ services.mailu.dns }}"
imap:
image: ghcr.io/mailu/dovecot:{{ services.mailu.version }}
restart: always
env_file: "{{ services.mailu.volume_folder }}/mailu.env"
volumes:
- "{{ services.mailu.volume_folder }}/mail:/mail"
- "{{ services.mailu.volume_folder }}/overrides/dovecot:/overrides:ro"
depends_on:
- front
- resolver
dns:
- "{{ services.mailu.dns }}"
smtp:
image: ghcr.io/mailu/postfix:{{ services.mailu.version }}
restart: always
env_file: "{{ services.mailu.volume_folder }}/mailu.env"
volumes:
- "{{ services.mailu.volume_folder }}/mailqueue:/queue"
- "{{ services.mailu.volume_folder }}/overrides/postfix:/overrides:ro"
depends_on:
- front
- resolver
dns:
- "{{ services.mailu.dns }}"
antispam:
image: ghcr.io/mailu/rspamd:{{ services.mailu.version }}
hostname: antispam
restart: always
env_file: "{{ services.mailu.volume_folder }}/mailu.env"
volumes:
- "{{ services.mailu.volume_folder }}/filter:/var/lib/rspamd"
- "{{ services.mailu.volume_folder }}/overrides/rspamd:/etc/rspamd/override.d:ro"
depends_on:
- front
- resolver
dns:
- "{{ services.mailu.dns }}"
webmail:
image: ghcr.io/mailu/rainloop:{{ services.mailu.version }}
restart: always
env_file: "{{ services.mailu.volume_folder }}/mailu.env"
volumes:
- "{{ services.mailu.volume_folder }}/webmail:/data"
- "{{ services.mailu.volume_folder }}/overrides/rainloop:/overrides:ro"
depends_on:
- imap
- resolver
dns:
- "{{ services.mailu.dns }}"
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: "{{ services.mailu.subnet }}"
external_services:
external:
name: external_services

View file

@ -1,222 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Create volume folder for Mastodon data
file:
name: "{{ services.mastodon.volume_folder }}/mastodon_data"
state: directory
owner: "991"
mode: u=rwx,g=rx,o=rx
- name: Create volume folder for PostgreSQL data
file:
name: "{{ services.mastodon.volume_folder }}/postgres_data"
state: directory
owner: "70"
mode: u=rwx,go=
- name: Create volume folder for PostgreSQL config
file:
name: "{{ services.mastodon.volume_folder }}/postgres_config"
state: directory
owner: root
mode: u=rwx,g=rx,o=rx
- name: Create volume folder for Redis data
file:
name: "{{ services.mastodon.volume_folder }}/redis_data"
state: directory
owner: "999"
group: "1000"
mode: u=rwx,g=rx,o=rx
- name: Copy mastodon environment file
template:
src: files/configs/mastodon/env_file.j2
dest: "{{ services.mastodon.volume_folder }}/env_file"
- name: Upload vhost config for root domain
template:
src: files/configs/mastodon/vhost-mastodon
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.mastodon.domain }}"
- name: Copy PostgreSQL config
copy:
src: files/configs/mastodon/postgresql.conf
dest: "{{ services.mastodon.volume_folder }}/postgres_config/postgresql.conf"
- name: Set up Mastodon
docker_compose:
project_name: mastodon
pull: true
restarted: true
definition:
x-sidekiq: &sidekiq
image: "tootsuite/mastodon:{{ services.mastodon.version }}"
restart: always
env_file: "{{ services.mastodon.volume_folder }}/env_file"
depends_on:
db:
condition: "service_healthy"
redis:
condition: "service_healthy"
networks:
- postfix
- external_services
- internal_network
volumes:
- "{{ services.mastodon.volume_folder }}/mastodon_data:/mastodon/public/system"
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
version: '3'
services:
db:
restart: always
image: "postgres:{{ services.mastodon.postgres_version }}"
shm_size: 256mb
networks:
- internal_network
healthcheck:
test: ['CMD', 'pg_isready', '-U', 'postgres']
volumes:
- "{{ services.mastodon.volume_folder }}/postgres_data:/var/lib/postgresql/data"
- "{{ services.mastodon.volume_folder }}/postgres_config:/config:ro"
command: postgres -c config_file=/config/postgresql.conf
environment:
- 'POSTGRES_HOST_AUTH_METHOD=trust'
redis:
restart: always
image: "redis:{{ services.mastodon.redis_version }}"
networks:
- internal_network
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
volumes:
- "{{ services.mastodon.volume_folder }}/redis_data:/data"
web:
image: "tootsuite/mastodon:{{ services.mastodon.version }}"
restart: always
env_file: "{{ services.mastodon.volume_folder }}/env_file"
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- external_services
- internal_network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
depends_on:
db:
condition: "service_healthy"
redis:
condition: "service_healthy"
volumes:
- "{{ services.mastodon.volume_folder }}/mastodon_data:/mastodon/public/system"
environment:
MAX_THREADS: 10
WEB_CONCURRENCY: 3
VIRTUAL_HOST: "{{ services.mastodon.domain }}"
VIRTUAL_PORT: "3000"
VIRTUAL_PATH: "/"
LETSENCRYPT_HOST: "{{ services.mastodon.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
streaming:
image: "tootsuite/mastodon:{{ services.mastodon.version }}"
restart: always
env_file: "{{ services.mastodon.volume_folder }}/env_file"
command: node ./streaming
networks:
- external_services
- internal_network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']
ports:
- '127.0.0.1:4000:4000'
depends_on:
db:
condition: "service_healthy"
redis:
condition: "service_healthy"
environment:
DB_POOL: 15
VIRTUAL_HOST: "{{ services.mastodon.domain }}"
VIRTUAL_PORT: "4000"
VIRTUAL_PATH: "/api/v1/streaming"
# sidekiq-default-push-pull: DB_POOL = 25, -c 25 for 25 connections
sidekiq-default-push-pull:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q default -q push -q pull
environment:
DB_POOL: 25
# sidekiq-default-pull-push: DB_POOL = 25, -c 25 for 25 connections
sidekiq-default-pull-push:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q default -q pull -q push
environment:
DB_POOL: 25
# sidekiq-pull-default-push: DB_POOL = 25, -c 25 for 25 connections
sidekiq-pull-default-push:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q pull -q default -q push
environment:
DB_POOL: 25
# sidekiq-push-default-pull: DB_POOL = 25, -c 25 for 25 connections
sidekiq-push-default-pull:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q push -q default -q pull
environment:
DB_POOL: 25
# sidekiq-push-scheduler: DB_POOL = 5, -c 5 for 5 connections
sidekiq-push-scheduler:
<<: *sidekiq
command: bundle exec sidekiq -c 5 -q push -q scheduler
environment:
DB_POOL: 5
# sidekiq-push-mailers: DB_POOL = 5, -c 5 for 5 connections
sidekiq-push-mailers:
<<: *sidekiq
command: bundle exec sidekiq -c 5 -q push -q mailers
environment:
DB_POOL: 5
# sidekiq-push-ingress: DB_POOL = 10, -c 10 for 10 connections
sidekiq-push-ingress:
<<: *sidekiq
command: bundle exec sidekiq -c 10 -q push -q ingress
environment:
DB_POOL: 10
networks:
external_services:
external: true
postfix:
external: true
internal_network:
internal: true
- name: Configure cron job to remove old Mastodon media daily
cron:
name: Clean Mastodon media data older than a week
cron_file: ansible_mastodon_clean_media
job: docker exec mastodon_web_1 tootctl media remove --days 7
special_time: daily
user: root
state: present
- name: Configure cron job to remove old Mastodon preview cards daily
cron:
name: Clean Mastodon preview card data older than two weeks
cron_file: ansible_mastodon_clean_preview_cards
job: docker exec mastodon_web_1 tootctl preview_cards remove --days 14
special_time: daily
user: root
state: present

View file

@ -1,120 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Create Matrix volume folders
file:
name: "{{ services.matrix.volume_folder }}/{{ volume }}"
state: directory
owner: "991"
group: "991"
loop:
- "data"
- "data/uploads"
- "data/media"
loop_control:
loop_var: volume
- name: Create Matrix DB folder
file:
name: "{{ services.matrix.volume_folder }}/db"
state: "directory"
- name: Create Element volume folders
file:
name: "{{ services.element.volume_folder }}/{{ volume }}"
state: directory
loop:
- "data"
loop_control:
loop_var: volume
- name: Upload Element config.json
template:
src: files/configs/element/config.json
dest: "{{ services.element.volume_folder }}/data/config.json"
- name: Upload Element riot.im.conf
template:
src: files/configs/element/riot.im.conf
dest: "{{ services.element.volume_folder }}/data/riot.im.conf"
- name: upload vhost config for matrix domain
template:
src: files/configs/matrix/vhost-matrix
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.matrix.domain }}"
- name: Upload vhost config for Element domain
template:
src: files/configs/matrix/vhost-element
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ item }}"
loop: "{{ services.element.domains }}"
- name: Upload homeserver.yaml
template:
src: "files/configs/matrix/homeserver.yaml.j2"
dest: "{{ services.matrix.volume_folder }}/data/homeserver.yaml"
- name: upload matrix logging config
template:
src: "files/configs/matrix/matrix.data.coop.log.config"
dest: "{{ services.matrix.volume_folder }}/data/matrix.data.coop.log.config"
- name: Set up Matrix and Element
docker_compose:
project_name: matrix
pull: true
definition:
version: "3.6"
services:
postgres:
image: "postgres:{{ services.matrix.postgres_version }}"
restart: unless-stopped
networks:
- matrix
volumes:
- "{{ services.matrix.volume_folder }}/db:/var/lib/postgresql/data"
environment:
POSTGRES_USER: "synapse"
POSTGRES_PASSWORD: "{{ postgres_passwords.matrix }}"
synapse:
image: "matrixdotorg/synapse:{{ services.matrix.version }}"
restart: unless-stopped
networks:
- matrix
- external_services
- postfix
volumes:
- "{{ services.matrix.volume_folder }}/data:/data"
environment:
SYNAPSE_CONFIG_PATH: "/data/homeserver.yaml"
SYNAPSE_CACHE_FACTOR: "2"
SYNAPSE_LOG_LEVEL: "INFO"
VIRTUAL_HOST: "{{ services.matrix.domain }}"
VIRTUAL_PORT: "8008"
LETSENCRYPT_HOST: "{{ services.matrix.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
element:
image: "avhost/docker-matrix-element:{{ services.element.version }}"
restart: unless-stopped
networks:
- matrix
- external_services
expose:
- 8080
volumes:
- "{{ services.element.volume_folder }}/data:/data"
environment:
VIRTUAL_HOST: "{{ services.element.domains | join(',') }}"
VIRTUAL_PORT: "8080"
LETSENCRYPT_HOST: "{{ services.element.domains | join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external:
name: external_services
postfix:
external: true
matrix:
name: "matrix"

View file

@ -1,52 +0,0 @@
# vim: ft=yaml.ansible
---
- name: run membersystem containers
docker_compose:
project_name: "member.data.coop"
pull: yes
definition:
version: "3"
services:
backend:
image: "docker.data.coop/membersystem:{{ services.membersystem.version }}"
restart: always
user: $UID:$GID
tty: true
depends_on:
- postgres
networks:
- membersystem
- external_services
- postfix
environment:
SECRET_KEY: "{{ membersystem_secrets.secret_key }}"
DATABASE_URL: postgres://postgres:{{ postgres_passwords.membersystem }}@postgres:5432/postgres
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
EMAIL_BACKEND: "django.core.mail.backends.smtp.EmailBackend"
EMAIL_URL: "smtp://noop@{{ smtp_host }}:{{ smtp_port }}"
VIRTUAL_HOST: "{{ services.membersystem.domain }}"
VIRTUAL_PORT: "8000"
LETSENCRYPT_HOST: "{{ services.membersystem.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
ALLOWED_HOSTS: "{{ services.membersystem.domain }}"
CSRF_TRUSTED_ORIGINS: "https://{{ services.membersystem.domain }}"
DJANGO_ADMINS: "{{ services.membersystem.django_admins }}"
DEFAULT_FROM_EMAIL: "noreply@{{ services.membersystem.domain }}"
postgres:
image: "postgres:{{ services.membersystem.postgres_version }}"
restart: always
volumes:
- "{{ volume_root_folder }}/membersystem/postgres/data:/var/lib/postgresql/data"
networks:
- membersystem
environment:
POSTGRES_PASSWORD: "{{ postgres_passwords.membersystem }}"
networks:
membersystem:
external_services:
external: true
postfix:
external: true

View file

@ -1,23 +0,0 @@
# vim: ft=yaml.ansible
---
- name: setup netdata docker container for system monitoring
docker_container:
name: netdata
image: netdata/netdata:{{ services.netdata.version }}
restart_policy: unless-stopped
hostname: "hevonen.servers.{{ base_domain }}"
capabilities:
- SYS_PTRACE
security_opts:
- apparmor:unconfined
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- name: external_services
env:
VIRTUAL_HOST : "{{ services.netdata.domain }}"
LETSENCRYPT_HOST: "{{ services.netdata.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
PGID: "999"

View file

@ -1,76 +0,0 @@
# vim: ft=yaml.ansible
---
- name: upload vhost config for cloud.data.coop
template:
src: files/configs/nextcloud/vhost
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.nextcloud.domain }}"
notify: "restart nginx"
- name: setup nextcloud containers
docker_compose:
project_name: "nextcloud"
pull: "yes"
definition:
services:
postgres:
image: "postgres:{{ services.nextcloud.postgres_version }}"
restart: "unless-stopped"
networks:
- "nextcloud"
volumes:
- "{{ services.nextcloud.volume_folder }}/postgres:/var/lib/postgresql/data"
environment:
POSTGRES_DB: "nextcloud"
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"
POSTGRES_USER: "nextcloud"
redis:
image: "redis:{{ services.nextcloud.redis_version }}"
restart: "unless-stopped"
command: "redis-server --requirepass {{ nextcloud_secrets.redis_password }}"
tmpfs:
- /var/lib/redis
networks:
- "nextcloud"
cron:
image: "nextcloud:{{ services.nextcloud.version }}"
restart: "unless-stopped"
entrypoint: "/cron.sh"
networks:
- "nextcloud"
volumes:
- "{{ services.nextcloud.volume_folder }}/app:/var/www/html"
depends_on:
- "postgres"
- "redis"
app:
image: "nextcloud:{{ services.nextcloud.version }}"
restart: "unless-stopped"
networks:
- "nextcloud"
- "postfix"
- "external_services"
volumes:
- "{{ services.nextcloud.volume_folder }}/app:/var/www/html"
environment:
VIRTUAL_HOST: "{{ services.nextcloud.domain }}"
LETSENCRYPT_HOST: "{{ services.nextcloud.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
POSTGRES_HOST: "postgres"
POSTGRES_DB: "nextcloud"
POSTGRES_USER: "nextcloud"
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"
REDIS_HOST: "redis"
REDIS_HOST_PASSWORD: "{{ nextcloud_secrets.redis_password }}"
depends_on:
- "postgres"
- "redis"
networks:
nextcloud:
postfix:
external: true
external_services:
external: true

View file

@ -1,48 +0,0 @@
# vim: ft=yaml.ansible
---
- name: create nginx-proxy volume folders
file:
name: "{{ services.nginx_proxy.volume_folder }}/{{ volume }}"
state: directory
loop:
- conf
- vhost
- html
- dhparam
- certs
loop_control:
loop_var: volume
- name: nginx proxy container
docker_container:
name: nginx-proxy
image: nginxproxy/nginx-proxy:{{ services.nginx_proxy.version }}
restart_policy: always
networks:
- name: external_services
published_ports:
- "80:80"
- "443:443"
volumes:
- "{{ services.nginx_proxy.volume_folder }}/conf:/etc/nginx/conf.d"
- "{{ services.nginx_proxy.volume_folder }}/vhost:/etc/nginx/vhost.d"
- "{{ services.nginx_proxy.volume_folder }}/html:/usr/share/nginx/html"
- "{{ services.nginx_proxy.volume_folder }}/dhparam:/etc/nginx/dhparam"
- "{{ services.nginx_proxy.volume_folder }}/certs:/etc/nginx/certs:ro"
- /var/run/docker.sock:/tmp/docker.sock:ro
- name: nginx letsencrypt container
docker_container:
name: nginx-proxy-le
image: nginxproxy/acme-companion:{{ services.nginx_acme_companion.version }}
restart_policy: always
volumes:
- "{{ services.nginx_proxy.volume_folder }}/vhost:/etc/nginx/vhost.d"
- "{{ services.nginx_proxy.volume_folder }}/html:/usr/share/nginx/html"
- "{{ services.nginx_proxy.volume_folder }}/dhparam:/etc/nginx/dhparam:ro"
- "{{ services.nginx_proxy.volume_folder }}/certs:/etc/nginx/certs"
- /var/run/docker.sock:/var/run/docker.sock:ro
env:
NGINX_PROXY_CONTAINER: nginx-proxy
when: letsencrypt_enabled

View file

@ -1,74 +0,0 @@
# vim: ft=yaml.ansible
---
- name: create ldap volume folders
file:
name: "{{ services.openldap.volume_folder }}/{{ volume }}"
state: directory
loop:
- "var/lib/ldap"
- "etc/slapd"
- "certs"
loop_control:
loop_var: volume
- name: Create a network for ldap
docker_network:
name: ldap
- name: openLDAP container
docker_container:
name: openldap
image: osixia/openldap:{{ services.openldap.version }}
tty: true
interactive: true
restart_policy: unless-stopped
volumes:
- "{{ services.openldap.volume_folder }}/var/lib/ldap:/var/lib/ldap"
- "{{ services.openldap.volume_folder }}/etc/slapd.d:/etc/ldap/slapd.d"
- "{{ services.openldap.volume_folder }}/certs:/container/service/slapd/assets/certs/"
published_ports:
- "389:389"
- "636:636"
hostname: "{{ services.openldap.domain }}"
domainname: "{{ services.openldap.domain }}" # important: same as hostname
networks:
- name: ldap
env:
LDAP_LOG_LEVEL: "256"
LDAP_ORGANISATION: "{{ base_domain }}"
LDAP_DOMAIN: "{{ base_domain }}"
LDAP_BASE_DN: ""
LDAP_ADMIN_PASSWORD: "{{ ldap_admin_password }}"
LDAP_CONFIG_PASSWORD: "{{ ldap_config_password }}"
LDAP_READONLY_USER: "false"
LDAP_RFC2307BIS_SCHEMA: "false"
LDAP_BACKEND: "mdb"
LDAP_TLS: "true"
LDAP_TLS_CRT_FILENAME: "ldap.crt"
LDAP_TLS_KEY_FILENAME: "ldap.key"
LDAP_TLS_CA_CRT_FILENAME: "ca.crt"
LDAP_TLS_ENFORCE: "false"
LDAP_TLS_CIPHER_SUITE: "SECURE256:-VERS-SSL3.0"
LDAP_TLS_PROTOCOL_MIN: "3.1"
LDAP_TLS_VERIFY_CLIENT: "demand"
LDAP_REPLICATION: "false"
KEEP_EXISTING_CONFIG: "false"
LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
LDAP_SSL_HELPER_PREFIX: "ldap"
- name: phpLDAPadmin container
docker_container:
name: phpldapadmin
image: osixia/phpldapadmin:{{ services.phpldapadmin.version }}
restart_policy: unless-stopped
networks:
- name: external_services
- name: ldap
env:
PHPLDAPADMIN_LDAP_HOSTS: "openldap"
PHPLDAPADMIN_HTTPS: "false"
PHPLDAPADMIN_TRUST_PROXY_SSL: "true"
VIRTUAL_HOST: "{{ services.openldap.domain }}"
LETSENCRYPT_HOST: "{{ services.openldap.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,53 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Create directory for Passit data
file:
name: "{{ services.passit.volume_folder }}/data"
owner: '70'
group: root
state: directory
- name: setup passit containers
docker_compose:
project_name: "passit"
pull: "yes"
definition:
version: "3.6"
services:
passit_db:
image: "postgres:{{ services.passit.postgres_version }}"
restart: "always"
networks:
- "passit"
volumes:
- "{{ services.passit.volume_folder }}/data:/var/lib/postgresql/data"
environment:
POSTGRES_USER: "passit"
POSTGRES_PASSWORD: "{{ postgres_passwords.passit }}"
passit_app:
image: "passit/passit:{{ services.passit.version }}"
command: "bin/start.sh"
restart: "always"
networks:
- "passit"
- "postfix"
- "external_services"
environment:
DATABASE_URL: "postgres://passit:{{ postgres_passwords.passit }}@passit_db:5432/passit"
SECRET_KEY: "{{ passit_secret_key }}"
IS_DEBUG: 'False'
EMAIL_URL: "smtp://noop@{{ smtp_host }}:{{ smtp_port }}"
DEFAULT_FROM_EMAIL: "noreply@{{ services.passit.domain }}"
EMAIL_CONFIRMATION_HOST: "https://{{ services.passit.domain }}"
FIDO_SERVER_ID: "{{ services.passit.domain }}"
VIRTUAL_HOST: "{{ services.passit.domain }}"
LETSENCRYPT_HOST: "{{ services.passit.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
passit:
postfix:
external: true
external_services:
external: true

View file

@ -1,22 +0,0 @@
# vim: ft=yaml.ansible
---
- name: create portainer volume folder
file:
name: "{{ services.portainer.volume_folder }}"
state: directory
- name: run portainer
docker_container:
name: portainer
image: portainer/portainer-ee:{{ services.portainer.version }}
restart_policy: always
networks:
- name: external_services
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- "{{ services.portainer.volume_folder }}:/data"
env:
VIRTUAL_HOST: "{{ services.portainer.domain }}"
VIRTUAL_PORT: "9000"
LETSENCRYPT_HOST: "{{ services.portainer.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,28 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Set up network for postfix
docker_network:
name: postfix
ipam_config:
- subnet: '172.16.0.0/16'
gateway: 172.16.0.1
- name: Create volume folders for Postfix
file:
name: "{{ services.postfix.volume_folder }}/dkim"
state: directory
- name: Set up Postfix Docker container for outgoing mail from services
docker_container:
name: postfix
image: boky/postfix:{{ services.postfix.version }}
restart_policy: always
networks:
- name: postfix
volumes:
- "{{ services.postfix.volume_folder }}/dkim:/etc/opendkim/keys"
env:
# Get all services which have allowed_sender_domain defined
ALLOWED_SENDER_DOMAINS: "{{ services | dict2items | selectattr('value.allowed_sender_domain', 'true') | map(attribute='value.domain') | join(' ') }}"
HOSTNAME: "{{ services.postfix.domain }}" # the name the smtp server will identify itself as
DKIM_AUTOGENERATE: "true"

View file

@ -1,31 +0,0 @@
# vim: ft=yaml.ansible
---
- name: create privatebin volume folders
file:
name: "{{ services.privatebin.volume_folder }}/{{ volume }}"
state: directory
loop:
- cfg
- data
loop_control:
loop_var: volume
- name: upload privatebin config
template:
src: files/configs/privatebin-conf.php
dest: "{{ services.privatebin.volume_folder }}/cfg/conf.php"
- name: privatebin app container
docker_container:
name: privatebin
image: jgeusebroek/privatebin:{{ services.privatebin.version }}
restart_policy: unless-stopped
volumes:
- "{{ services.privatebin.volume_folder }}/cfg:/privatebin/cfg"
- "{{ services.privatebin.volume_folder }}/data:/privatebin/data"
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ services.privatebin.domain }}"
LETSENCRYPT_HOST: "{{ services.privatebin.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,61 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Create rallly volume folders
file:
name: "{{ services.rallly.volume_folder }}/postgres"
state: directory
- name: Copy Rallly environment file
template:
src: files/configs/rallly/env_file.j2
dest: "{{ services.rallly.volume_folder }}/env_file"
- name: Set up Rallly
docker_compose:
project_name: "rallly"
pull: "yes"
definition:
version: "3.8"
services:
rallly_db:
image: "postgres:{{ services.rallly.postgres_version }}"
restart: "always"
shm_size: "256mb"
networks:
rallly_internal:
volumes:
- "{{ services.rallly.volume_folder }}/postgres:/var/lib/postgresql/data"
environment:
POSTGRES_PASSWORD: "{{ postgres_passwords.rallly }}"
POSTGRES_DB: "rallly_db"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
rallly:
image: "lukevella/rallly:{{ services.rallly.version }}"
restart: "always"
networks:
rallly_internal:
external_services:
postfix:
depends_on:
rallly_db:
condition: "service_healthy"
env_file:
- "{{ services.rallly.volume_folder }}/env_file"
environment:
VIRTUAL_HOST: "{{ services.rallly.domain }}"
VIRTUAL_PORT: "3000"
LETSENCRYPT_HOST: "{{ services.rallly.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
rallly_internal:
internal: true
external_services:
external: true
postfix:
external: true

View file

@ -1,89 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Create SSH directory
file:
path: "{{ services.restic.volume_folder }}/ssh"
owner: root
group: root
mode: '0755'
state: directory
- name: Copy private SSH key
copy:
dest: "{{ services.restic.volume_folder }}/ssh/id_ed25519"
owner: root
group: root
mode: '0600'
content: "{{ restic_secrets.ssh_privkey }}"
- name: Derive public SSH key
shell: >-
ssh-keygen -f {{ services.restic.volume_folder }}/ssh/id_ed25519 -y
> {{ services.restic.volume_folder }}/ssh/id_ed25519.pub
args:
creates: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub"
- name: Set file permissions on public SSH key
file:
path: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub"
owner: root
group: root
mode: '0644'
state: touch
- name: Create SSH config
template:
src: restic.ssh.config.j2
dest: "{{ services.restic.volume_folder }}/ssh/config"
owner: root
group: root
mode: '0600'
- name: Create SSH known_hosts file
template:
src: restic.ssh.known_hosts.j2
dest: "{{ services.restic.volume_folder }}/ssh/known_hosts"
owner: root
group: root
mode: '0600'
- name: Setup restic backup
docker_compose:
project_name: restic
pull: true
definition:
version: '3.6'
services:
backup:
image: mazzolino/restic:{{ services.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: "false"
BACKUP_CRON: "0 30 3 * * *"
RESTIC_REPOSITORY: "sftp:{{ services.restic.user }}@{{ services.restic.domain }}:{{ services.restic.repository }}"
RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}"
RESTIC_BACKUP_SOURCES: "/mnt/volumes"
RESTIC_BACKUP_ARGS: >-
--tag datacoop-volumes
--exclude '*.tmp'
--verbose
RESTIC_FORGET_ARGS: >-
--keep-last 10
--keep-daily 7
--keep-weekly 5
--keep-monthly 12
TZ: Europe/Copenhagen
volumes:
- "{{ services.restic.volume_folder }}/ssh:/run/secrets/.ssh:ro"
- /docker-volumes:/mnt/volumes:ro
prune:
image: "mazzolino/restic:{{ services.restic.version }}"
environment:
RUN_ON_STARTUP: "false"
PRUNE_CRON: "0 0 4 * * *"
RESTIC_REPOSITORY: "sftp:{{ services.restic.user }}@{{ services.restic.domain }}:{{ services.restic.repository }}"
RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}"
TZ: Europe/copenhagen
volumes:
- "{{ services.restic.volume_folder }}/ssh:/run/secrets/.ssh:ro"

View file

@ -1,19 +0,0 @@
# vim: ft=yaml.ansible
---
- name: setup 2022.slides.data.coop website using unipi
docker_container:
name: 2022.slides.data.coop_website
image: docker.data.coop/unipi:{{ services.slides_2022_website.version }}
restart_policy: unless-stopped
purge_networks: yes
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ services.slides_2022_website.domain }}"
LETSENCRYPT_HOST: "{{ services.slides_2022_website.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
command: "--remote=https://git.data.coop/data.coop/slides.git#slides2022"
capabilities:
- NET_ADMIN
devices:
- "/dev/net/tun"

View file

@ -1,13 +0,0 @@
# vim: ft=yaml.ansible
---
- name: setup cryptoaarhus.dk website docker container
docker_container:
name: cryptoaarhus_website
restart_policy: unless-stopped
image: docker.data.coop/cryptoaarhus-website
networks:
- name: external_services
env:
VIRTUAL_HOST : "{{ services.cryptoaarhus_website.domains|join(',') }}"
LETSENCRYPT_HOST: "{{ services.cryptoaarhus_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,13 +0,0 @@
# vim: ft=yaml.ansible
---
- name: setup cryptohagen.dk website docker container
docker_container:
name: cryptohagen_website
restart_policy: unless-stopped
image: docker.data.coop/cryptohagen-website
networks:
- name: external_services
env:
VIRTUAL_HOST : "{{ services.cryptohagen_website.domains|join(',') }}"
LETSENCRYPT_HOST: "{{ services.cryptohagen_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,37 +0,0 @@
# vim: ft=yaml.ansible
---
- name: Upload vhost config for root domain
copy:
src: files/configs/matrix/vhost-root
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.data_coop_website.domain }}"
- name: Upload vhost config for WWW domain
copy:
src: files/configs/vhost-www
dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.data_coop_website.www_domain }}"
- name: setup data.coop website docker container
docker_container:
name: "{{ services.data_coop_website.domain }}_website"
image: docker.data.coop/data-coop-website:{{ services.data_coop_website.version }}
pull: true
restart_policy: unless-stopped
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ services.data_coop_website.domain }},{{ services.data_coop_website.www_domain }}"
LETSENCRYPT_HOST: "{{ services.data_coop_website.domain }},{{ services.data_coop_website.www_domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
- name: setup staging data.coop website using hugo
docker_container:
name: "{{ services.data_coop_website.staging_domain }}_website"
image: docker.data.coop/data-coop-website:{{ services.data_coop_website.staging_version }}
pull: true
restart_policy: unless-stopped
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ services.data_coop_website.staging_domain }}"
LETSENCRYPT_HOST: "{{ services.data_coop_website.staging_domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,13 +0,0 @@
# vim: ft=yaml.ansible
---
- name: setup ulovliglogning.dk website docker container
docker_container:
name: ulovliglogning_website
restart_policy: unless-stopped
image: ulovliglogning/ulovliglogning.dk:latest
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ services.ulovliglogning_website.domains|join(',') }}"
LETSENCRYPT_HOST: "{{ services.ulovliglogning_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View file

@ -1,19 +0,0 @@
# vim: ft=yaml.ansible
---
- name: setup vhs.data.coop website with unipi
docker_container:
name: vhs.data.coop_website
image: docker.data.coop/unipi:{{ services.vhs_website.version }}
restart_policy: unless-stopped
purge_networks: yes
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ services.vhs_website.domain }}"
LETSENCRYPT_HOST: "{{ services.vhs_website.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
command: "--remote=https://git.data.coop/vhs.data.coop/website.git#main"
capabilities:
- NET_ADMIN
devices:
- "/dev/net/tun"

View file

@ -1,23 +0,0 @@
PYTHONUNBUFFERED=1
DJANGO_SETTINGS_MODULE=byro.settings
BYRO_DEBUG="False"
BYRO_DATA_DIR="/var/byro/data"
BYRO_FILESYSTEM_MEDIA="/var/byro/data/media"
BYRO_FILESYSTEM_LOGS="/var/byro/data/logs"
BYRO_SITE_URL="https://{{ services.byro.domain }}"
BYRO_DB_NAME="postgres"
BYRO_DB_USER="postgres"
BYRO_DB_PASS="{{ postgres_passwords.byro }}"
BYRO_DB_HOST="postgres"
BYRO_DB_PORT="5432"
BYRO_MAIL_FROM="noreply@{{ services.byro.domain}}"
BYRO_MAIL_HOST="{{ smtp_host }}"
BYRO_MAIL_PORT="{{ smtp_port }}"
BYRO_MAIL_USER="noop"
BYRO_MAIL_TLS="True"
BYRO_MAIL_SSL="False"
BYRO_LOGGING_EMAIL="admin@data.coop"
VIRTUAL_HOST="{{ services.byro.domain }}"
VIRTUAL_PORT="8345"
LETSENCRYPT_HOST="{{ services.byro.domain }}"
LETSENCRYPT_EMAIL="{{ letsencrypt_email }}"

View file

@ -0,0 +1,17 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
web:
image: docker.data.coop/cryptoaarhus-website
restart: unless-stopped
networks:
- external_services
environment:
VIRTUAL_HOST : "{{ services.cryptoaarhus_website.domains | join(',') }}"
LETSENCRYPT_HOST: "{{ services.cryptoaarhus_website.domains | join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -0,0 +1,17 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
web:
image: docker.data.coop/cryptohagen-website
restart: unless-stopped
networks:
- external_services
environment:
VIRTUAL_HOST : "{{ services.cryptohagen_website.domains | join(',') }}"
LETSENCRYPT_HOST: "{{ services.cryptohagen_website.domains | join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -0,0 +1,27 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
prod-web:
image: docker.data.coop/data-coop-website:{{ services.data_coop_website.version }}
restart: unless-stopped
networks:
- external_services
environment:
VIRTUAL_HOST: "{{ services.data_coop_website.domain }},{{ services.data_coop_website.www_domain }}"
LETSENCRYPT_HOST: "{{ services.data_coop_website.domain }},{{ services.data_coop_website.www_domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
staging-web:
image: docker.data.coop/data-coop-website:{{ services.data_coop_website.staging_version }}
restart: unless-stopped
networks:
- external_services
environment:
VIRTUAL_HOST: "{{ services.data_coop_website.staging_domain }}"
LETSENCRYPT_HOST: "{{ services.data_coop_website.staging_domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -0,0 +1,23 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: registry:{{ services.docker_registry.version }}
restart: always
networks:
- external_services
volumes:
- "./registry:/var/lib/registry"
- "./auth:/auth"
environment:
VIRTUAL_HOST: "{{ services.docker_registry.domain }}"
LETSENCRYPT_HOST: "{{ services.docker_registry.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
REGISTRY_AUTH: "htpasswd"
REGISTRY_AUTH_HTPASSWD_PATH: "/auth/htpasswd"
REGISTRY_AUTH_HTPASSWD_REALM: "data.coop docker registry"
networks:
external_services:
external: true

View file

@ -0,0 +1,40 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: drone/drone:{{ services.drone.version }}
restart: unless-stopped
networks:
- default
- external_services
volumes:
- ".:/data"
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
DRONE_GITEA_SERVER: https://{{ services.forgejo.domain }}
DRONE_GITEA_CLIENT_ID: "{{ drone_secrets.oauth_client_id }}"
DRONE_GITEA_CLIENT_SECRET: "{{ drone_secrets.oauth_client_secret }}"
DRONE_GIT_ALWAYS_AUTH: true
DRONE_SERVER_HOST: "{{ services.drone.domain }}"
DRONE_SERVER_PROTO: https
DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}"
VIRTUAL_HOST: "{{ services.drone.domain }}"
LETSENCRYPT_HOST: "{{ services.drone.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
runner:
image: drone/drone-runner-docker:{{ services.drone.version }}
restart: unless-stopped
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
DRONE_RPC_HOST: "{{ services.drone.domain }}"
DRONE_RPC_PROTO: https
DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}"
DRONE_RUNNER_CAPACITY: 2
DRONE_RUNNER_NAME: data.coop_drone_runner
networks:
external_services:
external: true

View file

@ -0,0 +1,22 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: avhost/docker-matrix-element:{{ services.element.version }}
restart: unless-stopped
networks:
- external_services
expose:
- "8080"
volumes:
- "./data:/data"
environment:
VIRTUAL_HOST: "{{ services.element.domain }}"
VIRTUAL_PORT: "8080"
LETSENCRYPT_HOST: "{{ services.element.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -1,19 +1,22 @@
# vim: ft=yaml.ansible # vim: ft=yaml.docker-compose
--- version: "3.8"
- name: setup fedi.dk website with unipi
docker_container: services:
name: fedi.dk_website web:
image: docker.data.coop/unipi:{{ services.fedi_dk_website.version }} image: docker.data.coop/unipi:{{ services.fedi_dk_website.version }}
restart_policy: unless-stopped restart: unless-stopped
purge_networks: yes
networks: networks:
- name: external_services - external_services
env: environment:
VIRTUAL_HOST: "{{ services.fedi_dk_website.domain }}" VIRTUAL_HOST: "{{ services.fedi_dk_website.domain }}"
LETSENCRYPT_HOST: "{{ services.fedi_dk_website.domain }}" LETSENCRYPT_HOST: "{{ services.fedi_dk_website.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
command: "--remote=https://git.data.coop/fedi.dk/website.git#main" command: --remote=https://git.data.coop/fedi.dk/website.git#main
capabilities: cap_add:
- NET_ADMIN - NET_ADMIN
devices: devices:
- "/dev/net/tun" - "/dev/net/tun"
networks:
external_services:
external: true

View file

@ -0,0 +1,38 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: codeberg.org/forgejo/forgejo:{{ services.forgejo.version }}
restart: unless-stopped
networks:
- external_services
- postfix
volumes:
- ".:/data"
ports:
- "22:22"
environment:
VIRTUAL_HOST: "{{ services.forgejo.domain }}"
VIRTUAL_PORT: "3000"
LETSENCRYPT_HOST: "{{ services.forgejo.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
# Forgejo customization, see: https://docs.gitea.io/en-us/install-with-docker/#customization
# https://docs.gitea.io/en-us/config-cheat-sheet/#security-security
FORGEJO__mailer__ENABLED: true
FORGEJO__mailer__FROM: noreply@{{ services.forgejo.domain }}
FORGEJO__mailer__PROTOCOL: smtp
FORGEJO__mailer__SMTP_ADDR: "{{ smtp_host }}"
FORGEJO__mailer__SMTP_PORT: "{{ smtp_port }}"
FORGEJO__security__LOGIN_REMEMBER_DAYS: "60"
FORGEJO__security__PASSWORD_COMPLEXITY: off
FORGEJO__security__MIN_PASSWORD_LENGTH: "8"
FORGEJO__security__PASSWORD_CHECK_PWN: true
FORGEJO__service__ENABLE_NOTIFY_MAIL: true
FORGEJO__service__REGISTER_EMAIL_CONFIRM: true
networks:
external_services:
external: true
postfix:
external: true

View file

@ -0,0 +1,44 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
db:
image: postgres:{{ services.hedgedoc.postgres_version }}
restart: unless-stopped
volumes:
- "./db:/var/lib/postgresql/data"
environment:
POSTGRES_USER: codimd
POSTGRES_PASSWORD: "{{ postgres_passwords.hedgedoc }}"
POSTGRES_DB: codimd
app:
image: quay.io/hedgedoc/hedgedoc:{{ services.hedgedoc.version }}
volumes:
- "./hedgedoc/uploads:/hedgedoc/public/uploads"
- "./sso.data.coop.pem:/sso.data.coop.pem"
restart: unless-stopped
networks:
- default
- external_services
environment:
CMD_DB_URL: postgres://codimd:{{ postgres_passwords.hedgedoc }}@db:5432/codimd
CMD_DOMAIN: "{{ services.hedgedoc.domain }}"
CMD_ALLOW_EMAIL_REGISTER: False
CMD_IMAGE_UPLOAD_TYPE: filesystem
CMD_EMAIL: False
CMD_SAML_IDPCERT: /sso.data.coop.pem
CMD_SAML_IDPSSOURL: https://{{ services.keycloak.domain }}/auth/realms/datacoop/protocol/saml
CMD_SAML_ISSUER: hedgedoc
CMD_SAML_IDENTIFIERFORMAT: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
CMD_USECDN: false
CMD_PROTOCOL_USESSL: true
VIRTUAL_HOST: "{{ services.hedgedoc.domain }}"
LETSENCRYPT_HOST: "{{ services.hedgedoc.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
depends_on:
- db
networks:
external_services:
external: true

View file

@ -0,0 +1,42 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
db:
image: postgres:{{ services.keycloak.postgres_version }}
restart: unless-stopped
volumes:
- "./data:/var/lib/postgresql/data"
environment:
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: "{{ postgres_passwords.keycloak }}"
POSTGRES_DB: keycloak
app:
image: quay.io/keycloak/keycloak:{{ services.keycloak.version }}
restart: unless-stopped
networks:
- default
- postfix
- external_services
command:
- "start"
- "--db=postgres"
- "--db-url=jdbc:postgresql://db:5432/keycloak"
- "--db-username=keycloak"
- "--db-password={{ postgres_passwords.keycloak }}"
- "--hostname={{ services.keycloak.domain }}"
- "--proxy=edge"
- "--https-port=8080"
- "--http-relative-path=/auth"
environment:
VIRTUAL_HOST: "{{ services.keycloak.domain }}"
VIRTUAL_PORT: "8080"
LETSENCRYPT_HOST: "{{ services.keycloak.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
postfix:
external: true
external_services:
external: true

View file

@ -0,0 +1,146 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
postgres:
image: postgres:{{ services.mailu.postgres_version }}
restart: unless-stopped
environment:
POSTGRES_DB: mailu
POSTGRES_USER: mailu
POSTGRES_PASSWORD: "{{ postgres_passwords.mailu }}"
volumes:
- "./postgres:/var/lib/postgresql/data"
dns:
- "{{ services.mailu.dns }}"
redis:
image: redis:{{ services.mailu.redis_version }}
restart: unless-stopped
volumes:
- "./redis:/data"
depends_on:
- resolver
dns:
- "{{ services.mailu.dns }}"
front:
image: ghcr.io/mailu/nginx:{{ services.mailu.version }}
restart: unless-stopped
env_file: mailu.env
environment:
VIRTUAL_HOST: "{{ services.mailu.domain }}"
LETSENCRYPT_HOST: "{{ services.mailu.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
volumes:
- "./certs:/certs"
- "./overrides/nginx:/overrides:ro"
expose:
- "80"
ports:
- "25:25"
- "465:465"
- "587:587"
- "110:110"
- "995:995"
- "143:143"
- "993:993"
networks:
- default
- webmail
- external_services
depends_on:
- resolver
dns:
- "{{ services.mailu.dns }}"
resolver:
image: ghcr.io/mailu/unbound:{{ services.mailu.version }}
restart: unless-stopped
env_file: mailu.env
networks:
default:
ipv4_address: "{{ services.mailu.dns }}"
admin:
image: ghcr.io/mailu/admin:{{ services.mailu.version }}
restart: unless-stopped
env_file: mailu.env
volumes:
- "./data:/data"
- "./dkim:/dkim"
networks:
default:
aliases:
- admin.mailu
depends_on:
- redis
- resolver
dns:
- "{{ services.mailu.dns }}"
imap:
image: ghcr.io/mailu/dovecot:{{ services.mailu.version }}
restart: unless-stopped
env_file: mailu.env
volumes:
- "./mail:/mail"
- "./overrides/dovecot:/overrides:ro"
depends_on:
- front
- resolver
dns:
- "{{ services.mailu.dns }}"
smtp:
image: ghcr.io/mailu/postfix:{{ services.mailu.version }}
restart: unless-stopped
env_file: mailu.env
volumes:
- "./mailqueue:/queue"
- "./overrides/postfix:/overrides:ro"
depends_on:
- front
- resolver
dns:
- "{{ services.mailu.dns }}"
antispam:
image: ghcr.io/mailu/rspamd:{{ services.mailu.version }}
hostname: antispam
restart: unless-stopped
env_file: mailu.env
volumes:
- "./filter:/var/lib/rspamd"
- "./overrides/rspamd:/overrides:ro"
depends_on:
- front
- redis
- resolver
dns:
- "{{ services.mailu.dns }}"
webmail:
image: ghcr.io/mailu/webmail:{{ services.mailu.version }}
restart: unless-stopped
env_file: mailu.env
volumes:
- "./webmail:/data"
- "./overrides/snappymail:/overrides:ro"
networks:
- webmail
depends_on:
- front
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: "{{ services.mailu.subnet }}"
webmail:
driver: bridge
external_services:
external: true

View file

@ -0,0 +1,146 @@
# vim: ft=yaml.docker-compose
x-sidekiq: &sidekiq
image: tootsuite/mastodon:{{ services.mastodon.version }}
restart: always
env_file: mastodon.env
networks:
- default
- postfix
- external_services
volumes:
- "./mastodon_data:/mastodon/public/system"
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
version: "3.8"
services:
db:
restart: always
image: postgres:{{ services.mastodon.postgres_version }}
shm_size: 256mb
volumes:
- "./postgres_data:/var/lib/postgresql/data"
- "./postgres_config:/config:ro"
command: postgres -c config_file=/config/postgresql.conf
environment:
POSTGRES_HOST_AUTH_METHOD: trust
healthcheck:
test: ['CMD', 'pg_isready', '-U', 'postgres']
redis:
restart: always
image: redis:{{ services.mastodon.redis_version }}
volumes:
- "./redis_data:/data"
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
web:
image: tootsuite/mastodon:{{ services.mastodon.version }}
restart: always
env_file: mastodon.env
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- default
- external_services
volumes:
- "./mastodon_data:/mastodon/public/system"
environment:
MAX_THREADS: 10
WEB_CONCURRENCY: 3
VIRTUAL_HOST: "{{ services.mastodon.domain }}"
VIRTUAL_PORT: "3000"
VIRTUAL_PATH: /
LETSENCRYPT_HOST: "{{ services.mastodon.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
healthcheck:
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
streaming:
image: tootsuite/mastodon:{{ services.mastodon.version }}
restart: always
env_file: mastodon.env
command: node ./streaming
networks:
- default
- external_services
ports:
- "127.0.0.1:4000:4000"
environment:
DB_POOL: 15
VIRTUAL_HOST: "{{ services.mastodon.domain }}"
VIRTUAL_PORT: "4000"
VIRTUAL_PATH: "/api/v1/streaming"
healthcheck:
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
# sidekiq-default-push-pull: DB_POOL = 25, -c 25 for 25 connections
sidekiq-default-push-pull:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q default -q push -q pull
environment:
DB_POOL: 25
# sidekiq-default-pull-push: DB_POOL = 25, -c 25 for 25 connections
sidekiq-default-pull-push:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q default -q pull -q push
environment:
DB_POOL: 25
# sidekiq-pull-default-push: DB_POOL = 25, -c 25 for 25 connections
sidekiq-pull-default-push:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q pull -q default -q push
environment:
DB_POOL: 25
# sidekiq-push-default-pull: DB_POOL = 25, -c 25 for 25 connections
sidekiq-push-default-pull:
<<: *sidekiq
command: bundle exec sidekiq -c 25 -q push -q default -q pull
environment:
DB_POOL: 25
# sidekiq-push-scheduler: DB_POOL = 5, -c 5 for 5 connections
sidekiq-push-scheduler:
<<: *sidekiq
command: bundle exec sidekiq -c 5 -q push -q scheduler
environment:
DB_POOL: 5
# sidekiq-push-mailers: DB_POOL = 5, -c 5 for 5 connections
sidekiq-push-mailers:
<<: *sidekiq
command: bundle exec sidekiq -c 5 -q push -q mailers
environment:
DB_POOL: 5
# sidekiq-push-ingress: DB_POOL = 10, -c 10 for 10 connections
sidekiq-push-ingress:
<<: *sidekiq
command: bundle exec sidekiq -c 10 -q push -q ingress
environment:
DB_POOL: 10
networks:
external_services:
external: true
postfix:
external: true

View file

@ -0,0 +1,36 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
postgres:
image: postgres:{{ services.matrix.postgres_version }}
restart: unless-stopped
volumes:
- "./db:/var/lib/postgresql/data"
environment:
POSTGRES_USER: synapse
POSTGRES_PASSWORD: "{{ postgres_passwords.matrix }}"
synapse:
image: matrixdotorg/synapse:{{ services.matrix.version }}
restart: unless-stopped
networks:
- default
- external_services
- postfix
volumes:
- "./data:/data"
environment:
SYNAPSE_CONFIG_PATH: /data/homeserver.yaml
SYNAPSE_CACHE_FACTOR: "2"
SYNAPSE_LOG_LEVEL: INFO
VIRTUAL_HOST: "{{ services.matrix.domain }}"
VIRTUAL_PORT: "8008"
LETSENCRYPT_HOST: "{{ services.matrix.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true
postfix:
external: true

View file

@ -0,0 +1,44 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: docker.data.coop/membersystem:{{ services.membersystem.version }}
restart: always
user: "$UID:$GID"
tty: true
networks:
- default
- external_services
- postfix
environment:
SECRET_KEY: "{{ membersystem_secrets.secret_key }}"
DATABASE_URL: postgres://postgres:{{ postgres_passwords.membersystem }}@postgres:5432/postgres
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
EMAIL_BACKEND: django.core.mail.backends.smtp.EmailBackend
EMAIL_URL: smtp://noop@{{ smtp_host }}:{{ smtp_port }}
VIRTUAL_HOST: "{{ services.membersystem.domain }}"
VIRTUAL_PORT: "8000"
LETSENCRYPT_HOST: "{{ services.membersystem.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
ALLOWED_HOSTS: "{{ services.membersystem.domain }}"
CSRF_TRUSTED_ORIGINS: https://{{ services.membersystem.domain }}
DJANGO_ADMINS: "{{ services.membersystem.django_admins }}"
DEFAULT_FROM_EMAIL: noreply@{{ services.membersystem.domain }}
depends_on:
- postgres
postgres:
image: postgres:{{ services.membersystem.postgres_version }}
restart: always
volumes:
- "./postgres/data:/var/lib/postgresql/data"
environment:
POSTGRES_PASSWORD: "{{ postgres_passwords.membersystem }}"
networks:
external_services:
external: true
postfix:
external: true

View file

@ -0,0 +1,36 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: netdata/netdata:{{ services.netdata.version }}
restart: unless-stopped
hostname: hevonen.servers.{{ base_domain }}
volumes:
- "/proc:/host/proc:ro"
- "/sys:/host/sys:ro"
- "/etc/os-release:/host/etc/os-release:ro"
networks:
- default
- external_services
environment:
VIRTUAL_HOST : "{{ services.netdata.domain }}"
LETSENCRYPT_HOST: "{{ services.netdata.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
PGID: "999"
DOCKER_HOST: "socket_proxy:2375"
cap_add:
- SYS_PTRACE
security_opt:
- apparmor:unconfined
socket-proxy:
image: tecnativa/docker-socket-proxy:latest
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
environment:
CONTAINERS: 1
networks:
external_services:
external: true

View file

@ -0,0 +1,59 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
postgres:
image: postgres:{{ services.nextcloud.postgres_version }}
restart: unless-stopped
volumes:
- "./postgres:/var/lib/postgresql/data"
environment:
POSTGRES_DB: nextcloud
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"
POSTGRES_USER: nextcloud
redis:
image: redis:{{ services.nextcloud.redis_version }}
restart: unless-stopped
command: redis-server --requirepass {{ nextcloud_secrets.redis_password }}
tmpfs:
- /var/lib/redis
cron:
image: nextcloud:{{ services.nextcloud.version }}
restart: unless-stopped
entrypoint: /cron.sh
volumes:
- "./app:/var/www/html"
depends_on:
- postgres
- redis
app:
image: nextcloud:{{ services.nextcloud.version }}
restart: unless-stopped
networks:
- default
- postfix
- external_services
volumes:
- "./app:/var/www/html"
environment:
VIRTUAL_HOST: "{{ services.nextcloud.domain }}"
LETSENCRYPT_HOST: "{{ services.nextcloud.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
POSTGRES_HOST: postgres
POSTGRES_DB: nextcloud
POSTGRES_USER: nextcloud
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"
REDIS_HOST: redis
REDIS_HOST_PASSWORD: "{{ nextcloud_secrets.redis_password }}"
depends_on:
- postgres
- redis
networks:
postfix:
external: true
external_services:
external: true

View file

@ -0,0 +1,38 @@
version: "3.8"
services:
proxy:
image: nginxproxy/nginx-proxy:{{ services.nginx_proxy.version }}
restart: always
networks:
- external_services
ports:
- "80:80"
- "443:443"
volumes:
- "./conf:/etc/nginx/conf.d"
- "./vhost:/etc/nginx/vhost.d"
- "./html:/usr/share/nginx/html"
- "./dhparam:/etc/nginx/dhparam"
- "./certs:/etc/nginx/certs:ro"
- "/var/run/docker.sock:/tmp/docker.sock:ro"
labels:
- com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
{% if letsencrypt_enabled %}
acme:
image: nginxproxy/acme-companion:{{ services.nginx_proxy.acme_companion_version }}
restart: always
volumes:
- "./vhost:/etc/nginx/vhost.d"
- "./html:/usr/share/nginx/html"
- "./dhparam:/etc/nginx/dhparam:ro"
- "./certs:/etc/nginx/certs"
- /var/run/docker.sock:/var/run/docker.sock:ro
depends_on:
- proxy
{% endif %}
networks:
external_services:
external: true

View file

@ -0,0 +1,58 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: osixia/openldap:{{ services.openldap.version }}
restart: unless-stopped
tty: true
stdin_open: true
volumes:
- "./var/lib/ldap:/var/lib/ldap"
- "./etc/slapd.d:/etc/ldap/slapd.d"
- "./certs:/container/service/slapd/assets/certs/"
ports:
- "389:389"
- "636:636"
hostname: "{{ services.openldap.domain }}"
domainname: "{{ services.openldap.domain }}" # important: same as hostname
environment:
LDAP_LOG_LEVEL: "256"
LDAP_ORGANISATION: "{{ base_domain }}"
LDAP_DOMAIN: "{{ base_domain }}"
LDAP_BASE_DN: ""
LDAP_ADMIN_PASSWORD: "{{ ldap_admin_password }}"
LDAP_CONFIG_PASSWORD: "{{ ldap_config_password }}"
LDAP_READONLY_USER: false
LDAP_RFC2307BIS_SCHEMA: false
LDAP_BACKEND: mdb
LDAP_TLS: true
LDAP_TLS_CRT_FILENAME: ldap.crt
LDAP_TLS_KEY_FILENAME: ldap.key
LDAP_TLS_CA_CRT_FILENAME: ca.crt
LDAP_TLS_ENFORCE: false
LDAP_TLS_CIPHER_SUITE: SECURE256:-VERS-SSL3.0
LDAP_TLS_PROTOCOL_MIN: "3.1"
LDAP_TLS_VERIFY_CLIENT: demand
LDAP_REPLICATION: false
KEEP_EXISTING_CONFIG: false
LDAP_REMOVE_CONFIG_AFTER_SETUP: true
LDAP_SSL_HELPER_PREFIX: ldap
admin:
image: osixia/phpldapadmin:{{ services.openldap.phpldapadmin_version }}
restart: unless-stopped
networks:
- default
- external_services
environment:
PHPLDAPADMIN_LDAP_HOSTS: app
PHPLDAPADMIN_HTTPS: false
PHPLDAPADMIN_TRUST_PROXY_SSL: true
VIRTUAL_HOST: "{{ services.openldap.domain }}"
LETSENCRYPT_HOST: "{{ services.openldap.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -0,0 +1,38 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
db:
image: postgres:{{ services.passit.postgres_version }}
restart: always
volumes:
- "./data:/var/lib/postgresql/data"
environment:
POSTGRES_USER: passit
POSTGRES_PASSWORD: "{{ postgres_passwords.passit }}"
app:
image: passit/passit:{{ services.passit.version }}
command: bin/start.sh
restart: always
networks:
- default
- postfix
- external_services
environment:
DATABASE_URL: postgres://passit:{{ postgres_passwords.passit }}@db:5432/passit
SECRET_KEY: "{{ passit_secret_key }}"
IS_DEBUG: "False"
EMAIL_URL: smtp://noop@{{ smtp_host }}:{{ smtp_port }}
DEFAULT_FROM_EMAIL: noreply@{{ services.passit.domain }}
EMAIL_CONFIRMATION_HOST: https://{{ services.passit.domain }}
FIDO_SERVER_ID: "{{ services.passit.domain }}"
VIRTUAL_HOST: "{{ services.passit.domain }}"
LETSENCRYPT_HOST: "{{ services.passit.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
postfix:
external: true
external_services:
external: true

View file

@ -0,0 +1,21 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: portainer/portainer-ee:{{ services.portainer.version }}
restart: always
networks:
- external_services
volumes:
- ".:/data"
- "/var/run/docker.sock:/var/run/docker.sock:rw"
environment:
VIRTUAL_HOST: "{{ services.portainer.domain }}"
VIRTUAL_PORT: "9000"
LETSENCRYPT_HOST: "{{ services.portainer.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -0,0 +1,22 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: boky/postfix:{{ services.postfix.version }}
restart: always
networks:
postfix:
aliases:
- postfix
volumes:
- "./dkim:/etc/opendkim/keys"
environment:
# Get all services which have allowed_sender_domain defined
ALLOWED_SENDER_DOMAINS: "{{ services | dict2items | selectattr('value.allowed_sender_domain', 'true') | map(attribute='value.domain') | join(' ') }}"
HOSTNAME: "{{ services.postfix.domain }}" # the name the smtp server will identify itself as
DKIM_AUTOGENERATE: true
networks:
postfix:
external: true

View file

@ -0,0 +1,20 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
app:
image: jgeusebroek/privatebin:{{ services.privatebin.version }}
restart: unless-stopped
volumes:
- "./cfg:/privatebin/cfg"
- "./data:/privatebin/data"
networks:
- external_services
environment:
VIRTUAL_HOST: "{{ services.privatebin.domain }}"
LETSENCRYPT_HOST: "{{ services.privatebin.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -0,0 +1,41 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
db:
image: postgres:{{ services.rallly.postgres_version }}
restart: always
shm_size: 256mb
volumes:
- "./postgres:/var/lib/postgresql/data"
environment:
POSTGRES_PASSWORD: "{{ postgres_passwords.rallly }}"
POSTGRES_DB: rallly_db
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
app:
image: lukevella/rallly:{{ services.rallly.version }}
restart: always
networks:
- default
- external_services
- postfix
env_file: rallly.env
environment:
VIRTUAL_HOST: "{{ services.rallly.domain }}"
VIRTUAL_PORT: "3000"
LETSENCRYPT_HOST: "{{ services.rallly.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
depends_on:
db:
condition: service_healthy
networks:
external_services:
external: true
postfix:
external: true

View file

@ -0,0 +1,48 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
backup:
image: mazzolino/restic:{{ services.restic.version }}
restart: always
environment:
RUN_ON_STARTUP: false
BACKUP_CRON: "0 30 3 * * *"
RESTIC_REPOSITORY: sftp:{{ services.restic.remote_user }}@{{ services.restic.remote_domain }}:{{ services.restic.repository }}
RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}"
RESTIC_BACKUP_SOURCES: /mnt/volumes
RESTIC_BACKUP_ARGS: >-
--tag datacoop-volumes
--exclude '*.tmp'
--exclude '/mnt/volumes/mastodon/mastodon_data/cache/'
--exclude '/mnt/volumes/restic/'
--verbose
RESTIC_FORGET_ARGS: >-
--keep-last 10
--keep-daily 7
--keep-weekly 5
--keep-monthly 12
TZ: Europe/Copenhagen
POST_COMMANDS_FAILURE: /run/libexec/failure.sh
POST_COMMANDS_SUCCESS: /run/libexec/success.sh
volumes:
- "./ssh:/run/secrets/.ssh:ro"
- "./scripts:/run/libexec:ro"
- "/docker-volumes:/mnt/volumes:ro"
networks:
- postfix
prune:
image: mazzolino/restic:{{ services.restic.version }}
environment:
RUN_ON_STARTUP: false
PRUNE_CRON: "0 30 4 * * *"
RESTIC_REPOSITORY: sftp:{{ services.restic.remote_user }}@{{ services.restic.remote_domain }}:{{ services.restic.repository }}
RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}"
TZ: Europe/copenhagen
volumes:
- "./ssh:/run/secrets/.ssh:ro"
networks:
postfix:
external: true

View file

@ -0,0 +1,22 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
web:
image: docker.data.coop/unipi:{{ services.slides_2022_website.version }}
restart: unless-stopped
networks:
- external_services
environment:
VIRTUAL_HOST: "{{ services.slides_2022_website.domain }}"
LETSENCRYPT_HOST: "{{ services.slides_2022_website.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
command: --remote=https://git.data.coop/data.coop/slides.git#slides2022
cap_add:
- NET_ADMIN
devices:
- "/dev/net/tun"
networks:
external_services:
external: true

View file

@ -0,0 +1,17 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
web:
image: ulovliglogning/ulovliglogning.dk:latest
restart: unless-stopped
networks:
- external_services
environment:
VIRTUAL_HOST: "{{ services.ulovliglogning_website.domains | join(',') }}"
LETSENCRYPT_HOST: "{{ services.ulovliglogning_website.domains | join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

View file

@ -0,0 +1,21 @@
# vim: ft=yaml.docker-compose
version: '3.3'
services:
uptime-kuma:
image: "louislam/uptime-kuma:{{ services.uptime_kuma.version }}"
restart: always
container_name: uptime-kuma
networks:
- external_services
volumes:
- "./uptime-kuma-data:/app/data"
environment:
VIRTUAL_HOST: "{{ services.uptime_kuma.domain }},{{ services.uptime_kuma.status_domain }}"
LETSENCRYPT_HOST: "{{ services.uptime_kuma.domain }},{{ services.uptime_kuma.status_domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external: true

Some files were not shown because too many files have changed in this diff Show more