Breakwaterharbor Net Deployment
This document turns Harbor's generic go-live plan into a concrete prelaunch deployment for:
BREAKWATERHARBOR_NET_DEPLOYMENT.md
Purpose
This document turns Harbor's generic go-live plan into a concrete prelaunch deployment for:
breakwaterharbor.net- VPS:
162.222.206.87 - Docker + Caddy
- Gitea reachable over Tailscale / MagicDNS
This is the recommended first public-facing shape for Breakwater Harbor.
Deployment stance
For the first live deployment, treat this VPS as the public ecosystem host, not as the default customer Harbor Node host.
That means the VPS should host:
- public website
- public docs
- public Harbor Hub
- public cloud API
- private/internal Harbor Admin
That VPS should not be the default place where customer Harbor Nodes live. Harbor Node remains local-first and should stay on operator-controlled machines unless we are running an internal demo node on purpose.
Domain layout
Recommended public layout:
https://breakwaterharbor.net-> main website landing page and gated previewhttps://www.breakwaterharbor.net-> redirect or alias to the main websitehttps://docs.breakwaterharbor.net-> Harbor Docshttps://hub.breakwaterharbor.net-> Harbor Hubhttps://api.breakwaterharbor.net-> Harbor Cloud APIhttps://admin.breakwaterharbor.net-> Harbor Admin, private/internal only
Recommended DNS records:
A breakwaterharbor.net -> 162.222.206.87A www.breakwaterharbor.net -> 162.222.206.87A docs.breakwaterharbor.net -> 162.222.206.87A hub.breakwaterharbor.net -> 162.222.206.87A api.breakwaterharbor.net -> 162.222.206.87A admin.breakwaterharbor.net -> 162.222.206.87
Public service mapping
Map the current Harbor Docker services behind Caddy like this:
breakwaterharbor.net->harbor-web:webon127.0.0.1:11824docs.breakwaterharbor.net->harbor-web:docson127.0.0.1:11823hub.breakwaterharbor.net->harbor-hub:dockon127.0.0.1:11826api.breakwaterharbor.net->harbor-cloud:cloud-apion127.0.0.1:11825admin.breakwaterharbor.net->harbor-web:adminon127.0.0.1:11822
For the first deployment, keep the container ports bound to localhost or firewall-restricted host ports and let Caddy own the public TLS-facing ports 80 and 443.
Recommended first server decision
Because Unstucktools.com has no traffic today, the simplest and safest launch posture is:
- remove it from the VPS for now
- dedicate the box to Breakwater Harbor
- bring Unstucktools back later only if needed
Reason:
- simpler Caddy config
- fewer moving parts during first TLS and DNS bring-up
- lower chance of certificate or route collisions
- easier rollback if something goes wrong
If we do keep it on the box, it should stay in a clearly separate Caddy site block and Docker project so it cannot interfere with Harbor ports, certs, or logs.
Admin access model
admin.breakwaterharbor.net should not be publicly open.
Recommended first version:
- public DNS record exists
- Caddy only proxies requests from Tailscale ranges and localhost
- all other traffic receives
403
That keeps Harbor Admin available from trusted operator devices over Tailscale while still allowing a stable hostname.
Cloud and auth posture
The first live website posture should be:
- public landing page
- gated preview after login
- invite/manual account creation
- email/password first
- Google auth prepared next
The first live cloud posture should be:
api.breakwaterharbor.netis the stable auth and member API origin- public sign-up stays invite-only during preview
- Harbor Admin remains internal-only
Google OAuth planning
The new domain is enough to start reserving the final public surfaces for future OAuth work:
- website/account auth should ultimately hang off
breakwaterharbor.net - cloud auth and provider callbacks should live under
api.breakwaterharbor.net - Harbor Node Gmail OAuth remains node-local and uses the configured
HARBOR_NODE_PUBLIC_BASE_URL
Important distinction:
- website/cloud auth is an ecosystem sign-in concern
- Harbor Node Gmail OAuth is a connector callback on the specific Harbor Node
Those should not be collapsed into one callback host.
Build and deploy model
Recommended first deployment loop:
- keep
mainas the deploy branch - pull the repo to the VPS over Tailscale-accessible Gitea
- build and run the Docker compose stacks on the VPS
- let Caddy reverse proxy the public domains to the local Harbor service ports
The public-facing stacks that belong on this VPS are:
infra/docker/compose.web.ymlinfra/docker/compose.cloud.ymlinfra/docker/compose.hub.yml
Do not deploy compose.node.yml here by default unless we intentionally want a demo node on this server.
Use this environment template as the starting point:
infra/env/breakwaterharbor.production.env.example
That env template already binds the public-facing Harbor services to loopback with:
WEB_BIND_PREFIX=127.0.0.1:DOCS_BIND_PREFIX=127.0.0.1:ADMIN_BIND_PREFIX=127.0.0.1:HUB_BIND_PREFIX=127.0.0.1:CLOUD_API_BIND_PREFIX=127.0.0.1:POSTGRES_BIND_PREFIX=127.0.0.1:REDIS_BIND_PREFIX=127.0.0.1:
The expected live server file should be:
infra/env/breakwaterharbor.production.env
Recommended production env values
For the first Breakwater Harbor deployment, these should become the public URL values:
HARBOR_PUBLIC_WEBSITE_URL=https://breakwaterharbor.net/HARBOR_PUBLIC_API_URL=https://api.breakwaterharbor.net/HARBOR_PUBLIC_DOCS_URL=https://docs.breakwaterharbor.net/HARBOR_PUBLIC_HUB_URL=https://hub.breakwaterharbor.net/HARBOR_PUBLIC_REPO_URL=http://cpu:3001/BreakwaterNinja/HarborHARBOR_WEBSITE_DOCS_URL=https://docs.breakwaterharbor.net/HARBOR_WEBSITE_INSTALL_URL=http://cpu:3001/BreakwaterNinja/HarborHARBOR_WEBSITE_STAGE=previewHUB_PUBLIC_BASE_URL=https://hub.breakwaterharbor.netCLOUD_API_CORS_ORIGIN=https://breakwaterharbor.net,https://www.breakwaterharbor.net,https://admin.breakwaterharbor.netCLOUD_SIGNUP_MODE=invite_only
When the site goes truly public, the repo/install link can move from the internal Gitea URL to a public docs or GitHub install target.
Server prep commands
After cloning the repo on the VPS:
cd /opt/harbor
cp infra/env/breakwaterharbor.production.env.example infra/env/breakwaterharbor.production.env
Then edit infra/env/breakwaterharbor.production.env and replace every placeholder secret before the first live deploy.
Recommended Git update flow:
cd /opt/harbor
git fetch origin
git checkout main
git pull --ff-only origin main
Recommended stack deploy flow:
cd /opt/harbor
./scripts/redeploy-breakwaterharbor.sh ./infra/env/breakwaterharbor.production.env
The helper script deploys:
- website, docs, and admin with loopback-only host bindings
- Harbor Hub with loopback-only host binding
- cloud API, Postgres, and Redis with loopback-only host bindings
That keeps the services reachable for Caddy on localhost without exposing them directly on the public interface.
First rollout order
Phase 1: Infrastructure bring-up
- point DNS to
162.222.206.87 - install or update Docker, Docker Compose, and Caddy
- remove or isolate
Unstucktools.com - deploy Caddy with the Breakwater Harbor site blocks
Phase 2: Public surfaces
- https://breakwaterharbor.net - https://docs.breakwaterharbor.net - https://hub.breakwaterharbor.net
- deploy
compose.web.yml - deploy
compose.hub.yml - verify:
Phase 3: Cloud API
- https://api.breakwaterharbor.net/health
- deploy
compose.cloud.yml - verify:
- verify website contact flow still works through the public API host
Phase 4: Admin lockdown
- deploy or expose Harbor Admin only after Caddy Tailscale restriction is in place
- verify public internet receives
403 - verify Tailscale-connected clients can reach the admin host
Phase 5: Gated preview
- deploy the website in landing-page plus gated-preview mode
- use manual/invite account creation first
- keep sign-up closed until the preview flow is stable
Known follow-up work before broad public launch
- move browser sessions toward
HttpOnlycookies - continue tightening Harbor Hub naming and import copy anywhere older Dock wording still exists in deeper docs or operator tooling
- add production reverse-proxy headers and TLS guidance to the main deployment docs
- add backup and restore drills for Postgres and Hub SQLite on this VPS
Recommended immediate next actions
- dedicate the VPS to Breakwater Harbor for now
- add the six DNS records
- add a Breakwater Harbor Caddy config using the example in
infra/caddy/Caddyfile.breakwaterharbor.example - create
infra/env/breakwaterharbor.production.envfrom the example template - deploy website, docs, and Hub first
- deploy cloud API second
- keep Harbor Admin Tailscale-only
- confirm preview login, docs, and Hub behavior before pointing apex DNS live