Compare commits

..

1 commit

Author SHA1 Message Date
benjaoming 5f4ac95280
Add security and password policy customization
I need someone with a functional Docker setup to help test this :)

Tip from a new user that we are requiring stupid password stuff

https://www.bbc.com/news/technology-40875534
2021-12-28 23:51:52 +01:00
123 changed files with 1995 additions and 2837 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* *.sw*
.vagrant/ .vagrant/
*.log *.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

40
Vagrantfile vendored
View file

@ -1,38 +1,24 @@
Vagrant.require_version ">= 2.0.0" Vagrant.require_version ">= 1.7.0"
PORT = 19022
def provisioned?(vm="default", provider="virtualbox")
File.exist?(".vagrant/machines/#{vm}/#{provider}/action_provision")
end
Vagrant.configure(2) do |config| 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.define "datacoop" do |datacoop|
config.vm.hostname = "datacoop" datacoop.vm.box = "ubuntu/bionic64"
datacoop.vm.hostname = "datacoop"
config.vm.provider :virtualbox do |v| datacoop.vm.provider "virtualbox" do |v|
v.cpus = 8 v.memory = 4096
v.memory = 16384
end end
datacoop.vm.network "private_network", ip: "192.168.0.42"
config.vm.provision :ansible do |ansible| datacoop.vm.provision "ansible" do |ansible|
ansible.verbose = "v"
ansible.compatibility_mode = "2.0" ansible.compatibility_mode = "2.0"
ansible.playbook = "playbook.yml" ansible.playbook = "playbook.yml"
ansible.ask_vault_pass = true ansible.ask_vault_pass = true
ansible.verbose = "v" ansible.host_vars = {
"datacoop" => {"ansible_python_interpreter" => "/usr/bin/python3.6"}
# 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
} }
else ansible.groups = {
ansible.extra_vars = { "all" => ["datacoop"]
from_vagrant: true
} }
end end
end end

View file

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

View file

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

View file

@ -1,26 +1,6 @@
#!/bin/sh #!/bin/sh
usage () { BASE_CMD="ansible-playbook playbook.yml --ask-vault-pass"
{
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
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "Deploying all!" echo "Deploying all!"
@ -30,21 +10,10 @@ else
"services") "services")
if [ -z "$2" ]; then if [ -z "$2" ]; then
echo "Deploying all services!" 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 else
echo "Deploying service: $2" echo "Deploying services: $2"
$BASE_CMD --tags setup_services --extra-vars '{"single_service": "'"$2"'"'"$(test -z "$VAGRANT_VAR" || printf '%s' ', "'"$VAGRANT_VAR"'": true')"'}' $BASE_CMD --tags setup_services --extra-vars "services=$2"
fi 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 esac
fi fi

View file

