Compare commits

..

3 Commits

123 changed files with 1949 additions and 2823 deletions

View File

@ -1,111 +0,0 @@
---
# .ansible-lint
profile: null # min, basic, moderate,safety, shared, production
# exclude_paths included in this file are parsed relative to this file's location
# and not relative to the CWD of execution. CLI arguments passed to the --exclude
# option are parsed relative to the CWD of execution.
exclude_paths:
- .cache/ # implicit unless exclude_paths is defined in config
- .github/
- test/fixtures/formatting-before/
- test/fixtures/formatting-prettier/
# parseable: true
# quiet: true
# strict: true
# verbosity: 1
# Mock modules or roles in order to pass ansible-playbook --syntax-check
mock_modules:
- zuul_return
# note the foo.bar is invalid as being neither a module or a collection
- fake_namespace.fake_collection.fake_module
- fake_namespace.fake_collection.fake_module.fake_submodule
mock_roles:
- mocked_role
- author.role_name # old standalone galaxy role
- fake_namespace.fake_collection.fake_role # role within a collection
# Enable checking of loop variable prefixes in roles
loop_var_prefix: "{role}_"
# Enforce variable names to follow pattern below, in addition to Ansible own
# requirements, like avoiding python identifiers. To disable add `var-naming`
# to skip_list.
# var_naming_pattern: "^[a-z_][a-z0-9_]*$"
use_default_rules: true
# Load custom rules from this specific folder
# rulesdir:
# - ./rule/directory/
# Ansible-lint completely ignores rules or tags listed below
skip_list:
- skip_this_tag
# Ansible-lint does not automatically load rules that have the 'opt-in' tag.
# You must enable opt-in rules by listing each rule 'id' below.
enable_list:
- empty-string-compare # opt-in
- no-log-password # opt-in
- no-same-owner # opt-in
# add yaml here if you want to avoid ignoring yaml checks when yamllint
# library is missing. Normally its absence just skips using that rule.
- yaml
# Report only a subset of tags and fully ignore any others
# tags:
# - jinja[spacing]
# Ansible-lint does not fail on warnings from the rules or tags listed below
warn_list:
- skip_this_tag
- experimental # experimental is included in the implicit list
# - role-name
# - yaml[document-start] # you can also use sub-rule matches
# Some rules can transform files to fix (or make it easier to fix) identified
# errors. `ansible-lint --write` will reformat YAML files and run these transforms.
# By default it will run all transforms (effectively `write_list: ["all"]`).
# You can disable running transforms by setting `write_list: ["none"]`.
# Or only enable a subset of rule transforms by listing rules/tags here.
# write_list:
# - all
# Offline mode disables installation of requirements.yml
offline: false
# Return success if number of violations compared with previous git
# commit has not increased. This feature works only in git
# repositories.
progressive: false
# Define required Ansible's variables to satisfy syntax check
extra_vars:
foo: bar
multiline_string_variable: |
line1
line2
complex_variable: ":{;\t$()"
# Uncomment to enforce action validation with tasks, usually is not
# needed as Ansible syntax check also covers it.
# skip_action_validation: false
# List of additional kind:pattern to be added at the top of the default
# match list, first match determines the file kind.
kinds:
# - playbook: "**/examples/*.{yml,yaml}"
# - galaxy: "**/folder/galaxy.yml"
# - tasks: "**/tasks/*.yml"
# - vars: "**/vars/*.yml"
# - meta: "**/meta/main.yml"
- yaml: "**/*.yaml-too"
# List of additional collections to allow in only-builtins rule.
# only_builtins_allow_collections:
# - example_ns.example_collection
# List of additions modules to allow in only-builtins rule.
# only_builtins_allow_modules:
# - example_module

4
.gitignore vendored
View File

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

View File

@ -1,14 +0,0 @@
repos:
#- repo: https://github.com/semaphor-dk/dansabel
# rev: b72c70351d1a9e32a75db505fcb3aa414f3282f8
# hooks:
# - id: dansabel
- repo: https://github.com/ansible/ansible-lint
rev: v6.9.0
hooks:
- id: ansible-lint
files: \.(yaml|yml)$
additional_dependencies:
- ansible

View File

@ -1,12 +0,0 @@
init: create_venv install_pre_commit install_ansible_galaxy_modules
create_venv:
python3 -m venv venv
venv/bin/pip install -U pip
venv/bin/pip install ansible pre-commit
install_pre_commit:
venv/bin/pre-commit install
install_ansible_galaxy_modules:
venv/bin/ansible-galaxy collection install community.general

108
README.md
View File

@ -1,108 +0,0 @@
# data.coop infrastructure
This repository contains the code used to deploy data.coop's services
and websites. We use Ansible to encode our infrastructure setup. Only
the association's administrators have access to deploy the services.
## Deploying
To deploy the services, the included `deploy.sh` script can be used. The
Ansible playbook uses two custom-made roles (in the `roles/` directory):
- `ubuntu_base` - used to configure the host itself and install the
necessary packages
- `docker` - used to deploy our services and websites with Docker
containers
The script has options to deploy only one of the roles. Select services
only can also be specified. By default, the script deploys everything.
Here is a summary of the options that can be used with the script:
```sh
# deploy everything
./deploy.sh
# deploy the ubuntu_base role only
./deploy.sh base
# deploy user setup only
./deploy.sh users
# deploy the docker role only
./deploy.sh services
# deploy SINGLE_SERVICE Docker service only
./deploy.sh services SINGLE_SERVICE
```
`SINGLE_SERVICE` should match one of the service names in the `services`
dictionary in `roles/docker/defaults/main.yml` (e.g. `gitea` or
`data_coop_website`).
## Testing
In order for us to be able to test our setup locally, we use Vagrant to
deploy the services in a virtual machine. To do this, Vagrant and
VirtualBox must both be installed on the development machine. Then, the
services can be deployed locally by using the `vagrant` command-line
tool. The working directory needs to be the root of the repository for
this to work properly.
> Note: As our secrets are contained in an Ansible Vault file, only the
> administrators have the ability to run the deployment in Vagrant.
> However, one could replace the vault file for testing purposes.
Here is a summary of the commands that are available with the `vagrant`
command-line tool:
```sh
# Create and provision the VM
vagrant up
# Re-provision the VM
vagrant provision
# SSH into the VM
vagrant ssh
# Power down the VM
vagrant halt
# Power down and delete the VM
vagrant destroy
```
The `vagrant` command-line tool does not support supplying extra
variables to Ansible on runtime, so to be able to deploy only parts of
the Ansible playbook to Vagrant, the `deploy.sh` script can be used with
the `--vagrant` flag. Here are some examples:
```sh
# deploy the ubuntu_base role only in the Vagrant VM
./deploy.sh --vagrant base
# deploy SINGLE_SERVICE Docker service only in the Vagrant VM
./deploy.sh --vagrant services SINGLE_SERVICE
```
Note that the `--vagrant` flag should be the first argument when using
the script.
## Contributing
If you want to contribute, you can fork the repository and submit a pull
request. We use a pre-commit hook for linting the YAML files before
every commit, so please use that. To initialize pre-commit, you need to
have Python and GNU make installed. Then, just run the following shell
command:
```sh
make init
```
## Nice tools
- [J2Live](https://j2live.ttl255.com/): A live Jinja2 parser, nice to
test out filters

48
Vagrantfile vendored
View File

@ -1,38 +1,24 @@
Vagrant.require_version ">= 2.0.0"
PORT = 19022
def provisioned?(vm="default", provider="virtualbox")
File.exist?(".vagrant/machines/#{vm}/#{provider}/action_provision")
end
Vagrant.require_version ">= 1.7.0"
Vagrant.configure(2) do |config|
config.vm.network :private_network, ip: "192.168.56.10"
config.vm.network :forwarded_port, guest: PORT, host: PORT
config.vm.box = "ubuntu/focal64"
config.vm.hostname = "datacoop"
config.vm.provider :virtualbox do |v|
v.cpus = 8
v.memory = 16384
end
config.vm.provision :ansible do |ansible|
ansible.compatibility_mode = "2.0"
ansible.playbook = "playbook.yml"
ansible.ask_vault_pass = true
ansible.verbose = "v"
# If the VM is already provisioned, we need to use the new port
if provisioned?
config.ssh.guest_port = PORT
ansible.extra_vars = {
ansible_port: PORT,
from_vagrant: true
config.vm.define "datacoop" do |datacoop|
datacoop.vm.box = "ubuntu/bionic64"
datacoop.vm.hostname = "datacoop"
datacoop.vm.provider "virtualbox" do |v|
v.memory = 4096
end
datacoop.vm.network "private_network", ip: "192.168.0.42"
datacoop.vm.provision "ansible" do |ansible|
ansible.verbose = "v"
ansible.compatibility_mode = "2.0"
ansible.playbook = "playbook.yml"
ansible.ask_vault_pass = true
ansible.host_vars = {
"datacoop" => {"ansible_python_interpreter" => "/usr/bin/python3.6"}
}
else
ansible.extra_vars = {
from_vagrant: true
ansible.groups = {
"all" => ["datacoop"]
}
end
end

View File

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

View File

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

View File

@ -1,26 +1,6 @@
#!/bin/sh
usage () {
{
echo "Usage: $0 [--vagrant]"
echo "Usage: $0 [--vagrant] base"
echo "Usage: $0 [--vagrant] users"
echo "Usage: $0 [--vagrant] services [SERVICE]"
} >&2
}
BASE_CMD="ansible-playbook playbook.yml"
if [ "$1" = "--vagrant" ]; then
BASE_CMD="$BASE_CMD --verbose --inventory=vagrant_host"
VAGRANT_VAR="from_vagrant"
shift
fi
if [ -z "$(ansible-galaxy collection list community.general 2>/dev/null)" ]; then
echo "Installing community.general modules"
ansible-galaxy collection install community.general
fi
BASE_CMD="ansible-playbook playbook.yml -i datacoop_hosts --ask-vault-pass"
if [ -z "$1" ]; then
echo "Deploying all!"
@ -30,21 +10,10 @@ else
"services")
if [ -z "$2" ]; then
echo "Deploying all services!"
eval "$BASE_CMD --tags setup_services $(test -z "$VAGRANT_VAR" || printf '%s' "$VAGRANT_VAR=true")"
$BASE_CMD --tags setup_services
else
echo "Deploying service: $2"
$BASE_CMD --tags setup_services --extra-vars '{"single_service": "'"$2"'"'"$(test -z "$VAGRANT_VAR" || printf '%s' ', "'"$VAGRANT_VAR"'": true')"'}'
echo "Deploying services: $2"
$BASE_CMD --tags setup_services --extra-vars "services=$2"
fi
;;
"base")
eval "$BASE_CMD --tags base_only $(test -z "$VAGRANT_VAR" || printf '%s' "$VAGRANT_VAR=true")"
;;
"users")
eval "$BASE_CMD --tags setup-users $(test -z "$VAGRANT_VAR" || printf '%s' "$VAGRANT_VAR=true")"
;;
*)
usage
exit 1
;;
esac
fi

View File

