Skip to content

rmaier/iac

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VPS Apps

App repository for my VPS.

This is both:

  1. A real setup I run and iterate on.
  2. A portfolio-friendly repo that shows end-to-end infra and ops (Terraform, Ansible, Docker).

Current apps:

  • Traefik (reverse proxy + TLS)
  • Uptime Kuma (monitoring)
  • LibreChat

Layout

  • traefik/ (Traefik config/compose; work in progress)
  • uptime-kuma/compose.yaml
  • librechat/compose.yaml

Planned:

  • terraform/ (Google Cloud: VM, firewall, static IP, optional DNS)
  • ansible/ (bootstrap: Docker/Compose + basic hardening)

Deploy (Manual Workflow)

  1. Provision a VPS on Google Cloud (planned via Terraform) and note its public IP.
  2. Ensure inbound 80/tcp and 443/tcp are allowed (and 22/tcp for SSH, ideally restricted).
  3. Install Docker + Docker Compose on the VPS (manual for now; planned via Ansible).
  4. Point your DNS A/AAAA records to the VPS public IP.
  5. Update the domain(s) in the Traefik config (host rules / ACME settings).
  6. Start Traefik: run docker compose up -d from traefik/.
  7. Start Uptime Kuma: docker compose -f uptime-kuma/compose.yaml up -d.
  8. Start LibreChat: docker compose -f librechat/compose.yaml up -d.

Notes

  • librechat/compose.yaml currently binds 80/443 directly and will conflict with Traefik as-is; for a Traefik-fronted deploy, remove those bindings and route it through Traefik.
  • Don’t commit secrets. Use a local .env (not checked in) or a secret manager.

Provision a VPS on Google Cloud

Install the gcloud tool https://docs.cloud.google.com/sdk/docs/install-sdk

gcloud auth login
gcloud projects list
gcloud config set project project-19f7eed5-b04a-472c-b23

gcloud compute instances list
gcloud compute ssh <instace> 

We need 1 instance e.g.

gcloud compute zones list
gcloud compute machine-types list
gcloud compute instances create my-vps \
  --zone=europe-southwest1-a \
  --machine-type=e2-medium \
  --boot-disk-size=30GB \
  --boot-disk-type=pd-balanced \
  --image-family=ubuntu-2404-lts-amd64 \
  --image-project=ubuntu-os-cloud

Create fw rule

gcloud compute firewall-rules create https --allow tcp:443
gcloud compute firewall-rules create http --allow tcp:80

Start, stop and delete.

# stop and resume
gcloud compute instances stop my-vps
gcloud compute instances start my-vps
# DELETE
gcloud compute instances delete my-vps

Set A Record on DNS Provider

Strato - gc.rudolphmaier.de

https://gc.rudolphmaier.de https://gpt.rudolphmaier.de https://speed.rudolphmaier.de https://up.rudolphmaier.de

Install Docker + Docker Compose on the VPS - Ansible

ansible-playbook -i ansible/inventory.ini ansible/playbooks/docker-ubuntu.yml

Push the vps config repo

# currently using rsync, later clone a github repo 
rsync -av --exclude='.git' ./ gc.rudolphmaier.de:~/
ssh gc.rudolphmaier.de
docker network create web
docker compose -f apps/traefik/compose.yaml up -d
docker compose -f apps/librespeed/compose.yaml up -d
docker compose -f apps/uptime-kuma/compose.yaml up -d
docker compose -f apps/librechat/compose.yaml up -d

Backup and Restore

What to back up

./apps/
├── librechat
│   ├── dump	# mongo db dump
│   ├── images
│   └── uploads
└── uptime-kuma
    └── data	# sqlite and data

Setup borgbase.com

ssh-keygen -t ed25519 -C "borgbase@ribeiromaier.de" -f ~/.ssh/id_ed25519_borgbase

# the private key is on my host inside keepassxc and can be consumed via the ubuntu ssh agent. 
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILoxXfyfp7ISJRDQfEMCs5/Y9lc8XSkn0GJTaxY467n9 borgbase@ribeiromaier.de

Repo: ssh://k5ba1xct@k5ba1xct.repo.borgbase.com/./repo

First setup on vps

ssh gc.rudolphmaier.de

mkdir -p ~/.ssh
chmod 700 ~/.ssh
umask 077
# copy the private key to the clipboard
cat > ~/.ssh/borgbase_ed25519 # ctrl - c
chmod 600 ~/.ssh/borgbase_ed25519

ssh-keyscan -H k5ba1xct.repo.borgbase.com >> ~/.ssh/known_hosts

Initialize the repo (you will be prompted for a Borg passphrase):

export BORG_REPO='ssh://k5ba1xct@k5ba1xct.repo.borgbase.com/./repo'

borg init --encryption=repokey-blake2 "$BORG_REPO"

Export the repo key OFF the VPS (required for disaster recovery):

borg key export "$BORG_REPO" /tmp/borgbase-repo-key.txt

saved to keepassxc

First Backup

from old server

docker exec chat-mongodb sh -lc 'mongodump --db LibreChat --archive --gzip' \
  > librechat/dump/mongodb-LibreChat.archive.gz
#!/usr/bin/env bash
export BORG_REPO='ssh://k5ba1xct@k5ba1xct.repo.borgbase.com/./repo'

# Backup Librechat
mkdir -p librechat/dump
docker exec chat-mongodb sh -lc 'mongodump --db LibreChat --archive --gzip' \
  > librechat/dump/mongodb-LibreChat.archive.gz
# docker exec vectordb sh -lc 'PGPASSWORD=mypassword pg_dump -U myuser -d mydatabase | gzip -c' > "/home/.../vps/librechat/dump/postgres-mydatabase-$(date +%F_%H%M).sql.gz"

docker compose -f librechat/compose.yaml down
docker compose -f uptime-kuma/compose.yaml down

borg create --stats --compression zstd,6 \
  "$BORG_REPO::vps-$(date +%F_%H%M)" \
  librechat/dump \
  librechat/images \
  librechat/uploads \
  uptime-kuma/data
borg prune --stats --keep-daily 2 --keep-weekly 1 --keep-monthly 1

# Bring services back:
docker compose -f uptime-kuma/compose.yaml up -d
docker compose -f librechat/compose.yaml up -d

Restore to gcp vps

export BORG_RSH='ssh -i ~/.ssh/borgbase_ed25519 -o IdentitiesOnly=yes' 
export BORG_REPO='ssh://k5ba1xct@k5ba1xct.repo.borgbase.com/./repo'

borg info 'ssh://k5ba1xct@k5ba1xct.repo.borgbase.com/./repo'

# get latest archive name
LATEST="$(borg list --short --last 1 "$BORG_REPO")"
echo "$LATEST"

# Restore that archive (run from your .../vps repo root):
docker compose -f librechat/compose.yaml down
docker compose -f uptime-kuma/compose.yaml down

borg extract "$BORG_REPO::$LATEST" \
  librechat/dump \
  librechat/images \
  librechat/uploads \
  uptime-kuma/data

# Bring services back:
docker compose -f uptime-kuma/compose.yaml up -d
docker compose -f librechat/compose.yaml up -d

# Then restore DBs from the extracted dumps:
gunzip -c librechat/dump/mongodb-LibreChat.archive.gz | \
docker exec -i chat-mongodb sh -lc 'mongorestore --drop --archive'
ansible-playbook -i ansible/inventory.ini ansible/playbooks/borg-restore.yml

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors