The Great Ansible Update.
5
.gitignore
vendored
|
@ -1,4 +1 @@
|
|||
coturn/secrets.conf
|
||||
.env
|
||||
synapse/matrix_access_token.txt
|
||||
synapse/secrets.yaml
|
||||
secrets.yml
|
||||
|
|
20
README.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# vps
|
||||
This repository contains all the files I use to manage services hosted on [viyurz.fr](https://viyurz.fr).
|
||||
|
||||
|
||||
## Requirements
|
||||
Ansible:
|
||||
```
|
||||
sudo apt install -y ansible
|
||||
```
|
||||
|
||||
Setup SSL certificates with Certbot beforehand:
|
||||
```
|
||||
sudo apt install -y certbot python3-certbot-dns-ovh
|
||||
```
|
||||
|
||||
|
||||
## Secrets
|
||||
Copy the existing `secrets.yml.example` to `secrets.yml`, run `ansible-vault encrypt secrets.yml` to encrypt the file with a password, and finally edit the newly encrypted file with `ansible-vault edit secrets.yml`.
|
||||
|
||||
If you want to change the vault password run `ansible-vault rekey secrets.yml`.
|
27
ansible-playbook-selector.sh
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/bin/bash
|
||||
|
||||
script_relative_path="$(dirname "$0")"
|
||||
declare -i playbook_number=1
|
||||
mapfile -t playbook_list < <(find "$script_relative_path/playbooks" -type f | grep -oP '[^/]+\.yml$')
|
||||
|
||||
|
||||
echo "Playbook list:"
|
||||
for playbook in "${playbook_list[@]}"; do
|
||||
echo " [$playbook_number] $playbook"
|
||||
playbook_number+=1
|
||||
done
|
||||
|
||||
read -rp "Select playbook number to execute: " selected_playbook_number
|
||||
|
||||
|
||||
selected_playbook_name="${playbook_list[((selected_playbook_number - 1))]}"
|
||||
|
||||
if ! echo "$selected_playbook_number" | grep -qP '^[1-9][0-9]*$' || [[ -z "$selected_playbook_name" ]]; then
|
||||
echo "Invalid playbook number entered."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
echo "Selected playbook: $selected_playbook_name"
|
||||
|
||||
ansible-playbook "$script_relative_path/playbooks/$selected_playbook_name"
|
3
ansible.cfg
Normal file
|
@ -0,0 +1,3 @@
|
|||
[defaults]
|
||||
roles_path = ./roles
|
||||
ask_vault_pass = True
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# If command starts with an option, prepend it with a `turnserver` binary.
|
||||
if [ "${1:0:1}" == '-' ]; then
|
||||
set -- turnserver "$@"
|
||||
fi
|
||||
|
||||
# Evaluate each argument separately to avoid mixing them up in a single `eval`.
|
||||
expanded=()
|
||||
for i in "$@"; do
|
||||
expanded+=("$(eval "echo $i")")
|
||||
done
|
||||
|
||||
cp /etc/coturn/server.conf /tmp/turnserver.conf
|
||||
cat /etc/coturn/secrets.conf >> /tmp/turnserver.conf
|
||||
|
||||
exec "${expanded[@]}"
|
|
@ -1,25 +0,0 @@
|
|||
services:
|
||||
coturn:
|
||||
container_name: coturn
|
||||
image: coturn/coturn:alpine
|
||||
restart: always
|
||||
user: '666:666'
|
||||
command:
|
||||
- "--log-file=stdout"
|
||||
- "-c"
|
||||
- "/tmp/turnserver.conf"
|
||||
ports:
|
||||
- 3478:3478
|
||||
- 3478:3478/udp
|
||||
- 5349:5349
|
||||
- 5349:5349/udp
|
||||
- 49152-49172:49152-49172/udp
|
||||
tmpfs:
|
||||
- /var/lib/coturn
|
||||
volumes:
|
||||
- ./turnserver.conf:/etc/coturn/server.conf
|
||||
- ./coturn-docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh
|
||||
- ./secrets.conf:/etc/coturn/secrets.conf
|
||||
- /etc/letsencrypt/live/turn.viyurz.fr/fullchain.pem:/etc/coturn/cert.pem
|
||||
# chown root:666 & chmod 640 on privkey file
|
||||
- /etc/letsencrypt/live/turn.viyurz.fr/privkey.pem:/etc/coturn/pkey.pem
|
|
@ -1 +0,0 @@
|
|||
static-auth-secret=XXX
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"default_server_name": "viyurz.fr"
|
||||
}
|
105
env.yml
Normal file
|
@ -0,0 +1,105 @@
|
|||
domain: viyurz.fr
|
||||
timezone: "Europe/Paris"
|
||||
host_uid: 1000
|
||||
docker_projects_dir: "{{ ansible_env['HOME'] }}/docker-projects"
|
||||
|
||||
# UID shift for mapping between host & containers
|
||||
uid_shift: 99999
|
||||
|
||||
|
||||
cifs_host: "{{ cifs_credentials['username'] }}.your-storagebox.de"
|
||||
|
||||
cifs_mounts:
|
||||
backups:
|
||||
src: "//{{ cifs_host }}/backup/backups"
|
||||
path: /mnt/storagebox/backups
|
||||
uid: 0
|
||||
gid: "{{ host_uid }}"
|
||||
file_mode: 640
|
||||
dir_mode: 750
|
||||
storagebox:
|
||||
src: "//{{ cifs_host }}/backup"
|
||||
path: /mnt/storagebox
|
||||
uid: 0
|
||||
gid: 0
|
||||
file_mode: 640
|
||||
dir_mode: 751
|
||||
syncthing:
|
||||
src: "//{{ cifs_host }}/backup/syncthing"
|
||||
path: /mnt/storagebox/syncthing
|
||||
uid: "{{ users['syncthing'] + uid_shift }}"
|
||||
gid: "{{ users['syncthing'] + uid_shift }}"
|
||||
file_mode: 640
|
||||
dir_mode: 750
|
||||
|
||||
|
||||
projects:
|
||||
- coturn
|
||||
- element
|
||||
- etebase
|
||||
- hedgedoc
|
||||
- homepage
|
||||
- reverse-proxy
|
||||
- searxng
|
||||
- synapse
|
||||
- syncthing
|
||||
- vaultwarden
|
||||
|
||||
|
||||
# Ports exposed to host
|
||||
ports:
|
||||
coturn_listening: 3478
|
||||
coturn_tls_listening: 5349
|
||||
coturn_relay_min: 49152
|
||||
coturn_relay_max: 49172
|
||||
element: 8084
|
||||
etebase: 3735
|
||||
hedgedoc: 8086
|
||||
homepage: 8082
|
||||
searxng: 8083
|
||||
synapse: 8008
|
||||
syncthing_discosrv: 8443
|
||||
syncthing_webui: 8384
|
||||
syncthing_tcp: 5432
|
||||
syncthing_udp: 22000
|
||||
vaultwarden: 8081
|
||||
|
||||
|
||||
# UID in containers
|
||||
users:
|
||||
coturn: 666
|
||||
etebase: 373
|
||||
hedgedoc: 1004
|
||||
hedgedoc_mysql: 1005
|
||||
homepage: 101
|
||||
searxng: 977
|
||||
searxng_redis: 999
|
||||
synapse: 991
|
||||
synapse_postgres: 70
|
||||
syncthing: 1001
|
||||
syncthing_discosrv: 1002
|
||||
vaultwarden: 1000
|
||||
|
||||
|
||||
volumes:
|
||||
coturn_tls_certificate_file: "/etc/letsencrypt/live/turn.{{ domain }}/fullchain.pem"
|
||||
coturn_tls_certificate_key_file: "/etc/letsencrypt/live/turn.{{ domain }}/privkey.pem"
|
||||
etebase_datadir: /mnt/etebasedata
|
||||
hedgedoc_mysql_datadir: /mnt/hedgedoc/mysql-data
|
||||
hedgedoc_configdir: /mnt/hedgedoc/config
|
||||
synapse_datadir: /mnt/synapsedata
|
||||
synapse_postgres_datadir: /mnt/synapsepgdata
|
||||
syncthing_datadir: "{{ cifs_mounts['syncthing']['path'] }}"
|
||||
vaultwarden_datadir: /mnt/vwdata
|
||||
|
||||
|
||||
# Service-specific variables
|
||||
reverse_proxy:
|
||||
ssl_certificate_file: "/etc/letsencrypt/live/{{ domain }}/fullchain.pem"
|
||||
ssl_certificate_key_file: "/etc/letsencrypt/live/{{ domain }}/privkey.pem"
|
||||
ssl_trusted_certificate_file: "/etc/letsencrypt/live/{{ domain }}/chain.pem"
|
||||
resolver: "185.12.64.12 [a01:4ff:ff00::add:2] [2a01:4ff:ff00::add:1]"
|
||||
|
||||
|
||||
synapse:
|
||||
max_upload_size: 50M
|
|
@ -1,15 +0,0 @@
|
|||
services:
|
||||
etebase:
|
||||
image: victorrds/etebase:alpine
|
||||
container_name: etebase
|
||||
restart: always
|
||||
user: '373:373'
|
||||
environment:
|
||||
SERVER: http
|
||||
ALLOWED_HOSTS: etebase.viyurz.fr
|
||||
SUPER_USER: v444599a8zJUBud60fu9uk9Vo3xXHinp
|
||||
AUTO_UPDATE: 'true'
|
||||
ports:
|
||||
- 3735:3735
|
||||
volumes:
|
||||
- /mnt/etebasedata:/data
|
|
@ -1,19 +0,0 @@
|
|||
services:
|
||||
nextcloud:
|
||||
image: nextcloud/all-in-one:latest
|
||||
restart: always
|
||||
container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly
|
||||
environment: # Is needed when using any of the options below
|
||||
- APACHE_PORT=11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
|
||||
- APACHE_IP_BINDING=127.0.0.1 # Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else) that is running on the same host. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
|
||||
- NEXTCLOUD_DATADIR=/mnt/ncdata # Allows to set the host directory for Nextcloud's datadir. ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done! See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir
|
||||
- WATCHTOWER_DOCKER_SOCKET_PATH=$XDG_RUNTIME_DIR/docker.sock
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work
|
||||
- $XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don't forget to also set 'WATCHTOWER_DOCKER_SOCKET_PATH'!
|
||||
|
||||
volumes:
|
||||
nextcloud_aio_mastercontainer:
|
||||
name: nextcloud_aio_mastercontainer # This line is not allowed to be changed as otherwise the built-in backup solution will not work
|
|
@ -1,8 +0,0 @@
|
|||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||
-----END DH PARAMETERS-----
|
|
@ -1,39 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
if [[ $UID -ne 0 ]]; then
|
||||
echo "This script must be run as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Chemin relatif pour les cas où
|
||||
# le script n'est pas exécuté depuis
|
||||
# le répertoire où il se trouve.
|
||||
rel_path="$(dirname "$0")"
|
||||
|
||||
# Fichiers requis pour le script
|
||||
files=('dhparam.txt' 'nginx.conf' 'reverse-proxy.conf')
|
||||
for file in "${files[@]}"; do
|
||||
if ! [[ -f "$rel_path/$file" ]]; then
|
||||
echo "Required file $file is missing, exiting."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
if [[ ! -x /usr/sbin/nginx ]]; then
|
||||
apt install -y nginx
|
||||
fi
|
||||
|
||||
|
||||
cp "$rel_path/nginx.conf" /etc/nginx/
|
||||
cp "$rel_path/reverse-proxy.conf" /etc/nginx/sites-available/
|
||||
cp "$rel_path/dhparam.txt" /etc/nginx/
|
||||
|
||||
|
||||
rm /etc/nginx/sites-enabled/*
|
||||
ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf
|
||||
|
||||
|
||||
systemctl start nginx
|
||||
systemctl reload nginx
|
10
playbooks/config-fstab.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Playbook to mount CIFS mounts defined in env.yml
|
||||
- name: Include variables files
|
||||
hosts: localhost
|
||||
roles:
|
||||
- include-vars
|
||||
|
||||
- name: Edit fstab configuration & mount CIFS devices
|
||||
hosts: localhost
|
||||
roles:
|
||||
- fstab
|
5
playbooks/setup-dockerd.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- name: Setup Docker rootless
|
||||
hosts: localhost
|
||||
roles:
|
||||
- include-vars
|
||||
- dockerd
|
28
playbooks/update-services.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
- name: Include variables files & load nftables.conf
|
||||
hosts: localhost
|
||||
roles:
|
||||
- include-vars
|
||||
- nftables
|
||||
|
||||
- name: Update project(s)
|
||||
hosts: localhost
|
||||
vars_prompt:
|
||||
- name: selected_projects
|
||||
prompt: "Choose projects to update (Keep empty to update all. Projects list: {{ hostvars['localhost']['projects'] }})"
|
||||
private: false
|
||||
unsafe: true
|
||||
|
||||
- name: docker_pull_images
|
||||
prompt: "Pull project(s) images?"
|
||||
default: false
|
||||
private: false
|
||||
|
||||
tasks:
|
||||
- name: Update project(s)
|
||||
include_role:
|
||||
name: "{{ project }}"
|
||||
loop: "{{ (selected_projects | split) | default(projects, true) }}"
|
||||
loop_control:
|
||||
# Do not use default variable name 'item' to prevent collisions with loops in roles.
|
||||
loop_var: project
|
||||
when: project in projects
|
17
ports.txt
|
@ -1,17 +0,0 @@
|
|||
80/443 -> NGINX reverse proxy
|
||||
995 -> SSH
|
||||
3478 -> coturn
|
||||
3735 -> Etebase
|
||||
5349 -> coturn
|
||||
5432 -> Syncthing
|
||||
8008 -> Synapse
|
||||
8080 -> Nextcloud AIO
|
||||
8081 -> Vaultwarden
|
||||
8082 -> nginx-www
|
||||
8083 -> SearXNG
|
||||
8084 -> element-web
|
||||
8384 -> Syncthing Web UI
|
||||
8443 -> stdisco
|
||||
11000 -> Nextcloud
|
||||
22000 -> Syncthing
|
||||
49152-49652/udp -> coturn
|
68
roles/coturn/tasks/main.yml
Normal file
|
@ -0,0 +1,68 @@
|
|||
- name: "Create {{ coturn_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ coturn_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ coturn_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: Template turnserver.conf to project directory
|
||||
template:
|
||||
src: turnserver.conf
|
||||
dest: "{{ coturn_project_dir }}/turnserver.conf"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
# Store result to restart services if the file changed
|
||||
register: coturn_template_turnserver_result
|
||||
|
||||
# Separate task because template module cannot chown/chgrp to a non-existing user/group
|
||||
- name: "Change group of turnserver.conf to coturn GID ({{ users['coturn'] + uid_shift }})"
|
||||
file:
|
||||
path: "{{ coturn_project_dir }}/turnserver.conf"
|
||||
group: "{{ users['coturn'] + uid_shift }}"
|
||||
become: true
|
||||
|
||||
- name: Set limited permissions on certificate directories
|
||||
file:
|
||||
path: "/etc/{{ item }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: '751'
|
||||
become: true
|
||||
loop:
|
||||
- letsencrypt
|
||||
- letsencrypt/live
|
||||
- letsencrypt/archive
|
||||
|
||||
- name: Set limited permissions on certificate directories
|
||||
file:
|
||||
path: "/etc/letsencrypt/{{ item }}/turn.{{ domain }}"
|
||||
state: directory
|
||||
owner: "{{ host_uid }}"
|
||||
group: "{{ users['coturn'] + uid_shift }}"
|
||||
mode: '550'
|
||||
become: true
|
||||
loop:
|
||||
- live
|
||||
- archive
|
||||
|
||||
- name: Set limited permissions on certificate key file
|
||||
file:
|
||||
path: "/etc/letsencrypt/live/turn.{{ domain }}/privkey.pem"
|
||||
owner: root
|
||||
group: "{{ users['coturn'] + uid_shift }}"
|
||||
mode: '640'
|
||||
become: true
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ coturn_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
||||
# Restart if config file(s) changed
|
||||
restarted: "{{ coturn_template_turnserver_result['changed'] | bool }}"
|
18
roles/coturn/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
services:
|
||||
coturn:
|
||||
container_name: coturn
|
||||
image: coturn/coturn:alpine
|
||||
restart: always
|
||||
user: {{ users['coturn'] }}:{{ users['coturn'] }}
|
||||
ports:
|
||||
- {{ ports['coturn_listening'] }}:{{ ports['coturn_listening'] }}
|
||||
- {{ ports['coturn_listening'] }}:{{ ports['coturn_listening'] }}/udp
|
||||
- {{ ports['coturn_tls_listening'] }}:{{ ports['coturn_tls_listening'] }}
|
||||
- {{ ports['coturn_tls_listening'] }}:{{ ports['coturn_tls_listening'] }}/udp
|
||||
- {{ ports['coturn_relay_min'] }}-{{ ports['coturn_relay_max'] }}:{{ ports['coturn_relay_min'] }}-{{ ports['coturn_relay_max'] }}/udp
|
||||
tmpfs:
|
||||
- /var/lib/coturn
|
||||
volumes:
|
||||
- ./turnserver.conf:/etc/coturn/turnserver.conf
|
||||
- {{ volumes['coturn_tls_certificate_file'] }}:/etc/coturn/cert.pem
|
||||
- {{ volumes['coturn_tls_certificate_key_file'] }}:/etc/coturn/pkey.pem
|
|
@ -1,19 +1,19 @@
|
|||
# Required behind NAT
|
||||
external-ip=167.235.49.84
|
||||
#external-ip=2a01:4f8:c0c:a25a::1
|
||||
listening-port={{ ports['coturn_listening'] }}
|
||||
tls-listening-port={{ ports['coturn_tls_listening'] }}
|
||||
|
||||
# Lower and upper bounds of the UDP relay endpoints:
|
||||
# (default values are 49152 and 65535)
|
||||
min-port=49152
|
||||
max-port=49172
|
||||
min-port={{ ports['coturn_relay_min'] }}
|
||||
max-port={{ ports['coturn_relay_max'] }}
|
||||
|
||||
#verbose
|
||||
fingerprint
|
||||
|
||||
# Credentials in secrets.conf (static-auth-secret)
|
||||
use-auth-secret
|
||||
static-auth-secret={{ coturn_secrets['static_auth_secret'] }}
|
||||
|
||||
realm=turn.viyurz.fr
|
||||
realm=turn.{{ domain }}
|
||||
|
||||
# TLS certificates, including intermediate certs.
|
||||
# For Let's Encrypt certificates, use `fullchain.pem` here.
|
1
roles/coturn/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
coturn_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
63
roles/dockerd/tasks/main.yml
Normal file
|
@ -0,0 +1,63 @@
|
|||
- name: Make sure required packages are installed
|
||||
apt:
|
||||
name:
|
||||
- docker.io
|
||||
- docker-compose
|
||||
- rootlesskit
|
||||
- slirp4netns
|
||||
- uidmap
|
||||
become: true
|
||||
|
||||
- name: Make sure system-wide Docker daemon is stopped & disabled
|
||||
service:
|
||||
name: docker
|
||||
state: stopped
|
||||
enabled: false
|
||||
become: true
|
||||
|
||||
- name: Make sure system-wide Docker socket is stopped & disabled
|
||||
service:
|
||||
name: docker.socket
|
||||
state: stopped
|
||||
enabled: false
|
||||
become: true
|
||||
|
||||
- name: Run dockerd-rootless-setuptool.sh script
|
||||
command:
|
||||
cmd: /usr/share/docker.io/contrib/dockerd-rootless-setuptool.sh install
|
||||
|
||||
- name: Make sure /usr/share/docker.io/contrib is in PATH variable
|
||||
lineinfile:
|
||||
path: "{{ ansible_env['HOME'] }}/.profile"
|
||||
regex: '^export PATH="/usr/share/docker\.io/contrib'
|
||||
line: 'export PATH="/usr/share/docker.io/contrib:$PATH"'
|
||||
|
||||
- name: Make sure DOCKER_HOST variable is set correctly
|
||||
lineinfile:
|
||||
path: "{{ ansible_env['HOME'] }}/.profile"
|
||||
regex: '^export DOCKER_HOST='
|
||||
line: "export DOCKER_HOST=unix:///run/user/{{ host_uid }}/docker.sock"
|
||||
|
||||
- name: "Make sure lingering is enabled for user {{ ansible_env['USER'] }}"
|
||||
command:
|
||||
cmd: "loginctl enable-linger {{ ansible_env['USER'] }}"
|
||||
become: true
|
||||
|
||||
- name: "Create directory {{ ansible_env['HOME'] }}/.config/systemd/user/docker.service.d to override environment variables"
|
||||
file:
|
||||
path: "{{ ansible_env['HOME'] }}/.config/systemd/user/docker.service.d"
|
||||
state: directory
|
||||
|
||||
- name: Add environment variables to Docker user service to use slirp4netns RootlessKit port driver, which enables source IP propagation
|
||||
copy:
|
||||
dest: "{{ ansible_env['HOME'] }}/.config/systemd/user/docker.service.d/override.conf"
|
||||
content: |
|
||||
[Service]
|
||||
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns"
|
||||
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns"
|
||||
|
||||
- name: Start/restart & enable Docker user service
|
||||
service:
|
||||
name: docker
|
||||
state: restarted
|
||||
enabled: true
|
28
roles/element/tasks/main.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
- name: "Create {{ element_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ element_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ element_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: Template config.json to project directory
|
||||
template:
|
||||
src: config.json
|
||||
dest: "{{ element_project_dir }}/config.json"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '644'
|
||||
register: element_template_config_result
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ element_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
||||
# Restart if config file(s) changed
|
||||
restarted: "{{ element_template_config_result['changed'] | bool }}"
|
3
roles/element/templates/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"default_server_name": "{{ domain }}"
|
||||
}
|
|
@ -4,6 +4,6 @@ services:
|
|||
image: vectorim/element-web:latest
|
||||
restart: always
|
||||
ports:
|
||||
- 8084:80
|
||||
- {{ ports['element'] }}:80
|
||||
volumes:
|
||||
- ./config.json:/app/config.json
|
1
roles/element/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
element_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
26
roles/etebase/tasks/main.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
- name: "Create {{ etebase_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ etebase_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ etebase_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: "Create directory {{ volumes['etebase_datadir'] }} with correct permissions"
|
||||
file:
|
||||
path: "{{ volumes['etebase_datadir'] }}"
|
||||
state: directory
|
||||
owner: "{{ users['etebase'] + uid_shift }}"
|
||||
group: "{{ users['etebase'] + uid_shift }}"
|
||||
mode: '770'
|
||||
become: true
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ etebase_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
15
roles/etebase/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
etebase:
|
||||
image: victorrds/etebase:alpine
|
||||
container_name: etebase
|
||||
restart: always
|
||||
user: {{ users['etebase'] }}:{{ users['etebase'] }}
|
||||
environment:
|
||||
SERVER: http
|
||||
ALLOWED_HOSTS: etebase.{{ domain }}
|
||||
AUTO_UPDATE: 'true'
|
||||
TIME_ZONE: {{ timezone }}
|
||||
ports:
|
||||
- {{ ports['etebase'] }}:3735
|
||||
volumes:
|
||||
- {{ volumes['etebase_datadir'] }}:/data
|
1
roles/etebase/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
etebase_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
24
roles/fstab/tasks/main.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
- name:
|
||||
become: true
|
||||
block:
|
||||
- name: Install package cifs-utils
|
||||
apt:
|
||||
name: cifs-utils
|
||||
|
||||
- name: "Template {{ fstab_cifs_credentials_filename }} to /etc/{{ fstab_cifs_credentials_filename }}"
|
||||
template:
|
||||
src: "{{ fstab_cifs_credentials_filename }}"
|
||||
dest: "/etc/{{ fstab_cifs_credentials_filename }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '600'
|
||||
register: fstab_template_cifs_credentials_result
|
||||
|
||||
- name: Mount/Remount CIFS devices & edit fstab accordingly
|
||||
mount:
|
||||
state: mounted
|
||||
src: "{{ item.value.src }}"
|
||||
path: "{{ item.value.path }}"
|
||||
fstype: cifs
|
||||
opts: "uid={{ item.value.uid }},gid={{ item.value.gid }},file_mode=0{{ item.value.file_mode }},dir_mode=0{{ item.value.dir_mode }},credentials=/etc/{{ fstab_cifs_credentials_filename }},iocharset=utf8,rw,mfsymlinks,vers=3.0,seal"
|
||||
loop: "{{ cifs_mounts | dict2items }}"
|
2
roles/fstab/templates/storagebox-cifs-credentials.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
username={{ cifs_credentials['username'] }}
|
||||
password={{ cifs_credentials['password'] }}
|
1
roles/fstab/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
fstab_cifs_credentials_filename: storagebox-cifs-credentials.txt
|
35
roles/hedgedoc/tasks/main.yml
Normal file
|
@ -0,0 +1,35 @@
|
|||
- name: "Create {{ hedgedoc_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ hedgedoc_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ hedgedoc_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: "Create directory {{ volumes['hedgedoc_configdir'] }} with correct permissions"
|
||||
file:
|
||||
path: "{{ volumes['hedgedoc_configdir'] }}"
|
||||
state: directory
|
||||
owner: "{{ users['hedgedoc'] + uid_shift }}"
|
||||
group: "{{ users['hedgedoc'] + uid_shift }}"
|
||||
mode: '770'
|
||||
become: true
|
||||
|
||||
- name: "Create directory {{ volumes['hedgedoc_mysql_datadir'] }} with correct permissions"
|
||||
file:
|
||||
path: "{{ volumes['hedgedoc_mysql_datadir'] }}"
|
||||
state: directory
|
||||
owner: "{{ users['hedgedoc_mysql'] + uid_shift }}"
|
||||
group: "{{ users['hedgedoc_mysql'] + uid_shift }}"
|
||||
mode: '770'
|
||||
become: true
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ hedgedoc_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
32
roles/hedgedoc/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,32 @@
|
|||
services:
|
||||
hedgedoc:
|
||||
container_name: hedgedoc
|
||||
image: lscr.io/linuxserver/hedgedoc:latest
|
||||
restart: always
|
||||
environment:
|
||||
- PUID={{ users['hedgedoc'] }}
|
||||
- PGID={{ users['hedgedoc'] }}
|
||||
- TZ={{ timezone }}
|
||||
- DB_HOST=hedgedoc-mysql
|
||||
- DB_PORT=3306
|
||||
- DB_USER=root
|
||||
- DB_PASS={{ hedgedoc_secrets['mysql_root_password'] }}
|
||||
- DB_NAME=hedgedoc
|
||||
- CMD_DOMAIN=hedgedoc.{{ domain }}
|
||||
ports:
|
||||
- {{ ports['hedgedoc'] }}:3000
|
||||
volumes:
|
||||
- {{ volumes['hedgedoc_configdir'] }}:/config
|
||||
|
||||
mysql:
|
||||
container_name: hedgedoc-mysql
|
||||
image: mysql:latest
|
||||
restart: always
|
||||
user: {{ users['hedgedoc_mysql'] }}:{{ users['hedgedoc_mysql'] }}
|
||||
environment:
|
||||
MYSQL_DATABASE: hedgedoc
|
||||
MYSQL_ROOT_PASSWORD: "{{ hedgedoc_secrets['mysql_root_password'] }}"
|
||||
volumes:
|
||||
- {{ volumes['hedgedoc_mysql_datadir'] }}:/var/lib/mysql
|
||||
|
||||
|
1
roles/hedgedoc/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
hedgedoc_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 251 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 978 B After Width: | Height: | Size: 978 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 230 KiB |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 576 KiB After Width: | Height: | Size: 576 KiB |
|
@ -1,4 +1,3 @@
|
|||
user nginx;
|
||||
pid /tmp/nginx.pid;
|
||||
|
||||
worker_processes auto;
|
29
roles/homepage/tasks/main.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
- name: "Create {{ homepage_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ homepage_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ homepage_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: Copy nginx.conf and index/ to project directory
|
||||
copy:
|
||||
src: "{{ role_path }}/files/"
|
||||
dest: "{{ homepage_project_dir }}"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '644'
|
||||
# Store result to restart services if the file(s) changed
|
||||
register: homepage_copy_files_result
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ homepage_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
||||
# Restart if config file(s) changed
|
||||
restarted: "{{ homepage_copy_files_result['changed'] | bool }}"
|
|
@ -1,11 +1,11 @@
|
|||
services:
|
||||
nginx-www:
|
||||
homepage:
|
||||
image: nginx:alpine
|
||||
restart: always
|
||||
container_name: nginx-www
|
||||
user: '101:101'
|
||||
container_name: homepage
|
||||
user: {{ users['homepage'] }}:{{ users['homepage'] }}
|
||||
ports:
|
||||
- 8082:80
|
||||
- {{ ports['homepage'] }}:80
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./index:/mnt/index
|
1
roles/homepage/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
homepage_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
7
roles/include-vars/tasks/main.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
- name: Include vars from env.yml file
|
||||
include_vars:
|
||||
file: "{{ playbook_dir }}/../env.yml"
|
||||
|
||||
- name: Include secrets from secrets.yml file
|
||||
include_vars:
|
||||
file: "{{ playbook_dir }}/../secrets.yml"
|
22
roles/nftables/tasks/main.yml
Normal file
|
@ -0,0 +1,22 @@
|
|||
- name:
|
||||
become: true
|
||||
block:
|
||||
- name: Install package nftables
|
||||
apt:
|
||||
name: nftables
|
||||
|
||||
- name: Template nftables.conf to /etc/nftables.conf
|
||||
template:
|
||||
src: nftables.conf
|
||||
dest: /etc/nftables.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
register: nftables_template_conf_result
|
||||
|
||||
- name: Restart nftables service
|
||||
service:
|
||||
name: nftables
|
||||
state: restarted
|
||||
enabled: true
|
||||
when: nftables_template_conf_result['changed']
|
|
@ -10,21 +10,25 @@ table inet filter {
|
|||
|
||||
ct state invalid drop
|
||||
ct state { established, related } accept
|
||||
|
||||
# Allow ICMP
|
||||
meta l4proto icmp limit rate 1/second accept
|
||||
meta l4proto ipv6-icmp limit rate 1/second accept
|
||||
|
||||
# HTTP & Syncthing Relay
|
||||
tcp dport { http, https, 5432, 22000 } limit rate 5/second accept
|
||||
udp dport 22000 limit rate 5/second accept
|
||||
# HTTP/S
|
||||
tcp dport { http, https } limit rate 5/second accept
|
||||
|
||||
# SSH
|
||||
tcp dport 995 limit rate 15/minute accept
|
||||
|
||||
# TURN
|
||||
tcp dport { 3478, 5349 } limit rate 5/second accept
|
||||
udp dport { 3478, 5349, 49152-49172 } limit rate 5/second accept
|
||||
# Syncthing
|
||||
tcp dport {{ ports['syncthing_tcp'] }} limit rate 5/second accept
|
||||
udp dport {{ ports['syncthing_udp'] }} limit rate 5/second accept
|
||||
|
||||
# Coturn
|
||||
tcp dport { {{ ports['coturn_listening'] }}, {{ ports['coturn_tls_listening'] }} } limit rate 5/second accept
|
||||
udp dport { {{ ports['coturn_listening'] }}, {{ ports['coturn_tls_listening'] }}, {{ ports['coturn_relay_min'] }}-{{ ports['coturn_relay_max'] }} } limit rate 5/second accept
|
||||
|
||||
# Allow ICMP
|
||||
meta l4proto icmp limit rate 1/second accept
|
||||
meta l4proto ipv6-icmp limit rate 1/second accept
|
||||
}
|
||||
|
||||
chain forward {
|
70
roles/reverse-proxy/tasks/main.yml
Normal file
|
@ -0,0 +1,70 @@
|
|||
- name:
|
||||
become: true
|
||||
block:
|
||||
- name: Install package nginx
|
||||
apt:
|
||||
name: nginx
|
||||
|
||||
- name: Template nginx.conf to /etc/nginx/nginx.conf
|
||||
template:
|
||||
src: nginx.conf
|
||||
dest: /etc/nginx/nginx.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
register: nginx_template_nginx_conf_result
|
||||
|
||||
- name: Template reverse-proxy.conf to /etc/nginx/sites-available/reverse-proxy.conf
|
||||
template:
|
||||
src: reverse-proxy.conf
|
||||
dest: /etc/nginx/sites-available/reverse-proxy.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
register: nginx_template_reverse_proxy_conf_result
|
||||
|
||||
- name: Remove all enabled NGINX sites
|
||||
file:
|
||||
state: "{{ item }}"
|
||||
path: "/etc/nginx/sites-enabled"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
loop:
|
||||
- absent
|
||||
- directory
|
||||
|
||||
- name: Enable reverse-proxy.conf site
|
||||
file:
|
||||
state: link
|
||||
src: /etc/nginx/sites-available/reverse-proxy.conf
|
||||
dest: /etc/nginx/sites-enabled/reverse-proxy.conf
|
||||
|
||||
- name: Get state of file /etc/nginx/dhparam.txt
|
||||
stat:
|
||||
path: /etc/nginx/dhparam.txt
|
||||
register: nginx_stat_dhparam_result
|
||||
|
||||
- name: Download dhparam file from Mozilla
|
||||
get_url:
|
||||
url: https://ssl-config.mozilla.org/ffdhe2048.txt
|
||||
dest: /etc/nginx/dhparam.txt
|
||||
when: not nginx_stat_dhparam_result.stat.exists
|
||||
|
||||
- name: Set correct permissions on certificate directories
|
||||
file:
|
||||
path: "/etc/letsencrypt/{{ item }}/{{ domain }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: '750'
|
||||
loop:
|
||||
- live
|
||||
- archive
|
||||
|
||||
- name: Start/Reload NGINX service
|
||||
service:
|
||||
name: nginx
|
||||
# Reload if conf changed, if not make sure it is started
|
||||
state: "{{ (nginx_template_nginx_conf_result['changed'] or nginx_template_reverse_proxy_conf_result['changed']) | ternary('reloaded', 'started') }}"
|
||||
enabled: yes
|
|
@ -32,9 +32,9 @@ http {
|
|||
# SSL Settings
|
||||
##
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/viyurz.fr/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/viyurz.fr/privkey.pem;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/viyurz.fr/chain.pem;
|
||||
ssl_certificate {{ reverse_proxy['ssl_certificate_file'] }};
|
||||
ssl_certificate_key {{ reverse_proxy['ssl_certificate_key_file'] }};
|
||||
ssl_trusted_certificate {{ reverse_proxy['ssl_trusted_certificate_file'] }};
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
|
||||
|
@ -61,7 +61,7 @@ http {
|
|||
# Headers
|
||||
##
|
||||
|
||||
resolver 185.12.64.12 [a01:4ff:ff00::add:2] [2a01:4ff:ff00::add:1];
|
||||
resolver {{ reverse_proxy['resolver'] }};
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
# add_header X-Robots-Tag "noindex, nofollow" always;
|
|
@ -21,26 +21,26 @@ server {
|
|||
}
|
||||
|
||||
|
||||
# Base domain / Homepage
|
||||
# Homepage
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name viyurz.fr;
|
||||
server_name {{ domain }};
|
||||
|
||||
location = /.well-known/matrix/server {
|
||||
default_type application/json;
|
||||
return 200 '{ "m.server": "matrix.viyurz.fr:443" }';
|
||||
return 200 '{ "m.server": "matrix.{{ domain }}:443" }';
|
||||
}
|
||||
|
||||
location = /.well-known/matrix/client {
|
||||
default_type application/json;
|
||||
add_header Access-Control-Allow-Origin '*';
|
||||
return 200 '{ "m.homeserver": { "base_url": "https://matrix.viyurz.fr" } }';
|
||||
return 200 '{ "m.homeserver": { "base_url": "https://matrix.{{ domain }}" } }';
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8082;
|
||||
proxy_pass http://localhost:{{ ports['homepage'] }};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ server {
|
|||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name dl.viyurz.fr;
|
||||
server_name dl.{{ domain }};
|
||||
|
||||
root /var/www/html;
|
||||
autoindex on;
|
||||
|
@ -62,10 +62,10 @@ server {
|
|||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name element.viyurz.fr;
|
||||
server_name element.{{ domain }};
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8084;
|
||||
proxy_pass http://localhost:{{ ports['element'] }};
|
||||
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
@ -83,23 +83,36 @@ server {
|
|||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name etebase.viyurz.fr;
|
||||
server_name etebase.{{ domain }};
|
||||
|
||||
location ~ ^/(?!admin) {
|
||||
proxy_pass http://localhost:3735;
|
||||
proxy_pass http://localhost:{{ ports['etebase'] }};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# SearxNG
|
||||
# Hedgedoc
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name searx.viyurz.fr;
|
||||
server_name hedgedoc.{{ domain }};
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:{{ ports['hedgedoc'] }};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# SearXNG
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name searx.{{ domain }};
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8083;
|
||||
proxy_pass http://localhost:{{ ports['searxng'] }};
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header Set-Cookie "Path=/; HttpOnly; Secure";
|
||||
|
@ -113,37 +126,37 @@ server {
|
|||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name matrix.viyurz.fr;
|
||||
server_name matrix.{{ domain }};
|
||||
|
||||
location ~ ^(/_matrix|/_synapse/client) {
|
||||
proxy_pass http://localhost:8008;
|
||||
proxy_pass http://localhost:{{ ports['synapse'] }};
|
||||
|
||||
# Nginx by default only allows file uploads up to 1M in size
|
||||
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
|
||||
client_max_body_size 50M;
|
||||
client_max_body_size {{ synapse['max_upload_size'] }};
|
||||
}
|
||||
|
||||
location / {
|
||||
return 308 https://element.viyurz.fr/;
|
||||
return 308 https://element.{{ domain }}/;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Syncthing Discovery
|
||||
upstream stdisco.viyurz.fr {
|
||||
upstream stdisco.{{ domain }} {
|
||||
# Local IP address:port for discovery server
|
||||
server localhost:8443;
|
||||
server localhost:{{ ports['syncthing_discosrv'] }};
|
||||
}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name stdisco.viyurz.fr;
|
||||
server_name stdisco.{{ domain }};
|
||||
|
||||
ssl_verify_client optional_no_ca;
|
||||
|
||||
location / {
|
||||
proxy_pass http://stdisco.viyurz.fr;
|
||||
proxy_pass http://stdisco.{{ domain }};
|
||||
|
||||
proxy_set_header X-Client-Port $remote_port;
|
||||
proxy_set_header X-SSL-Cert $ssl_client_cert;
|
||||
|
@ -156,14 +169,14 @@ server {
|
|||
# Vaultwarden
|
||||
upstream vaultwarden-default {
|
||||
zone vaultwarden-default 64k;
|
||||
server localhost:8081;
|
||||
server localhost:{{ ports['vaultwarden'] }};
|
||||
keepalive 2;
|
||||
}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name vw.viyurz.fr;
|
||||
server_name vw.{{ domain }};
|
||||
|
||||
location / {
|
||||
proxy_pass http://vaultwarden-default;
|
29
roles/searxng/tasks/main.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
- name: "Create {{ searxng_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ searxng_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ searxng_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: Copy settings.yml and limiter.toml to project directory
|
||||
copy:
|
||||
src: "{{ role_path }}/files/"
|
||||
dest: "{{ searxng_project_dir }}"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '644'
|
||||
# Store result to restart services if the file(s) changed
|
||||
register: searxng_copy_files_result
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ searxng_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
||||
# Restart if config file(s) changed
|
||||
restarted: "{{ searxng_copy_files_result['changed'] | bool }}"
|
|
@ -3,10 +3,8 @@ services:
|
|||
container_name: searxng-redis
|
||||
image: docker.io/library/redis:alpine
|
||||
restart: always
|
||||
user: {{ users['searxng_redis'] }}:{{ users['searxng_redis'] }}
|
||||
command: redis-server --save 30 1 --loglevel warning
|
||||
user: '999:999'
|
||||
networks:
|
||||
- searxng
|
||||
volumes:
|
||||
- redis:/data
|
||||
|
||||
|
@ -21,12 +19,10 @@ services:
|
|||
- SETGID
|
||||
- SETUID
|
||||
environment:
|
||||
- SEARXNG_BASE_URL=https://searx.viyurz.fr/
|
||||
- SEARXNG_SECRET=${SEARXNG_SECRET}
|
||||
networks:
|
||||
- searxng
|
||||
- SEARXNG_BASE_URL=https://searx.{{ domain }}
|
||||
- SEARXNG_SECRET={{ searxng_secrets['searxng_secret'] }}
|
||||
ports:
|
||||
- 8083:8080
|
||||
- {{ ports['searxng'] }}:8080
|
||||
volumes:
|
||||
- ./settings.yml:/etc/searxng/settings.yml
|
||||
- ./limiter.toml:/etc/searxng/limiter.toml
|
||||
|
@ -36,10 +32,5 @@ services:
|
|||
max-size: "1m"
|
||||
max-file: "1"
|
||||
|
||||
networks:
|
||||
searxng:
|
||||
ipam:
|
||||
driver: default
|
||||
|
||||
volumes:
|
||||
redis:
|
1
roles/searxng/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
searxng_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
53
roles/synapse/tasks/main.yml
Normal file
|
@ -0,0 +1,53 @@
|
|||
- name: "Create {{ synapse_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ synapse_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ synapse_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: Template homeserver.yaml to project directory
|
||||
template:
|
||||
src: homeserver.yaml
|
||||
dest: "{{ synapse_project_dir }}/homeserver.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
# Store result to restart services if the file changed
|
||||
register: synapse_template_homeserver_result
|
||||
|
||||
# Separate task because template module cannot chown/chgrp to a non-existing user/group
|
||||
- name: "Change group of homeserver.yaml to synapse GID ({{ users['synapse'] + uid_shift }})"
|
||||
file:
|
||||
path: "{{ synapse_project_dir }}/homeserver.yaml"
|
||||
group: "{{ users['synapse'] + uid_shift }}"
|
||||
become: true
|
||||
|
||||
- name: "Create directory {{ volumes['synapse_datadir'] }} with correct permissions"
|
||||
file:
|
||||
path: "{{ volumes['synapse_datadir'] }}"
|
||||
state: directory
|
||||
owner: "{{ users['synapse'] + uid_shift }}"
|
||||
group: "{{ users['synapse'] + uid_shift }}"
|
||||
mode: '770'
|
||||
become: true
|
||||
|
||||
- name: "Create directory {{ volumes['synapse_postgres_datadir'] }} with correct permissions"
|
||||
file:
|
||||
path: "{{ volumes['synapse_postgres_datadir'] }}"
|
||||
state: directory
|
||||
owner: "{{ users['synapse_postgres'] + uid_shift }}"
|
||||
group: "{{ users['synapse_postgres'] + uid_shift }}"
|
||||
mode: '770'
|
||||
become: true
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ synapse_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
||||
# Restart if config file(s) changed
|
||||
restarted: "{{ synapse_template_homeserver_result['changed'] | bool }}"
|
27
roles/synapse/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,27 @@
|
|||
services:
|
||||
postgres:
|
||||
container_name: synapse-postgres
|
||||
image: postgres:alpine
|
||||
restart: always
|
||||
user: {{ users['synapse_postgres'] }}:{{ users['synapse_postgres'] }}
|
||||
environment:
|
||||
LANG: C
|
||||
POSTGRES_INITDB_ARGS: "--locale=C --encoding=UTF8"
|
||||
POSTGRES_USER: {{ synapse_secrets['postgres_user'] }}
|
||||
POSTGRES_PASSWORD: {{ synapse_secrets['postgres_password'] }}
|
||||
volumes:
|
||||
- {{ volumes['synapse_postgres_datadir'] }}:/var/lib/postgresql/data
|
||||
|
||||
synapse:
|
||||
container_name: synapse
|
||||
image: matrixdotorg/synapse:latest
|
||||
restart: always
|
||||
environment:
|
||||
UID: {{ users['synapse'] }}
|
||||
GID: {{ users['synapse'] }}
|
||||
TZ: {{ timezone }}
|
||||
ports:
|
||||
- {{ ports['synapse'] }}:8008
|
||||
volumes:
|
||||
- {{ volumes['synapse_datadir'] }}:/data
|
||||
- ./homeserver.yaml:/data/homeserver.yaml
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
|
||||
# Server
|
||||
server_name: "viyurz.fr"
|
||||
server_name: "{{ domain }}"
|
||||
pid_file: /data/homeserver.pid
|
||||
listeners:
|
||||
- port: 8008
|
||||
|
@ -24,8 +24,8 @@ max_avatar_size: 2M
|
|||
database:
|
||||
name: psycopg2
|
||||
args:
|
||||
user: synapse
|
||||
password: synapse
|
||||
user: {{ synapse_secrets['postgres_user'] }}
|
||||
password: {{ synapse_secrets['postgres_password'] }}
|
||||
dbname: synapse
|
||||
host: synapse-postgres
|
||||
cp_min: 5
|
||||
|
@ -33,13 +33,13 @@ database:
|
|||
|
||||
|
||||
# Logging
|
||||
log_config: "/data/viyurz.fr.log.config"
|
||||
log_config: "/data/{{ domain }}.log.config"
|
||||
|
||||
|
||||
# Media Store
|
||||
media_store_path: /data/media_store
|
||||
# Changer aussi le max_body_size dans le reverse proxy
|
||||
max_upload_size: 50M
|
||||
max_upload_size: {{ synapse['max_upload_size'] }}
|
||||
media_retention:
|
||||
remote_media_lifetime: 14d
|
||||
url_preview_enabled: true
|
||||
|
@ -70,7 +70,8 @@ url_preview_accept_language:
|
|||
|
||||
|
||||
# TURN
|
||||
turn_uris: ["turns:turn.viyurz.fr?transport=udp", "turns:turn.viyurz.fr?transport=tcp"]
|
||||
turn_uris: ["turns:turn.{{ domain }}?transport=udp", "turns:turn.{{ domain }}?transport=tcp"]
|
||||
turn_shared_secret: "{{ synapse_secrets['turn_shared_secret'] }}"
|
||||
turn_user_lifetime: 86400000
|
||||
turn_allow_guests: true
|
||||
|
||||
|
@ -84,8 +85,13 @@ registration_requires_token: true
|
|||
report_stats: true
|
||||
|
||||
|
||||
# API Configuration
|
||||
macaroon_secret_key: "{{ synapse_secrets['macaroon_secret_key'] }}"
|
||||
form_secret: "{{ synapse_secrets['form_secret'] }}"
|
||||
|
||||
|
||||
# Signing Keys
|
||||
signing_key_path: "/data/viyurz.fr.signing.key"
|
||||
signing_key_path: "/data/{{ domain }}.signing.key"
|
||||
trusted_key_servers:
|
||||
- server_name: "matrix.org"
|
||||
suppress_key_server_warning: true
|
1
roles/synapse/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
synapse_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
17
roles/syncthing/tasks/main.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
- name: "Create {{ syncthing_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ syncthing_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ syncthing_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ syncthing_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
35
roles/syncthing/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,35 @@
|
|||
services:
|
||||
syncthing:
|
||||
image: syncthing/syncthing:latest
|
||||
container_name: syncthing
|
||||
restart: always
|
||||
user: {{ users['syncthing'] }}:{{ users['syncthing'] }}
|
||||
environment:
|
||||
- PUID={{ users['syncthing'] }}
|
||||
- PGID={{ users['syncthing'] }}
|
||||
ports:
|
||||
- {{ ports['syncthing_webui'] }}:8384 # Web UI
|
||||
- {{ ports['syncthing_tcp'] }}:22000/tcp # TCP file transfers
|
||||
- {{ ports['syncthing_udp'] }}:22000/udp # QUIC file transfers
|
||||
volumes:
|
||||
- {{ volumes['syncthing_datadir'] }}:/var/syncthing
|
||||
|
||||
stdiscosrv:
|
||||
image: syncthing/discosrv:latest
|
||||
container_name: syncthing-discosrv
|
||||
restart: always
|
||||
entrypoint:
|
||||
- "/bin/entrypoint.sh"
|
||||
- "/bin/stdiscosrv"
|
||||
- "-http"
|
||||
- "-debug"
|
||||
environment:
|
||||
- PUID={{ users['syncthing_discosrv'] }}
|
||||
- PGID={{ users['syncthing_discosrv'] }}
|
||||
networks:
|
||||
- discosrv
|
||||
ports:
|
||||
- {{ ports['syncthing_discosrv'] }}:8443
|
||||
|
||||
networks:
|
||||
discosrv:
|
1
roles/syncthing/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
syncthing_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
26
roles/vaultwarden/tasks/main.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
- name: "Create {{ vaultwarden_project_dir }} project directory"
|
||||
file:
|
||||
path: "{{ vaultwarden_project_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: Template docker-compose.yaml to project directory
|
||||
template:
|
||||
src: docker-compose.yaml
|
||||
dest: "{{ vaultwarden_project_dir }}/docker-compose.yaml"
|
||||
owner: "{{ ansible_env['USER'] }}"
|
||||
group: "{{ ansible_env['USER'] }}"
|
||||
mode: '640'
|
||||
|
||||
- name: "Create directory {{ volumes['vaultwarden_datadir'] }} with correct permissions"
|
||||
file:
|
||||
path: "{{ volumes['vaultwarden_datadir'] }}"
|
||||
state: directory
|
||||
owner: "{{ users['vaultwarden'] + uid_shift }}"
|
||||
group: "{{ users['vaultwarden'] + uid_shift }}"
|
||||
mode: '770'
|
||||
become: true
|
||||
|
||||
- name: Pull/Create/Restart project services
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ vaultwarden_project_dir }}"
|
||||
pull: "{{ docker_pull_images | bool }}"
|
|
@ -3,12 +3,12 @@ services:
|
|||
image: vaultwarden/server:alpine
|
||||
container_name: vaultwarden
|
||||
restart: always
|
||||
user: '1000:1000'
|
||||
user: {{ users['vaultwarden'] }}:{{ users['vaultwarden'] }}
|
||||
environment:
|
||||
- DOMAIN=https://vw.viyurz.fr # Your domain; vaultwarden needs to know it's https to work properly with attachments
|
||||
- DOMAIN=https://vw.{{ domain }}
|
||||
- SIGNUPS_ALLOWED=false
|
||||
- INVITATIONS_ALLOWED=false
|
||||
ports:
|
||||
- 8081:80
|
||||
- {{ ports['vaultwarden'] }}:80
|
||||
volumes:
|
||||
- /mnt/vwdata:/data
|
||||
- {{ volumes['vaultwarden_datadir' ] }}:/data
|
1
roles/vaultwarden/vars/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
vaultwarden_project_dir: "{{ docker_projects_dir }}/{{ role_name }}"
|
|
@ -1,4 +0,0 @@
|
|||
# Generate secret with:
|
||||
# $ cat /dev/urandom | tr -dc 'a-z-A-Z-0-9' | head -c 50
|
||||
|
||||
SEARXNG_SECRET=XXX
|
22
secrets.yml.example
Normal file
|
@ -0,0 +1,22 @@
|
|||
ansible_become_password:
|
||||
|
||||
cifs_credentials:
|
||||
username:
|
||||
password:
|
||||
|
||||
# To generate random secret: openssl rand -base64 50
|
||||
coturn_secrets:
|
||||
static_auth_secret:
|
||||
|
||||
hedgedoc_secrets:
|
||||
mysql_root_password:
|
||||
|
||||
searxng_secrets:
|
||||
searxng_secret:
|
||||
|
||||
synapse_secrets:
|
||||
postgres_user:
|
||||
postgres_password:
|
||||
turn_shared_secret: "{{ coturn_secrets['static_auth_secret'] }}"
|
||||
macaroon_secret_key:
|
||||
form_secret:
|
|
@ -1,26 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
sudo apt install -y uidmap slirp4netns rootlesskit
|
||||
|
||||
if ! grep -q '/usr/share/docker.io/contrib' "$HOME/.profile" > /dev/null; then
|
||||
echo 'export PATH="/usr/share/docker.io/contrib:$PATH"' >> "$HOME/.profile"
|
||||
fi
|
||||
|
||||
if ! grep -q 'DOCKER_HOST' "$HOME/.profile" > /dev/null; then
|
||||
echo "export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock" >> "$HOME/.profile"
|
||||
fi
|
||||
|
||||
sudo loginctl enable-linger "$USER"
|
||||
|
||||
PATH="/usr/share/docker.io/contrib:$PATH" dockerd-rootless-setuptool.sh install
|
||||
|
||||
mkdir -p "$HOME/.config/systemd/user/docker.service.d"
|
||||
|
||||
cat << EOF > "$HOME/.config/systemd/user/docker.service.d/override.conf"
|
||||
[Service]
|
||||
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns"
|
||||
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns"
|
||||
EOF
|
||||
|
||||
systemctl --user enable docker
|
||||
systemctl --user restart docker
|
|
@ -1,44 +0,0 @@
|
|||
services:
|
||||
postgres:
|
||||
container_name: synapse-postgres
|
||||
image: postgres:alpine
|
||||
restart: always
|
||||
user: '70:70'
|
||||
environment:
|
||||
LANG: C
|
||||
POSTGRES_INITDB_ARGS: "--locale=C --encoding=UTF8"
|
||||
POSTGRES_USER: synapse
|
||||
POSTGRES_PASSWORD: synapse
|
||||
networks:
|
||||
- synapse
|
||||
volumes:
|
||||
- /mnt/synapsepgdata:/var/lib/postgresql/data
|
||||
|
||||
synapse:
|
||||
container_name: synapse
|
||||
image: matrixdotorg/synapse:latest
|
||||
# command: generate
|
||||
restart: always
|
||||
user: '991:991'
|
||||
command: >
|
||||
run
|
||||
--config-path=/data/homeserver.yaml
|
||||
--config-path=/data/secrets.yaml
|
||||
environment:
|
||||
SYNAPSE_SERVER_NAME: viyurz.fr
|
||||
SYNAPSE_REPORT_STATS: "yes"
|
||||
SYNAPSE_HTTP_PORT: 8008
|
||||
TZ: "Europe/Paris"
|
||||
networks:
|
||||
- synapse
|
||||
ports:
|
||||
- 8008:8008
|
||||
volumes:
|
||||
- /mnt/synapsedata:/data
|
||||
- ./homeserver.yaml:/data/homeserver.yaml
|
||||
- ./secrets.yaml:/data/secrets.yaml
|
||||
|
||||
networks:
|
||||
synapse:
|
||||
ipam:
|
||||
driver: default
|
|
@ -1,9 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
rel_path="$(dirname "$0")"
|
||||
access_token="$(cat $rel_path/./matrix_access_token.txt)"
|
||||
|
||||
curl --header "Authorization: Bearer $access_token" \
|
||||
-H "Content-Type: application/json" -w "\n" \
|
||||
-X POST http://localhost:8008/_synapse/admin/v1/registration_tokens/new \
|
||||
-d '{ "uses_allowed": 1, "expiry_time": '"$(date +%s000 -d tomorrow)"' }'
|
|
@ -1 +0,0 @@
|
|||
syt_XXX
|
|
@ -1,6 +0,0 @@
|
|||
# Generate random secret:
|
||||
# $ cat /dev/urandom | tr -dc '[:graph:]' | tr -d '"\\' | head -c 50
|
||||
|
||||
turn_shared_secret: "XXX"
|
||||
macaroon_secret_key: "XXX"
|
||||
form_secret: "XXX"
|
|
@ -1,36 +0,0 @@
|
|||
services:
|
||||
syncthing:
|
||||
image: syncthing/syncthing:latest
|
||||
container_name: syncthing
|
||||
restart: always
|
||||
user: '1001:1001'
|
||||
environment:
|
||||
- PUID=1001
|
||||
- PGID=1001
|
||||
ports:
|
||||
- 8384:8384 # Web UI
|
||||
- 22000:22000/tcp # TCP file transfers
|
||||
- 22000:22000/udp # QUIC file transfers
|
||||
- 5432:22000/tcp
|
||||
volumes:
|
||||
- /mnt/syncthing:/var/syncthing
|
||||
|
||||
stdiscosrv:
|
||||
image: syncthing/discosrv:latest
|
||||
container_name: stdiscosrv
|
||||
restart: always
|
||||
entrypoint:
|
||||
- "/bin/entrypoint.sh"
|
||||
- "/bin/stdiscosrv"
|
||||
- "-http"
|
||||
- "-debug"
|
||||
environment:
|
||||
- PUID=1002
|
||||
- PGID=1002
|
||||
networks:
|
||||
- disco
|
||||
ports:
|
||||
- 8443:8443
|
||||
|
||||
networks:
|
||||
disco:
|
81
update.sh
|
@ -1,81 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
services=(coturn element etebase nginx-www searxng synapse syncthing vw)
|
||||
needs_backup=(etebase synapse vw)
|
||||
|
||||
|
||||
rel_path="$(dirname "$0")"
|
||||
|
||||
|
||||
function pull {
|
||||
docker-compose -f "$rel_path/$1/docker-compose.yaml" pull
|
||||
}
|
||||
|
||||
|
||||
# Runs compose up & eventually make a backup before
|
||||
# $1 = project name
|
||||
function up {
|
||||
if echo "${needs_backup[*]}" | grep -qP "\b$1\b" && has_update "$1"; then
|
||||
sudo "$rel_path/backup.sh" "$1" --norestart
|
||||
fi
|
||||
|
||||
docker-compose -f "$rel_path/$1/docker-compose.yaml" up -d
|
||||
}
|
||||
|
||||
|
||||
# To use after pulling latest images of project
|
||||
# Checks if at least one container can be updated
|
||||
# $1 = project name
|
||||
function has_update {
|
||||
readarray -t cont_list < <(docker-compose -f "$rel_path/$1/docker-compose.yaml" ps -a | tail -n+3 | cut -d ' ' -f 1)
|
||||
for cont in "${cont_list[@]}"; do
|
||||
# Return true if container doesn't exist
|
||||
if ! docker ps -a --format='{{.Names}}' | grep -q "$cont"; then
|
||||
return 0
|
||||
fi
|
||||
cont_image_id="$(docker inspect "$cont" --format='{{.Image}}')"
|
||||
repo_url="$(docker inspect "$cont" --format='{{.Config.Image}}')"
|
||||
repo_image_id="$(docker image inspect "$repo_url" --format='{{.Id}}')"
|
||||
if [[ "$cont_image_id" != "$repo_image_id" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
service="$(echo "$2" | sed -E 's/[/ ]//g')"
|
||||
|
||||
|
||||
case "$1" in
|
||||
pull)
|
||||
if [[ -z "$service" ]]; then
|
||||
for serv in "${services[@]}"; do
|
||||
pull "$serv"
|
||||
done
|
||||
elif echo "${services[*]}" | grep -qP "\b$service\b"; then
|
||||
pull "$service"
|
||||
else
|
||||
echo "invalid project name. it should be one of: ${services[*]}."
|
||||
fi
|
||||
;;
|
||||
|
||||
up)
|
||||
if [[ -z "$service" ]]; then
|
||||
for serv in "${services[@]}"; do
|
||||
pull "$serv"
|
||||
up "$serv"
|
||||
done
|
||||
elif echo "${services[*]}" | grep -qP "\b$service\b"; then
|
||||
pull "$service"
|
||||
up "$service"
|
||||
else
|
||||
echo "Invalid project name. It should be one of: ${services[*]}."
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Invalid action. It should be one of: pull, up."
|
||||
;;
|
||||
esac
|