@ -1,185 +1,102 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
31303330643235313132323363306532616164646565636532646131386663633330333335353938 32336562633266653862666430393834306131343538636136643866306639313132383063393335
6632373337386339323566373163306435663562303663320a666438653936356335653534353464 3437383263343337323637616330383761346661383065390a396466663135313433643830316439
37373932623562326430396132316138373930383365313433646536343839636637386232306235 65626336303339653730643435353366633839366165393463663031333030356464373338353765
6566393031643037340a643463373163663062643932353931646366306566346230336362623561 3662646137623936650a633038376161633737376432306466663938333838333339626235663362
30323138333636343165666239393138653462396538386139376432346335373066363366613535 34303237306533343435346361346461613339323931666461313261623936653936656439663139
38623130333434386266393363306139333666393537663161626666323262646364636136393736 39666639616234653565303235313866636463656237363861636366666433393631366364623534
37656438373365353335633237326635636263653534353961396562646535303764613564306133 39313638363231646539383133383938353439356335313263656362376538623531636166383233
39373362343133643536383937386633373437333763636331663761646432663636373738373332 32653461653965303835613833383736396563306436623762613138343665343461623964666464
36383638363539663034303536636264336230636630636331336438333338356431666332313931 31363836343534616235323238663262343963376133636337333937353732623938616434333666
66653738656263613739333835366139633335643661373135396333346361343032303832353562 37386231356633653034656130383463643065373935633334653766396539326262646465376338
61376531343861656532626630623330336362373666343863373738306430616530373565663438 31346134356162613266393132313839363166623562316230313338373062393535363236363133
37373131646233656533633466356162326162616433613964616530393734336438326133373763 62653261663865323933323061353864643435323538633733363030356636653162616237323839
65663266313939363361396231663564663664393363373061646436653535663338336138373961 33636235396166326336303133613431326231356434383431623366386437303162396234626563
66303662323930376564313562376661336162316430316439313565633935323835386561356333 66333232343234613661363339653234343333323965353537353337303964653066356664303265
61393330333965633764633364366336646166353031613438373234333436326330336537643464 62333237343334333836623566643633656134353034623630323361376562353464636538623664
32383732336166303535393837353061353333386363356162323966336138363864663464356430 65313435316533633834303734636233333164616230393664646261663133323536356338323430
62396530393234666339346537616637323334383365663732663365653636383036616263303362 38623734366530313461653062376136336634386132333138666439326636373536636134333432
38623063623035616336346562396263336236376435386264336632336165336463613932383465 61396432353962366333373961323263633036656362653330393236333737306664633335313438
37323634633831363938616137373335653130303465383939303332333131363866303863383965 34383335313933613930376436323236343539363035323461333366646462623961633933313432
62333866333830666361613637333230363566333035366664353034303766633264643365343566 38656530653336306130313932393162626437383736393162656364333162623831356163303365
30326530383562633764643630363963646337363865343431353530353036616434363062313132 66343433316131313332346537343863343966323765373035306661366633336261306661363966
37393661326139613732636236633239653837333063646566653861643635363537386137393434 39326131336561633463613731396663336639613634636631373435623263353961323539623162
64616437363666653664303132666630376665646666323733376164653636623465623964336638 30383831393164373632336265373662663936336131306563323833643236616338653835633832
33623838616330353265333733343261356462613665653530333431343732646136346164626534 33383530623733386564373935663437613366633536386131363465363466306632373535646661
34343463646262623464613832393963633366353835393531653634623234393230343430666161 62616531363737336536616132343034663038623665666636613232663666303164663661366232
62306164616636616461306464333536333265313765326665626331363463363038393935653334 33626536336435323031663662383836326331633262386634393333373630343431333461393234
64646132393835656366643239303063333233303331373961346631633034343136623663666462 33656664666466623262353533363833616663303637393164633633336438393131366261326230
64306262636636346131333662626639323865343435373037306130366566343230656338626537 63623266353432613832633163663363663964303461386366373236386131376336623138366134
62336234373136326330306633306637326239356439326339373839383130623836383338373561 33626234383661646637323062363265623630663061353630313466626632623062386638643433
32646163616336623838373436303464643937333164643639623631393764623064626235303733 36333262666562396433393866393362303134616664616531386637336233306334383434616238
61633063303962343931333437313031653435636432393531393130336234613462343838366363 62353237396432353335316631336265326135616430383735353638346339623539393064373365
35383134303137633833363233376365666538333535306434373139333633386630636161636261 66336463653139323962333065666363363733376161613434363830663161303735306264396339
63373339386364326231366634303962636437353336346461336661396566623034306132326332 35643535326130313033636135656634303731323030623131613866653932346665343365343537
33633434326365353438313362616664393264633937393762336264633061313134656536363062 30393534346438343833336262646161643665613639373835336438663664643763323735646566
37303861663732336238386331363164363436363966393534613332393230666266616364303661 30303339386131353863643463383333616432333262633962656434343563323165366533643730
31323633656332643839616434313066643833616639353562386432663538366563633766393639 36646431336361316234393731373563656164646437636536353530343731373531373932313633
33636534363263633261323533666366366665323437346431653464646233303636366231626535 61363462386663333465333465363864643039346238303635323362646335363037323437633462
33373134333163373633313739626636303830383232616663636639646564643436313331643334 62373839666639326465383766333462356635636163376366373764373462386430616566386564
37663132343030666566333431633136653064626466626362373864613334663737326233313138 39353662346632623661326238306136373364343231303664626630663761643433393033633335
38336261663765633331393766333965613364306136333362626466623235303033396362346365 62336232376134656537383632643730303330353533626634633138383163356533646461656230
36633963333561366265633633303262393832336364333365313336383066363065316133303634 31373733326436323937373537363839653034356137343864656364313831336235396530373265
65363037646566323831363365653937623966323735353439353339616439306534663831653663 31663035326365373033313030363032343030346635343333656637343961303861393336316134
34623537666435313661326631326235313130363938643635666531636165306539663630366265 35383635393737643935646334373865386637373636303162363562326239326433396466396435
65323234613133663337363466336663633464316361656564326136633064373365373239363662 66336235373238326662323763333733636635313862653233353165346233313663353164383937
37323834633163653938633435323763333539396532393664653162643832646535353262336631 37373934343261373462373832363633323438663536356133343464316563316362343932396234
61386237663136336338663165613238663035386361643135333361383666643432396363363132 30343335396562336433353233306132656239663036663064653235376264653933363636326132
66323832643339346534373066326333396232386166383161383764633338373533623236346366 33353064663930626330386562396564323965393432353430326362616235353464623861313336
33373138303864323532363761313762376439343130316432613933353033363536336337363566 37363333623736306632643931356138373031363938363966616632666236346265323562306538
31396133663330323665313033656436396238623630633465313734343063633537323939356337 39303365613463393964376536383431326661323237616538353333373930616438633630633961
62306364633765323834333836316161366531643763333434383062363032653164353037336562 35303436353231373133666165306534346137396662653736343135303431613438363864616237
61653332333062643362386665633665306662356532653031383365356632643861363038383137 65643338633065663266303232643264316564373066663038306632653962626336346639393061
36326666356231396433363538666131353839353366323934343532306532633866623733663138 33326638323066323264353338636535336363376639646233336234643137646262666238363865
33376665333430653533383439373463323661666165333636353434643739386363356536333837 34623236396437623539653466653331326434643036663930333065393836383265613036393233
39313365643039386638623731386635363632376139666638643734303035386564376136656537 64333530636138356361643635613933313335636662646666656131613834376632313734373261
39356162346164313839373931653139386464653232633339616166306235323232336139306538 66626262373630386337303539323332343831373731643830323661656435626266386633366666
32623135666535633462613430646637313030343933653461333230656564396663653364633238 38626330663635623262336435373432383066393335633261383633343633616564353135613334
30336161323431323337636135323539663466323637313366376535666132663662356239366339 34616663333562643232333133626433313265316561633638633236343334323337643066386363
66373830336132336439653637366664656230323834623039306337636433663931373138616466 33316637303533393165656665373931313666616330316465643531303730333036613965383161
30616437376435643535303237313831383534656634353265386565376564623431616263643334 65346133303835643134643030373966636632663937343434633263633161366236613039313866
65613633656533646138663138393831623330363635313662653264646636396461326664633362 63343362303866313732326438393262643630633461316534313638343230653462636330363437
38633765316333373363616563346230393866363365623862333162306263613938373663633963 36613561366235646465326163343165633764333466643766316235396534363366366238626161
31363639613238316334333437326631353830383734393765303037346436343036386437653637 32656566386130623962643865643562623338353939306463663034653939383864356164316332
32636139313464383264376663393730363038343831336565663565383135653139663765303239 34396661303364323430323764346438393165313430623464373436323337303966613437626136
31653036623138316566666461313665663462383662343461353332366634666437363263373864 34303166396636666237383138636230306161323161343738353062383262373631643637366139
30323564343934386666666338373238383333303939626237363131346261386562663566323365 36313033623162366530366130376338623634363661623965643364666330313066646233303963
37316563653231346336343166646661393431363739346237303161363838613237666533353034 65353137616236396266336238346562343331363964356237356132303734326138646164663961
64623435376462613961326333393930346663353737386130346461616638363639386364313266 62383761663837326431343939666432663132396464646439626364373833653164313931353631
34353465326632356233343633636331343638333937303562356133363432323939633865316630 34633737333961646137663764363763356138396264353534303236633135643936313039303565
33353539653162333734653338363764313439376439656435313932626431313930346662633838 37663937613961643563346130653536653236346165633333383666623961303138363961646138
39636463393861396531633833343264393339323133316566356562613932663131633631303065 36613062346562326537656236343835383663386235353638653861613865333635333161326337
31323937663764613563333736313733326639643961653161303237353165343939666461396263 66343664373262383164313838393261663566393838633364363931653164613663643966643063
34323136356632336138643162326163653331616561626263616132393734396237666434326264 39656261643733663763383339653433616231653737623865353038646331373334666232346334
65653837383063306436643466383964386661643336343230393436326139313963633036613065 39653730613439393532326430623239666239616361313738343738376536303839623938396439
31393930386463626131653565393932386462313236623531616235393064656237663837346539 37393134343333383430303963356563633862336134373962306634613261653131636631626638
34333730666337353537613564363531363831323035353532363366363731306335316138366361 35613635643336306435643832383761353465633537666563333763646338656164333661666462
37353438326130366439303136356636653030666464366436366566626464626262663838393462 38643765313865626535326136343365643362373234326262366332653264363863646539366630
34626662396239636536666433636436316535363539636261343131313430613765353836643133 36623635396635363636373139383530633332386263656339396433653936333834656631373637
38653839336663353663313535633231363765636633666363386561303039313438353838643561 65663564353938623737303332373261623862646566386230313865643835323231373933303165
32643131623162386661653464623461623434313733643564343435386636326531633136306139 39356561656534326661346636633933613532373137393737623737383134333132363436373630
38613937336132653238616561356338303264393962306431356463613764613364363738323366 63653139356565356566663532313736613437623634313236663537376462383465613332656233
31326562613764386533353135643737323161616363656362326262653765353764626166363338 65306131356165366131633432383730356163326561326332346535373738636333333165666365
34646231633764383962326135323164326565343034656430326531653231666633666465336231 31636564303838333061323063653135623162636464656263613538306561303361633864383634
62366635356566613766643832386234383766363236306638623133643036643662396430623330 35613164386334646338613661356134303766393239366530666137376362646263333530623565
31396239366338656565346563313430353463366465373534636536393131303166333263613663 34643166313038376136643032393630303435376631336366343632383735626335333232303463
36393864663636333666396566303638646166346665303765343531313661376632623137613131 33643363313434363633393964323064653966353161636135633264333766386266646366316132
32653031343861363831646635356232353836363536613834343663326261623262336336393838 63303935356138356566306234356435343961356166646430633335386435366666333234636465
35623638636538626566353864343362633264366435383633333562366365326432663839613934 36336439663731643663353732353261313037363231306430373962613838616238313662343761
34323466396565303963333531346362363338623537343439666265353332303230356533323834 33316335316236626631636636386137376263323862306262316366663039396334326564303762
61333838356665653138346337336532333931616432353936306261356537663036643064333964 34623562363839386439366639323662393831653530663463396230663133396466326363303065
39643065303032393932323136363264316264386131353035383933386535303632613033633363 35646635323439323062333864336332333938663536373834663535643832316532313262326265
66346437333465653633626235336336353738343036326265376162383163326530373032663335 63376436356662663165616532613963303030613166663865376531613031383865363864333238
66643663666166366165396137383133396635336237343161303666393437303538316661336335 33616230336263306434643933356530303163653232323331643731353134353939363762303933
32396434323532303238303538303864393031303832346161303535386461666161316565646539 32363061346537666637663733346431643164323364363133316265306336626466353366313635
37303261336435323139663962316562346265343064346562393633616666653066623466316634 66653162643533316162363035373532656239356434623761666663626366663336376539656537
61346263366161366232386138666131323162333031623533303739646336623864613333323662 31323561356363393038323762646633323461666263633937313264346364356439343761623337
35363539646433323430313839633363393936356438313037613434663161653964366635363464 34643731393763323339653636656565663665646431313531616337616363373764626334656264
62643539393631386531313966643339383865623065393936666235653035376139656663616336 66633366346137613032313865666363613530643663373834313731353437373239653332656134
65663136326466616161376232316463643834356531336362336163343637326238663836363734 62376164313138303233623964663234643661336232366165616163313866336230353565393365
30363032653962306530633562636161396634363131633065326433363136316666633738343966 36613361346437336431376164663930393530626339626361323764623635396137396634316364
66303939383232373738373965393934653439396666623039353933633935393731653839623737 31393030323539376233383965366433623562646161643866346138316536613437383035656139
35376338363338306332353539313664303962353064306434323530623161323064633766643035 6533
38363234343036616335393461643964386664616134313831663565633366616633626266393937
31623435646138646131356164313936656639393532343630663933613066333432666132363338
30356136303763376465396637613565386661333265633636643435313035313064383936306437
39626265643862313435343465643063656266373035356538393262363561356433323134333537
66663233313832326136366163623337373835663961313938636134613933663534333730333761
39313334346364623431646439386162633961316161393636656139303966626265623035366335
66666634363036326631376562623039303961663136366461313637343932303338356334383139
38383133306436303261643535353532383538613764616233363864656665633264623236623537
31353335343064626465626130356433366531306338623830623139316462316662633665663164
38363363656237326239633930623862663230623464663031363463356133626166353433633535
63343231326438383535356235343530393361636465363933356164323565326566303034383466
63323136643835623563393666333030656534333565316466333266663365346561363937336665
32323637366138303233373565333932626435306130633064656336623764366130323534333039
64613934383530343036343334396439373066326264353638353462613266663935343436353130
38616238313133363732343634663962666435656330396536643836326636373032623734353832
32313064663164626534336363376131656438623035646263666336633862613833323565656437
63616463613732663966643039653761633231616462363761336231313335363165646134356137
38633963393264653139356333626534303936326563326433363164623131393562393533383564
62646532643366376333373364646139363635323034613262386265383066303365323134633836
66666536653264393138326436393037373537393561613864343730366135353166633765323938
38306562326238613331343337306239376165636562666433356266313030613136656162646166
36303966373931363463383631386136313262633136383637626562353336306465613435336434
32303136393638396233393232386534643733626539653961366637316135373439386432643264
63663837306461376461306664366538396436386234366638626263303735323661393839343938
36393264306132313130326435636266643363616438613538303530306434636331333033323138
39656337666635363263316363363133616538356336646337373762613666323663656665383733
31623433396466383939306666373562303330373731323864363266323261383736353465633662
38356130353233663161623139653465646238363630643239386634623262303836333232303239
61313930346263643565333534373430653430363965373037646639633638333861346262373433
65346133636162396332373130356238346438626330373163326632323137333862373436363133
37373663396461613062616664336662373432383863333536366465313838333835653966353661
38343336316136316532613661306336636131653236663336396638316136626434303533323365
38356534353530633766646466663266613735396333386263356662613939373030396436363530
38333939623534356266323237623835373038663534616532326665346631616665616665666663
33633266333630646563363637666562336339393138326435373836336566346661646464613730
39616438373062656130393134353535313232376266386262623862383162366662626231373338
37373561376435323361316337636239366263656336303636346436373363663164343333656538
32633835353436623565393538643563646630366633343632633532396433616139303766666435
30373235373262633134383033363137316366316563613662313437663832356165353661666533
63343138393230333335323938666566623365623762643563633036613339636537366264333138
62656265363261663233396266616466333332633266326661373736353135383563313666633765
37316430633763326438326263643766396137363333353035623036346662303834376463613162
30363938396638336565303535663831326135393061383634646430343931373135636638333866
64623032366163386530313563656266376334343835366665633362643339643534643738373839
34323134636330383963353439376436323530373066623435376230306435333832633964653639
39373235353262383864303430336635393435656430646233613461306135643230666437393361
36616134356461616534646535396338656138616636396538373031626136323264323936366633
61373631306538363437323934316434663735323533656364393135613761326337303833383934
37383162356162373737336666663430343334356532333335363463623238643662333232333336
31376639386632626161303232653363626637376630333733343035323539623463626132373763
36613535623064636163643236383336653934663739326264653362333237303237393335613339
30323030353632613434393636336562363064306332663931393061393964393661363163326632
37353434656464333532343263363961613866643338396335656131373134333665353437613837
37336533366635616138366566666635366634613633616533373966336637303334613731316436
66376565643033383162373166373665633362313164643530356561383630343531346436343663
62313836323530623535356532303362333436643434663131653539646331346535666133336162
37653036376165333364373661386262633030363165353638386139646266623365306338383963
36373732356364333166386566653835663466346630356438323866636564663966363832613862
64623831646261333064663939613763323466336431343861386537633337396637383330333633
32636436343564633365616331626465613163333465373961656631373736373430396633393733
64386534353131666438346362376462636331353761636535663234613731356130666534323735
35636162323234386435646132396366326165663234653637363139303162613832346333383665
64323737306634613530633636643761346461326130663234373363326230616331336430353261
38346630356136333966656562343730356234643537323635653532396337373331363537393662
33373862336232623563636436643239623837623862386638353361383830303365333362353665
33666236363035616363326462376337363736333234613133383636396464306236386238333863
39316237326638663535646361393939393938656335653262633063326132663331343235626364
35366532333161343562383763653130306235633934393066356239653565633962343235643036
62333363323065663137393736383964613061393131376637363031393335306534626230383139
35333437613963386664646336383637323534366635336264333039643861396561373461636439
30323831333335393365383834386138626664653531333830363862363330346466646432656663
62383534343131636331353763356166386339303564353035383466353636636335653333383431
30616133383565623430326534396432376331636161393930366263366539343332666631616530
36383937313164663631626163646339623365653937616634656235303039636439646335616561
31623135366136333766663833333932383032343438376336366533636466353666633437353338
33386166386231353430646665323164363961666538343537313734343465366333383763666666
33326363656134613031393033646435333937353865316161626137633939333934316536643830
37386364356233353964326661386564656132643937366665353139653533336331323138356633
35656562663961343238386132636331636439383236383761306337626262303764656431303964
62646133323361643162313231376633663231313833633964613862353265336538633261643834
62353230316334363363343133626530643832356631353937353334613538616366396438383338
39336366623332363966383535373365666263383231356532346533386262643465306430336462
64623764333861663031