@ -1,170 +1,87 @@
$ANSIBLE_VAULT;1.1;AES256
30613439636234396439623634656338666330643936373563656336323831353464353239353661
6234316535383838653865643964353033623935313432630a666563316534343733363464396635
34396664643137643136633837656432623633383361633336343562333039326538393034616637
6634613631636433610a663835343739376534356133323163343132323233643135613333313132
65373233666535366137343839363938303561653731633038376631386161653038613631396364
33636131636536306134346336636332393436303063306262333430613137376438626133353963
66396332363335333436623335613966323730616139353762656662386530356435623831656632
30333363376132653362323339386437346134323232363336363461323332613962613131386264
37383435653061653466613834346430656632626338316564656136666266353231363661666461
32646461313365626232376536376463313531613861363462643062326538326234613332646430
33383438613961623134343665383638346164653031363435656162306163653232353162343431
38333239393332613466663231383932316330376535383466643233326134623530306361393639
63386530643733393033646139613730313239313866343730643337393533366330373363353338
62313739613531636166663135646262396334373538636634393534616337363337323630666261
39643164363437653661633666376431303662396431633661663933343666613234326637636231
38383537333532326636343366343564646630363838323162373339323365666262303836636232
31343637616261636130656637393633383165353332346239323063646162306235313962363935
64633639653261363563646664393630666564646165393736363562623231626634326163306630
37613635306136643334616364303439323332666431386264623265323636623738303364396636
37626161363466646166633434333265623236633033666562643264303662333363396631646638
36626636363261313966393235313866353936323064343331626362306162323166323063656433
63303762346330323031353034356162373433356436663134373930633634366330653233613139
63363639343833616431633765613938623037323961623663336662666135313466303661316133
39353664633036323031373862393530653433373062623233313965653735353566306538393439
30366162663138326535346639393337393362366630343266643035353465663332333539613337
30666666363134313239306231356663343166363137366636643931313039333732383833313036
37393064396662623063613462336363386336393839313465323062646535373733326338353766
31666639303836316266343764336462343765363930326338313635336633323662366238356264
38613631313434383830333031643938393566633236383861633266326336653033663163336132
61313132643062666434346333653234393865656463343363313636613364616361353561343739
38313231333431303664323730626162613264343630356438336636373739653234336666646438
37636437623336323461613063396137396533353265333034333435306666636261353933613232
65363632383039666666323030323830333534376362326136313232393732613166303461383933
62303166396533616538666566356238393265663163343264333664393936613066313665616137
38613030623937633730646461666233333035323661363835313161613930336237396332623338
30666166636662613130363430333436613532326437393730376536353963356633393736303065
31393534646537323037316664313438643836386333613961663031383231663932633934656461
62313163616635626131663961326438396439383432346337386261313330343330353637376330
38346532396533326135303264613361663836646163623630323832653032396237353966663661
36353365313962663832393333336138346335363832396535346336643565366465643565616638
63616565356663623531323935393334326639626236353338643237343764366464666131393332
64396665343535323339383434366133613235313866653663313639633930323864646536346232
65316465643662376264373536393232326666663335316631376433343062646361376165363732
66326165643163333737313139386461363431353239626236366238343035386663363435366464
31633738336263633961306436613233303861633263343030336637373165663261316632663537
31613636663163323365303038373134306264343831326264326261633834393366623061616262
63393463333833393636666232626662643738653634306364326231343830633834643664353730
37346131346263356539363630363230626364663161643064323538396131636633623866383939
66346434323935353632633837363530663438636539616130633532346236343661633766383434
34343339646662393030323661623665643432376365633435666333316439356631386234303062
35346631656230346565323130333765663933373638303639363530373431343232393864656639
33666433366131396464323137393239653531376662646235343962613639343831636261326265
65663564613766313634653938316339306434663463623563316431633234323330623738646636
37643535623664323433626561383462393033343232303838333930653366376536353765613036
35663165623265616630373161336632646435613331373166303632373633313865386134636362
61636134343839643735636461626663626237613262316564646339323933363864303935353834
39396637646264633736366336616336643032313237653662646331383963366533373766356539
35306165306534393463663332336430336635666135643561303935386635393838323865623162
36323565616232353261303139623465646234313136383436376162376165303664613164356162
33373237333666616135636231653637396330663930663962636161326664333261343737343735
37313465396130653138613539376436373237343138636535626632326435383234326466363235
34646663653038396630353637636166346261346233333632363361326536383634663433613564
35633864343630333033613133626635313931333031643564396164393135346131343832363861
61366664363838653438653137383933386233633836323332643531303936353237623734666135
31356166613664636634336536343032646239643130346564303162356431346539646336323339
61626236346535336638353134353838333434663838303730613363393365633739383563613434
64336331306639323061386338656361653636353831346237373134346538623464343562393735
39333764343139333133393233626564643266373034623764633835383561366265636632633937
62343635343161363231653138613263313562366439316435633964396161343566316435303465
39666236316339653839313333396264623636663561653932386638366366663933353761353162
61343038383939396231346534336361306430373564353633653139306334623630343738636430
66376631366662313131646130363530323232383535333163363466636262363461633232343532
63626430336261353861633362396638643937623832386638626334663333363637393637373939
64303039666432303535636265613564376139333331653336666563663238366639393366363334
36303635633933333832396562373965653361303034653139643466656534326231383162336366
31656138656539383539396462326134333331653131306537643962653762373035343235333233
34373730623663346430303962653061623330653263393633383835663739663961326566323036
30336365616532303362396230616531386639333636336332366335613935623836616134393033
62653535396630383436393631396337336163323361663930323532633666663238333366383462
36393261376262643336643761613731643032626632646332366661626331333233363436613937
34653731666137313733653863396164323963383037353265373532303137623037343733616537
66336433343334626536323639636139653931383466633833326234633332613431353432343561
36626339656536383862623833633634356435393764316633353135326639623534366538313330
62633333303266613630326330333336353264343937393864393239623664323366373565383334
37383237376664643065383834633961366632643261343635336335353765353863323131653866
31326531303461323736303730623638663863353939636437636231636437323730656463633733
65383934343534383631363162363830386365313935663337366335326131393262353030663765
30643665383332613030336439346332363135366232303166623534333637366133656437643231
30306634636430643864363561316334383530613165326663326665613633636237353830393334
62653333623563626131666166646335663334393662336337333836376631303631666136376332
37316537356531346464623363653033306537636239633065646533643239653063613835363665
30383139326465613864316533643033333430326230646334353364633138666532353736313265
34623733613864646661353730666433613961643261346166303264386435643565373565323864
61346465336231613865363263303034396439346163393534666439666437353266323565653032
39386439646438313938356237643831643434666161383632316530356465616632313235643834
33303865653836303632656663366465333331616634313863656438393838636631313364633637
38646230643734393733663261326161376536643237626130353831363731306231313864613066
34623239396362336639363163313161323065653461363563353631613730373830643133336464
31336439636361363539383539323631303462633833353032373530333539336538363033383363
32613733623839623938326165356237313165383366646233393933393965613363666532646434
63316133613130313363303537366230646235663130313538333761633237383262316633366364
65373664616237316534613831313966623939396331626334313430386638653461386334363939
35333339643837666264356535643365353331393437313866643034663934336466336534343035
61313837666662343363613962623462333935353837333336363839623466303534303837396634
38656330666661356235626130303538666533666563323936633564383164633834353831306634
36343836353464623962333362353133386563343831336463646635646263383832666232323736
38613730316634373365343938623237356231643931303333366462373134383137366339613662
62643832323734363635643634373066303366306366663036623139393761636533326130313336
30316536396466383463393233363035393335343565323635333665346464366139626165636661
39363066643437613537653836636363376532643038363063383234353066313737663061363334
38306563613561663165623630366135303332636133343733343836383865613661393761333031
62653162626461616564643138613737623632313739393962396439306133646138303936636435
39393663653865363166316365376562353461633163353734343132343831386434653037323732
36356162356336616330636630376438636165653439376137313934663939376639396266323962
37383736333536653438363963316435326632393966383534326337303336386135616636363936
35393331313938653830646332376631623763383439623633396433633739663038313264323835
33373664313562366664363630316132643465363964383339363339656237323465626262306364
33306133373065303135613235623262396365363634316365356364373561363762666235666430
62336362643564313238363933623366396138646237336336623062326161326536323534326364
39316162643966616436343737313434616230346237346237363962653033613930623462386431
38343662356665383763633034393236613733643430313937326335356466376139653533333965
39386138623134666132663837616637376362303561393133656139653438386363613965393661
36343566643931393061373031343331336463643034383065383763663234373438383064303232
64666236313935346237666466333562613935646163653331303661386138313739326538353935
64323737323532663731353136336138633533386464616362333838396332323563353537613430
33633631326238366166346437316638363161386562383630623466386564323266333033313461
63666535363034613232346239636233623130393032353030363334333531646238373262323765
61373739396162643661353031613663353531653836323730326166383463613330333966336233
30386136346466336361303237303534373064353230653238363231633530613866663461643465
30396266356164353063323432663561396564636231346534366661663766613634376235356637
39313839616336666461313431326430333932623262333437386464636264373430653566386631
64653866623662363864376663613136306165393863346533303634623936373835633864313462
61333562646233303232623861366634383466633537383831626334356561353637663038643531
39386635326366646134333231653737653630356135396634326537633232333166616161653136
33393562383233656564356530386465623239386666313964343534343466616134373132636631
39666365393063323838343963366339373434353839383039383238613133636237316365323861
30626330643665626465666338353030653839383234393237623633646566376361646536353233
31393235623561323765633835313139313538343761393064353632316335656231353930656437
31313639313931636633333230653730666638373864326239333561393134356632623138366131
65356462373336383039316131626562633330666363386631383663343838393435663538343934
65386339626362623664393532386131303234633466363437383236616463343831353862323961
39663835313234326137303965663963663761656531653437343234643634316565333762663139
65393830633237623031303234636134633539316131396135616237316266333437633861303831
62656630373763343366636635653033666630613533363365636261323661383364343161343439
35626531346665656263643461306261376238353033343032353731373861333239333862653231
31336562653133623163353230633331346237356534333534613161323462636639636662623435
63633035336662376636623339326433393035646539626231363762643532323463316263393736
62613038333733636362356636373331313661663830633433643039653233626261613739663836
38643030313338383266323134326337323334343230623331386664333937316266623134336362
61373037353664623863393233376264616438656332386130316361663665323135386463383763
33303633356133353439393664363630336133306364363430393232326665393339323265383630
31656463343064383837333630366465396633393465666235626330343937313630623039383465
63326361663238653035613935343932623237396362643833313731323830313962616362613539
32346165303930323739313837643933363863643937346561643930653530393636383036613235
61376166386563643733333233343437623630323632643463353131386461663936313065313562
31393032646262386634353436643466323731366631393136393433616332613036666163336635
37303365633338613630656463663533653336666562653236336264303238383930383132346365
35386662636439653930343738633265363635626132343030653462306431363234633635643537
61666363346430653131623762666564313665653262386332396532646339383136383337353863
38386632316632373338653535323335363265653563376330663239343861346563646366313039
33306364623536346339393566326533633133393866303535326535306435626531346264616138
34356231373561633337653663643566633632393330386564393966666365306565316135646163
63366365383839343134303635376233343865663631633331333230616630366633396231333435
30366137383238393139336433353764633038616238326136663636656132626538393565393130
38653765326137393136386233383636383165613235373437353730306564643033306534386666
61623538663537653166313264303533623162356134393333373732383535386261333535383039
65613166666230336265366335323434636336663835323034373930393430363065376665666337
35363265666130653830333536326433316639613638613730666139623137333736663535633032
33363135376636636536623731323134343237393633333038393364376237386165
62393230613162353938306335363361323162356461613234306332653236326632323038663738
3832663036633166373961623738323162363532633638350a636565346534616431343862356534
62306562623663623438623263636262303938303562343463333365613834623434623232303531
6135343464616438360a383163343838323762626435346564313364376566356638623165363537
65616337373633613530393361613561333939666131316366303761303964343762306462633038
36303332336633653432613036346332663863376531623561343433383662623861633862363230
65316536626365303764393839626364326539336637643631336439653761633730636562653066
62353637633365336237663935383937633732363830623232376463326132353062336232363539
64376632616631353138376263383162353866316366316562666538383538633038373535663033
32663363383037666663373335306138623032343939313436656531616234303763396630663639
66656538393538666166386635643563633465306662366436383936306233376361663331353630
64333731396134646236653963356435656535613365353635383734346131383066356431663061
37333533623439623164323738363035633664353831363162376331613965613635653663303339
36623035633865633131363061346366643865636433303733613731643863333764313135616433
30396636653734656631323562343330653839346461653037353439636135316134396533383731
62303164366366616163656462346264383633353164333335613034363636373339613538376166
38333238666334656632376465346538323938653661656130313232656137316463346430663134
36636465356661666138616530326436326238383834336635663963363530316335613233396334
36346634656331623039383266303437323239646563326161653831363833653338386533616231
39613939393334353536613262643030323535396634363330396465303230646133356238373865
62316630303366643965363835336563393838373933393435616532636338376265303830376162
64653931343464656532373831666663326532373631376265636338323430396666383736636438
37346535373761663338653035653738396430316261326333313532653638393535386139376266
32333037303831653364336130646462616537383035633338653435633938303638633364336635
33343963666162356534656635316261353930336431323539393066333930323236396566356330
62333162353965616465396365616630313363636135633835353939633662363664343266373562
36636666343765653530653435316466356139323236356638383230623730643637613633633565
32353234656233353734653233323563313764613333653331333232653730396635633438633362
34306337653732646236346361663937616332353765613131393339393766313131633561376430
62386662393864303865303438616637303363646462313634383431373736643230653665636165
39636638656534363862633134663962383138656637386462356261336465386431343036646233
64666166346334333862653035303461626235633830623639643166373238373136343061303837
39633133653761646231653639653262366334373963343236363233373635306638653865653730
34616230343637616232313639333136313231393133346532353761623038656531376337333339
63316364386162616438303263653936643135316661633266613033366232383232356331336133
35313836363361363637383637643831313238613136396637386136633061666430313963633933
37343663666130326139643663313534313835643162363566396430363831343965613363366161
30353165313932623536393734306461616662663763333031623738383437643862623632656161
31323432633962613366306435626339663638633931323161373331353635306536623836376432
37373033306530623162316430613933366331303766386538396666346464363662646639643634
31373064646630343035326336376464663231343239643137353731303761643037313561313039
32613631353862376230316130333936376565373961383838383932396363396533316530383830
37386139396637613131366161376431323565643434333531656330643331653734393038303336
31366538663231623937653730326264633531623333363932656138396637303932333662383935
39323437396361613038376335353732333839383965313262643165363635386231666634653665
63333034663735623438393063333064363133396537646433383861613337313631633634343063
34303065343965343633653331393131613334356162323466656164343730323032396134303763
63393835646361316530643932613531326235313961663937653264656535623932303038616662
39336136346361636132303434373461333466333833313139346531303837306238613664613731
33363766393862663336383930326638346132326138623537656263366262353637626436313736
32643837303761336230353037663235323265313939323436323736366565663533626365376361
62633730373864386438653137326136373866363164616633636137356133643330623035323838
33326137393937383833346537633361383966313230636133363663373638373864393838636161
64386631366530653063656634336537396330633763336235393538356139323565336134326337
61633330333164643166373064623032356135623336393262386461646535326462393638373866
37626266393962393564306530336462323137386434626363383365366238636235356432323533
65343262666162643932393061363531346464393363623037366639376536386234646135646330
36623837356637353132643435633632356266323830653866393636316130306538336334376234
36303265363037306436346666376337653837373839313732386131306535666639653733353737
66353531623431663532623865373931656233333234356532363730643234633963653435356237
61633134333536616235626666333738613637366264613961333663336330653132313234653132
39383336623736333634633863356366383430306465373932366534626131343236336439343663
38643133626566366163653164356436313661626432653435616630336563386466383939613038
30336433663563343532663032633161363535643962646161396531646130343431663863633736
33656437363432623135313163323064353863303164656661633161616536313165383939663935
65393164363533663934643034316332643137643861333233303062333138633337323330323865
63633538626537363739623132336466393835316565633936616562656466316363623432303231
37383465393034346130616632616539653735323730633035333138373632313662373566373265
63623761323763616634343966386233306435633965633764363133306531363739613039386231
39376432656662653165373162623565393964396538653065343164663233313465363537663963
35326461313761363734306664623265663335333661633732626233323332383335613437633936
66383031363332353937303165643864666236356133643861373032613366333837356434613437
63346637316465306330306135343338623238363139633939653730323961353630353365323938
30373165336337303434316336363737623439306633306363383433383666653661613030393466
35323762616664393838396365636334626130663839666438633361356164663562303930623664
39653235646230363031613061383563663761636131623064633265363737633433623130316234
32643836393530373535353732373730303932313131653465353432353065326566633965656531
64323462616638646234636662346532663964366538653934646538303237366531613939666338
64643666626338333036363234663664326439306432353833633637373439616661666434313831
34383334386538656564653862333565623165316439666235376535396232336263663033396532
31393866636661303934306536343065366265376131326238616338336161646139393464346534
34643664646535316133636236356430316434613762313738623066653336616339383366653934
32663930333366623032663838656632643532303136663664303035346237616630653262346461
33343066346233313534323831646139636263306132666563333963633664323463333262316664
65636635333562636333303964666164393533653033336539663162333764376362373165613734
6366393631666464616334646262316161363136646334356133

