Skip to content

Commit

Permalink
feat: betisier
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvainmetayer committed Sep 23, 2024
1 parent c8abfaf commit fb9ad79
Show file tree
Hide file tree
Showing 28 changed files with 401 additions and 38 deletions.
50 changes: 50 additions & 0 deletions 00-provision/02-healthchecks.tf
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,62 @@ resource "healthchecksio_check" "rss_backup" {
]
}

resource "healthchecksio_check" "betisier_backup" {
name = "Betisier Backup"
desc = "Ensure backup of Betisier did run at least once per day."

tags = [
"backup",
"betisier",
"hetzner"
]

timeout = 24 * 3600
grace = 3600
channels = [
data.healthchecksio_channel.signal.id
]
}

resource "healthchecksio_check" "betisier_reset" {
name = "Betisier Reset"
desc = "Ensure Betisier is reset each day"

tags = [
"betisier",
"hetzner"
]

timeout = 24 * 3600
grace = 3600
channels = [
data.healthchecksio_channel.signal.id
]
}

resource "healthchecksio_check" "monica_v4_cron" {
name = "Monica v4 CRON"
desc = "Ensure monica v4 cron run at least once per hour"

tags = [
"monica_v4",
"hetzner"
]

timeout = 1800
grace = 3600
channels = [
data.healthchecksio_channel.signal.id
]
}

resource "healthchecksio_check" "monica_v4_backup" {
name = "monica_v4 Backup"
desc = "Ensure backup of monica_v4 did run at least once per day."

tags = [
"backup",
"monica_v4",
"hetzner"
]

Expand Down
18 changes: 9 additions & 9 deletions 00-provision/99-dns-entries-gandi.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ data "gandi_domain" "zone" {
name = "sylvain.dev"
}

# resource "gandi_livedns_record" "betisier" {
# zone = data.gandi_domain.zone.id
# name = "betisier"
# type = "A"
# ttl = 300
# values = [
# hcloud_server.services.ipv4_address
# ]
# }
resource "gandi_livedns_record" "betisier" {
zone = data.gandi_domain.zone.id
name = "betisier"
type = "A"
ttl = 300
values = [
hcloud_server.services.ipv4_address
]
}

resource "gandi_livedns_record" "monica_v4" {
zone = data.gandi_domain.zone.id
Expand Down
3 changes: 3 additions & 0 deletions 00-provision/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ output "healthcheck_ids" {
wiki: healthchecksio_check.wiki_backup.ping_url
rss: healthchecksio_check.rss_backup.ping_url
monica_v4: healthchecksio_check.monica_v4_backup.ping_url
monica_v4_cron: healthchecksio_check.monica_v4_cron.ping_url
betisier: healthchecksio_check.betisier_backup.ping_url
betisier_reset: healthchecksio_check.betisier_reset.ping_url
}
}

Expand Down
2 changes: 2 additions & 0 deletions 01-configure/01-services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
tags: app
- role: monica_v4
tags: app
- role: betisier
tags: app
- role: geerlingguy.certbot
become: true
tags: app
12 changes: 6 additions & 6 deletions 01-configure/requirements.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
collections:
- name: sylvainmetayer.workstation
version: 1.2.38
version: 1.2.39
- name: devsec.hardening
version: 9.0.1
version: 10.0.0
- name: community.sops
version: 1.4.1
version: 1.9.0
roles:
- src: geerlingguy.certbot
version: 5.0.1
version: 5.2.0
- src: escalate.swap
version: v2.0.0
- src: geerlingguy.docker
version: 7.3.0
version: 7.4.1
- src: andrewrothstein.starship
version: v1.2.1
version: v1.2.2
7 changes: 7 additions & 0 deletions 01-configure/roles/betisier/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
betisier_base_path: /opt/betisier
betisier_domain: betisier.sylvain.dev
betisier_local_port: 9004
betisier_db_password: ""
betisier_healthcheck_url: ""
betisier_reset_healthcheck_url: ""
49 changes: 49 additions & 0 deletions 01-configure/roles/betisier/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
- name: Ensure Betisier app folder exists
become: true
file:
mode: "0700"
path: "{{ betisier_base_path }}"
state: directory
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_gid }}"

- name: Add restic profile
tags: backup
ansible.builtin.blockinfile:
path: ~/.config/resticprofile/profiles.yaml
prepend_newline: true
block: "{{ lookup('ansible.builtin.template', 'templates/resticprofile.yaml') }}"
marker: "# {mark} betisier ANSIBLE MANAGED"

- name: Template docker-compose configuration
template:
src: "templates/docker-compose.yml.j2"
dest: "{{ betisier_base_path }}/docker-compose.yml"
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_gid }}"
mode: "0644"

- name: Template nginx host
become: true
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/sites-available/betisier.conf
owner: "root"
group: "root"
mode: "0644"

- name: Enable nginx host
become: true
ansible.builtin.file:
src: /etc/nginx/sites-available/betisier.conf
dest: /etc/nginx/sites-enabled/betisier.conf
owner: root
group: root
state: link

- name: Add domain to certificate to be generated
set_fact:
certbot_certs: '{{ certbot_certs + [ { "domains": [betisier_domain] } ] }}'

- import_tasks: service.yaml
16 changes: 16 additions & 0 deletions 01-configure/roles/betisier/tasks/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
- name: Copy betisier service
template:
src: ./templates/betisier.service.j2
dest: ~/.config/systemd/user/betisier.service
group: "{{ ansible_user_gid }}"
owner: "{{ ansible_user_uid }}"
mode: "0644"

