Skip to content
Snippets Groups Projects
Verified Commit ecf99a5c authored by Sheogorath's avatar Sheogorath :european_castle:
Browse files

feat(terraform): Add hedgedoc-demo instance terraform resources

As I still maintain the demo instance, it's useful to integrate the demo
instance into the current terraform configuration, this allows it to
benefit from further developement of this repository.

The current README and variable descriptions should help anyone
interested in creating their own demo instance equivalent, to deploy
this to their hetzer cloud account. Even if not, it might provide some
nice inspiration regarding the instance handling.
parent 4afa7226
No related branches found
No related tags found
No related merge requests found
Showing with 801 additions and 0 deletions
......@@ -4,3 +4,6 @@ creation_rules:
pgp: >-
286791FB6648539775DB31B8FCB98C2A3EC6F601,
B137EE1549DFAF960DD1E2B15147025FB9F09E07
- path_regex: terraform/.*\.tfvars
pgp: >-
286791FB6648539775DB31B8FCB98C2A3EC6F601
......@@ -31,6 +31,14 @@
"datasourceTemplate": "docker",
"versioningTemplate": "docker"
},
{
"fileMatch": ["terraform/hedgedoc-demo/templates/docker-compose.tpl$"],
"matchStrings": [
"# renovate:\\n\\s+image: \"?'?(?<depName>[^:\\s]+?):(?<currentValue>[^\"]*?)\"?'?\\s"
],
"datasourceTemplate": "docker",
"versioningTemplate": "docker"
},
{
"fileMatch": ["Chart\\.yaml$"],
"matchStrings": [
......
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/cloudflare/cloudflare" {
version = "3.34.0"
constraints = "3.34.0"
hashes = [
"h1:4jOI2ZUyp/EvIVE9rNvCMTqrIaG7j7XxUD1i43xD0Jg=",
"zh:03729b0fcf189e732aca54452a105d82fec839580cb5d0137317af9163e0e4dd",
"zh:121b16a779e9f2fe8c96e98f32514ee9228346fc240ce12c3fb440958b93d127",
"zh:14509f521845eedd57a8791d76958e50bea4928760a152cd853e43f2c81a329b",
"zh:273336ec2bc59ab90916706c074be27f3fe6ab42addc61a354a0ef5e10c2efa5",
"zh:54931c30f71666856c5d749698264c15196103667c87d961f3d293ff8a5c3237",
"zh:58a35eea3b9e1d2f39d7b5b1c6cf107b70eacdf5891017d6667902903db3bd94",
"zh:5ec958afe392a76a1fea262d9070df839c4d811fc6ffd613a37f8b939ab159ef",
"zh:7c24c0572aa9beee20a33cb18ac54d5088a09653e94664a9f74a9af2ae0e3554",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:9248c43f795dbe54e07c6dbc2fb8e2f20aeac8f21ec91373d52b9975f285ba7e",
"zh:b09abd506601b7c3e0b3bfde0b8b9e1aed7f52b5ad629ef2865b8321852409c7",
"zh:e00032df4cd4aad12adf3b7955fca3d1baa8bff9436c775588417da171a4e1d9",
"zh:e4a8812770914d6ce9d1f8399d702e3fb0ecc4bfd6220ba015fcb3884b243c69",
"zh:f2ad0991ef0820b3fc5bd0a500be4dceffe0b5b2ac6c9c5fd17cbb350f2f1209",
"zh:fea3a9dfb1e752dc2864028049a4af05fabf7b62eb57fff26d139a424e3476fd",
]
}
provider "registry.terraform.io/hashicorp/local" {
version = "2.3.0"
constraints = "2.3.0"
hashes = [
"h1:+l9ZTDGmGdwnuYI5ftUjwP8UgoLw4f4V9xoCzal4LW0=",
"zh:1f1920b3f78c31c6b69cdfe1e016a959667c0e2d01934e1a084b94d5a02cd9d2",
"zh:550a3cdae0ddb350942624e7b2e8b31d28bc15c20511553432413b1f38f4b214",
"zh:68d1d9ccbfce2ce56b28a23b22833a5369d4c719d6d75d50e101a8a8dbe33b9b",
"zh:6ae3ad6d865a906920c313ec2f413d080efe32c230aca711fd106b4cb9022ced",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:a0f413d50f54124057ae3dcd9353a797b84e91dc34bcf85c34a06f8aef1f9b12",
"zh:a2ac6d4088ceddcd73d88505e18b8226a6e008bff967b9e2d04254ef71b4ac6b",
"zh:a851010672e5218bdd4c4ea1822706c9025ef813a03da716d647dd6f8e2cffb0",
"zh:aa797561755041ef2fad99ee9ffc12b5e724e246bb019b21d7409afc2ece3232",
"zh:c6afa960a20d776f54bb1fc260cd13ead17280ebd87f05b9abcaa841ed29d289",
"zh:df0975e86b30bb89717b8c8d6d4690b21db66de06e79e6d6cfda769f3304afe6",
"zh:f0d3cc3da72135efdbe8f4cfbfb0f2f7174827887990a5545e6db1981f0d3a7c",
]
}
provider "registry.terraform.io/hashicorp/random" {
version = "3.4.3"
hashes = [
"h1:xZGZf18JjMS06pFa4NErzANI98qi59SEcBsOcS2P2yQ=",
"zh:41c53ba47085d8261590990f8633c8906696fa0a3c4b384ff6a7ecbf84339752",
"zh:59d98081c4475f2ad77d881c4412c5129c56214892f490adf11c7e7a5a47de9b",
"zh:686ad1ee40b812b9e016317e7f34c0d63ef837e084dea4a1f578f64a6314ad53",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:84103eae7251384c0d995f5a257c72b0096605048f757b749b7b62107a5dccb3",
"zh:8ee974b110adb78c7cd18aae82b2729e5124d8f115d484215fd5199451053de5",
"zh:9dd4561e3c847e45de603f17fa0c01ae14cae8c4b7b4e6423c9ef3904b308dda",
"zh:bb07bb3c2c0296beba0beec629ebc6474c70732387477a65966483b5efabdbc6",
"zh:e891339e96c9e5a888727b45b2e1bb3fcbdfe0fd7c5b4396e4695459b38c8cb1",
"zh:ea4739860c24dfeaac6c100b2a2e357106a89d18751f7693f3c31ecf6a996f8d",
"zh:f0c76ac303fd0ab59146c39bc121c5d7d86f878e9a69294e29444d4c653786f8",
"zh:f143a9a5af42b38fed328a161279906759ff39ac428ebcfe55606e05e1518b93",
]
}
provider "registry.terraform.io/hashicorp/template" {
version = "2.2.0"
constraints = "2.2.0"
hashes = [
"h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=",
"zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386",
"zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53",
"zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603",
"zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16",
"zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776",
"zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451",
"zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae",
"zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde",
"zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d",
"zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2",
]
}
provider "registry.terraform.io/hetznercloud/hcloud" {
version = "1.36.2"
constraints = "1.36.2"
hashes = [
"h1:VO/dl+g5NfJd436hmT+9NOMQk6oRU4Z9TSJJJrNlN0M=",
"zh:0498ef4209924b30ce7b4a232dd6aee08feab2ebbc90064db699adc10c16707e",
"zh:292e3c0c55d320cf164cdd431ee31580dd86f435aec99721597204bab5de3970",
"zh:3ce8558658baa7c4b9f1eeb92427665b4b930e5b157fbf352977778c90e11aaa",
"zh:46abd0bdeeba46b86832ed31338ad837b584f7b2152f8a9bfa6c3802f481a6da",
"zh:5804e71d411577f06abc0986c8c2e475c49042a192efce5936e4d5bdd874fc22",
"zh:7cef0782e8198346bfe7b61601e1cf8f2158280a5cf665140b72838545ca3127",
"zh:be81782af391ff4cc0859d976637aa00e6fe34061fe4f1df1f5ab5d62ef94f82",
"zh:bf2660e70edf758305085698fc9d05306b174b99559cd0f3f61c0b705ba22275",
"zh:caf727b0a378dc8c9c3594bbf176865f87aa732077820ff045eb352f5a48aeed",
"zh:cf95fc3121b358c7b7b667193ab36b8cb6140e2f6dfbf6f1b4c55b7fec1bb6ef",
"zh:d6d3119f8b971e982b6421dfa3b86314ccaeceaf047a3b6505f79e1a30f8301e",
"zh:e6f7f65dced2e88e3082c57ddcd118412595678cf3c7289bc7e12c724b3bd892",
"zh:f41f59ca511ab1a591d5abdc7f6d32d2e03a1d6087d206a741f95b7b0dd2ea17",
"zh:fbe59fbb5f272a6b206a380f6dbf49837b199960dd038afca2e89b11f72fdfda",
]
}
Hedgedoc Demo Terraform Repository
===
This directory contains the deployment of the [Hedgedoc](https://hedgedoc.org) [Demo instance](https://demo.hedgedoc.org).
The demo instance is hosted on [Hetzner Cloud](https://hetzner.cloud) in combination with [Cloudflare](https://cloudflare.com) as DNS, CDN and WAF provider and [Backblaze](https://backblaze.com) as Backup storage.
The Terraform setup itself is slightly opinionated and allows reproduction of the instance by replacing the existing one, which includes a minor downtime, until the new instance has downloaded all images as started the containers.
Features
---
This setup provides with some features that weren't available or limited before:
1. Fully reproducible instance creation
2. Automated update installation
3. Automatic nightly deployment
4. Automatic nightly backups including monitoring
5. Fully self-contained setup -> All components (hedgedoc, s3, postgresql, reverse-proxy) of the demo instance run on the host
To be done
---
- [x] Automated installation of Hedgedoc
- [x] Automated docker-compose revisions
- [x] Automated updates to latest nightly image
- [x] Fully restricted network access to backend host
- [x] Automated backup of Hedgedoc
- [x] Automated backup monitoring
- [ ] Automated restore of Hedgedoc
- [ ] Add safeguard preventing volume deletion
- [ ] Add safeguard preventing destruction while backup process in progress
Usage
---
Be aware, that without the `.tfstate` this repository will produce another demo instance, not modify the existing one.
1. Initialise terraform using `terraform init -upgrade`
2. Decrypt or fill/adjust the `terraform.tfvars` file to your needs. (all variables are described in the `variables.tf` file, if you want to start from scratch)
3. Run `terraform apply` and review the changes
4. Initiate deployment of the changes by typing `yes`.
Technology reference
---
- [terraform](https://developer.hashicorp.com/terraform/intro)
- [rockylinux](https://docs.rockylinux.org/)
- [docker](https://docs.docker.com)
- [restic](https://restic.readthedocs.io/en/stable/)
- [hedgedoc](https://docs.hedgedoc.org)
- [traefik](https://docs.traefik.io/)
- [postgresql](https://www.postgresql.org/docs/)
- [minio](https://min.io/docs/minio/container/index.html)
- [watchtower](https://containrrr.dev/watchtower/)
\ No newline at end of file
resource "cloudflare_record" "demo-instance" {
count = 1
zone_id = var.dns_zone_id
name = "demo"
value = module.hedgedoc.server_names[0]
type = "CNAME"
proxied = true
}
resource "cloudflare_record" "s3-storage" {
count = 1
zone_id = var.dns_zone_id
name = "s3"
value = module.hedgedoc.server_names[0]
type = "CNAME"
proxied = true
}
\ No newline at end of file
data "cloudflare_ip_ranges" "cloudflare" {}
resource "hcloud_firewall" "ingress-web" {
name = "ingress-web"
apply_to {
label_selector = "firewall.hetzner.si-infra.de/web=true"
}
# ICMP is always a good idea
#
# Network reachability tests
rule {
direction = "in"
protocol = "icmp"
source_ips = [
"0.0.0.0/0",
"::/0"
]
}
# Allow HTTP and HTTPS traffic in
rule {
direction = "in"
protocol = "tcp"
port = "80"
source_ips = data.cloudflare_ip_ranges.cloudflare.cidr_blocks
}
rule {
direction = "in"
protocol = "tcp"
port = "443"
source_ips = data.cloudflare_ip_ranges.cloudflare.cidr_blocks
}
}
resource "hcloud_firewall" "ingress-ssh" {
name = "ingress-ssh"
apply_to {
label_selector = "firewall.hetzner.si-infra.de/ssh=true"
}
# ICMP is always a good idea
#
# Network reachability tests
rule {
direction = "in"
protocol = "icmp"
source_ips = [
"0.0.0.0/0",
"::/0"
]
}
# Allow SSH traffic in
rule {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = var.ssh_firewall_cidr
}
}
module "hedgedoc" {
source = "../modules/hcloud_instance"
instance_count = 1
location = var.location
name = "srv"
dns_domain = var.dns_domain
dns_zone_id = var.dns_zone_id
dns_record_aaaa = false
image = "rocky-9"
user_data = templatefile("templates/cloud-init.tpl", {
docker_compose_file = templatefile("templates/docker-compose.tpl", {
hedgedoc_db_user = "${var.hedgedoc_db_user}",
hedgedoc_db_password = "${var.hedgedoc_db_password}",
hedgedoc_session_secret = "${var.hedgedoc_session_secret}",
hedgedoc_minio_accesskey = "${var.hedgedoc_minio_accesskey}",
hedgedoc_minio_secretkey = "${var.hedgedoc_minio_secretkey}",
hedgedoc_minio_endpoint = "${var.hedgedoc_minio_endpoint}",
hedgedoc_minio_bucketname = "${var.hedgedoc_minio_bucketname}",
hedgedoc_github_clientid = "${var.hedgedoc_github_clientid}",
hedgedoc_github_clientsecret = "${var.hedgedoc_github_clientsecret}",
letsencrypt_email = "${var.letsencrypt_email}",
}),
restic_b2_account_id = "${var.restic_b2_account_id}",
restic_b2_account_key = "${var.restic_b2_account_key}",
restic_repo_url = "${var.restic_repo_url}",
restic_repo_password = "${var.restic_repo_password}",
restic_monitoring_url = "${var.restic_monitoring_url}",
hedgedoc_db_user = "${var.hedgedoc_db_user}",
})
ssh_keys = data.hcloud_ssh_keys.all_keys.ssh_keys.*.name
server_type = "cx11"
labels = {
"firewall.hetzner.si-infra.de/web" = "true",
"firewall.hetzner.si-infra.de/ssh" = "true",
}
volume = true
volume_size = 45
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
provider "hcloud" {
token = var.hcloud_token
}
provider "template" {
}
provider "local" {
}
provider "random" {
}
data "hcloud_ssh_keys" "all_keys" {
}
#!/bin/bash
set -e
dnf upgrade -y
# Enable automatic updates
dnf install -y dnf-automatic
systemctl enable --now dnf-automatic-install.timer
# Install docker
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable --now docker
# Setup volume
echo "/dev/sdb /srv xfs discard,nofail,defaults 0 0" >> /etc/fstab
mount /dev/sdb /srv
mountpoint /srv
# Create docker-compose backup
if -e /srv/docker-compose.yaml; then
mv /srv/docker-compose.yaml /srv/docker-compose.yaml.1
fi
CUR=1
for i in $(seq 2 10); do
if -e "/srv/docker-compose.yaml.$${CUR}"; then
mv "/srv/docker-compose.yaml.$${CUR}" "/srv/docker-compose.yaml.$${i}"
else
break
fi
CUR="$${i}"
done
cat > /srv/docker-compose.yaml <<EOF
${docker_compose_file}
EOF
cd /srv
docker compose up -d
dnf install -y epel-release
dnf install -y restic
mkdir -p /root/.cache/
cat > /etc/sysconfig/restic <<EOF
BACKUP_PATHS="/srv"
B2_ACCOUNT_ID=${restic_b2_account_id}
B2_ACCOUNT_KEY=${restic_b2_account_key}
RETENTION_DAYS=7
RETENTION_WEEKS=2
RETENTION_MONTHS=3
RETENTION_YEARS=1
RESTIC_REPOSITORY=${restic_repo_url}
RESTIC_PASSWORD=${restic_repo_password}
RESTIC_CACHE_DIR=/root/.cache/restic
EOF
set -a
source /etc/sysconfig/restic
set +a
if ! restic snapshots; then
restic init
fi
# Inspired by https://fedoramagazine.org/automate-backups-with-restic-and-systemd/
# Inspired by https://www.mavjs.org/post/automatic-backup-restic-systemd-service/
cat > /etc/systemd/system/offsite-backup.service <<EOF
[Unit]
Description=Offsite backup with restic
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# Low CPU priority
CPUShares=512
EnvironmentFile=/etc/sysconfig/restic
ExecStart=/usr/local/libexec/restic-backup-hedgedoc
EOF
# Inspired by https://github.com/mhw/restic-backup-scripts/blob/e3fe81ba25acc5ae3ccdb28807eea8b0be38ce20/postgresql-backup.sh
cat > /usr/local/libexec/restic-backup-hedgedoc <<EOF
#!/bin/bash
set -e
set -o pipefail
# Run general backup, excluding the database
/usr/bin/restic backup /srv \
--exclude=/srv/database/* \
--one-file-system \
--tag systemd.timer \
--tag persistentvolume
cd /srv
# Run database backup separately by dumping the database for consistency
docker compose exec database pg_dump --create --clean --if-exists --no-owner --no-privileges -U ${hedgedoc_db_user} hedgedoc | \
gzip --rsyncable | \
restic backup \
--stdin --stdin-filename postgresql/hedgedoc.sql.gz \
--tag "systemd.timer" \
--tag "hedgedoc-database"
# Notify monitoring about success
curl --retry-all-errors --retry 10 '${restic_monitoring_url}'
EOF
chmod +x /usr/local/libexec/restic-backup-hedgedoc
cat > /etc/systemd/system/offsite-backup-prune.service <<EOF
[Unit]
Description=Restic backup service (data pruning)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/sysconfig/restic
ExecStart=/usr/bin/restic forget --prune \
--tag systemd.timer \
--group-by "paths,tags" \
--keep-daily \$RETENTION_DAYS \
--keep-weekly \$RETENTION_WEEKS \
--keep-monthly \$RETENTION_MONTHS \
--keep-yearly \$RETENTION_YEARS
EOF
cat > /etc/systemd/system/offsite-backup.timer <<EOF
[Unit]
Description=Offsite backup with restic
After=network-online.target
Wants=network-online.target
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=600
[Install]
WantedBy=timers.target
EOF
cat > /etc/systemd/system/offsite-backup-prune.timer <<EOF
[Unit]
Description=Prune data from the restic repository monthly
After=network-online.target
Wants=network-online.target
[Timer]
OnCalendar=*-*-* 4:00:00
Persistent=true
RandomizedDelaySec=600
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now offsite-backup.timer offsite-backup-prune.timer
sleep 60
reboot
version: '2'
services:
database:
# renovate:
image: docker.io/library/postgres:13
mem_limit: 896mb
memswap_limit: 1024mb
read_only: true
tmpfs:
- /run/postgresql:size=512K
- /tmp:size=128K
stop_grace_period: 2m
stop_signal: SIGINT
environment:
- POSTGRES_USER=${hedgedoc_db_user}
- POSTGRES_PASSWORD=${hedgedoc_db_password}
- POSTGRES_DB=hedgedoc
volumes:
- ./database:/var/lib/postgresql/data:z
networks:
backend:
restart: always
hedgedoc:
# renovate:
image: quay.io/hedgedoc/hedgedoc-nightly:debian
mem_limit: 1gb
memswap_limit: 1536mb
read_only: true
tmpfs:
- /tmp:size=10M
depends_on:
- database
environment:
- "CMD_DB_URL=postgres://${hedgedoc_db_user}:${hedgedoc_db_password}@database:5432/hedgedoc"
- "CMD_DOMAIN=demo.hedgedoc.org"
- "CMD_PROTOCOL_USESSL=true"
- "CMD_URL_ADDPORT=false"
- "CMD_SESSION_SECRET=${hedgedoc_session_secret}"
- "CMD_MINIO_PORT=443"
- "CMD_MINIO_ENDPOINT=${hedgedoc_minio_endpoint}"
- "CMD_MINIO_ACCESS_KEY=${hedgedoc_minio_accesskey}"
- "CMD_MINIO_SECRET_KEY=${hedgedoc_minio_secretkey}"
- "CMD_MINIO_SECURE=true"
- "CMD_IMAGE_UPLOAD_TYPE=minio"
- "CMD_S3_BUCKET=${hedgedoc_minio_bucketname}"
- "CMD_GITHUB_CLIENTID=${hedgedoc_github_clientid}"
- "CMD_GITHUB_CLIENTSECRET=${hedgedoc_github_clientsecret}"
- "CMD_USECDN=false"
- "CMD_ALLOW_FREE_URL=false"
- "CMD_EMAIL=true"
- "CMD_ALLOW_PDF_EXPORT=false"
- "CMD_CSP_REPORTURI=https://hedgedoc.report-uri.com/r/d/csp/enforce"
- "CMD_OPENID=true"
- "CMD_TOOBUSY_LAG=250"
- "CMD_CSP_ALLOW_FRAMING=false"
- "CMD_CSP_ADD_DISQUS=false"
- "CMD_CSP_ADD_GOOGLE_ANALYTICS=false"
labels:
- "traefik.http.routers.hedgedoc_demo.rule=Host(\`demo.hedgedoc.org\`) && PathPrefix(\`/\`) && ! PathPrefix(\`/metrics\`)"
- "traefik.http.routers.hedgedoc_demo.entrypoints=websecure"
- "traefik.http.routers.hedgedoc_demo.tls=true"
- "traefik.http.routers.hedgedoc_demo.tls.certresolver=letsencrypt_http"
- "traefik.http.routers.hedgedoc_demo.middlewares=hedgedoc_demo"
- "traefik.http.routers.hedgedoc_demo.service=hedgedoc_demo"
- "traefik.http.services.hedgedoc_demo.loadbalancer.server.port=3000"
- "traefik.http.middlewares.hedgedoc_demo.headers.sslredirect=true"
- "traefik.http.middlewares.hedgedoc_demo.headers.stsSeconds=63072000"
- "traefik.http.middlewares.hedgedoc_demo.headers.browserXssFilter=true"
- "traefik.http.middlewares.hedgedoc_demo.headers.contentTypeNosniff=true"
- "traefik.enable=true"
- "traefik.port=3000"
- "traefik.docker.network=proxy"
volumes:
- './privacy.md:/hedgedoc/public/docs/privacy.md:ro,z'
networks:
backend:
proxy:
restart: always
minio:
# renovate:
image: docker.io/minio/minio:latest
mem_limit: 256mb
memswap_limit: 512mb
read_only: true
tmpfs:
- /root/.minio:size=128K
environment:
- "MINIO_ACCESS_KEY=${hedgedoc_minio_accesskey}"
- "MINIO_SECRET_KEY=${hedgedoc_minio_secretkey}"
- "MINIO_BROWSER=off"
- "MINIO_DOMAIN=${hedgedoc_minio_endpoint}"
volumes:
- "./s3-storage:/data:z"
command: ["server", "/data"]
restart: always
labels:
- "traefik.http.routers.minio_hedgedoc.rule=Host(\`${hedgedoc_minio_endpoint}\`) && PathPrefix(\`/\`)"
- "traefik.http.routers.minio_hedgedoc.entrypoints=websecure"
- "traefik.http.routers.minio_hedgedoc.tls=true"
- "traefik.http.routers.minio_hedgedoc.tls.certresolver=letsencrypt_http"
- "traefik.http.routers.minio_hedgedoc.middlewares=minio_hedgedoc"
- "traefik.http.routers.minio_hedgedoc.service=minio_hedgedoc"
- "traefik.http.services.minio_hedgedoc.loadbalancer.server.port=9000"
- "traefik.http.middlewares.minio_hedgedoc.headers.sslredirect=true"
- "traefik.http.middlewares.minio_hedgedoc.headers.stsSeconds=63072000"
- "traefik.http.middlewares.minio_hedgedoc.headers.referrerPolicy=no-referrer"
- "traefik.http.middlewares.minio_hedgedoc.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.minio_hedgedoc.headers.browserXssFilter=true"
- "traefik.enable=true"
- "traefik.port=9000"
- "traefik.docker.network=proxy"
networks:
proxy:
proxy:
# renovate:
image: docker.io/library/traefik:v2.9
security_opt:
- "label:disable"
read_only: true
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- "./acme:/etc/traefik/acme:z"
- "/var/run/docker.sock:/var/run/docker.sock"
command:
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--accesslog=false"
- "--providers.docker=true"
- "--certificatesResolvers.letsencrypt_http.acme.email=${letsencrypt_email}"
- "--certificatesResolvers.letsencrypt_http.acme.storage=/etc/traefik/acme/acme-v2.json"
- "--certificatesResolvers.letsencrypt_http.acme.httpChallenge.entrypoint=web"
networks:
proxy:
watchtower:
# renovate:
image: docker.io/containrrr/watchtower:latest
restart: always
security_opt:
- "label:disable"
environment:
- "WATCHTOWER_CLEANUP=true"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
networks:
proxy:
name: proxy
backend:
\ No newline at end of file
{
"data": "ENC[AES256_GCM,data:AvfL4Gvv1+/YJi/7Qcq42x24lK9irGWnTmo8cvazsYgMOciIyCz7Jru6LItoCMrALgXSfuT6v2ezgQJ++shTBllfOnGfvyk4nIjNeeJDwellVoardgiwBO+xxUSyHG6exbuODFw0xE0m3N1hSOyyy1wbOpG6pFGDfkZYtzD6F5MVzyGBpgg+py3/nggIMtWwrm03frSxWESggJ+bLQWsOmVqXVq9fWEAsB4tXfsaR3QaALcyAEeyVNB+111abhxuSLn/+jQHuzovQky8ORpLBGRlR7VtWj2Z6xnJ+KsSWtONJn1qdZddi24ybrJ33R8OCDX2ISQx0wV/XG5APAquAxeNsSik3nOBIqhHjWM9gTNrZohyfGc044WO9xF6zKqSKpuZ8zqnEqd/0qcWUvvFeFL4UEXtYugAQm1LbSj21ulYLEkO0KSMwHTLdeysa53KECBL9rkRh2FjXFtxva7ctDjE5uyfE4sqEB3VpdRu3Frd3nDTrKbI5qtf99Ujbv8fwCkrxKMEkYmHXGBRtBndabafknugUPTCfWk0eLLzxAJ/hSWJ/tFciALFPujqEdtM78zpBvYbmr68DuqO3zq8i2r+7tFhZKHYk6Sk/+kWB202I4RoO5d/MV1tx7ZSvFVeYxJJfRb+ZHR7RfEofLv+EE/Ku7YCb8ABzFPvnTZpqaLxc8BLnl5ahoZzvyhrngu5ZIwVjW9s/SkjynslPC0l2PH7gHpVLXH6rz3ggUU8siOW1885Khwp/Par3vG2C7wXGjXSVitzVM+ssRSI55TVr81ar2DJtriujPBR7vUJnQ1yexOOyPMwg0Q804MjXsFE0N4POB0zIOU390LscyEzLKblqUhi843yrZX+Y4n0AbmZpOUMsDgqqa9BhdrHtMGRGWd6xT+bDwc4mcysHS1VHr+oDaAU4oNh/Px4168DFsLhXexPBtneCV3AEZ1LscL0DjGxVlaNKD6hcl1JqIGwIM+6QbDmpAhjIPNFHR2PYBmYJ9Q92WYUkQw3/CubZ7amY7ItANERBPyYQ5uB1Oq/2LniL4QmLiBFZTOse6amunzwJMMkfEaKqHs+ELjPVSl3qCJjGtHVKDOybbRTX+k4Q22xMI8Vbk71ix60zkUNxnxxpwTaOPE/HhNsPWF3KuXJwXC+xlnG4SPjQAgk0qKyIGNBs0YFV8WVw5mKbSUTxNPndbU2Y1KYnU9L6vyKYBsNST9wg0ehiZPpZlmaRdHrnS7hTX6220nXuUM59ef0cBzZqrbGmVVTgxjI1KA+Cw7xJwr9iMf0JY6vb+s3V7gw9XZ5xJY20JRZsgrAzOAMBWBCtFjEt7UqqcloGQ6zDIsGhnMUdJC/Xxaf/PmxuD/RjUBk8mlaSfIAX43xKVJsRpcX96k+3GtF/lRGnu+AOprwsdqtx0mmdi1/GL8ph7/le+WZHvmyTZ00Y5VQ9mgX/BloY2dK+Yem6zCN/cxlwzTX0ZTdOZ93COs=,iv:wl3rX28j9AxiIldid/fnnbLUEW22WI+KpyH7i+GGJnM=,tag:aDwZAuHYWXhA3gpVIHG25g==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": null,
"lastmodified": "2023-03-01T00:12:49Z",
"mac": "ENC[AES256_GCM,data:0ooMWpnFkMGj2qI+ZrStExZoxRCkKLa00BqQLFIiG09Qq3JKrbixpR2a/AP7zloauB8TtSyl5DvXHSvpRvWMjvMhA61aUk6w3WQ0I3mdTZv7TLzP172lPo6DzvG35e8TAujH+fEUNfFW0zutMff/Z/9zWJJ5H9f6Z6IusrD1qkA=,iv:4YdQREC5g6chGJjFBKLW0RzZXIpsRHS3SxVEKixCgJU=,tag:AVNiRyZLwLmdesdyWwqp1g==,type:str]",
"pgp": [
{
"created_at": "2023-03-01T00:12:49Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nwcFMA7kpg2bgzVHcAQ/+MdRgsdX6mCEGY3Tuqy4Kf2HrCpV1eNLJIgEjMJXupTVZ\nqSVhT5TRDt1kSW7D0czHJTS/Nm9nD6Y0+MFY+UMK2VqFkLPatfkyMHli5JIskpR1\nyi+UsZ5o3UQBjccM7m91kaF3me/+92h2EE2monVFPYNsABlXmNjS9yqei2Jm63ry\nXVCWCpKPLmDDOpCZk7CnJggKO2f+gdgT3JGapkSU0j8to3JoleLuszSDxmiE8S7/\nrmMNTzRzOynN6lLZkS6nQQpYBM9fYzpyxN1AexeX2qzKT18oajcu7uws9Rq5Nr7Z\naS4sPmnJfkIwG5PVBlDg/5GKt4QiMIPHXFl86QW64Du2Roe4T01G3af2FzniDrxi\npL3CgXx+HpcievUI9+fs3as77r0DTIpHZOyTmTW4PDczqdNjviTIlCse/2GiYPhJ\ngHlBkGUoY1CWpJgU4bYZjeJ9DFWSVSkYvjLUO146TyiK+AmNCykff9ipXjH5TKto\nktT80Tgd2rgzgq+536aswr7a86X7PuYXjqJ4qXYM3F+7sRJF5ZEVcuOnsWzpZ8Rh\nAi5tuwWUmCR7bfJHShp381iZbkfT6TWwa4hOx9sXNLtebgf8DOynhPMP9itCIUnE\nJxg/1EtxOp4AvyjqLv0LgRv/tZa58HEGVSKBdWyR96Vq4JQqkVNF1S4PLUHuA+TS\nUQEBoS5+5Zo8nJp/LnZ7k1rzodu7MjZnwbnbkaXTjMZKl0gi2n2NLeITghfgWyQE\nqMUiOZAp+wM676u1r8Mnj8wILofk2EejikMK45bDp7BGQw==\n=xjMK\n-----END PGP MESSAGE-----",
"fp": "286791FB6648539775DB31B8FCB98C2A3EC6F601"
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.7.3"
}
}
\ No newline at end of file
variable "dns_domain" {
type = string
description = "Name of the Cloudflare domain"
nullable = false
}
variable "dns_zone_id" {
type = string
description = "Zone ID of the Cloudflare domain"
nullable = false
}
variable "location" {
type = string
description = "Region used to deploy the Hetzner Cloud instance. See: https://docs.hetzner.cloud/#locations"
default = "nbg1"
nullable = false
}
variable "ssh_firewall_cidr" {
type = list(string)
description = "List of CIDRs addresses that are allow to SSH into the host"
default = ["127.0.0.1/32"]
nullable = false
}
variable "hedgedoc_db_user" {
type = string
description = "Username used to authenticate to the PostgreSQL database. See: https://docs.hedgedoc.org/configuration/#hedgedoc-basics"
nullable = false
}
variable "hedgedoc_db_password" {
type = string
description = "Password used to authenticate to the PostgreSQL database. See: https://docs.hedgedoc.org/configuration/#hedgedoc-basics"
sensitive = true
nullable = false
}
variable "hedgedoc_session_secret" {
type = string
description = "Secret used for securing the Hedgedoc session token, this ensures after a restart users stay authenticated. See: https://docs.hedgedoc.org/configuration/#users-and-privileges"
sensitive = true
nullable = false
}
variable "hedgedoc_minio_accesskey" {
type = string
description = "S3/Minio access key/ id for authentication. See: https://docs.hedgedoc.org/guides/minio-image-upload/"
sensitive = true
nullable = false
}
variable "hedgedoc_minio_secretkey" {
type = string
description = "S3/Minio secret key for authentication. See: https://docs.hedgedoc.org/guides/minio-image-upload/"
sensitive = true
nullable = false
}
variable "hedgedoc_minio_endpoint" {
type = string
description = "Connection Endpoint used for uploading files to S3/Minio backend. See: https://docs.hedgedoc.org/guides/minio-image-upload/"
nullable = false
}
variable "hedgedoc_minio_bucketname" {
type = string
description = "Name of the S3/Minio Bucket. See: https://docs.hedgedoc.org/guides/minio-image-upload/"
nullable = false
}
variable "hedgedoc_github_clientid" {
type = string
description = "GitHub Client ID used for GitHub SSO. See: https://docs.hedgedoc.org/guides/auth/github/"
sensitive = true
nullable = false
}
variable "hedgedoc_github_clientsecret" {
type = string
description = "GitHub Client Secret used for GitHub SSO. See: https://docs.hedgedoc.org/guides/auth/github/"
sensitive = true
nullable = false
}
variable "restic_b2_account_id" {
type = string
description = "ID to access B2 backup storage. See: https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2"
sensitive = true
nullable = false
}
variable "restic_b2_account_key" {
type = string
description = "Token to access B2 backup storage. See: https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2"
sensitive = true
nullable = false
}
variable "restic_repo_url" {
type = string
description = "URL for restric backup location, should start with b2:. See: https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2"
nullable = false
}
variable "restic_repo_password" {
type = string
description = "Password used to secure the restic backups. See: https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html"
sensitive = true
nullable = false
}
variable "restic_monitoring_url" {
type = string
description = "URL that curl will call after finishing a backup, allows push monitoring"
default = "http://example.com"
sensitive = true
nullable = false
}
variable "letsencrypt_email" {
description = "E-Mail address used for Let's Encrypt certificates"
nullable = false
}
variable "cloudflare_api_token" {
description = "API token for Cloudflare authentication. See: https://developers.cloudflare.com/fundamentals/api/get-started/create-token/"
sensitive = true
nullable = false
}
variable "hcloud_token" {
description = "API token for Hetzner Cloud authentication. See: https://docs.hetzner.cloud/#getting-started"
sensitive = true
nullable = false
}
../versions.tf
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment