A production-lean, self-hosted infrastructure deployed on Oracle Cloud Infrastructure (OCI) Always-Free across two compute instances — documented end-to-end from provisioning to day-2 operations.
This repository documents the full lifecycle of a self-hosted homelab stack running on two OCI Always-Free ARM compute instances. The stack covers:
- Cloud infrastructure provisioning — VCN, subnets, NSGs, gateways, compute instances via OCI Console and CLI
- DNS + TLS — Public DNS A records + Caddy automatic HTTPS via ACME/Let's Encrypt
- Application stacks — Two isolated VMs, each running a purpose-built Docker Compose stack
- Backups — Volume snapshots,
pg_dumpexports, and sidecar backup containers - Operations — Upgrade procedures, log management, health checks, and troubleshooting runbooks
Everything is parameterized. No real hostnames, IPs, or secrets appear anywhere in this repo. Copy .env.example → .env and fill in your values.
Internet
│
┌─────────────┴─────────────┐
│ OCI VCN (10.0.0.0/16)│
│ │
│ ┌────────────────────┐ │
│ │ Public Subnet │ │
│ │ 10.0.1.0/24 │ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │ VM1 │ │ │
│ │ │ Memos │ │ │
│ │ │ Linkding │ │ │
│ │ │ Caddy │ │ │
│ │ └──────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │ VM2 │ │ │
│ │ │ Paperless │ │ │
│ │ │ Vaultwarden │ │ │
│ │ │ Postgres │ │ │
│ │ │ Redis │ │ │
│ │ │ Caddy │ │ │
│ │ └──────────────┘ │ │
│ └────────────────────┘ │
│ │
│ Internet Gateway (IGW) │
└───────────────────────────┘
DNS: A records → VM1 public IP (vm1 services)
A records → VM2 public IP (vm2 services)
Admin access: SSH (key-based) on port 22, restricted by NSG to trusted source IPs
| Service | Purpose |
|---|---|
| Memos | Lightweight self-hosted note-taking / knowledge base |
| Linkding | Bookmark manager with tagging and full-text search |
| Caddy | Reverse proxy with automatic HTTPS |
| Service | Purpose |
|---|---|
| Paperless-ngx | Document management, OCR, and search |
| Vaultwarden | Bitwarden-compatible password manager (Rust) |
| PostgreSQL | Database backend for Paperless-ngx |
| Redis | Task queue and cache broker for Paperless-ngx |
| Caddy | Reverse proxy with automatic HTTPS |
homelab-cloud-stack/
├── README.md
├── JOURNAL.md ← Process log: decisions, issues, lessons learned
├── .gitignore
│
├── docs/
│ ├── 00-overview.md ← Goals, scope, design philosophy
│ ├── 01-architecture.md ← Network topology, component diagram, data flows
│ ├── 02-prereqs.md ← Accounts, tools, knowledge prerequisites
│ ├── 03-oci-infra.md ← VCN, subnets, NSGs, compute provisioning
│ ├── 04-dns-tls.md ← DNS records, Caddy ACME, certificate strategy
│ ├── 05-bootstrap.md ← VM hardening, Docker, user setup
│ ├── 06-vm1-stack.md ← VM1 deployment walkthrough
│ ├── 07-vm2-stack.md ← VM2 deployment walkthrough
│ ├── 08-operations.md ← Upgrades, logs, health checks, monitoring
│ ├── 09-backups.md ← Backup strategy, pg_dump, restore procedures
│ └── 10-troubleshooting.md ← Common issues, debug commands, fix runbook
│
├── scripts/
│ ├── bootstrap.sh ← VM initial setup script
│ ├── backup.sh ← Manual backup trigger
│ └── update-stack.sh ← Pull + redeploy all services
│
├── vm1/
│ ├── stack/
│ │ ├── docker-compose.yml
│ │ └── .env.example
│ └── caddy/
│ └── Caddyfile
│
└── vm2/
├── stack/
│ ├── docker-compose.yml
│ └── .env.example
└── caddy/
└── Caddyfile
Full guided setup is in the
docs/directory. Read in order.
# 1. Provision OCI infra (see docs/03-oci-infra.md)
# 2. Set up DNS (see docs/04-dns-tls.md)
# 3. Bootstrap both VMs (see docs/05-bootstrap.md)
# On VM1:
git clone https://github.com/daedalus410/homelab-cloud-stack.git
cd homelab-cloud-stack/vm1/stack
cp .env.example .env && nano .env # fill your values
cp ../caddy/Caddyfile /etc/caddy/Caddyfile # or volume-mount path
docker compose up -d
# On VM2:
cd homelab-cloud-stack/vm2/stack
cp .env.example .env && nano .env
docker compose up -d- No secrets committed — all sensitive values live in
.envfiles excluded by.gitignore - NSG-gated — OCI Network Security Groups restrict inbound to ports
80,443, and22(SSH, source-restricted) - Automatic TLS — Caddy handles certificate issuance and renewal; no manual cert management
- SSH hardened — key-based authentication only; password auth disabled
- Vaultwarden hardened — signups disabled by default; invite-only flow enforced
| # | Document | Description |
|---|---|---|
| 00 | Overview | Goals and design philosophy |
| 01 | Architecture | Full topology and component breakdown |
| 02 | Prerequisites | What you need before starting |
| 03 | OCI Infrastructure | Cloud provisioning step-by-step |
| 04 | DNS & TLS | Domain setup and certificate automation |
| 05 | Bootstrap | VM hardening and Docker installation |
| 06 | VM1 Stack | Memos + Linkding + Caddy deployment |
| 07 | VM2 Stack | Paperless + Vaultwarden + Caddy deployment |
| 08 | Operations | Day-2 management and upgrades |
| 09 | Backups | Backup strategy and restore procedures |
| 10 | Troubleshooting | Common issues and debug runbook |
MIT — use freely, adapt as needed.