Skip to content

ADR 0001: MVP hosting and commerce foundation

  • Status: Accepted
  • Date: 2026-08-24
  • Scope: First production-capable MVP foundation

Context

AndreaWeb needs to combine a bilingual architecture portfolio with a small cement-object store. Andrea must be able to manage products, images, Colombian-peso prices, and inventory without editing source code. The initial purchase flow will create a WhatsApp or email inquiry rather than accepting payment.

The application will run on an existing OVH VPS. Read-only discovery found Ubuntu 26.04, Nginx 1.28, Docker Engine and Docker Compose, approximately 3.7 GiB of memory, and approximately 21 GiB of free root-disk capacity. Nginx and Docker are enabled. Only the stock default Nginx site is enabled, no application containers are running, and the public listeners observed were SSH and HTTP. Reading the effective privileged Nginx configuration and firewall state requires interactive sudo, so both must be verified before deployment.

Decision

  1. Use andreazambrano.co as configuration rather than a hard-coded application constant. Spanish remains the default language and English uses /en routes.
  2. Route the apex portfolio/store and the explicit www, api, admin, and media hostnames to the VPS. The apex uses one IPv4 A record; the other names use explicit CNAMEs to the apex. Do not publish IPv6 until it is deliberately configured and tested.
  3. Keep the VPS's system Nginx as the only public reverse proxy. AndreaWeb receives additive site files; existing configuration is never replaced wholesale. Application services bind to loopback or private Docker networks.
  4. Use Let's Encrypt certificates managed by Certbot. Cover every public hostname, redirect HTTP to HTTPS after issuance, redirect www to the apex, verify unattended renewal, and monitor certificate expiration.
  5. Keep the existing Vinext application as the MVP portfolio. Use the supported Medusa v2 backend and Admin for commerce, and use the official Medusa DTC Next.js storefront as the commerce frontend.
  6. Run the Medusa server, Medusa worker, PostgreSQL, Redis, and S3-compatible product-media storage as separate services. Persistent database and media state must survive application replacement and must have verified off-VPS backups before launch.
  7. Treat Medusa as the commerce system of record. Storefront clients consume documented Medusa APIs and never decide authoritative price, availability, inventory, or order state.
  8. Establish launch observability with structured logs, health checks, bounded container logs, host/container resource visibility, external uptime and certificate checks, and OpenTelemetry-compatible service/resource naming. Do not deploy a full observability platform until capacity and operational value justify it.
  9. Build images away from the production VPS when practical. The VPS capacity is suitable for a small runtime stack, but stateful-service memory limits, disk growth, backups, and image cleanup must be monitored.

Initial public topology

Address Responsibility
andreazambrano.co/portfolio Architecture portfolio
andreazambrano.co/cementos Cement catalog and inquiry cart
andreazambrano.co/contact Public contact options
andreazambrano.co/en/... English public routes
api.andreazambrano.co Medusa Store API and health endpoint
admin.andreazambrano.co/app Authenticated Medusa Admin
media.andreazambrano.co Product-media delivery

Consequences

  • The portfolio and storefront remain independently replaceable and can later use different release schedules.
  • Changing the VPS address changes one apex DNS record. Moving media to hosted object storage or a CDN changes only the media record and corresponding configuration.
  • A domain change requires DNS, TLS, Nginx hostnames, application origins, canonical URLs, and provider callback configuration to change, but should not require application rewrites.
  • PostgreSQL and product media become production data and require backups, restore tests, explicit migrations, and controlled access.
  • The initial VPS is one failure domain. Separate containers improve isolation and replacement but do not provide high availability.
  • Full Grafana/Loki/Tempo deployment, real payments, customer accounts, and automated inventory reservation remain outside the first MVP.

Deployment gate

Before any public deployment:

  1. inspect the complete effective Nginx configuration and firewall with interactive administrative access;
  2. confirm no hostname, port, directory, or certificate conflicts;
  3. verify DNS resolution and HTTP routing before requesting certificates;
  4. validate new Nginx files with nginx -t before an additive reload;
  5. test database and media backup restoration;
  6. deploy a reviewed immutable commit and retain a known-good rollback target.