View file

@ -1,17 +1,18 @@
# These are the variables contained in secrets.yml # These are the variables contained in secrets.yml
# Secrets are usually 32 characters or more, matching [a-Z0-9] # Secrets are usually 32 characters or more, matching [a-Z0-9]
---
postgres_passwords: postgres_passwords:
fider: xxx
nextcloud: xxx nextcloud: xxx
passit: xxx passit: xxx
gitea: xxx gitea: xxx
matrix: xxx matrix: xxx
codimd: xxx
mailu: xxx mailu: xxx
ttrss: xxx
keycloak: xxx keycloak: xxx
hedgedoc: xxx
mastodon: xxx fider_jwt_secret: xxx
rallly: xxx
membersystem: xxx
ldap_admin_password: xxx ldap_admin_password: xxx
ldap_config_password: xxx ldap_config_password: xxx
@ -22,18 +23,14 @@ docker_password: xxx
mailu_secret_key: xxx mailu_secret_key: xxx
nextcloud_secrets:
redis_password: xxx
drone_secrets: drone_secrets:
oauth_client_id: xxx oauth_client_id: xxx
oauth_client_secret: xxx oauth_client_secret: xxx
rpc_shared_secret: xxx rpc_shared_secret: xxx
restic_secrets: restic_secrets:
repository_password: xxx user_secret: xxx
ssh_privkey: xxx encryption_secret: xxx
uptime_kuma_url: xxx
matrix_secrets: matrix_secrets:
registration_shared_secret: xxx registration_shared_secret: xxx
@ -41,22 +38,5 @@ matrix_secrets:
form_secret: xxx form_secret: xxx
keycloak_secrets: keycloak_secrets:
admin_user: xxx # used for setting up the initial admin user on first run admin_user: xxx //used for setting up the initial admin user on first run
admin_password: xxx 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
stripe_api_key: xxx
stripe_endpoint_secret: xxx
diun:
matrix_password: xxx

View file

@ -1,35 +1,24 @@
# vim: ft=yaml.ansible
--- ---
users: users:
- name: graffen graffen:
comment: Jesper Hess Nielsen comment: Jesper Hess Nielsen
password: '!' 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)
groups: [] password: $6$6bgPWZ76LvB$DZ3ipFsFtL2b1nSC0AQ63k8ibJidyIE9iIsWWzY0fux0ynz9L/o7b2sR2XYSaDuG.jewFV36IGStTF3NCZRC30
ssh_keys: [] groups:
- sudo
- name: valberg valberg:
comment: Vidir Valberg Gudmundsson 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/ password: $6$qt3G.E.CxhC$OwBDn4rZUbCz06HLEMBHjgvKjxiv/eeerbklTHi.gpHIn1OejzX3k2.0NM0Dforaw6Yn5Y8Cgn8kL2FdbQLZ3/
groups: groups:
- sudo - 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 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 password: $6$MiPv.ZFlWnLHGNOb$jdQD9NaPMRUGaP2YHRJNwrMPBGl9qwK0HFhI6x51Xpn7hdzuC4GIwvOw1DJK33sNs/gGP5bWB0izviXkDcq7B0
groups: groups:
- sudo - 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 volume_root_folder: "/docker-volumes"
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

View file

