Compare commits

..

1 commit

Author SHA1 Message Date
Ayden Jahola
5b6133de55
DCUSR listmonk: migrate and update listmonk to latest 2025-01-20 23:15:30 +00:00
19 changed files with 161 additions and 471 deletions

View file

@ -1,64 +0,0 @@
job "esports-minecraft" {
datacenters = ["aperture"]
type = "service"
group "esports-mc" {
count = 1
network {
port "mc" {
to = 25565
}
port "rcon" {
to = 25575
}
}
service {
name = "esports-mc"
port = "mc"
}
service {
name = "esports-mc-rcon"
port = "rcon"
}
task "esports-minecraft" {
driver = "docker"
config {
image = "itzg/minecraft-server"
ports = ["mc", "rcon"]
volumes = [
"/storage/nomad/${NOMAD_TASK_NAME}:/data"
]
}
resources {
cpu = 5000 # 5000 MHz
memory = 20480 # 20 GB
}
template {
data = <<EOF
EULA = "TRUE"
TYPE = "PAPER"
VERSION = "1.21.4"
ICON = "https://liquipedia.net/commons/images/thumb/5/53/DCU_Esports_allmode.png/37px-DCU_Esports_allmode.png"
USE_AIKAR_FLAGS = true
MAX_MEMORY = 18G
MOTD = "Powered by Redbrick"
MAX_PLAYERS = "32"
VIEW_DISTANCE = "32"
ENABLE_RCON = true
RCON_PASSWORD = {{ key "games/mc/esports-mc/rcon/password" }}
# Auto-download plugins
SPIGET_RESOURCES=83581,62325,118271,28140,102931 # RHLeafDecay, GSit, GravesX, Luckperms, NoChatReport
MODRINTH_PROJECTS=datapack:no-enderman-grief,thizzyz-tree-feller,imageframe,bmarker,datapack:players-drop-heads,viaversion,viabackwards
EOF
destination = "local/.env"
env = true
}
}
}
}

View file

@ -1,44 +0,0 @@
job "uptime-kuma" {
datacenters = ["aperture"]
type = "service"
group "web" {
count = 1
network {
port "http" {
to = 3001
}
}
service {
port = "http"
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
tags = [
"traefik.enable=true",
"traefik.http.routers.uptime-kuma.rule=Host(`status.redbrick.dcu.ie`)",
"traefik.http.routers.uptime-kuma.entrypoints=web,websecure",
"traefik.http.routers.uptime-kuma.tls.certresolver=lets-encrypt",
]
}
task "web" {
driver = "docker"
config {
image = "louislam/uptime-kuma:1"
ports = ["http"]
volumes = [
"/storage/nomad/uptime-kuma/data:/app/data"
]
}
}
}
}

View file