- name: Make sure betisier service is running
ansible.builtin.systemd:
state: started
daemon_reload: true
name: betisier
scope: user
enabled: true
18 changes: 18 additions & 0 deletions 01-configure/roles/betisier/templates/betisier.service.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Thanks https://github.com/MiGoller/dc-systemd-template#creating-docker-compose-powered-services-using-systemd-templates
[Unit]
Description=Betisier service powered by docker compose

[Service]
TimeoutStartSec=60
# Restart each day by resetting data - https://stackoverflow.com/a/50332245
Restart=always
RuntimeMaxSec=1d

WorkingDirectory={{ betisier_base_path }}

ExecStartPre=/usr/bin/curl {{ betisier_reset_healthcheck_url }}
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
30 changes: 30 additions & 0 deletions 01-configure/roles/betisier/templates/docker-compose.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
services:
betisier:
container_name: betisier
image: ghcr.io/sylvainmetayer/betisier-tp:latest
environment:
- PUID={{ ansible_user_uid }}
- PGID={{ ansible_user_gid }}
- TZ=Europe/Paris
ports:
- 127.0.0.1:{{ betisier_local_port }}:80
volumes:
- ./config:/config
restart: unless-stopped

betisier_db:
image: lscr.io/linuxserver/mariadb
container_name: betisier_db
environment:
- PUID={{ ansible_user_uid }}
- PGID={{ ansible_user_gid }}
- TZ=Europe/Paris
- MYSQL_ROOT_PASSWORD={{ betisier_db_password }}
- MYSQL_DATABASE=betisier
- MYSQL_USER=betisier
- MYSQL_PASSWORD={{ betisier_db_password }}
volumes:
# No DB volume, since we want to reset database on restart
- ./dump.sql:/config/initdb.d/betisier.sql:ro
restart: unless-stopped
55 changes: 55 additions & 0 deletions 01-configure/roles/betisier/templates/nginx.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
upstream betisier {
server 127.0.0.1:{{ betisier_local_port }};
}

server {
listen 443 ssl http2;
server_name {{ betisier_domain }};
root /var/www/default/;
index index.php;
client_max_body_size 10M;
#add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; form-action 'self'; frame-src 'self'; font-src 'self'; img-src 'self' *; media-src https://storage.googleapis.com; script-src 'self'; style-src 'self' 'unsafe-inline'";
location = /robots.txt { access_log off; log_not_found off; }
location = /favicon.ico { access_log off; log_not_found off; }
# Deny access to .htaccess files, if Apache's document root concurs with nginx's one
location /.ht {
deny all;
}

# Deny access to hidden dotfiles (beginning with '.')
location /. {
deny all;
}

access_log /var/log/nginx/{{ betisier_domain }}.access.log combined;
error_log /var/log/nginx/{{ betisier_domain }}.error.log;

location / {
include proxy_params;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://betisier;
}

# https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1;

# https://ssl-config.mozilla.org/#server=nginx&version=1.14.2&config=modern&openssl=1.1.1d&hsts=false&guideline=5.6
ssl_certificate /etc/letsencrypt/live/{{ betisier_domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ betisier_domain }}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/{{ betisier_domain }}/chain.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;

# modern configuration
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
}

server {
listen 80;
server_name {{ betisier_domain }};
return 301 https://$host$request_uri;
}
66 changes: 66 additions & 0 deletions 01-configure/roles/betisier/templates/resticprofile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# $schema: ../../../schema/resticprofile.json
# https://creativeprojects.github.io/resticprofile/jsonschema/config-1.json

betisier:
lock: "/tmp/resticprofile-profile-betisier.lock"
status-file: backup-betisier-status.json
repository: "s3:{{ restic_s3_endpoint }}"
password-file: "~/.restic.password.txt"
env:
AWS_ACCESS_KEY_ID: "{{ restic_access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ restic_secret_key }}"
retention:
after-backup: true
keep-daily: 2
keep-weekly: 7
keep-monthly: 5
keep-yearly: 2
backup:
schedule-lock-mode: fail
retry-lock: 2m
schedule-lock-wait: 1h
option:
- s3.storage-class=ONEZONE_IA
run-before:
- curl {{ betisier_healthcheck_url }}/start
# Do not backup current database as we want to rollback it.
run-after:
- curl {{ betisier_healthcheck_url }}/0
run-after-fail:
- curl {{ betisier_healthcheck_url }}/fail
schedule: "03:00"
verbose: 2
tag:
- hetzner
- betisier
source:
- "/opt/betisier/docker-compose.yml"
- "/opt/betisier/config"
- "/opt/betisier/dump.sql"

forget:
keep-daily: 1
keep-weekly: 1
keep-monthly: 1
keep-yearly: 1
prune: true
schedule: "05:00"
schedule-permission: user
schedule-lock-wait: 1h

prune:
schedule:
- "sun 3:30"
schedule-permission: user
schedule-lock-wait: 1h

# Verify command
check:
schedule: "06:00"
schedule-permission: user
schedule-lock-wait: 1h

description: Backup Betisier {{ betisier_domain }}

verbose: true
cleanup-cache: true
3 changes: 2 additions & 1 deletion 01-configure/roles/monica_v4/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ monica_v4_base_path: /opt/monica_v4
monica_v4_domain: crm.sylvain.dev
monica_v4_local_port: 9003
monica_v4_db_password: ""
monica_v4_healthcheck_url: ""
monica_v4_healthcheck_url: ""
monica_v4_cron_healthcheck_url: ""
Loading

0 comments on commit fb9ad79

Please sign in to comment.