@ -1,27 +1,39 @@
# vim: ft=yaml.ansible
--- ---
- hosts: production - hosts: all
gather_facts: true gather_facts: False
become: true become: true
vars: vars:
base_domain: data.coop
letsencrypt_email: bestyrelsen@data.coop
ldap_dn: "dc=data,dc=coop" ldap_dn: "dc=data,dc=coop"
vagrant: "{{ from_vagrant is defined and from_vagrant }}" services:
letsencrypt_enabled: "{{ not vagrant }}" - nginx-proxy
- openldap
base_domain: "{{ 'datacoop.devel' if vagrant else 'data.coop' }}" - thelounge
letsencrypt_email: "admin@{{ base_domain }}" - 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_host: "postfix"
smtp_port: "587" smtp_port: "587"
services_exclude:
- uptime_kuma
tasks: tasks:
- import_role: - import_role:
name: ubuntu_base name: ubuntu_base
tags:
- base_only
- import_role: - import_role:
name: docker name: docker

View file

@ -1,229 +1,101 @@
# vim: ft=yaml.ansible
---
volume_root_folder: "/docker-volumes" volume_root_folder: "/docker-volumes"
volume_website_folder: "{{ volume_root_folder }}/websites"
services: nginx:
### Internal services ###
postfix:
domain: "smtp.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/postfix"
pre_deploy_tasks: true
version: "v3.6.1-alpine"
nginx_proxy:
volume_folder: "{{ volume_root_folder }}/nginx" volume_folder: "{{ volume_root_folder }}/nginx"
pre_deploy_tasks: true
version: "1.3-alpine"
acme_companion_version: "2.2"
openldap: ldap:
domain: "ldap.{{ base_domain }}" domain: "ldap.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/openldap" volume_folder: "{{ volume_root_folder }}/openldap"
pre_deploy_tasks: true
version: "1.5.0"
phpldapadmin_version: "0.9.0"
netdata: thelounge:
domain: "netdata.{{ base_domain }}" domain: "irc.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/netdata"
version: "v1"
portainer:
domain: "portainer.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/portainer"
version: "2.19.0"
keycloak:
domain: sso.{{ base_domain }}
volume_folder: "{{ volume_root_folder }}/keycloak"
version: "22.0"
postgres_version: "10"
allowed_sender_domain: true
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 }}"
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"
### External services ###
nextcloud: nextcloud:
domain: "cloud.{{ base_domain }}" domain: "cloud.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/nextcloud" volume_folder: "{{ volume_root_folder }}/nextcloud"
pre_deploy_tasks: true
version: 28-apache
postgres_version: "10"
redis_version: 7-alpine
allowed_sender_domain: true
forgejo: gitea:
domain: "git.{{ base_domain }}" domain: "git.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/forgejo" volume_folder: "{{ volume_root_folder }}/gitea"
version: "7.0.5"
allowed_sender_domain: true
passit: passit:
domain: "passit.{{ base_domain }}" domain: "passit.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/passit" volume_folder: "{{ volume_root_folder }}/passit"
version: stable
postgres_version: 15-alpine fider:
allowed_sender_domain: true domain: "feedback.{{ base_domain }}"
matrix: matrix:
domain: "matrix.{{ base_domain }}" domain: "matrix.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/matrix" volume_folder: "{{ volume_root_folder }}/matrix"
pre_deploy_tasks: true
version: v1.114.0
postgres_version: 15-alpine
allowed_sender_domain: true
element: riot:
domain: "element.{{ base_domain }}" domains:
volume_folder: "{{ volume_root_folder }}/element" - "riot.{{ base_domain }}"
pre_deploy_tasks: true - "element.{{ base_domain }}"
version: v1.11.80 volume_folder: "{{ volume_root_folder }}/riot"
privatebin: privatebin:
domain: "paste.{{ base_domain }}" domain: "paste.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/privatebin" volume_folder: "{{ volume_root_folder }}/privatebin"
pre_deploy_tasks: true
version: "20221009" codimd:
domain: "oldpad.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/codimd"
hedgedoc: hedgedoc:
domain: "pad.{{ base_domain }}" domain: "pad.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/hedgedoc" volume_folder: "{{ volume_root_folder }}/hedgedoc"
pre_deploy_tasks: true
version: 1.9.9-alpine netdata:
postgres_version: 10-alpine domain: "netdata.{{ base_domain }}"
docker_registry:
domain: "docker.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/docker-registry"
username: "docker"
password: "{{ docker_password }}"
data_coop_website: data_coop_website:
domain: "{{ base_domain }}" domains:
www_domain: "www.{{ base_domain }}" - "{{ base_domain }}"
volume_folder: "{{ volume_website_folder }}/datacoop" - "www.{{ base_domain }}"
pre_deploy_tasks: true
version: stable
staging_domain: "staging.{{ base_domain }}"
staging_version: staging
slides_2022_website:
domain: "2022.slides.{{ base_domain }}"
volume_folder: "{{ volume_website_folder }}/slides-2022"
version: latest
fedi_dk_website:
domain: fedi.dk
volume_folder: "{{ volume_website_folder }}/fedidk"
version: latest
vhs_website:
domain: vhs.data.coop
volume_folder: "{{ volume_website_folder }}/vhs"
version: latest
cryptohagen_website: cryptohagen_website:
domains: domains:
- "cryptohagen.dk" - "cryptohagen.dk"
- "www.cryptohagen.dk" - "www.cryptohagen.dk"
volume_folder: "{{ volume_website_folder }}/cryptohagen"
ulovliglogning_website: ulovliglogning_website:
domains: domains:
- "ulovliglogning.dk" - "ulovliglogning.dk"
- "www.ulovliglogning.dk" - "www.ulovliglogning.dk"
- "ulovlig-logning.dk" - "ulovlig-logning.dk"
- "www.ulovlig-logning.dk"
volume_folder: "{{ volume_website_folder }}/ulovliglogning"
cryptoaarhus_website: cryptoaarhus_website:
domains: domains:
- "cryptoaarhus.dk" - "cryptoaarhus.dk"
- "www.cryptoaarhus.dk" - "www.cryptoaarhus.dk"
volume_folder: "{{ volume_website_folder }}/cryptoaarhus"
drone: drone:
domain: "drone.{{ base_domain }}" domain: "drone.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/drone" volume_folder: "{{ volume_root_folder }}/drone"
version: "1"
mailu: mailu:
version: 1.6
domain: "mail.{{ base_domain }}" domain: "mail.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/mailu"
pre_deploy_tasks: true
dns: 192.168.203.254 dns: 192.168.203.254
subnet: 192.168.203.0/24 subnet: 192.168.203.0/24
version: "2.0" volume_folder: "{{ volume_root_folder }}/mailu"
postgres_version: 14-alpine
redis_version: alpine
mastodon: portainer:
domain: "social.{{ base_domain }}" domain: "portainer.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/mastodon" volume_folder: "{{ volume_root_folder }}/portainer"
pre_deploy_tasks: true
post_deploy_tasks: true
version: v4.2.10
postgres_version: 14-alpine
redis_version: 6-alpine
allowed_sender_domain: true
rallly: ttrss:
domain: "when.{{ base_domain }}" domain: rss.{{ base_domain }}
volume_folder: "{{ volume_root_folder }}/rallly" volume_folder: "{{ volume_root_folder }}/tt-rss"
pre_deploy_tasks: true
version: "2"
postgres_version: 14-alpine
allowed_sender_domain: true
membersystem: keycloak:
domain: "member.{{ base_domain }}" domain: sso.{{ base_domain }}
django_admins: "Vidir:valberg@orn.li,Balder:benjaoming@data.coop" volume_folder: "{{ volume_root_folder }}/keycloak"
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.28"
volume_folder: "{{ volume_root_folder }}/diun"
matrix_user: "@diun:data.coop"
matrix_room: "#datacoop-services-update:data.coop"
### Uptime monitoring ###
uptime_kuma:
domain: "uptime.{{ base_domain }}"
status_domain: "status.{{ base_domain }}"
volume_folder: "{{ volume_root_folder }}/uptime_kuma"
pre_deploy_tasks: true
version: "latest"
services_exclude: []
services_include: "{{ services | dict2items | map(attribute='key') | list | difference(services_exclude) }}"