View File

@ -1,17 +1,17 @@
# These are the variables contained in secrets.yml
# Secrets are usually 32 characters or more, matching [a-Z0-9]
---
postgres_passwords:
fider: xxx
nextcloud: xxx
passit: xxx
gitea: xxx
matrix: xxx
codimd: xxx
mailu: xxx
keycloak: xxx
hedgedoc: xxx
mastodon: xxx
rallly: xxx
membersystem: xxx
ttrss: xxx
fider_jwt_secret: xxx
ldap_admin_password: xxx
ldap_config_password: xxx
@ -22,36 +22,16 @@ docker_password: xxx
mailu_secret_key: xxx
nextcloud_secrets:
redis_password: xxx
drone_secrets:
oauth_client_id: xxx
oauth_client_secret: xxx
rpc_shared_secret: xxx
restic_secrets:
repository_password: xxx
ssh_privkey: xxx
uptime_kuma_url: xxx
user_secret: xxx
encryption_secret: xxx
matrix_secrets:
registration_shared_secret: xxx
macaroon_secret_key: xxx
form_secret: xxx
keycloak_secrets:
admin_user: xxx # used for setting up the initial admin user on first run
admin_password: xxx
mastodon_secrets:
secret_key_base: xxx
otp_secret: xxx
vapid_private_key: xxx
vapid_public_key: xxx
rallly_secrets:
secret_password: xxx
membersystem_secrets:
secret_key: xxx
mailman_secrets:
postgres_password: xxx
hyperkitty_api_key: xxx
django_secret_key: xxx

View File

