2026-07-23 17:57:17 +02:00
2026-07-23 15:27:58 +00:00
2026-07-23 17:57:17 +02:00
2026-07-23 15:27:58 +00:00
2026-07-23 17:57:17 +02:00

Uses debian 13 as I had difficulties setting up everything in nixos.

Personal Server Setup Guide

This document explains how to rebuild and deploy the personal server stack on a fresh Debian VPS.

The server uses:

  • Debian
  • Docker CE
  • Docker Compose
  • Caddy as reverse proxy
  • Containers for all self-hosted services
  • Git as the source of truth for configuration

1. Create the VPS

Recommended:

  • Debian 13
  • SSH key authentication enabled
  • Public IPv4 enabled
  • Firewall enabled

After creation:

ssh root@SERVER_IP

2. Bootstrap the server

Copy the bootstrap script to the server:

scp bootstrap.sh root@SERVER_IP:

Connect:

ssh root@SERVER_IP

Run:

chmod +x bootstrap.sh
./bootstrap.sh

This installs:

  • Docker CE
  • Docker Compose
  • Git
  • Basic administration tools
  • Firewall rules

Verify:

docker --version
docker compose version

3. Create an administrator user

Do not run everything as root.

Create a user:

adduser USERNAME

Add permissions:

usermod -aG sudo,docker USERNAME

Copy SSH keys:

mkdir -p /home/USERNAME/.ssh
cp /root/.ssh/authorized_keys /home/USERNAME/.ssh/
chown -R USERNAME:USERNAME /home/USERNAME/.ssh
chmod 700 /home/USERNAME/.ssh
chmod 600 /home/USERNAME/.ssh/authorized_keys

Test:

ssh USERNAME@SERVER_IP

4. Clone the server configuration

Create the deployment directory:

mkdir -p /opt/server
cd /opt/server

Clone the configuration repository:

git clone YOUR_REPOSITORY_URL .

The structure should look like:

server/
├── compose.yml
├── Caddyfile
├── .env
├── scripts/
└── README.md

5. Configure secrets

Never store passwords or tokens in Git.

Create:

nano .env

Example:

DOMAIN=example.com

FRESHRSS_ADMIN_PASSWORD=change_me

KDRIVE_USERNAME=user
KDRIVE_PASSWORD=password

Set permissions:

chmod 600 .env

6. Start the Docker stack

From /opt/server:

docker compose up -d

Check running containers:

docker ps

View logs:

docker compose logs -f

7. Reverse proxy

Caddy handles HTTPS automatically.

Example:

website.com
├── freshrss.website.com
├── archivebox.website.com
├── hledger.website.com
├── calendar.website.com
└── ntfy.website.com

The Caddyfile defines where traffic goes.

After changing it:

docker compose restart caddy

8. Updating services

Update images:

docker compose pull

Restart:

docker compose up -d

Remove unused images:

docker image prune

9. Backups

Important data is stored in Docker volumes.

List volumes:

docker volume ls

Back up using:

  • restic
  • kDrive
  • another storage provider

Recommended backup targets:

FreshRSS database
ArchiveBox data
Calendar/contact data
hledger files
Caddy configuration
.env secrets

10. Disaster recovery

To rebuild:

  1. Install Debian
  2. Run bootstrap.sh
  3. Clone this repository
  4. Restore backups
  5. Restore .env
  6. Start Docker:
docker compose up -d

The complete server should be operational again.


Planned services

Current stack:

  • Caddy
  • FreshRSS
  • ArchiveBox
  • hledger-web
  • Calendar/contact server
  • ntfy
  • Monitoring

Possible additions:

  • Uptime Kuma
  • Authelia or Authentik
  • Vaultwarden
  • Gitea
  • Miniflux
  • Mealie
  • Paperless-ngx

Principles

  • Configuration belongs in Git
  • Data belongs in backups
  • Secrets never go into Git
  • Containers are disposable
  • Volumes contain persistent data
  • The server should be reproducible
S
Description
Mirror of https://github.com/tomasriveral/vps-config This vps config is powering all the services at tomasrivera.ch (including this gitea instance)
Readme GPL-3.0
115 KiB
Languages
Shell 43.9%
HTML 25.7%
Python 25%
CSS 5.4%