View file

@ -44,7 +44,7 @@ pid_file: /data/homeserver.pid
# use synapse with a reverse proxy, this should be the URL to reach # use synapse with a reverse proxy, this should be the URL to reach
# synapse via the proxy. # 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 # 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 # Zero is used to indicate synapse should set the soft limit to the
@ -339,11 +339,10 @@ database:
user: "synapse" user: "synapse"
password: "{{ postgres_passwords.matrix }}" password: "{{ postgres_passwords.matrix }}"
database: "synapse" database: "synapse"
host: "postgres" host: "matrix_db"
port: "5432" port: "5432"
cp_min: 5 cp_min: 5
cp_max: 10 cp_max: 10
allow_unsafe_locale: true
# Number of events to cache in memory. # Number of events to cache in memory.
event_cache_size: "10K" event_cache_size: "10K"
@ -416,7 +415,7 @@ uploads_path: "/data/uploads"
# The largest allowed upload size in bytes # The largest allowed upload size in bytes
# #
max_upload_size: "512M" max_upload_size: "50M"
# Maximum number of pixels that will be thumbnailed # Maximum number of pixels that will be thumbnailed
# #
@ -676,8 +675,15 @@ report_stats: false
## API Configuration ## ## API Configuration ##
room_prejoin_state: # A list of event types that will be included in the room_invite_state
disable_default_event_types: false #
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 # A list of application service config file to use
# #
@ -820,10 +826,23 @@ password_config:
# If your SMTP server requires authentication, the optional smtp_user & # If your SMTP server requires authentication, the optional smtp_user &
# smtp_pass variables should be used # smtp_pass variables should be used
# #
email: #email:
smtp_host: "{{ smtp_host }}" # enable_notifs: false
smtp_port: {{ smtp_port }} # smtp_host: "localhost"
notif_from: "{{ services.matrix.domain }} <no-reply@{{ services.matrix.domain }}>" # 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: #password_providers:
# - module: "ldap_auth_provider.LdapAuthProvider" # - module: "ldap_auth_provider.LdapAuthProvider"

View file

@ -1,2 +1,2 @@
listen 3000; listen 8008;
client_max_body_size 50M; # default is 1M 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": { "default_hs_url": "https://{{ matrix.domain }}",
"m.homeserver": { "default_is_url": "https://vector.im",
"base_url": "https://{{ services.matrix.domain }}"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"brand": "element.data.coop", "brand": "element.data.coop",
"integrations_ui_url": "https://scalar.vector.im/", "integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api", "integrations_rest_url": "https://scalar.vector.im/api",
@ -37,7 +31,7 @@
] ]
}, },
"enable_presence_by_hs_url": { "enable_presence_by_hs_url": {
"https://{{ services.matrix.domain }}": false "https://{{ matrix.domain }}": false
}, },
"terms_and_conditions_links": [ "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 @@
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: apt_key:
keyserver: pgp.mit.edu keyserver: pgp.mit.edu
id: 8D81803C0EBFCD88 id: 8D81803C0EBFCD88
state: present state: present
- name: Add Docker apt repository - name: add docker apt repository
apt_repository: apt_repository:
repo: deb https://download.docker.com/linux/ubuntu bionic stable repo: deb https://download.docker.com/linux/ubuntu bionic stable
state: present state: present
update_cache: yes update_cache: yes
- name: Install Docker - name: install docker-ce
apt: apt:
name: "{{ pkgs }}" name: docker-ce
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
state: present 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: file:
name: "{{ item }}" name: "{{ volume_root_folder }}"
state: directory state: directory
loop:
- "{{ volume_root_folder }}"
- "{{ volume_website_folder }}"
- name: Set up services - name: setup services
import_tasks: services.yml import_tasks: services.yml
tags: tags:
- setup_services - 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: docker_network:
name: external_services name: external_services
- name: Deploy all services - name: setup services
include_tasks: include_tasks: "services/{{ item }}.yml"
file: block.yml with_items: "{{ services }}"
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))

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,28 @@
---
- name: gitea network
docker_network:
name: gitea
# old DNS: 138.68.71.153
- name: gitea container
docker_container:
name: gitea
image: gitea/gitea:1.15.7
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 }}"
# Gitea customization, see: https://docs.gitea.io/en-us/install-with-docker/#customization
# https://docs.gitea.io/en-us/config-cheat-sheet/#security-security
GITEA__security__PASSWORD_COMPLEXITY: "off"
GITEA__security__MIN_PASSWORD_LENGTH: "8"
GITEA__security__PASSWORD_CHECK_PWN: "true"