@ -1,35 +1,24 @@
# vim: ft=yaml.ansible
---
users:
- name: graffen
graffen:
comment: Jesper Hess Nielsen
password: '!'
groups: []
ssh_keys: []
key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCbxFVukt5TIzoB0HX2q8b8lHJmXD1juzsWOu5XkexVDlCsvupa1cZ/OVkrIEAbDKk6RmJQj0TJ2O5+v9hbf0TDi0Pi+V8ADZIgO+OW5a4EeXsU72a4CN0nEocQhUPfQuC4IU+F7icoG2/I9jXg7U6p1LhBr8vlC3cNHnrH3yqrakrUR51/iRVIwo4FKvQg7jutaKTyOjlYa1uTdaczvAzNHWEdytCQgFnkzpR9fHvzkA79qHUD9n32rIpJicRJsHY3NnyDGfBcDv+4sLq15sM9jN83duGnSuMMtZgfSriwMUd/UwVReU2ZKxjMLe3WHB7+ZE/p39OJk/gjVfWJVh/za1/teTAwaLLmxh/HFt+AVYWkCj22fUxscl0dh2zy6Ki1Ua3ApChn6v6Gvng6khobFlxawSJZ49+0KoAl1qqFMR1o9EGWvqgDPuITAqJFN+ik0jxcxfmKrG3mbOYM1ikhJd0ER8wbS8e6NowHUBV7PUyDqxP5VM2gum58IYrDqaP2RYYi9vWWnXJJA8J1t+Wp3bF7fdktyVgkd7HQk02uVkxdMQQ802GCrQQuvJhWTCzrgkgrjPY8p0KcbCNt6jYQOUKV0T2vp6PbTJ5XWKb5u7gVXW1xiP9dYzgAr0DroiTK4xIuF80mv1Rfst0ceHAIQVcQ3GcGbh000QUYzbHT2Q== openpgp:0x265EE03C (Graffen)
password: $6$6bgPWZ76LvB$DZ3ipFsFtL2b1nSC0AQ63k8ibJidyIE9iIsWWzY0fux0ynz9L/o7b2sR2XYSaDuG.jewFV36IGStTF3NCZRC30
groups:
- sudo
- name: valberg
valberg:
comment: Vidir Valberg Gudmundsson
key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUmGeHc6QXDcJHkmVxbTUv04Q3vs20avquoGr6eOkkvYbcgjuFnBOOtvs2Nul1odcvvnHa1nN7DfL8XJamiwsB1B/xe2seaNS1axgwk9XowlVN9pgga8gsC+4gZWBtSObG2GR8n4NtPENzPmW5deNn8dRpTvULPMxZ0VRE9yNQOx8v8w85yYh+vxbbkWGVDYJU23yuJI50U9y6bXxNHinsACDFBeR/giXDlw29TaOaSxz0R6zrRPBoX+V68RyWwBL+KWQKtX2ULtJI40S98Ohd6p41bIxYHCBS/zroqNne8PjYOLcHHsjHUGfTvhcS5a3zdz/iHsvsaOOjFjsydAXH valberg
password: $6$qt3G.E.CxhC$OwBDn4rZUbCz06HLEMBHjgvKjxiv/eeerbklTHi.gpHIn1OejzX3k2.0NM0Dforaw6Yn5Y8Cgn8kL2FdbQLZ3/
groups:
- sudo
ssh_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUmGeHc6QXDcJHkmVxbTUv04Q3vs20avquoGr6eOkkvYbcgjuFnBOOtvs2Nul1odcvvnHa1nN7DfL8XJamiwsB1B/xe2seaNS1axgwk9XowlVN9pgga8gsC+4gZWBtSObG2GR8n4NtPENzPmW5deNn8dRpTvULPMxZ0VRE9yNQOx8v8w85yYh+vxbbkWGVDYJU23yuJI50U9y6bXxNHinsACDFBeR/giXDlw29TaOaSxz0R6zrRPBoX+V68RyWwBL+KWQKtX2ULtJI40S98Ohd6p41bIxYHCBS/zroqNne8PjYOLcHHsjHUGfTvhcS5a3zdz/iHsvsaOOjFjsydAXH valberg
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4FRrbTpxwGdlF6RVi/thJaMlaEE0Z9YCQA4Y+KnHbBoVWMjzgbIkSWw3MM+E/iiVnix8SFh4tjDSdFjb8lCvHt/PqhMFhZJ02vhVgSwyU+Ji5ur23i202LB9ua54NLN4kNG8K47U0tKi2/EV6LWl2QdRviAcOUctz6u9XDkkMLUgPEYH384XSTRRj4GJ8+0LRzB2rXqetH3gBe9v1vlv0ETYWvzTnpfZUxcrrqEGtXV9Wa0BZoWLos2oKOsYVjNdLZMoFpmyBxPnqzAi1hr7beblFZKqBkvD7XA9RnERbZn1nxkWufVahppPjKQ+se3esWJCp6ri/vNP4WNKY3hiIoekBLbpvGcP1Te7cAIQXiZOilN92NKKYrzN2gAtsxgqGZw7lI1PE71luGdPir2Evl6hPj6/nnNdEHZWgcmBSPy17uCpVvZYBcDDzj8L3hbkLVQ3kcLZTz6I8BXvuGqoeLvRQpBtn5EaLpCCOmXuKqm+dzHzsOIwh+SA5NA8M3P0=
- name: reynir
reynir:
comment: Reynir Björnsson
key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDJl8/rikIUnqr9fPF3rE0rjWHCNzte10LvkjGmpdO9ka/NubQ7O25fp08rC+n0d1pUooYwHBAgiv9Hsql6HF9QfNKNUp7IKp7CXWcjb4ga02kuzWGSXjm40Vf0jSadIrJ33M4SeJHTByDGoeYPQBQ7n+qHdwcqJADBQygBuc5sRzxm8i0sbmzF3DJDDVeTJjEY5pfR4vnJlpmU8SC2d1ZkhCjmKCsL0PShntTIt1ztCt0yO71KoHKaNPu1jutGxcU9u7J1pEqcPT6EzU/cQJ4DMVzrGp26nIV0msRl3NeGNjukwXOzAh6KmsmXG7yWFyQmLRqgc/bjUeyhuWJ10vwUbaYVeIef7YrgEOgnkYLIFeWRMhdnwtL/W8g1D66SFx7+iYJj180eTi8Lc8rZm2NaiGynvWlFcJ4PGdTYZsWcFzQ+SaDziNMw1H3IixxdlD8Shw9mxpijJ+A4dH2kkUXyGVsc13zRIU7hq9ax8nrw6HVLGFLn09rEPig+SkyWrqRpRGMBWyqTRJywIV6jk0ll+i8rJZA2McY0rABbACrzXT5VBj5dLKnnRITLDicAYgt7YuEiQ0ffErQrPXXHUVeI0QKnJgplSHxH5QsX9a1Y+NoaoditdMT2bjvEqROi+/JYRycLR/BQV/d2nFPhqwq1x1AFvL4f8UvVH/hxp3PXWw== reynir yubikey
password: $6$MiPv.ZFlWnLHGNOb$jdQD9NaPMRUGaP2YHRJNwrMPBGl9qwK0HFhI6x51Xpn7hdzuC4GIwvOw1DJK33sNs/gGP5bWB0izviXkDcq7B0
groups:
- sudo
ssh_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDJl8/rikIUnqr9fPF3rE0rjWHCNzte10LvkjGmpdO9ka/NubQ7O25fp08rC+n0d1pUooYwHBAgiv9Hsql6HF9QfNKNUp7IKp7CXWcjb4ga02kuzWGSXjm40Vf0jSadIrJ33M4SeJHTByDGoeYPQBQ7n+qHdwcqJADBQygBuc5sRzxm8i0sbmzF3DJDDVeTJjEY5pfR4vnJlpmU8SC2d1ZkhCjmKCsL0PShntTIt1ztCt0yO71KoHKaNPu1jutGxcU9u7J1pEqcPT6EzU/cQJ4DMVzrGp26nIV0msRl3NeGNjukwXOzAh6KmsmXG7yWFyQmLRqgc/bjUeyhuWJ10vwUbaYVeIef7YrgEOgnkYLIFeWRMhdnwtL/W8g1D66SFx7+iYJj180eTi8Lc8rZm2NaiGynvWlFcJ4PGdTYZsWcFzQ+SaDziNMw1H3IixxdlD8Shw9mxpijJ+A4dH2kkUXyGVsc13zRIU7hq9ax8nrw6HVLGFLn09rEPig+SkyWrqRpRGMBWyqTRJywIV6jk0ll+i8rJZA2McY0rABbACrzXT5VBj5dLKnnRITLDicAYgt7YuEiQ0ffErQrPXXHUVeI0QKnJgplSHxH5QsX9a1Y+NoaoditdMT2bjvEqROi+/JYRycLR/BQV/d2nFPhqwq1x1AFvL4f8UvVH/hxp3PXWw== reynir yubikey
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR8t/wNRp7Dt3wr9uZKVTofTDVYrcoQNru5ETxL+37t reynir@spurv
- name: samsapti
comment: Sam Al-Sapti
password: $6$18dN367fG162hQ9A$Aqkf3O24Ve1btzh1PPOPg3uyydv/AQYUxethcoB4klotebJq3/XsydYT7XBuarxfDccVwyPTMlsP3U8VfQpG60
groups:
- sudo
ssh_keys:
- sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIFWZGLov8wPBNxuvnaPK+8vv6wK5hHUVEFzXKsN9QeuBAAAADHNzaDpzYW1zYXB0aQ== ssh:samsapti
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd/4fQV7CL8/KVwbo/phiV5UdXFBIDlkZ+ps8C7FeRf cardno:14 336 332
volume_root_folder: "/docker-volumes"

View File

@ -1,27 +1,39 @@
# vim: ft=yaml.ansible
---
- hosts: production
gather_facts: true
- hosts: all
gather_facts: False
become: true
vars:
base_domain: data.coop
letsencrypt_email: bestyrelsen@data.coop
ldap_dn: "dc=data,dc=coop"
vagrant: "{{ from_vagrant is defined and from_vagrant }}"
letsencrypt_enabled: "{{ not vagrant }}"
base_domain: "{{ 'datacoop.devel' if vagrant else 'data.coop' }}"
letsencrypt_email: "admin@{{ base_domain }}"
services:
- nginx-proxy
- openldap
- thelounge
- nextcloud
- fider
- passit
- gitea
- postfix
- matrix_riot
- privatebin
- codimd
- netdata
- docker_registry
- drone
- websites
- ulovliglogning-dk
- ouroboros
- mailu
- portainer
# - tt-rss
smtp_host: "postfix"
smtp_port: "587"
services_exclude:
- uptime_kuma
tasks:
- import_role:
name: ubuntu_base
tags:
- base_only
- import_role:
name: docker

View File

@ -1,227 +1,92 @@
# vim: ft=yaml.ansible
---
volume_root_folder: "/docker-volumes"
volume_website_folder: "{{ volume_root_folder }}/websites"
services:
### Internal services ###
postfix:
domain: "smtp.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/postfix"
pre_deploy_tasks: true
version: "v3.6.1-alpine"
nginx:
volume_folder: "{{ volume_root_folder }}/nginx"
nginx_proxy:
volume_folder: "{{ volume_root_folder }}/nginx"
pre_deploy_tasks: true
version: "1.3-alpine"
acme_companion_version: "2.2"
ldap:
domain: "ldap.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/openldap"
openldap:
domain: "ldap.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/openldap"
pre_deploy_tasks: true
version: "1.5.0"
phpldapadmin_version: "0.9.0"
thelounge:
domain: "irc.{{ base_domain }}"
netdata:
domain: "netdata.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/netdata"
version: "v1"
nextcloud:
domain: "cloud.{{ base_domain }}"
portainer:
domain: "portainer.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/portainer"
version: "2.19.0"
gitea:
domain: "git.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/gitea"
keycloak:
domain: sso.{{ base_domain }}
volume_folder: "{{ volume_root_folder }}/keycloak"
version: "22.0"
postgres_version: "10"
allowed_sender_domain: true
passit:
domain: "passit.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/passit"
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
version: "1.7.0"
disabled_in_vagrant: true
# mail dance
domain: "noreply.{{ base_domain }}"
allowed_sender_domain: true
mail_from: "backup@noreply.{{ base_domain }}"
fider:
domain: "feedback.{{ base_domain }}"
docker_registry:
domain: "docker.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/docker-registry"
pre_deploy_tasks: true
post_deploy_tasks: true
username: "docker"
password: "{{ docker_password }}"
version: "2"
matrix:
domain: "matrix.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/matrix"
### External services ###
nextcloud:
domain: "cloud.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/nextcloud"
pre_deploy_tasks: true
version: 28-apache
postgres_version: "10"
redis_version: 7-alpine
allowed_sender_domain: true
riot:
domains:
- "riot.{{ base_domain }}"
- "element.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/riot"
forgejo:
domain: "git.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/forgejo"
version: "1.21.8-0"
allowed_sender_domain: true
privatebin:
domain: "paste.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/privatebin"
passit:
domain: "passit.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/passit"
version: stable
postgres_version: 15-alpine
allowed_sender_domain: true
codimd:
domain: "pad.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/codimd"
matrix:
domain: "matrix.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/matrix"
pre_deploy_tasks: true
version: v1.98.0
postgres_version: 15-alpine
allowed_sender_domain: true
netdata:
domain: "netdata.{{ base_domain }}"
element:
domain: "element.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/element"
pre_deploy_tasks: true
version: v1.11.51
docker_registry:
domain: "docker.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/docker-registry"
username: "docker"
password: "{{ docker_password }}"
privatebin:
domain: "paste.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/privatebin"
pre_deploy_tasks: true
version: "20221009"
data_coop_website:
domains:
- "{{ base_domain }}"
- "www.{{ base_domain }}"
hedgedoc:
domain: "pad.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/hedgedoc"
pre_deploy_tasks: true
version: 1.9.9-alpine
postgres_version: 10-alpine
cryptohagen_website:
domains:
- "cryptohagen.dk"
- "www.cryptohagen.dk"
data_coop_website:
domain: "{{ base_domain }}"
www_domain: "www.{{ base_domain }}"
volume_folder: "{{ volume_website_folder }}/datacoop"
pre_deploy_tasks: true
version: stable
staging_domain: "staging.{{ base_domain }}"
staging_version: staging
ulovliglogning_website:
domains:
- "ulovliglogning.dk"
- "www.ulovliglogning.dk"
- "ulovlig-logning.dk"
slides_2022_website:
domain: "2022.slides.{{ base_domain }}"
volume_folder: "{{ volume_website_folder }}/slides-2022"
version: latest
cryptoaarhus_website:
domains:
- "cryptoaarhus.dk"
- "www.cryptoaarhus.dk"
fedi_dk_website:
domain: fedi.dk
volume_folder: "{{ volume_website_folder }}/fedidk"
version: latest
drone:
domain: "drone.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/drone"
vhs_website:
domain: vhs.data.coop
volume_folder: "{{ volume_website_folder }}/vhs"
version: latest
mailu:
version: 1.6
domain: "mail.{{ base_domain }}"
dns: 192.168.203.254
subnet: 192.168.203.0/24
volume_folder: "{{ volume_root_folder }}/mailu"
cryptohagen_website:
domains:
- "cryptohagen.dk"
- "www.cryptohagen.dk"
volume_folder: "{{ volume_website_folder }}/cryptohagen"
portainer:
domain: "portainer.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/portainer"
ulovliglogning_website:
domains:
- "ulovliglogning.dk"
- "www.ulovliglogning.dk"
- "ulovlig-logning.dk"
- "www.ulovlig-logning.dk"
volume_folder: "{{ volume_website_folder }}/ulovliglogning"
cryptoaarhus_website:
domains:
- "cryptoaarhus.dk"
- "www.cryptoaarhus.dk"
volume_folder: "{{ volume_website_folder }}/cryptoaarhus"
drone:
domain: "drone.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/drone"
version: "1"
mailu:
domain: "mail.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/mailu"
pre_deploy_tasks: true
dns: 192.168.203.254
subnet: 192.168.203.0/24
version: "2.0"
postgres_version: 14-alpine
redis_version: alpine
mastodon:
domain: "social.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/mastodon"
pre_deploy_tasks: true
post_deploy_tasks: true
version: v4.2.9
postgres_version: 14-alpine
redis_version: 6-alpine
allowed_sender_domain: true
rallly:
domain: "when.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/rallly"
pre_deploy_tasks: true
version: "2"
postgres_version: 14-alpine
allowed_sender_domain: true
membersystem:
domain: "member.{{ base_domain }}"
django_admins: "Vidir:valberg@orn.li"
volume_folder: "{{ volume_root_folder }}/membersystem"
version: latest
postgres_version: 13-alpine
allowed_sender_domain: true
writefreely:
domain: "write.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/writefreely"
pre_deploy_tasks: true
version: v0.15.0
mariadb_version: "11.2"
allowed_sender_domain: true
watchtower:
volume_folder: "{{ volume_root_folder }}/watchtower"
version: "1.5.3"
diun:
version: "4.27"
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) }}"
ttrss:
domain: rss.{{ base_domain }}
volume_folder: "{{ volume_root_folder }}/tt-rss"

