> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Private networking and connections

> Connect one service to another so StackShift injects the internal URL as an environment variable — no IPs or hostnames to copy, and private services never touch the public internet.

<Tip>
  **Live.** This area is documented as current, user-reliable behavior.
</Tip>

## Goal

Wire services together with explicit connections instead of hardcoded URLs.

## Prerequisites

* An application with at least two services

## Workflow

<Steps>
  <Step>
    Open the application and choose Connect.
  </Step>

  <Step>
    Pick the service that needs access, the target service or database, and the environment variable name.
  </Step>

  <Step>
    Redeploy the source service — the dashboard flags it until the new variable is applied.
  </Step>

  <Step>
    Read the variable in your code exactly like any other environment variable.
  </Step>
</Steps>

## Public and private services

* Public services get a stackshift.app URL and answer to the internet.
* Private services have no public URL at all — not a hidden one, none. They are reachable only from services in the same application.
* Workers, scheduled jobs, and databases are always private.
* Flipping a service to private removes its public routes; flipping it back assigns a fresh URL.

## How internal traffic works

* Every service gets an internal hostname: \<service>.\<application-network>.stackshift.internal.
* Internal hostnames only resolve inside your application network — they do not exist on public DNS.
* Traffic between applications is blocked at the platform level, so another tenant can never reach your private services.
* The same internal URL works whether the target runs in a standard container or a Kata MicroVM.

## Expected result

<Check>
  The source service reads something like API\_URL=[http://api.myapp-1a2b3c4d.stackshift.internal:8080](http://api.myapp-1a2b3c4d.stackshift.internal:8080) and calls its sibling over the private network.
</Check>

## Common failures

<Warning>
  * the variable is missing at runtime: redeploy the source service after adding the connection.
  * the target does not define a port: set a port on the target service, then reconnect.
  * your own environment variable overrides the connection: the dashboard warns you when a variable you set shadows an injected one.
  * a database connection points at the database host, not an internal hostname: managed databases are reached through their database endpoint, and the injected URL includes credentials — treat it as a secret.
</Warning>

## Related guides

<CardGroup cols={2}>
  <Card title="Build a multi-service application" href="/applications/build-a-multi-service-application">
    Create an application, add public and private services from one repo or many, and let each service deploy independently while sharing one private network.
  </Card>

  <Card title="Project environment, domains, and previews" href="/projects/environment-domains-and-previews">
    Configure the project surfaces that most often decide whether a deployment works after it builds, including runtime shape, domains, previews, and storage.
  </Card>
</CardGroup>
