πΊοΈ Server Topology & Infrastructure Map
This document outlines the physical and logical architecture of the main Apollyon server. Because this bare-metal host is a multi-tenant environment (running Apollyon infrastructure, client sites, and internal sandbox projects), understanding the physical storage limits and network boundaries is critical.
1. Bare-Metal Hardware Specifications
Our primary deployment target is a custom-built home server acting as the central hub for our development, CI/CD, and internal cloud infrastructure.
- CPU: AMD Ryzen 5 PRO 3400G (8 Threads) with Radeon Vega Graphics
- RAM: 13 GiB total (with a 5.9 GiB Swap partition)
- OS: Debian 13 (Trixie) / Kernel
6.12.113+deb13-amd64(checked 2026-10-18) - Runtimes on the host: Python 3.13 (the Debian default; no 3.14 package), Node 22 and npm (
/usr/bin), Poetry via pipx (/usr/local/bin/poetry), PostgreSQL 17, Docker with Compose v2, Caddy 2.6
2. Storage Architecture & Mounts
To protect the root OS from hitting 100% capacity and crashing the Docker daemon, we employ a strict multi-disk tiering strategy with absolute isolation between enterprise data and personal sandbox media.
| Disk / Partition | Size | Mount Point | Purpose |
|---|---|---|---|
/dev/sdb2 |
112 GB | / (Root OS) |
Hosts the OS, Docker overlay layers, and latency-sensitive databases (PostgreSQL). |
/dev/sde1 |
931 GB | /mnt/newhdd |
Apollyon Persistent Storage. |
/dev/sda1 |
931 GB | /mnt/anime_disk1 |
Sandbox / Media Pool 1 |
/dev/sdc |
931 GB | /mnt/anime_disk2 |
Sandbox / Media Pool 2 |
AnimePool |
1.8 TB | /media/anime_storage |
Merged filesystem for media. |
/dev/sdf |
1.8 TB | /media/jellyfin_media |
Dedicated streaming storage. |
Enterprise Storage Standard
All persistent Docker volumes for Apollyon infrastructure (e.g., Nextcloud user data, GitLab registries, LLM models) MUST be strictly mapped to /mnt/newhdd/<service_name>/. The /media/ and anime_disk mounts are exclusively reserved for the ramsus.site streaming sandbox and must never be used for company data.
3. Network Routing & External DNS
Traffic reaches our server through a combination of external DNS resolution and internal reverse proxying.
External DNS (Namecheap)
Domain resolution for our core domains (apollyon.lat, gsalud.co, and ramsus.site) is managed via Namecheap.
* To expose a new service, an A Record must be created in Namecheap pointing to the host's public IP address before Caddy can provision an SSL certificate.
Internal Routing (The Caddy Layer)
All inbound web traffic passes through Caddy, which acts as our reverse proxy, static file server, and SSL manager.
1. Static Frontends (SPA): For sites like apollyon.lat, Caddy directly serves the /dist folders using file_server.
2. Reverse Proxies: For dynamic services (like GitLab), Caddy terminates SSL and routes to the specific localhost port.
3. Per-project site blocks: most projects keep their site block in their repository as deploy/Caddyfile, and the main /etc/caddy/Caddyfile imports it straight from the checkout (import /opt/<project>/deploy/Caddyfile). See the warning in Deployment Patterns: a merged change goes live at the next reload.
The host-gateway Standard: Containers requiring DNS resolution to other internal subdomains must define extra_hosts in their docker-compose.yml:
extra_hosts:
- "gitlab.apollyon.lat:host-gateway"
4. Host Security & Firewall Topology
To enforce a Zero-Trust architecture, the bare-metal host restricts all inbound traffic except for essential routing and administrative ports.
- Port
80/443(TCP): Open for Caddy to route HTTP/HTTPS traffic. - Port
22(TCP): Open for SSH administrative access (Restricted to SSH Key authentication only; passwords disabled). - Port
2222(TCP): GitLab's own SSH (the GitLab container's port 22), forgit clone/pushover SSH. - Port
25565(TCP/UDP): Open strictly for the Minecraft Sandbox environments. - All other ports: Blocked by the host firewall (e.g., UFW). Docker containers communicate via internal Docker networks or loopback (
127.0.0.1), relying entirely on Caddy for external exposure.
5. Active Services Matrix
A. Apollyon Core Infrastructure
| Service | Domain | Internal Port | Documentation |
|---|---|---|---|
| GitLab CE | gitlab.apollyon.lat |
8929 (HTTP), 2222 (SSH) |
GitLab CI/CD |
| GitLab Wiki | wiki.apollyon.lat |
4441 |
Engineering Workflow |
| Image Server | images.apollyon.lat |
3902 (Public), 3900 (S3 API) |
Media and Image Storage |
| Nextcloud | cloud.apollyon.lat |
4433 |
Internal Cloud |
| Apollyon Main Site | apollyon.lat |
Static (/dist) |
Deployment Patterns |
| PostgreSQL 17 | Internal | 5432 (127.0.0.1) |
Shared host database server: one role and database per project (Deployment Patterns) |
| NetBird VPN | netbird.ramsus.site |
8080 / 8081 (both 127.0.0.1-only) |
Remote Access |
B. Client & Research Deployments
| Service | Domain | Internal Port | Purpose |
|---|---|---|---|
| GSalud Dentistry | gsalud.co |
Static (/dist) |
Client SPA Frontend. |
| Korvyn API | korvyn.ramsus.site |
1313 |
FastAPI backend for AI services (systemd ram-korvy-api.service). |
| TEApoyo | teapoyo.apollyon.lat |
Static (/opt/teapoyo/teapoyo/dist) |
PWA for caregivers of autistic children; deployed by deploy/deploy.sh on every merge to main. |
| TEApoyo API | teapoyo-api.apollyon.lat |
8010 (127.0.0.1) |
FastAPI backend for TEApoyo (systemd teapoyo-api.service, checkout /opt/teapoyo-api; being set up as of 2026-10-18); registration closed. |
| Overleaf | latex.ramsus.site |
4455 |
Collaborative LaTeX compilation. |
| Ollama LLM | Internal API | 11434 |
Local inference engine. |
C. Internal Sandbox & Media (ramsus.site)
This environment runs isolated from Apollyon Core and includes our sandbox testing tools.
- Media Stack: Jellyfin (
8096), Sonarr (8989), Radarr (7878), Prowlarr (9696). - Host Management: Cockpit (
9090).
For Garage and Caddy object storage architecture, operational boundaries, and runbooks, see Media and Image Storage.
6. Docker Deployment Standards
To prevent host filesystem drift and ensure fast disaster recovery, all deployments must adhere to these physical file structure rules:
- Configuration (
/opt/): Alldocker-compose.ymlfiles and lightweight config directories reside here (e.g.,/opt/gitlab-ops/). - Persistent Data (
/mnt/newhdd/): As defined in Section 2, all heavy data volumes map here. - Permission Mapping (UID/GID): Core services map to a dedicated application user ID (e.g.,
987:987) to prevent containers from writing root-owned files to the host.
Data Loss Warning
Never execute a docker compose down on a service without verifying its volumes: block. Unmapped data sitting in the 112GB root /var/lib/docker/overlay2 layer will be permanently lost.