View File

@ -44,7 +44,7 @@ pid_file: /data/homeserver.pid
# use synapse with a reverse proxy, this should be the URL to reach
# synapse via the proxy.
#
public_baseurl: "https://{{ services.matrix.domain }}"
public_baseurl: "https://{{ matrix.domain }}"
# Set the soft limit on the number of file descriptors synapse can use
# Zero is used to indicate synapse should set the soft limit to the
@ -339,11 +339,10 @@ database:
user: "synapse"
password: "{{ postgres_passwords.matrix }}"
database: "synapse"
host: "postgres"
host: "matrix_db"
port: "5432"
cp_min: 5
cp_max: 10
allow_unsafe_locale: true
# Number of events to cache in memory.
event_cache_size: "10K"
@ -416,7 +415,7 @@ uploads_path: "/data/uploads"
# The largest allowed upload size in bytes
#
max_upload_size: "512M"
max_upload_size: "50M"
# Maximum number of pixels that will be thumbnailed
#
@ -578,7 +577,7 @@ turn_allow_guests: True
## Registration ##
# Enable registration for new users.
enable_registration: False
enable_registration: True
# The user must provide all of the below types of 3PID when registering.
#
@ -605,7 +604,7 @@ enable_registration: False
# If set, allows registration by anyone who also has the shared
# secret, even if registration is otherwise disabled.
#
registration_shared_secret: "{{ matrix_secrets.registration_shared_secret }}"
registration_shared_secret: "jnJ5gfTj_qi#H0:vnPZx7OH*Qz.9u4cxpq.wHcHEAfuhcMgpxG"
# Set the number of bcrypt rounds used to generate password hash.
# Larger numbers increase the work factor needed to generate the hash.
@ -676,8 +675,15 @@ report_stats: false
## API Configuration ##
room_prejoin_state:
disable_default_event_types: false
# A list of event types that will be included in the room_invite_state
#
room_invite_state_types:
- "m.room.join_rules"
- "m.room.canonical_alias"
- "m.room.avatar"
- "m.room.encryption"
- "m.room.name"
# A list of application service config file to use
#
@ -693,7 +699,7 @@ track_appservice_user_ips: False
# the registration_shared_secret is used, if one is given; otherwise,
# a secret key is derived from the signing key.
#
macaroon_secret_key: "{{ matrix_secrets.macaroon_secret_key }}"
macaroon_secret_key: "PLawJ8o.Q_.pR3Rr.vJO3=F&eAe=b~g6hVOKbrRrSl#w5Eqr8X"
# Used to enable access token expiration.
#
@ -703,7 +709,7 @@ expire_access_token: False
# falsification of values. Must be specified for the User Consent
# forms to work.
#
form_secret: "{{ matrix_secrets.form_secret }}"
form_secret: "ssHGS0,URi,oQ8~Upfi53meultXQ-Vo-r5XgKjP.u42qL;WGc-"
## Signing Keys ##
@ -820,10 +826,23 @@ password_config:
# If your SMTP server requires authentication, the optional smtp_user &
# smtp_pass variables should be used
#
email:
smtp_host: "{{ smtp_host }}"
smtp_port: {{ smtp_port }}
notif_from: "{{ services.matrix.domain }} <no-reply@{{ services.matrix.domain }}>"
#email:
# enable_notifs: false
# smtp_host: "localhost"
# smtp_port: 25
# smtp_user: "exampleusername"
# smtp_pass: "examplepassword"
# require_transport_security: False
# notif_from: "Your Friendly %(app)s Home Server <noreply@example.com>"
# app_name: Matrix
# # if template_dir is unset, uses the example templates that are part of
# # the Synapse distribution.
# #template_dir: res/templates
# notif_template_html: notif_mail.html
# notif_template_text: notif_mail.txt
# notif_for_new_users: True
# riot_base_url: "http://localhost/riot"
#password_providers:
# - module: "ldap_auth_provider.LdapAuthProvider"

View File

@ -1,2 +1,2 @@
listen 3000;
listen 8008;
client_max_body_size 50M; # default is 1M

View File

@ -0,0 +1 @@
client_max_body_size 50M; # default is 1M

View File

