DOCKYARD
Own your cloud
- Role
- Solo build, design
- Type
- Personal · Pre-implementation
- Systems
- Kubernetes · Traefik · Terraform
- Scale
- 12 API endpoints · 7 deploy states
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.
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.
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.
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.
By the numbers
Stack
FastAPI, Docker, Kubernetes, Terraform, Traefik, Prometheus/Grafana, PostgreSQL
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.
