Skip to content
HostStack Docs

Networking

HostStack creates a private Docker network per project. Services and databases inside the same project can reach each other by name; nothing inside that network is reachable from the public internet unless you explicitly attach a domain or open a port.

Inter-Service DNS

Every service and database registers a stable alias on the project's Docker network. From any container in the same project, you can connect by alias:

# From a "web" service in the same project as a "redis" addon
curl http://api:3000/health           # talk to a sibling web_service named "api"
redis-cli -h redis -p 6379            # talk to the project's Redis
psql postgres://hoststack@app-db/app  # talk to the project's Postgres

Auto-Injected URLs

HostStack auto-injects two classes of env vars so you can call siblings without hard-coding hosts or duplicating credentials:

  • Linked resources — when you link a managed resource to a service (Service → Resources) you give it an alias, and HostStack injects alias-prefixed vars: <ALIAS>_URL, <ALIAS>_HOST, <ALIAS>_PORT, <ALIAS>_DATABASE, <ALIAS>_USERNAME, <ALIAS>_PASSWORD (object storage and queues get their own field set). On top of that, the first linked database of each engine also gets the canonical name apps expect: DATABASE_URL (Postgres / MySQL / MariaDB), REDIS_URL, and MONGO_URL.
  • Sibling service URLs — for every other service in the same project + environment, HostStack injects both <NAME>_INTERNAL_URL (ergonomic, follows renames) and <PUBLIC_ID>_INTERNAL_URL (stable across renames). Both point at the same container.

Override any auto-injected value by setting the same key explicitly in Service → Environment. Setting it to an empty string disables the auto-injection entirely. See Custom Domains → sibling services for the full key naming rules.

Public Exposure

Web services automatically get a *.hoststack.dev subdomain served over HTTPS via Traefik. Attach a custom domain in Settings → Custom Domains; HostStack issues a Let's Encrypt certificate and routes traffic once you set the DNS records.

Visitor Country Header

HostStack resolves each visitor's country from their IP at the edge and injects it as a request header on every request to your web service — no GeoIP database or third-party API to wire up in your app. The lookup runs inside our own infrastructure, so visitor IPs are never sent to an external provider.

Two headers carry the same value:

  • Hs-Ipcountry — the canonical HostStack header
  • Cf-Ipcountry — a Cloudflare-compatible alias, so anything that already reads Cloudflare's CF-IPCountry works unchanged

The value is an ISO 3166-1 alpha-2 country code, uppercase (e.g. DK, US). The header is omitted entirely when the country can't be determined (private IP, unknown range), so check for its presence rather than a sentinel value.

// Express / Node — read the injected header
app.get("/", (req, res) => {
  const country = req.get("hs-ipcountry"); // "DK", or undefined
  res.send(country ? `Hello from ${country}` : "Hello");
});

Need the raw visitor IP as well? Read X-Real-Ip, or the left-most entry of X-Forwarded-For.

Private services are reached on the project network directly and bypass the edge, so they receive neither the country header nor the rewritten forwarding headers. If you need the country inside a private backend, forward it inward from your public web tier.

Accuracy. Country resolution is roughly 99% accurate — great for analytics, geo-routing, and content localization, but it can be wrong for VPNs, carrier NAT, and satellite ranges. Don't rely on it as a hard identity or fraud control.

Country data by DB-IP (CC BY 4.0).

Private Services

Set a service's type to Private to skip the public subdomain entirely. The service is reachable on the project network only, ideal for internal APIs and gRPC backends. Workers and cron jobs are private by definition.

Cross-Environment Boundaries

Each environment in a project gets its own slice of the project network. Production services can't reach Staging databases by alias — the alias resolves to the same-environment sibling. This isolates blast radius between environments without forcing separate projects.

Essential cookies only — for login sessions. No tracking. Details