@ -1,12 +1,6 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://{{ services.matrix.domain }}"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"default_hs_url": "https://{{ matrix.domain }}",
"default_is_url": "https://vector.im",
"brand": "element.data.coop",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
@ -37,7 +31,7 @@
]
},
"enable_presence_by_hs_url": {
"https://{{ services.matrix.domain }}": false
"https://{{ matrix.domain }}": false
},
"terms_and_conditions_links": [
{

View File

@ -0,0 +1,511 @@
"use strict";
module.exports = {
//
// Set the server mode.
// Public servers does not require authentication.
//
// Set to 'false' to enable users.
//
// @type boolean
// @default false
//
public: false,
//
// IP address or hostname for the web server to listen on.
// Setting this to undefined will listen on all interfaces.
//
// For UNIX domain sockets, use unix:/absolute/path/to/file.sock.
//
// @type string
// @default undefined
//
host: undefined,
//
// Set the port to listen on.
//
// @type int
// @default 9000
//
port: 9000,
//
// Set the local IP to bind to for outgoing connections. Leave to undefined
// to let the operating system pick its preferred one.
//
// @type string
// @default undefined
//
bind: undefined,
//
// Sets whether the server is behind a reverse proxy and should honor the
// X-Forwarded-For header or not.
//
// @type boolean
// @default false
//
reverseProxy: false,
//
// Set the default theme.
// Find out how to add new themes at https://thelounge.github.io/docs/plugins/themes.html
//
// @type string
// @default "example"
//
theme: "example",
//
// Prefetch URLs
//
// If enabled, The Lounge will try to load thumbnails and site descriptions from
// URLs posted in channels.
//
// @type boolean
// @default false
//
prefetch: false,
//
// Store and proxy prefetched images and thumbnails.
// This improves security and privacy by not exposing client IP address,
// and always loading images from The Lounge instance and making all assets secure,
// which in result fixes mixed content warnings.
//
// If storage is enabled, The Lounge will fetch and store images and thumbnails
// in the `${THELOUNGE_HOME}/storage` folder.
//
// Images are deleted when they are no longer referenced by any message (controlled by maxHistory),
// and the folder is cleaned up on every The Lounge restart.
//
// @type boolean
// @default false
//
prefetchStorage: false,
//
// Prefetch URLs Image Preview size limit
//
// If prefetch is enabled, The Lounge will only display content under the maximum size.
// Specified value is in kilobytes. Default value is 2048 kilobytes.
//
// @type int
// @default 2048
//
prefetchMaxImageSize: 2048,
//
// Display network
//
// If set to false network settings will not be shown in the login form.
//
// @type boolean
// @default true
//
displayNetwork: true,
//
// Lock network
//
// If set to true, users will not be able to modify host, port and tls
// settings and will be limited to the configured network.
//
// @type boolean
// @default false
//
lockNetwork: false,
//
// Hex IP
//
// If enabled, clients' username will be set to their IP encoded has hex.
// This is done to share the real user IP address with the server for host masking purposes.
//
// @type boolean
// @default false
//
useHexIp: false,
//
// WEBIRC support
//
// If enabled, The Lounge will pass the connecting user's host and IP to the
// IRC server. Note that this requires to obtain a password from the IRC network
// The Lounge will be connecting to and generally involves a lot of trust from the
// network you are connecting to.
//
// Format (standard): {"irc.example.net": "hunter1", "irc.example.org": "passw0rd"}
// Format (function):
// {"irc.example.net": function(client, args, trusted) {
// // here, we return a webirc object fed directly to `irc-framework`
// return {username: "thelounge", password: "hunter1", address: args.ip, hostname: "webirc/"+args.hostname};
// }}
//
// @type string | function(client, args):object(webirc)
// @default null
webirc: null,
//
// Log settings
//
// Logging has to be enabled per user. If enabled, logs will be stored in
// the 'logs/<user>/<network>/' folder.
//
// @type object
// @default {}
//
logs: {
//
// Timestamp format
//
// @type string
// @default "YYYY-MM-DD HH:mm:ss"
//
format: "YYYY-MM-DD HH:mm:ss",
//
// Timezone
//
// @type string
// @default "UTC+00:00"
//
timezone: "UTC+00:00",
},
//
// Maximum number of history lines per channel
//
// Defines the maximum number of history lines that will be kept in
// memory per channel/query, in order to reduce the memory usage of
// the server. Setting this to -1 will keep unlimited amount.
//
// @type integer
// @default 10000
maxHistory: 10000,
//
// Default values for the 'Connect' form.
//
// @type object
// @default {}
//
defaults: {
//
// Name
//
// @type string
// @default "Freenode"
//
name: "Freenode",
//
// Host
//
// @type string
// @default "chat.freenode.net"
//
host: "chat.freenode.net",
//
// Port
//
// @type int
// @default 6697
//
port: 6697,
//
// Password
//
// @type string
// @default ""
//
password: "",
//
// Enable TLS/SSL
//
// @type boolean
// @default true
//
tls: true,
//
// Nick
//
// @type string
// @default "lounge-user"
//
nick: "lounge-user",
//
// Username
//
// @type string
// @default "lounge-user"
//
username: "lounge-user",
//
// Real Name
//
// @type string
// @default "The Lounge User"
//
realname: "The Lounge User",
//
// Channels
// This is a comma-separated list.
//
// @type string
// @default "#thelounge"
//
join: "#thelounge",
},
//
// Set socket.io transports
//
// @type array
// @default ["polling", "websocket"]
//
transports: ["polling", "websocket"],
//
// Run The Lounge using encrypted HTTP/2.
// This will fallback to regular HTTPS if HTTP/2 is not supported.
//
// @type object
// @default {}
//
https: {
//
// Enable HTTP/2 / HTTPS support.
//
// @type boolean
// @default false
//
enable: false,
//
// Path to the key.
//
// @type string
// @example "sslcert/key.pem"
// @default ""
//
key: "",
//
// Path to the certificate.
//
// @type string
// @example "sslcert/key-cert.pem"
// @default ""
//
certificate: "",
//
// Path to the CA bundle.
//
// @type string
// @example "sslcert/bundle.pem"
// @default ""
//
ca: "",
},
//
// Default quit and part message if none is provided.
//
// @type string
// @default "The Lounge - https://thelounge.github.io"
//
leaveMessage: "The Lounge - https://thelounge.github.io",
//
// Run The Lounge with identd support.
//
// @type object
// @default {}
//
identd: {
//
// Run the identd daemon on server start.
//
// @type boolean
// @default false
//
enable: false,
//
// Port to listen for ident requests.
//
// @type int
// @default 113
//
port: 113,
},
//
// Enable oidentd support using the specified file
//
// Example: oidentd: "~/.oidentd.conf",
//
// @type string
// @default null
//
oidentd: null,
//
// LDAP authentication settings (only available if public=false)
// @type object
// @default {}
//
// The authentication process works as follows:
//
// 1. Lounge connects to the LDAP server with its system credentials
// 2. It performs a LDAP search query to find the full DN associated to the
// user requesting to log in.
// 3. Lounge tries to connect a second time, but this time using the user's
// DN and password. Auth is validated iff this connection is successful.
//
// The search query takes a couple of parameters in `searchDN`:
// - a base DN `searchDN/base`. Only children nodes of this DN will be likely
// to be returned;
// - a search scope `searchDN/scope` (see LDAP documentation);
// - the query itself, build as (&(<primaryKey>=<username>) <filter>)
// where <username> is the user name provided in the log in request,
// <primaryKey> is provided by the config and <fitler> is a filtering complement
// also given in the config, to filter for instance only for nodes of type
// inetOrgPerson, or whatever LDAP search allows.
//
// Alternatively, you can specify the `bindDN` parameter. This will make the lounge
// ignore searchDN options and assume that the user DN is always:
// <bindDN>,<primaryKey>=<username>
// where <username> is the user name provided in the log in request, and <bindDN>
// and <primaryKey> are provided by the config.
//
ldap: {
//
// Enable LDAP user authentication
//
// @type boolean
// @default false
//
enable: true,
//
// LDAP server URL
//
// @type string
//
url: "ldap://{{ ldap.domain }}",
//
// LDAP connection tls options (only used if scheme is ldaps://)
//
// @type object (see nodejs' tls.connect() options)
// @default {}
//
// Example:
// You can use this option in order to force the use of IPv6:
// {
// host: 'my::ip::v6',
// servername: 'example.com'
// }
tlsOptions: {},
//
// LDAP base dn, alternative to searchDN
//
// @type string
//
// baseDN: "",
//
// LDAP primary key
//
// @type string
// @default "uid"
//
primaryKey: "uid",
//
// LDAP search dn settings. This defines the procedure by which the
// lounge first look for user DN before authenticating her.
// Ignored if baseDN is specified
//
// @type object
//
searchDN: {
//
// LDAP searching bind DN
// This bind DN is used to query the server for the DN of the user.
// This is supposed to be a system user that has access in read only to
// the DNs of the people that are allowed to log in.
//
// @type string
//
rootDN: "cn=admin,dc=data,dc=coop",
//
// Password of the lounge LDAP system user
//
// @type string
//
rootPassword: "{{ ldap_admin_password }}",
//
// LDAP filter
//
// @type string
// @default "uid"
//
//filter: "(objectClass=inetOrgPerson)(memberOf=ou=members,dc=data,dc=coop)",
filter: "(objectClass=inetOrgPerson)",
//
// LDAP search base (search only within this node)
//
// @type string
//
base: "{{ ldap_dn }}",
//
// LDAP search scope
//
// @type string
// @default "sub"
//
scope: "sub",
},
},
// Extra debugging
//
// @type object
// @default {}
//
debug: {
// Enables extra debugging output provided by irc-framework.
//
// @type boolean
// @default false
//
ircFramework: false,
// Enables logging raw IRC messages into each server window.
//
// @type boolean
// @default false
//
raw: false,
},
};

View File

@ -1,20 +0,0 @@
# DB Version: 14
# OS Type: linux
# DB Type: oltp
# Total Memory (RAM): 16 GB
# Connections num: 300
# Data Storage: hdd
listen_addresses = '*'
max_connections = 300
shared_buffers = 4GB
effective_cache_size = 12GB
maintenance_work_mem = 1GB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 4
effective_io_concurrency = 2
work_mem = 6990kB
min_wal_size = 2GB
max_wal_size = 8GB

View File

@ -1 +0,0 @@
MIICszCCAZsCBgF8WpKKwTANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJkYXRhLmNvb3Agc2VydmljZXMwHhcNMjExMDA3MTE0MzQ1WhcNMzExMDA3MTE0NTI1WjAdMRswGQYDVQQDDBJkYXRhLmNvb3Agc2VydmljZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdV0stfU8aA1bi+GYd/a5DOyoox01BgzWwBFqVjlo80frsOsH8g814eDuMuff/UJy+2YxaozYQGxP+DcOVXi+0Fts9zjRj6wa6HCQqiR/SNUa69fGHcyAo2Tr0faxOyf3QMBqIngTRZB99quNMuAM96RCg25LtDaaWjNVxdHlj78+kU1bQXExp0ZfELlKGtllWP07cyz4nGfZmuK1AiWSsRbDIbyK5dvzw/pMS1kexh6ylnQu1iLqD3vYZBUDX9lPNkavTYZNCEL4ElUvR81S0ko2zkYAUiuVTtTUKucc98dTRhkuV4YCiiW6UQGY/jzmXYBfpzAY3n5eH5iUu/tRXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFQc8ytexKiXOIGrSYYtFaF/lxv8AwMgsndv8YxJ+x/cUwN9tdmA8IAZDIS13qBrCOdZE4pJ/09VkYdErcpbtV7PWC3LDv/c2qakyiBUYZj4WgJio+oD0GCqXsby3aqJeVt9cJr4gSsXxn1c+7GV7p/gc/2FFmlWcqMN/2F7LvFvObu55QlppWZrn8kreaUQmRuTTIviFQRmvrmwKyK52LEcK7qoh/v1aHyYDl91gu3nLMEluz6hy3UEPYgpdH1t2C7K0Kjri25pJNGCFrpKjWWveteKazUeDd4adHMiw2MVfeEyTCXEFoaxQS9QmbmhSMRhiHjbdffL7xi//aSh1bo=

View File

@ -1 +0,0 @@
client_max_body_size 1G; # default is 1M

View File

@ -1,2 +0,0 @@
listen 8008;
client_max_body_size 1G; # default is 1M

View File

@ -1 +0,0 @@
client_max_body_size 1G; # default is 1M

View File

@ -1,4 +0,0 @@
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,2 +0,0 @@
server_name www.data.coop;
return 301 $scheme://data.coop$request_uri;

View File

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

View File

@ -1,26 +0,0 @@
# 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,44 +1,33 @@
# vim: ft=yaml.ansible
---
- name: Add Docker PGP key
- name: add docker gpg key
apt_key:
keyserver: pgp.mit.edu
id: 8D81803C0EBFCD88
state: present
- name: Add Docker apt repository
- name: add docker apt repository
apt_repository:
repo: deb https://download.docker.com/linux/ubuntu bionic stable
state: present
update_cache: yes
- name: Install Docker
- name: install docker-ce
apt:
name: "{{ pkgs }}"
state: present
vars:
pkgs:
- docker-ce
- docker-compose-plugin
- name: Configure cron job to prune unused Docker data weekly
cron:
name: Prune unused Docker data
cron_file: ansible_docker_prune
job: 'docker system prune -fa && docker volume prune -fa'
special_time: weekly
user: root
name: docker-ce
state: present
- name: Create folder structure for bind mounts
- name: install docker python bindings
pip:
executable: "pip3"
name: "docker-compose"
state: present
- name: create folder structure for bind mounts
file:
name: "{{ item }}"
name: "{{ volume_root_folder }}"
state: directory
loop:
- "{{ volume_root_folder }}"
- "{{ volume_website_folder }}"
- name: Set up services
- name: setup services
import_tasks: services.yml
tags:
- setup_services

View File

@ -1,13 +0,0 @@
# 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

@ -1,19 +0,0 @@
# 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

@ -1,11 +0,0 @@
# 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

@ -1,17 +0,0 @@
# 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

@ -1,21 +0,0 @@
# 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

@ -1,17 +0,0 @@
# 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

@ -1,45 +0,0 @@
# 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

@ -1,45 +0,0 @@
# 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

@ -1,34 +0,0 @@
# 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

@ -1,17 +0,0 @@
# 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

@ -1,14 +0,0 @@
# 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

@ -1,12 +0,0 @@
# 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

@ -1,13 +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 subfolder
file:
name: "{{ services.postfix.volume_folder }}/dkim"
state: directory

View File

@ -1,16 +0,0 @@
# 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

@ -1,11 +0,0 @@
# 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

@ -1,72 +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: 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

@ -1,9 +0,0 @@
- 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

@ -1,20 +0,0 @@
# 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,28 +1,8 @@
# vim: ft=yaml.ansible
---
- name: Set up external services network
- name: setup external services network
docker_network:
name: external_services
- name: Deploy all services
include_tasks:
file: block.yml
vars:
service:
name: "{{ item }}"
vars: "{{ services[item] }}"
loop: "{{ services_include }}"
when: single_service is not defined and
(item.vars.disabled_in_vagrant is not defined or
not (item.vars.disabled_in_vagrant and vagrant))
- name: Deploy single service
include_tasks:
file: block.yml
vars:
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
not (services[single_service].disabled_in_vagrant and vagrant))
- name: setup services
include_tasks: "services/{{ item }}.yml"
with_items: "{{ services }}"

View File

@ -0,0 +1,57 @@
---
- name: codimd network
docker_network:
name: codimd
- name: create codimd volume folders
file:
name: "{{ 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:
- "{{ 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:
- "{{ 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: "{{ codimd.domain }}"
LETSENCRYPT_HOST: "{{ codimd.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View File

@ -0,0 +1,35 @@
---
- name: copy docker registry nginx configuration
copy:
src: "files/configs/docker_registry/nginx.conf"
dest: "/docker-volumes/nginx/vhost/{{ docker_registry.domain }}"
mode: "0644"
- name: docker registry container
docker_container:
name: registry
image: registry:2
restart_policy: always
volumes:
- "{{ docker_registry.volume_folder }}/registry:/var/lib/registry"
- "{{ docker_registry.volume_folder }}/auth:/auth"
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ docker_registry.domain }}"
LETSENCRYPT_HOST: "{{ 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 }} > {{ docker_registry.volume_folder }}/auth/htpasswd"
args:
creates: "{{ docker_registry.volume_folder }}/auth/htpasswd"
- name: log in to local registry
docker_login:
registry: "{{ docker_registry.domain }}"
username: "docker"
password: "{{ docker_password }}"

View File

@ -0,0 +1,51 @@
---
- 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:1
restart: unless-stopped
networks:
- external_services
- drone
volumes:
- "{{ drone.volume_folder }}:/data"
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
DRONE_GITEA_SERVER: "https://{{ gitea.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: "{{ drone.domain }}"
DRONE_SERVER_PROTO: "https"
DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}"
PLUGIN_CUSTOM_DNS: "91.239.100.100"
VIRTUAL_HOST: "{{ drone.domain }}"
LETSENCRYPT_HOST: "{{ drone.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
drone-runner-docker:
container_name: "drone-runner-docker"
image: "drone/drone-runner-docker:1"
restart: unless-stopped
networks:
- drone
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
DRONE_RPC_HOST: "{{ 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

