Public personal project · Containers · Networking · CI/CD

Self-hosting and secure delivery for socket23.com

I built and hardened the full path that serves this site: DNS, Cloudflare, firewall policy, Docker Swarm, NGINX, certificates, protected changes, immutable images, deployment verification, and rollback.

Context

socket23.com is self-hosted through Cloudflare and Sophos into a Docker Swarm service. The deployment repository and CI pipeline are private, while this portfolio and selected sanitized engineering artifacts remain public.

My role

I built the hosting stack, investigated its failure paths, replaced the unsafe delivery model, and verified the complete protected release cycle.

Result

A reviewed change now becomes a scanned multi-architecture image, is deployed by immutable digest, runs non-root and read-only with health checks and two replicas, and is accepted only after runtime and public verification.

Safe working sequence

How I reduced risk

  1. Review
  2. Test
  3. Build
  4. Publish
  5. Deploy
  6. Verify

Conceptual workflow only. No live topology, identifiers, or operational data are shown.

The problem

Why the work needed more than one tool

The original deployment used a mutable image, root execution, host bind mounts, one replica, and stop-first updates. The repository could pass a check while production still ran something different.

What could go wrong

  • Repository-to-runtime drift
  • Credentials crossing from production into hosted CI
  • Update gaps from stop-first deployment
  • Stale browser assets after a successful release
  • Container privilege and writable-root exposure
  • A green build being mistaken for a successful public deployment

What I did

The working sequence

  • Moved all changes behind protected pull requests and required CI
  • Built digest-pinned multi-architecture NGINX images
  • Added static, configuration, workflow, shell, secret, vulnerability, architecture, and runtime checks
  • Changed the runtime to non-root, read-only, dropped capabilities, and no-new-privileges
  • Configured two same-node replicas, start-first updates, health checks, and rollback
  • Kept deployment outbound-only from the private node so GitHub receives no production SSH key
  • Automated wildcard certificates with Dehydrated and Cloudflare DNS-01
  • Added deployment and public-edge verification for exact digest, routes, headers, redirects, and 404 behavior

How I validated it

Evidence before completion

  • Verified PR checks and post-merge image publication
  • Resolved and compared the registry digest with the running Swarm service
  • Checked 2/2 replicas, running tasks, runtime hardening, and empty deployment-error logs
  • Crawled every public route with cache bypass
  • Verified security headers, custom 404 behavior, legacy redirects, and browser-console state
  • Exercised rollback and update continuity during the hardening work

What this demonstrates

The skill behind the tools

The implementation is public and inspectable. This site now demonstrates the same change-control, least-privilege, verification, and rollback principles described in the portfolio.

Production details are intentionally anonymized. I do not publish organization names, internal addresses, credentials, private topology, or sensitive recovery information.

Platforms and tools

Cloudflare Sophos Docker Swarm NGINX GitHub Actions GHCR Let’s Encrypt Dehydrated Gitleaks Trivy OpenSSL

Continue through the project inventory