@ -42,7 +42,7 @@ job "hedgedoc" {
driver = "docker"
config {
image = "quay.io/hedgedoc/hedgedoc:1.10.2"
image = "quay.io/hedgedoc/hedgedoc:1.10.0"
ports = ["http"]
volumes = [
"/storage/nomad/hedgedoc/banner:/hedgedoc/public/banner",

View file

@ -7,15 +7,12 @@ job "plausible" {
port "http" {
to = 8000
}
port "clickhouse" {
static = 8123
}
port "db" {
static = 5432
static = 8123
}
}
task "app" {
task "plausible" {
service {
name = "plausible"
port = "http"
@ -38,11 +35,8 @@ job "plausible" {
driver = "docker"
config {
image = "ghcr.io/plausible/community-edition:v2.1"
image = "ghcr.io/plausible/community-edition:v2.1.1"
ports = ["http"]
volumes = [
"/storage/nomad/${NOMAD_JOB_NAME}/${NOMAD_TASK_NAME}:/var/lib/plausible"
]
command = "/bin/sh"
args = ["-c", "sleep 10 && /entrypoint.sh db migrate && /entrypoint.sh run"]
@ -50,8 +44,6 @@ job "plausible" {
template {
data = <<EOH
TMPDIR=/var/lib/plausible/tmp
BASE_URL=https://plausible.redbrick.dcu.ie
SECRET_KEY_BASE={{ key "plausible/secret" }}
TOTP_VAULT_KEY={{ key "plausible/totp/key" }}
@ -65,8 +57,8 @@ GOOGLE_CLIENT_ID={{ key "plausible/google/client_id" }}
GOOGLE_CLIENT_SECRET={{ key "plausible/google/client_secret" }}
# Database settings
DATABASE_URL=postgres://{{ key "plausible/db/user" }}:{{ key "plausible/db/password" }}@{{ env "NOMAD_ADDR_db" }}/{{ key "plausible/db/name" }}
CLICKHOUSE_DATABASE_URL=http://{{ env "NOMAD_ADDR_clickhouse" }}/plausible_events_db
DATABASE_URL=postgres://{{ key "plausible/db/user" }}:{{ key "plausible/db/password" }}@postgres.service.consul:5432/{{ key "plausible/db/name" }}
CLICKHOUSE_DATABASE_URL=http://{{ env "NOMAD_ADDR_db" }}/plausible_events_db
# Email settings
MAILER_NAME="Redbrick Plausible"
@ -88,43 +80,24 @@ EOH
}
}
task "db" {
driver = "docker"
config {
image = "postgres:17-alpine"
ports = ["db"]
volumes = [
"/storage/nomad/${NOMAD_JOB_NAME}/${NOMAD_TASK_NAME}:/var/lib/postgresql/data",
]
}
template {
data = <<EOH
POSTGRES_PASSWORD={{ key "plausible/db/password" }}
POSTGRES_USER={{ key "plausible/db/user" }}
POSTGRES_NAME={{ key "plausible/db/name" }}
EOH
destination = "local/db.env"
env = true
}
}
task "clickhouse" {
constraint {
attribute = "${attr.unique.hostname}"
value = "chell"
}
service {
name = "plausible-clickhouse"
port = "clickhouse"
port = "db"
}
driver = "docker"
config {
image = "clickhouse/clickhouse-server:24.3.3.102-alpine"
ports = ["clickhouse"]
ports = ["db"]
volumes = [
"/storage/nomad/${NOMAD_JOB_NAME}/${NOMAD_TASK_NAME}:/var/lib/clickhouse",
"/opt/plausible/clickhouse:/var/lib/clickhouse",
"local/clickhouse.xml:/etc/clickhouse-server/config.d/logging.xml:ro",
"local/clickhouse-user-config.xml:/etc/clickhouse-server/users.d/logging.xml:ro"
]
@ -167,7 +140,7 @@ EOH
}
resources {
memory = 1000
memory = 800
}
}
}

View file

@ -1,4 +1,4 @@
job "privatebin-backup" {
job "postgres-backup" {
datacenters = ["aperture"]
type = "batch"
@ -20,17 +20,17 @@ job "privatebin-backup" {
data = <<EOH
#!/bin/bash
file=/storage/backups/nomad/privatebin/postgresql-privatebin-$(date +%Y-%m-%d_%H-%M-%S).sql
file=/storage/backups/nomad/postgres/postgres-$(date +%Y-%m-%d_%H-%M-%S).sql
mkdir -p /storage/backups/nomad/privatebin
mkdir -p /storage/backups/nomad/postgres
alloc_id=$(nomad job status privatebin | grep running | tail -n 1 | cut -d " " -f 1)
alloc_id=$(nomad job status postgres | grep running | tail -n 1 | cut -d " " -f 1)
job_name=$(echo ${NOMAD_JOB_NAME} | cut -d "/" -f 1)
nomad alloc exec -task db $alloc_id pg_dumpall -U {{ key "privatebin/db/user" }} > "${file}"
nomad alloc exec $alloc_id pg_dumpall -U {{ key "postgres/username/root" }} > "${file}"
find /storage/backups/nomad/privatebin/postgresql-privatebin* -ctime +3 -exec rm {} \; || true
find /storage/backups/nomad/postgres/postgres* -ctime +3 -exec rm {} \; || true
if [ -s "$file" ]; then # check if file exists and is not empty
echo "Backup successful"

View file

@ -0,0 +1,96 @@
job "postgres" {
datacenters = ["aperture"]
constraint {
attribute = "${attr.unique.hostname}"
value = "wheatley"
}
group "db" {
network {
port "db" {
static = 5432
}
}
task "postgres-db" {
driver = "docker"
template {
data = <<EOH
POSTGRES_PASSWORD="{{ key "postgres/password/root" }}"
POSTGRES_USER="{{ key "postgres/username/root" }}"
EOH
destination = "local/file.env"
env = true
}
config {
image = "postgres:16-alpine"
ports = ["db"]
volumes = [
"/opt/postgres:/var/lib/postgresql/data",
"local/postgresql.conf:/etc/postgres/postgresql.conf",
"local/pg_hba.conf:/pg_hba.conf",
]
}
template {
data = <<EOH
max_connections = 100
shared_buffers = 2GB
effective_cache_size = 6GB
maintenance_work_mem = 512MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 5242kB
min_wal_size = 1GB
max_wal_size = 4GB
max_worker_processes = 4
max_parallel_workers_per_gather = 2
max_parallel_workers = 4
max_parallel_maintenance_workers = 2
hba_file = "/pg_hba.conf"
EOH
destination = "local/postgresql.conf"
}
template {
data = <<EOH
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
local replication all trust
host replication all 127.0.0.1/32 trust
host replication all ::1/128 trust
host all all all scram-sha-256
EOH
destination = "local/pg_hba.conf"
}
resources {
cpu = 400
memory = 800
}
service {
name = "postgres"
port = "db"
check {
type = "tcp"
interval = "2s"
timeout = "2s"
}
}
}
}
}

View file

@ -10,9 +10,6 @@ job "privatebin" {
port "http" {
to = 8080
}
port "db" {
to = 5432
}
}
service {
@ -28,7 +25,7 @@ job "privatebin" {
tags = [
"traefik.enable=true",
"traefik.http.routers.privatebin.rule=Host(`paste.redbrick.dcu.ie`) || Host(`paste.rb.dcu.ie`)",
"traefik.http.routers.privatebin.rule=Host(`paste.rb.dcu.ie`) || Host(`paste.redbrick.dcu.ie`)",
"traefik.http.routers.privatebin.entrypoints=web,websecure",
"traefik.http.routers.privatebin.tls.certresolver=lets-encrypt",
]
@ -45,10 +42,15 @@ job "privatebin" {
"local/conf.php:/srv/data/conf.php",
]
}
env {
TZ = "Europe/Dublin"
PHP_TZ = "Europe/Dublin"
CONFIG_PATH = "/srv/data/"
template {
destination = "local/.env"
env = true
change_mode = "restart"
data = <<EOH
TZ=Europe/Dublin
PHP_TZ=Europe/Dublin
CONFIG_PATH=/srv/data/
EOH
}
template {
@ -57,7 +59,7 @@ job "privatebin" {
[main]
name = "Redbrick PasteBin"
basepath = "https://paste.redbrick.dcu.ie/"
basepath = "https://paste.rb.dcu.ie/"
discussion = true
@ -183,36 +185,13 @@ batchsize = 10
[model]
class = Database
[model_options]
dsn = "pgsql:host={{ env "NOMAD_ADDR_db" }};dbname={{ key "privatebin/db/name" }}"
tbl = "{{ key "privatebin/db/name" }}" ; table prefix
dsn = "pgsql:host=postgres.service.consul;dbname={{ key "privatebin/db/name" }}"
tbl = "privatebin_" ; table prefix
usr = "{{ key "privatebin/db/user" }}"
pwd = "{{ key "privatebin/db/password" }}"
opt[12] = true ; PDO::ATTR_PERSISTENT ; use persistent connections - default
EOH
}
}
task "db" {
driver = "docker"
config {
image = "postgres:17-alpine"
ports = ["db"]
volumes = [
"/storage/nomad/${NOMAD_JOB_NAME}/${NOMAD_TASK_NAME}:/var/lib/postgresql/data",
]
}
template {
data = <<EOH
POSTGRES_PASSWORD={{ key "privatebin/db/password" }}
POSTGRES_USER={{ key "privatebin/db/user" }}
POSTGRES_NAME={{ key "privatebin/db/name" }}
EOH
destination = "local/db.env"
env = true
}
}
}
}

View file

@ -1,50 +0,0 @@
job "vaultwarden-backup" {
datacenters = ["aperture"]
type = "batch"
periodic {
crons = ["0 */3 * * * *"]
prohibit_overlap = true
}
group "db-backup" {
task "postgres-backup" {
driver = "raw_exec"
config {
command = "/bin/bash"
args = ["local/script.sh"]
}
template {
data = <<EOH
#!/bin/bash
file=/storage/backups/nomad/vaultwarden/postgresql-vaultwarden-$(date +%Y-%m-%d_%H-%M-%S).sql
mkdir -p /storage/backups/nomad/vaultwarden
alloc_id=$(nomad job status vaultwarden | grep running | tail -n 1 | cut -d " " -f 1)
job_name=$(echo ${NOMAD_JOB_NAME} | cut -d "/" -f 1)
nomad alloc exec -task db $alloc_id pg_dumpall -U {{ key "vaultwarden/db/user" }} > "${file}"
find /storage/backups/nomad/vaultwarden/postgresql-vaultwarden* -ctime +3 -exec rm {} \; || true
if [ -s "$file" ]; then # check if file exists and is not empty
echo "Backup successful"
exit 0
else
rm $file
curl -H "Content-Type: application/json" -d \
'{"content": "<@&585512338728419341> `PostgreSQL` backup for **'"${job_name}"'** has just **FAILED**\nFile name: `'"$file"'`\nDate: `'"$(TZ=Europe/Dublin date)"'`\nTurn off this script with `nomad job stop '"${job_name}"'` \n\n## Remember to restart this backup job when fixed!!!"}' \
{{ key "postgres/webhook/discord" }}
fi
EOH
destination = "local/script.sh"
}
}
}
}

View file

@ -9,9 +9,6 @@ job "vaultwarden" {
port "http" {
to = 80
}
port "db" {
to = 5432
}
}
service {
@ -34,15 +31,14 @@ job "vaultwarden" {
ports = ["http"]
volumes = [
"/storage/nomad/${NOMAD_JOB_NAME}:/data",
"/etc/localtime:/etc/localtime:ro"
"/storage/nomad/vaultwarden:/data"
]
}
template {
data = <<EOF
DOMAIN=https://vault.redbrick.dcu.ie
DATABASE_URL=postgresql://{{ key "vaultwarden/db/user" }}:{{ key "vaultwarden/db/password" }}@{{ env "NOMAD_ADDR_db" }}/{{ key "vaultwarden/db/name" }}
DATABASE_URL=postgresql://{{ key "vaultwarden/db/user" }}:{{ key "vaultwarden/db/password" }}@postgres.service.consul:5432/{{ key "vaultwarden/db/name" }}
SIGNUPS_ALLOWED=false
INVITATIONS_ALLOWED=true
@ -68,28 +64,5 @@ EOF
memory = 500
}
}
task "db" {
driver = "docker"
config {
image = "postgres:17-alpine"
ports = ["db"]
volumes = [
"/storage/nomad/${NOMAD_JOB_NAME}/${NOMAD_TASK_NAME}:/var/lib/postgresql/data",
]
}
template {
data = <<EOH
POSTGRES_PASSWORD={{ key "vaultwarden/db/password" }}
POSTGRES_USER={{ key "vaultwarden/db/user" }}
POSTGRES_NAME={{ key "vaultwarden/db/name" }}
EOH
destination = "local/db.env"
env = true
}
}
}
}

View file

@ -41,7 +41,7 @@ $wgDBpassword = "{{ key "mediawiki/db/password" }}";
# MySQL specific settings
$wgDBprefix = "rbwiki_";
# MySQL table options to use during installation or update
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=utf8mb4";
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary";
## Shared memory settings
$wgMainCacheType = CACHE_NONE;
@ -89,15 +89,11 @@ wfLoadSkin( 'Vector' );
wfLoadSkin( 'Citizen' );
wfLoadSkin( 'Timeless' );
wfLoadSkin( 'MinervaNeue' );
wfLoadSkin( 'Medik' );
$wgCitizenThemeColor = "#a81e22";
$wgCitizenShowPageTools = "permission";
$wgCitizenSearchDescriptionSource = "pagedescription";
$wgMedikColor = "#a81e22";
$wgMedikShowLogo = "main";
$wgLocalisationUpdateDirectory = "$IP/cache";
# load extensions

View file

@ -30,7 +30,7 @@ job_name=$(echo ${NOMAD_JOB_NAME} | cut -d "/" -f 1)
nomad alloc exec -task rbwiki-db $alloc_id mariadb-dump -u {{ key "mediawiki/db/username" }} -p'{{ key "mediawiki/db/password"}}' {{ key "mediawiki/db/name" }} > "${file}"
find /storage/backups/nomad/wiki/mysql/rbwiki-mysql* -ctime +30 -exec rm {} \; || true
find /storage/backups/nomad/wiki/mysql/rbwiki-mysql* -ctime +3 -exec rm {} \; || true
if [ -s "$file" ]; then # check if file exists and is not empty
echo "Backup successful"

View file

@ -213,18 +213,6 @@ EOH
template {
data = <<EOH
[mysqld]
# Ensure full UTF-8 support
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
skip-character-set-client-handshake
# Fix 1000-byte key length issue
innodb_large_prefix = 1
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_default_row_format = dynamic
# Performance optimizations (Keep these based on your system)
max_connections = 100
key_buffer_size = 2G
query_cache_size = 0
@ -236,14 +224,13 @@ innodb_io_capacity = 200
tmp_table_size = 5242K
max_heap_table_size = 5242K
innodb_log_buffer_size = 16M
innodb_file_per_table = 1
bind-address = 0.0.0.0
# Logging
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
# Network
bind-address = 0.0.0.0
EOH
destination = "local/conf.cnf"
@ -251,7 +238,7 @@ EOH
resources {
cpu = 800
memory = 2500
memory = 1200
}
template {

View file

@ -62,8 +62,6 @@ job "dcusr-listmonk" {
data = <<EOH
[app]
address = "0.0.0.0:{{ env "NOMAD_PORT_http" }}"
admin_username = "{{ key "dcusr/listmonk/admin/username" }}"
admin_password = "{{ key "dcusr/listmonk/admin/password" }}"
# Database.
[db]

View file

@ -10,7 +10,6 @@ job "esports-discord-bot" {
config {
image = "ghcr.io/aydenjahola/discord-multipurpose-bot:main"
force_pull = true
}
resources {
@ -29,15 +28,6 @@ RAPIDAPI_KEY={{ key "socs/esports/bot/rapidapi/key" }}
TRACKER_API_KEY={{ key "socs/esports/bot/trackerapi/key" }}
TRACKER_API_URL={{ key "socs/esports/bot/trackerapi/url" }}
WORDNIK_API_KEY={{key "socs/esports/bot/wordnikapi/key" }}
HUGGING_FACE_API_KEY={{ key "socs/esports/bot/huggingface/key" }}
RCON_HOST=esports-mc-rcon.service.consul
# https://discuss.hashicorp.com/t/passing-registered-ip-and-port-from-consul-to-env-nomad-job-section/35647
{{ range service "esports-mc-rcon" }}
RCON_PORT={{ .Port }}{{ end }}
RCON_PASSWORD={{ key "games/mc/esports-mc/rcon/password" }}
EOH
destination = "local/.env"
env = true

View file

@ -38,7 +38,7 @@ job "style-thelook" {
tags = [
"traefik.enable=true",
"traefik.http.routers.thelook.rule=Host(`${NOMAD_META_domain}`) || Host(`style.redbrick.dcu.ie`)",
"traefik.http.routers.thelook.rule=Host(`${NOMAD_META_domain}`)",
"traefik.http.routers.thelook.entrypoints=web,websecure",
"traefik.http.routers.thelook.tls.certresolver=lets-encrypt",
]

View file

@ -1,36 +0,0 @@
job "urri-meetups-update" {
datacenters = ["aperture"]
type = "batch"
periodic {
crons = ["0 */6 * * * *"]
prohibit_overlap = true
}
group "urri-meetups-update" {
task "urri-meetups-update" {
driver = "raw_exec"
config {
command = "/bin/bash"
args = ["local/script.sh"]
}
template {
data = <<EOH
#!/bin/bash
# stop the urri-meetups job
nomad job stop urri-meetups
sleep 1
# revert the urri-meetups job to the previous version
# this will trigger a new deployment, which will pull the latest image
nomad job revert urri-meetups $(($(nomad job inspect urri-meetups | jq '.Job.Version')-1))
EOH
destination = "local/script.sh"
}
}
}
}

View file

@ -1,47 +0,0 @@
job "urri-meetups" {
datacenters = ["aperture"]
type = "service"
group "urri-meetups" {
count = 1
network {
port "http" {
to = 8000
}
}
service {
port = "http"
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
tags = [
"traefik.enable=true",
"traefik.http.routers.urri-meetups.rule=Host(`urri-meetups.rb.dcu.ie`)",
"traefik.http.routers.urri-meetups.entrypoints=web,websecure",
"traefik.http.routers.urri-meetups.tls.certresolver=lets-encrypt",
]
}
task "web" {
driver = "docker"
config {
image = "ghcr.io/haefae222/pizza_app:latest"
ports = ["http"]
force_pull = true
}
resources {
cpu = 1000
memory = 800
}
}
}
}

View file

@ -1,61 +0,0 @@
job "cands-room-bookings" {
datacenters = ["aperture"]
type = "service"
meta {
git-sha = ""
}
group "clubsandsocs-room-bookings" {
count = 1
network {
port "http" {
to = 5000
}
}
service {
port = "http"
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
tags = [
"traefik.enable=true",
"traefik.http.routers.clubsandsocs-room-bookings.rule=Host(`rooms.rb.dcu.ie`)",
"traefik.http.routers.clubsandsocs-room-bookings.entrypoints=web,websecure",
"traefik.http.routers.clubsandsocs-room-bookings.tls.certresolver=lets-encrypt",
]
}
task "web" {
driver = "docker"
config {
image = "ghcr.io/wizzdom/clubsandsocs-room-bookings:latest"
ports = ["http"]
force_pull = true
volumes = [
"local/.env:/app/.env"
]
}
template {
data = <<EOF
UPLOAD_FOLDER=uploads
SECRET_KEY={{ key "user-projects/wizzdom/clubsandsocs-room-bookings/secret" }}
EOF
destination = "local/.env"
}
resources {
cpu = 1000
memory = 800
}
}
}
}

View file

@ -38,7 +38,7 @@ alloc_id=$(nomad job status -verbose bastion-vm | grep running | tail -n 1 | cut
job_name=$(echo ${NOMAD_JOB_NAME} | cut -d "/" -f 1)
echo "Backing up alloc id: ${alloc_id} on: ${host} to ${path}/${file}..."
ssh -i {{ key "bastion-vm/service/key" }} {{ key "bastion-vm/service/user" }}@${host} "sudo cat /opt/nomad/alloc/${alloc_id}/bastion-vm/local/bastion-vm.qcow2" > ${path}/${file}
scp -B -i {{ key "bastion-vm/service/key" }} {{ key "bastion-vm/service/user" }}@${host}:/opt/nomad/alloc/${alloc_id}/bastion-vm/local/bastion-vm.qcow2 ${path}/${file}
find ${path}/bastion-vm-* -ctime +2 -exec rm {} \; || true