← Back
002 DOCKYARD

DOCKYARD

Own your cloud

ActiveAdvancedUpdated Aug 2026
Role
Solo build, design
Type
Personal · Pre-implementation
Systems
Kubernetes · Traefik · Terraform
Scale
12 API endpoints · 7 deploy states
01

Objective

A platform-as-a-service that lets a developer run one command from a project directory and get a live, HTTPS-secured, auto-scaling deployment — with zero manual server work after initial platform setup.

dockyard login → dockyard deploy → public HTTPS URL, with logs, env vars, and rollbacks — no kubectl, Docker, or DNS touched directly.

Why this is hard: Heroku and Vercel make this look trivial precisely because the hard part is hidden — every layer between a Dockerfile and a live HTTPS URL (registry auth, cluster scheduling, TLS issuance, DNS propagation) has its own failure modes, and a PaaS is only as good as its worst-behaved layer. The goal isn't reimplementing Kubernetes; it's hiding it convincingly enough that a developer never needs to know it's there.

02

Decisions

Why a stateless API + separate build workers?

The Deployment API (FastAPI) owns auth, validation, and orchestration but never touches Docker or Kubernetes directly — it only writes rows to Postgres and lets build workers pick them up. That separation is what makes the worker horizontally scalable and independently deployable.

Why Postgres row-locking for the queue?

Workers claim queued deployments with SELECT ... FOR UPDATE SKIP LOCKED — simple, no extra infrastructure, and safe to run more than one worker instance against. Redis/RQ is a later swap only if polling becomes an actual bottleneck.

Why Traefik over Nginx?

Native Let's Encrypt integration and dynamic config mean less YAML than Nginx + cert-manager for the same result — every deployment gets HTTPS with zero manual certificates.

Why Docker Hub over self-hosted Harbor?

Docker Hub for dev — a self-hosted registry is one more stateful service to operate before the pipeline has even proven itself end to end. Harbor is deliberately deferred to a later phase, once registry limits or privacy requirements actually force the issue.

03

Architecture

Runtime architecture

CLI → Deployment API → Postgres queue → Build Worker → Registry / Kubernetes → Traefik → Live URL

  • Boxes are components, lines are who calls whom.
  • The build worker clones the repo, builds and tags the image with the commit SHA, and generates the Deployment/Service/Ingress manifests.
  • Traefik provisions a Let's Encrypt certificate automatically for every new hostname.

Deploy state machine

Queued → Building → Pushing → Deploying → Live / Failed → Rolled back

  • Seven distinguishable states so a failure branches visibly instead of silently retrying.
04

Result

Definition of done for v1: a developer with only a Git repo and the DOCKYARD CLI can go from dockyard login to a public HTTPS URL serving their app — with logs, env vars, and rollbacks — without touching kubectl, Docker, or DNS directly.

05

By the numbers

12
API ENDPOINTS
7
DEPLOY STATES
13
CLI COMMANDS
15
BUILD PHASES
06

Stack

FastAPI, Docker, Kubernetes, Terraform, Traefik, Prometheus/Grafana, PostgreSQL

07

Lessons learned

  • The first pass reached for multi-cloud abstraction and a self-hosted registry from day one. Both got cut — targeting one cluster type and Docker Hub first isn't a missing feature, it's the constraint that keeps the first 15 phases actually shippable.
  • I'd write the failure-state contract (queued, building, pushing, deploying, live, failed, rolled back) before any code, not discover it mid-implementation.
  • I'd build the rollback path right after the first successful deploy, not later — a deployment platform without a tested rollback is a platform that will lose someone's production app exactly once.