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.