View file

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

View file

@ -0,0 +1,45 @@
- name: setup keycloak containers for sso.data.coop
docker_compose:
project_name: "keycloak"
pull: "yes"
definition:
version: "3.6"
services:
postgres:
image: "postgres:10"
restart: "unless-stopped"
networks:
- "keycloak"
volumes:
- "{{ keycloak.volume_folder }}/data:/var/lib/postgresql/data"
environment:
POSTGRES_USER: "keycloak"
POSTGRES_PASSWORD: "{{ postgres_passwords.keycloak }}"
POSTGRES_DB: "keycloak"
app:
image: "quay.io/keycloak/keycloak:15.0.2"
restart: "unless-stopped"
networks:
- "keycloak"
- "postfix"
- "external_services"
environment:
VIRTUAL_HOST: "{{ keycloak.domain }}"
VIRTUAL_PORT: "8080"
LETSENCRYPT_HOST: "{{ keycloak.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
DB_USER: "keycloak"
DB_PASSWORD: "{{ postgres_passwords.keycloak }}"
DB_ADDR: "keycloak_postgres_1"
#KEYCLOAK_USER: "{{ keycloak_secrets.admin_user }}" # Only used for the first run of the application to set up the admin user
#KEYCLOAK_PASSWORD: "{{ keycloak_secrets.admin_password }}"
PROXY_ADDRESS_FORWARDING: "true"
networks:
keycloak:
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.j2"
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.47.1
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.9.0
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,42 @@
---
- name: setup nextcloud containers
docker_compose:
project_name: "nextcloud"
pull: "yes"
definition:
services:
postgres:
image: "postgres:10"
restart: "unless-stopped"
networks:
- "nextcloud"
volumes:
- "{{ nextcloud.volume_folder }}/postgres:/var/lib/postgresql/data"
environment:
POSTGRES_DB: "nextcloud"
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"
POSTGRES_USER: "nextcloud"
app:
image: "nextcloud:22-apache"
restart: "unless-stopped"
networks:
- "nextcloud"
- "external_services"
volumes:
- "{{ nextcloud.volume_folder }}/app:/var/www/html"
environment:
VIRTUAL_HOST: "{{ nextcloud.domain }}"
LETSENCRYPT_HOST: "{{ nextcloud.domain }}"
LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}"
POSTGRES_HOST: "nextcloud_postgres_1"
POSTGRES_DB: "nextcloud"
POSTGRES_USER: "nextcloud"
POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}"
networks:
nextcloud:
postfix:
external: true
external_services:
external: true

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.5.0
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:0.9.0
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.9.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,19 @@
---
- 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
docker_container:
name: postfix
image: boky/postfix
restart_policy: unless-stopped
networks:
- name: postfix
env:
ALLOWED_SENDER_DOMAINS: "services.{{ base_domain }}"

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,26 +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"
- "DIUN_NOTIF_MATRIX_HOMESERVERURL=https://{{ services.matrix.domain }}"
- "DIUN_NOTIF_MATRIX_USER={{ services.diun.matrix_user }}"
- "DIUN_NOTIF_MATRIX_ROOMID={{ services.diun.matrix_room }}"
- "DIUN_NOTIF_MATRIX_PASSWORD={{ diun_secrets.matrix_password }}"
- "DIUN_NOTIF_MATRIX_MSGTYPE=text"
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: ghcr.io/element-hq/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,46 +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 }}
STRIPE_API_KEY: "{{ membersystem_secrets.stripe_api_key }}"
STRIPE_ENDPOINT_SECRET: "{{ membersystem_secrets.stripe_endpoint_secret }}"
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: "data.coop {{ 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