@ -0,0 +1,47 @@
---
- name: fider network
docker_network:
name: fider
- name: fider database volume
docker_volume:
name: fider_db
- name: fider database container
docker_container:
name: fider_db
image: postgres:10
state: started
restart_policy: always
networks:
- name: fider
volumes:
- fider_db:/var/lib/postgresql/data
env:
POSTGRES_USER: "fider"
POSTGRES_PASSWORD: "{{ postgres_passwords.fider }}"
- name: fider app container
docker_container:
name: fider
image: getfider/fider:stable
restart_policy: always
networks:
- name: fider
- name: external_services
- name: postfix
env:
GO_ENV: "production"
DATABASE_URL: "postgres://fider:{{ postgres_passwords.fider }}@fider_db:5432/fider?sslmode=disable"
JWT_SECRET: "{{ fider_jwt_secret }}"
EMAIL_NOREPLY: noreply@{{ fider.domain }}
EMAIL_SMTP_HOST: "{{ smtp_host }}"
EMAIL_SMTP_PORT: "{{ smtp_port }}"
EMAIL_SMTP_USERNAME: "noop"
EMAIL_SMTP_PASSWORD: "noop"
VIRTUAL_HOST: "{{ fider.domain }}"
LETSENCRYPT_HOST: "{{ fider.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email}}"

View File

@ -0,0 +1,23 @@
---
- name: gitea network
docker_network:
name: gitea
# old DNS: 138.68.71.153
- name: gitea container
docker_container:
name: gitea
image: gitea/gitea:1.12.3
restart_policy: unless-stopped
networks:
- name: gitea
- name: external_services
volumes:
- "{{ gitea.volume_folder }}:/data"
published_ports:
- "22:22"
env:
VIRTUAL_HOST: "{{ gitea.domain }}"
VIRTUAL_PORT: "3000"
LETSENCRYPT_HOST: "{{ gitea.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View File

@ -0,0 +1,72 @@
---
- name: run mailman server containers
docker_compose:
project_name: "mailman"
definition:
version: '2'
services:
mailman-web:
image: maxking/mailman-web:0.3.5
depends_on:
- database
links:
- database:database
volumes:
- /opt/mailman/web:/opt/mailman-web-data
environment:
DATABASE_TYPE: "postgres"
DATABASE_URL: "postgres://mailman:{{ mailman_secrets.postgres_password }}@database/mailmandb"
HYPERKITTY_API_KEY: "{{ mailman_secrets.hyperkitty_api_key }}"
SERVE_FROM_DOMAIN: "lists.data.coop"
MAILMAN_ADMIN_USER: "valberg"
MAILMAN_ADMIN_EMAIL: "valberg@orn.li"
SECRET_KEY: "{{ mailman_secrets.django_secret_key }}"
VIRTUAL_HOST: "lists.data.coop"
VIRTUAL_PORT: 8000
LETSENCRYPT_HOST: "lists.data.coop"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
- "mailman"
- "postfix"
- "external_services"
mailman-core:
image: maxking/mailman-core:0.3
volumes:
- /opt/mailman/core:/opt/mailman/
stop_grace_period: 30s
links:
- mailman-web:mailmain-web
- database:database
depends_on:
- database
environment:
DATABASE_URL: "postgres://mailman:{{ mailman_secrets.postgres_password }}@database/mailmandb"
DATABASE_TYPE: "postgres"
DATABASE_CLASS: "mailman.database.postgresql.PostgreSQLDatabase"
HYPERKITTY_API_KEY: "{{ mailman_secrets.hyperkitty_api_key }}"
networks:
- "mailman"
- "postfix"
- "external_services"
database:
environment:
POSTGRES_DB: mailmandb
POSTGRES_USER: mailman
POSTGRES_PASSWORD: "{{ mailman_secrets.postgres_password }}"
restart: always
image: postgres:13
volumes:
- /opt/mailman/database:/var/lib/postgresql/data
networks:
- "mailman"
networks:
mailman:
postfix:
external: true
external_services:
external: true

View File

@ -0,0 +1,161 @@
---
- name: create mailu volume folders
file:
name: "{{ mailu.volume_folder }}/{{ volume }}"
state: directory
loop:
- redis
- certs
- overrides
- data
- dkim
- mail
- filter
- dav
- webmail
loop_control:
loop_var: volume
- name: upload mailu.env file
template:
src: mailu.env.j2
dest: "{{ mailu.volume_folder}}/mailu.env"
- name: hard link to Let's Encrypt TLS certificate
file:
src: "{{ nginx.volume_folder }}/certs/{{ mailu.domain }}/fullchain.pem"
dest: "{{ mailu.volume_folder }}/certs/cert.pem"
state: hard
force: yes
- name: hard link to Let's Encrypt TLS key
file:
src: "{{ nginx.volume_folder }}/certs/{{ mailu.domain }}/key.pem"
dest: "{{ mailu.volume_folder }}/certs/key.pem"
state: hard
force: yes
- name: run mail server containers
docker_compose:
project_name: mail_server
pull: yes
definition:
version: '3.6'
services:
redis:
image: redis:alpine
restart: always
volumes:
- "{{ mailu.volume_folder }}/redis:/data"
database:
image: mailu/postgresql:{{ mailu.version }}
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
volumes:
- "{{ mailu.volume_folder }}/data/psql_db:/data"
- "{{ mailu.volume_folder }}/data/psql_backup:/backup"
networks:
- default
- external_services
front:
image: mailu/nginx:{{ mailu.version }}
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
environment:
VIRTUAL_HOST: "{{ mailu.domain }}"
LETSENCRYPT_HOST: "{{ mailu.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
volumes:
- "{{ mailu.volume_folder }}/certs:/certs"
- "{{ mailu.volume_folder }}/overrides/nginx:/overrides"
expose:
- "80"
ports:
- "993:993"
- "25:25"
- "587:587"
- "465:465"
networks:
- default
- external_services
resolver:
image: mailu/unbound:{{ mailu.version }}
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
networks:
default:
ipv4_address: "{{ mailu.dns }}"
admin:
image: mailu/admin:{{ mailu.version }}
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
volumes:
- "{{ mailu.volume_folder }}/data:/data"
- "{{ mailu.volume_folder }}/dkim:/dkim"
depends_on:
- redis
imap:
image: mailu/dovecot:{{ mailu.version }}
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
volumes:
- "{{ mailu.volume_folder }}/mail:/mail"
- "{{ mailu.volume_folder }}/overrides:/overrides"
depends_on:
- front
smtp:
image: mailu/postfix:{{ mailu.version }}
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
volumes:
- "{{ mailu.volume_folder }}/overrides:/overrides"
depends_on:
- front
- resolver
dns:
- "{{ mailu.dns }}"
antispam:
image: mailu/rspamd:{{ mailu.version }}
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
volumes:
- "{{ mailu.volume_folder }}/filter:/var/lib/rspamd"
- "{{ mailu.volume_folder }}/dkim:/dkim"
- "{{ mailu.volume_folder }}/overrides/rspamd:/etc/rspamd/override.d"
depends_on:
- front
- resolver
dns:
- "{{ mailu.dns }}"
webmail:
image: mailu/rainloop:1.6
restart: always
env_file: "{{ mailu.volume_folder}}/mailu.env"
volumes:
- "{{ mailu.volume_folder }}/webmail:/data"
depends_on:
- front
- resolver
dns:
- "{{ mailu.dns }}"
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: "{{ mailu.subnet }}"
external_services:
external:
name: external_services

View File

@ -0,0 +1,125 @@
---
- name: create matrix volume folders
file:
name: "{{ 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: "{{ matrix.volume_folder }}/db"
state: "directory"
- name: create riot volume folders
file:
name: "{{ riot.volume_folder }}/{{ volume }}"
state: directory
loop:
- "data"
loop_control:
loop_var: volume
- name: upload riot config.json
template:
src: files/configs/riot/config.json
dest: "{{ riot.volume_folder }}/data/config.json"
- name: upload riot.im.conf
template:
src: files/configs/riot/riot.im.conf
dest: "{{ riot.volume_folder }}/data/riot.im.conf"
- name: upload vhost config for root domain
template:
src: files/configs/matrix/vhost-root
dest: "{{ nginx.volume_folder }}/vhost/{{ base_domain }}"
- name: upload vhost config for matrix domain
template:
src: files/configs/matrix/vhost-matrix
dest: "{{ nginx.volume_folder }}/vhost/{{ matrix.domain }}"
- name: upload vhost config for riot domain
template:
src: files/configs/matrix/vhost-riot
dest: "{{ nginx.volume_folder }}/vhost/{{ riot.domains[0] }}"
- name: upload homeserver.yaml
template:
src: "files/configs/matrix/homeserver.yaml"
dest: "{{ matrix.volume_folder }}/data/homeserver.yaml"
- name: upload matrix logging config
template:
src: "files/configs/matrix/matrix.data.coop.log.config"
dest: "{{ matrix.volume_folder }}/data/matrix.data.coop.log.config"
- name: set up matrix and riot
docker_compose:
project_name: matrix
pull: yes
definition:
version: "3.6"
services:
matrix_db:
container_name: matrix_db
image: postgres:10
restart: unless-stopped
networks:
- matrix
volumes:
- "{{ matrix.volume_folder }}/db:/var/lib/postgresql/data"
environment:
POSTGRES_USER: "synapse"
POSTGRES_PASSWORD: "{{ postgres_passwords.matrix }}"
matrix_app:
container_name: matrix
image: matrixdotorg/synapse:v1.18.0
restart: unless-stopped
networks:
- matrix
- external_services
ports:
- 8008
volumes:
- "{{ matrix.volume_folder }}/data:/data"
environment:
SYNAPSE_CONFIG_PATH: "/data/homeserver.yaml"
SYNAPSE_CACHE_FACTOR: "2"
SYNAPSE_LOG_LEVEL: "INFO"
VIRTUAL_HOST: "{{ matrix.domain }}"
VIRTUAL_PORT: "8008"
LETSENCRYPT_HOST: "{{ matrix.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
riot:
container_name: riot_app
image: avhost/docker-matrix-riot:v1.7.3
restart: unless-stopped
networks:
- matrix
- external_services
ports:
- 8080
volumes:
- "{{ riot.volume_folder }}/data:/data"
environment:
VIRTUAL_HOST: "{{ riot.domains|join(',') }}"
VIRTUAL_PORT: "8080"
LETSENCRYPT_HOST: "{{ riot.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
external_services:
external:
name: external_services
matrix:
name: "matrix"

View File

@ -0,0 +1,27 @@
---
- name: setup netdata docker container for system monitoring
docker_container:
name: netdata
image: netdata/netdata
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 : "{{ netdata.domain }}"
LETSENCRYPT_HOST: "{{ netdata.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
PGID: "999"
labels:
com.ouroboros.enable: "true"

View File

@ -0,0 +1,48 @@
---
- name: nextcloud network
docker_network:
name: nextcloud
- name: nextcloud database volume
docker_volume:
name: nextcloud_db
- name: nextcloud database container
docker_container:
name: nextcloud_db
image: postgres:10
state: started
restart_policy: always
networks:
- name: nextcloud
volumes:
- nextcloud_db:/var/lib/postgresql/data
env:
POSTGRES_DB: somethingelse
POSTGRES_USER: nextcloud
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"
- name: nextcloud app volume
docker_volume:
name: nextcloud_app
- name: nextcloud app container
docker_container:
name: nextcloud_app
image: nextcloud:apache
state: started
restart_policy: always
networks:
- name: nextcloud
- name: external_services
volumes:
- nextcloud_app:/var/www/html
env:
VIRTUAL_HOST: "{{ nextcloud.domain }}"
LETSENCRYPT_HOST: "{{ nextcloud.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
POSTGRES_HOST: nextcloud_db
POSTGRES_DB: nextcloud
POSTGRES_USER: nextcloud
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"

View File

@ -0,0 +1,47 @@
---
- name: create nginx-proxy volume folders
file:
name: "{{ nginx.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: jwilder/nginx-proxy
restart_policy: always
networks:
- name: external_services
published_ports:
- "80:80"
- "443:443"
volumes:
- "{{ nginx.volume_folder }}/conf:/etc/nginx/conf.d"
- "{{ nginx.volume_folder }}/vhost:/etc/nginx/vhost.d"
- "{{ nginx.volume_folder }}/html:/usr/share/nginx/html"
- "{{ nginx.volume_folder }}/dhparam:/etc/nginx/dhparam"
- "{{ nginx.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: jrcs/letsencrypt-nginx-proxy-companion
restart_policy: always
volumes:
- "{{ nginx.volume_folder }}/vhost:/etc/nginx/vhost.d"
- "{{ nginx.volume_folder }}/html:/usr/share/nginx/html"
- "{{ nginx.volume_folder }}/dhparam:/etc/nginx/dhparam:ro"
- "{{ nginx.volume_folder }}/certs:/etc/nginx/certs"
- /var/run/docker.sock:/var/run/docker.sock:ro
env:
NGINX_PROXY_CONTAINER: nginx-proxy

View File

@ -0,0 +1,71 @@
---
- name: create ldap volume folders
file:
name: "{{ ldap.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:1.2.2
tty: true
interactive: true
volumes:
- "{{ ldap.volume_folder }}/var/lib/ldap:/var/lib/ldap"
- "{{ ldap.volume_folder }}/etc/slapd.d:/etc/ldap/slapd.d"
- "{{ ldap.volume_folder }}/certs:/container/service/slapd/assets/certs/"
published_ports:
- "389:389"
- "636:636"
hostname: "{{ ldap.domain }}"
domainname: "{{ ldap.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:latest
networks:
- name: external_services
- name: ldap
env:
PHPLDAPADMIN_LDAP_HOSTS: "openldap"
PHPLDAPADMIN_HTTPS: "false"
PHPLDAPADMIN_TRUST_PROXY_SSL: "true"
VIRTUAL_HOST: "{{ ldap.domain }}"
LETSENCRYPT_HOST: "{{ ldap.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View File

@ -0,0 +1,18 @@
---
- name: ouroboros container
docker_container:
name: ouroboros
image: pyouroboros/ouroboros
restart_policy: unless-stopped
networks:
- name: external_services
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/.docker/config.json:/root/.docker/config.json
env:
LABEL_ENABLE: "true"
LABELS_ONLY: "true"
CLEANUP: "true"
LATEST: "true"
CRON: "*/10 * * * *"

View File

@ -0,0 +1,47 @@
---
- name: setup passit containers
docker_compose:
project_name: "passit"
pull: "yes"
definition:
version: "3.6"
services:
passit_db:
image: "postgres:10"
restart: "always"
networks:
- "passit"
volumes:
- "{{ passit.volume_folder }}/data:/var/lib/postgresql/data"
environment:
POSTGRES_USER: "passit"
POSTGRES_PASSWORD: "{{ postgres_passwords.passit }}"
passit_app:
image: "passit/passit:stable"
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@{{ passit.domain }}"
EMAIL_CONFIRMATION_HOST: "https://{{ passit.domain }}"
VIRTUAL_HOST: "{{ passit.domain }}"
LETSENCRYPT_HOST: "{{ passit.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
networks:
passit:
postfix:
external: true
external_services:
external: true

View File

@ -0,0 +1,24 @@
---
- name: create portainer volume folder
file:
name: "{{ portainer.volume_folder }}"
state: directory
- name: run portainer
docker_container:
name: portainer
image: portainer/portainer-ce:2.0.1
restart_policy: always
networks:
- name: external_services
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- "{{ portainer.volume_folder }}:/data"
published_ports:
- 9001:9000
env:
VIRTUAL_HOST: "{{ portainer.domain }}"
VIRTUAL_PORT: "9000"
LETSENCRYPT_HOST: "{{ portainer.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View File

@ -0,0 +1,27 @@
---
- name: setup network for postfix
docker_network:
name: postfix
ipam_config:
- subnet: '172.16.0.0/16'
gateway: 172.16.0.1
- name: setup postfix docker container for outgoing mail
vars:
mynetworks:
- 127.0.0.0/8
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 172.19.199.2
- 172.19.199.3
docker_container:
name: postfix
image: boky/postfix
restart_policy: unless-stopped
networks:
- name: postfix
env:
ALLOWED_SENDER_DOMAINS: "{{ base_domain }}"
MYNETWORKS: "{{ mynetworks|join(',') }}"

View File

@ -0,0 +1,31 @@
---
- name: create privatebin volume folders
file:
name: "{{ 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: "{{ privatebin.volume_folder }}/cfg/conf.php"
- name: privatebin app container
docker_container:
name: privatebin
image: jgeusebroek/privatebin:latest
restart_policy: unless-stopped
volumes:
- "{{ privatebin.volume_folder }}/cfg:/privatebin/cfg"
- "{{ privatebin.volume_folder }}/data:/privatebin/data"
networks:
- name: external_services
env:
VIRTUAL_HOST: "{{ privatebin.domain }}"
LETSENCRYPT_HOST: "{{ privatebin.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View File

@ -0,0 +1,38 @@
---
- name: setup restic backup
docker_compose:
project_name: restic_backup
pull: yes
definition:
version: '3.6'
services:
restic-backup:
image: mazzolino/restic
restart: always
environment:
RUN_ON_STARTUP: "true"
BACKUP_CRON: "0 30 3 * * *"
RESTIC_REPOSITORY: "rest:https://datacoop:{{ restic_secrets.user_secret }}@restic.graffen.io/datacoop-hevonen"
RESTIC_PASSWORD: "{{ restic_secrets.encryption_secret }}"
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:
- /docker-volumes:/mnt/volumes:ro
restic-prune:
image: "mazzolino/restic"
environment:
RUN_ON_STARTUP: "true"
PRUNE_CRON: "0 0 4 * * *"
RESTIC_REPOSITORY: "rest:https://datacoop:{{ restic_secrets.user_secret }}@restic.graffen.io/datacoop-hevonen"
RESTIC_PASSWORD: "{{ restic_secrets.encryption_secret }}"
TZ: Europe/copenhagen

View File

@ -0,0 +1,25 @@
---
- name: thelounge volume
docker_volume:
name: thelounge
- name: upload thelounge config
template:
src: files/configs/thelounge.js
dest: /var/lib/docker/volumes/thelounge/_data/config.js
- name: thelounge container
docker_container:
name: thelounge
image: thelounge/lounge:latest
restart_policy: always
volumes:
- thelounge:/home/lounge/data
networks:
- name: external_services
- name: ldap
env:
VIRTUAL_HOST: "{{ thelounge.domain }}"
LETSENCRYPT_HOST: "{{ thelounge.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"

View File

@ -0,0 +1,53 @@
---
- name: create tt-rss folders
file:
name: "{{ ttrss.volume_folder }}/{{ volume }}"
state: directory
loop:
- "config"
- "db"
loop_control:
loop_var: volume
- name: "set up tt-rss"
docker_compose:
project_name: "tt-rss"
pull: yes
definition:
version: "3.6"
services:
ttrss_db:
container_name: "ttrss_db"
image: "postgres:11"
restart: "unless-stopped"
networks:
- "ttrss"
volumes:
- "{{ ttrss.volume_folder }}/db:/var/lib/postgresql/data"
environment:
POSTGRES_USER: "ttrss"
POSTGRES_PASSWORD: "{{ postgres_passwords.ttrss }}"
ttrss_app:
container_name: ttrss_app
image: "linuxserver/tt-rss"
restart: unless-stopped
networks:
- ttrss
- external_services
volumes:
- "{{ ttrss.volume_folder }}/config:/config"
environment:
VIRTUAL_HOST: "{{ ttrss.domain }}"
LETSENCRYPT_HOST: "{{ ttrss.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
TZ: "Europe/Copenhagen"
labels:
com.ouroboros.enable: "true"
networks:
external_services:
external:
name: external_services
ttrss:
name: "ttrss"

View File

@ -0,0 +1,13 @@
- 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: "{{ ulovliglogning_website.domains|join(',') }}"
LETSENCRYPT_HOST: "{{ ulovliglogning_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
labels:
com.ouroboros.enable: "true"

View File

@ -0,0 +1,57 @@
---
- name: setup data.coop website docker container
docker_container:
name: data.coop_website
image: docker.data.coop/data-coop-website
restart_policy: unless-stopped
networks:
- name: external_services
env:
VIRTUAL_HOST : "{{ data_coop_website.domains|join(',') }}"
LETSENCRYPT_HOST: "{{ data_coop_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
labels:
com.ouroboros.enable: "true"
- name: setup new data.coop website using hugo
docker_container:
name: new.data.coop_website
image: docker.data.coop/data-coop-website:hugo
restart_policy: unless-stopped
networks:
- name: external_services
env:
VIRTUAL_HOST : "new.{{ data_coop_website.domains|join(',') }}"
LETSENCRYPT_HOST: "new.{{ data_coop_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
labels:
com.ouroboros.enable: "true"
- 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 : "{{ cryptohagen_website.domains|join(',') }}"
LETSENCRYPT_HOST: "{{ cryptohagen_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
labels:
com.ouroboros.enable: "true"
- 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 : "{{ cryptoaarhus_website.domains|join(',') }}"
LETSENCRYPT_HOST: "{{ cryptoaarhus_website.domains|join(',') }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
labels:
com.ouroboros.enable: "true"

View File

@ -1,17 +0,0 @@
# 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

@ -1,17 +0,0 @@
# 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

@ -1,27 +0,0 @@
# 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

@ -1,21 +0,0 @@
# vim: ft=yaml.ansible
---
version: "3.5"
services:
diun:
image: "ghcr.io/crazy-max/diun:{{ services.diun.version }}"
command: serve
volumes:
- "./data:/data"
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
- "TZ=Europe/Paris"
- "DIUN_WATCH_WORKERS=20"
- "DIUN_WATCH_SCHEDULE=0 */6 * * *"
- "DIUN_WATCH_JITTER=30s"
- "DIUN_PROVIDERS_DOCKER=true"
- "DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true"
labels:
- "diun.enable=true"
restart: always

View File

@ -1,23 +0,0 @@
# 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

@ -1,40 +0,0 @@
# 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

@ -1,22 +0,0 @@
# 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,22 +0,0 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
web:
image: docker.data.coop/unipi:{{ services.fedi_dk_website.version }}
restart: unless-stopped
networks:
- external_services
environment:
VIRTUAL_HOST: "{{ services.fedi_dk_website.domain }}"
LETSENCRYPT_HOST: "{{ services.fedi_dk_website.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
command: --remote=https://git.data.coop/fedi.dk/website.git#main
cap_add:
- NET_ADMIN
devices:
- "/dev/net/tun"
networks:
external_services:
external: true

View File

@ -1,38 +0,0 @@
# 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

@ -1,44 +0,0 @@
# 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

@ -1,42 +0,0 @@
# 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

@ -1,146 +0,0 @@
# 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

@ -1,146 +0,0 @@
# 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

@ -1,36 +0,0 @@
# 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

@ -1,44 +0,0 @@
# 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

@ -1,36 +0,0 @@
# 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

@ -1,59 +0,0 @@
# 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

@ -1,38 +0,0 @@
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

@ -1,58 +0,0 @@
# 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

@ -1,38 +0,0 @@
# 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

@ -1,21 +0,0 @@
# 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

@ -1,22 +0,0 @@
# 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

@ -1,20 +0,0 @@
# 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

@ -1,41 +0,0 @@
# 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

@ -1,50 +0,0 @@
# vim: ft=yaml.docker-compose
version: "3.8"
services:
backup:
image: mazzolino/restic:{{ services.restic.version }}
restart: always
hostname: {{ inventory_hostname_short }}
domainname: {{ inventory_hostname }}
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

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