Many projects deployed on Upsun contain multiple applications. For example, you might have a frontend application and a separate backend API, or several microservices working together. Upsun lets you create relationships between your applications, similar to how you connect services like databases. However, these relationships are mainly for server-side communication over the internal network. Sometimes, one application needs the public hostname, or Uniform Resource Identifier (URI), of another application in the same project. For instance, imagine a Next.js frontend application. It might need to call your API application from both server components (running on the server) and client components (running in the user’s browser). To do this, the frontend needs the API’s public URI. Every application container deployed on Upsun automatically gets an environment variable calledDocumentation Index
Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
Use this file to discover all available pages before exploring further.
PLATFORM_ROUTES. This variable contains information about all the project’s routes. This guide uses the following example project structure:

Define route identifiers
First, define your application routes in your project’s routing configuration, within.upsun/config.yaml. Here’s a basic example:
id attribute to each one. Choose a meaningful string for the ID. Using the application name often works well:
Fetch specific URIs from $PLATFORM_ROUTES
After deploying these changes, connect to one of your application containers using the Upsun CLI. For example, use upsun ssh -A api where api is your application’s name. Inside the container, you can view the PLATFORM_ROUTES variable:
jq. jq is a command-line tool for processing JSON data. It helps you parse, filter, and transform JSON, which is useful when working with APIs and configuration files. You can find more information on the jq website.
jq query to extract the specific URI you want, using the route id defined earlier. Here’s how you can select the URI associated with the id “api”:
jq query works:
(You can experiment with this query and the example JSON using the online jq playground.)
to_entries[]: Converts the JSON object into an array where each item has akey(the URI) and avalue(the route details object). The[]processes each item in the array.select(.value.id=="api"): Filters these items, keeping only those where theidfield inside thevalueobject equals"api". Change"api"to the route ID you need..key: Extracts thekeyfield (the URI) from the filtered item.- The
-rflag tellsjqto output the raw value instead of its JSON representation.
Set up environment variables using .environment
Upsun lets you define environment variables dynamically during the build process. You do this using a special script file named .environment placed in your application’s source code directory. Find more details in the documentation on setting variables via script.
Suppose your Next.js application needs an API_HOST variable with the API’s URI. And your API application needs a NEXT_PUBLIC_BASE_URL variable with the frontend’s URI. You can create a .environment file using the jq queries from the previous step.
.environment file(s) to your repository and push the changes to Upsun. After the deployment finishes, connect to an application container again and check the variables:
Bonus tip: Use these variables in statically exported JavaScript applications
JavaScript applications that are statically exported (like some Next.js static exports or Create React App builds) generate their assets and configuration during a build phase. The way most static generators work is that they will replace theprocess.env.* variables at build time with their actual values. Let’s take an example with a variable called API_ENDPOINT.
This API_ENDPOINT variable has a value of https://api.example.com in either your .env file or the server environment variable. Your Javascript code refers to that variable with process.env.API_ENDPOINT.
When you are triggering the generation of the static export with npm run build, the process.env.API_ENDPOINT get replaced in the generated code with the actual value https://api.example.com.
While it does seem to be a satisfactory way of doing it, it creates a problem when that code needs to run on multiple environments where that variable could have different values.
On production, you might want to query https://api.example.com but staging should target “https://staging.api.example.com`.
“Hard-coding” the value during prevent us from running the exact same build on different environments with different configurations make the build process undertiministic. Upsun’s goal is to run the exact same applications builds on all environment to guarantee the exact same behaviors during testing.
Injecting different variable values on different environments
In our example, the client application running in the user’s browser needs to be able to query a differentAPI_ENDPOINT based on the environment it is running in. Let’s explore two approaches.
Approach 1: Dynamically constructing the URI (If applicable)
The simplest approach, if your routes structure allows it, is to dynamically construct the necessary URI in the browser. For example, consider these routes again:api.{all}) is always on the same base domain as the frontend ({all}), just prefixed with api.. You could potentially use the browser’s current location.hostname to figure out the API endpoint:
Approach 2: Using a Deploy Hook and Runtime Configuration File
When dynamic construction isn’t suitable, the recommended alternative is to write the necessary environment-specific variables to a JSON configuration file during thedeploy hook. This hook runs after your application build is complete and deployed to the server, at which point it has access to runtime environment variables, services, and mounts.
Let’s assume your project uses an API_ENDPOINT environment variable whose value changes per environment (e.g., defined using Upsun’s environment variables features).
During the deploy hook, you can read this variable’s value and store it in a publicly accessible JSON file, for example, variables.json.
First, ensure you have a writable mount defined in your application configuration where you can store this file:
web settings:
passthru, scripts, allow, and expires based on your security and caching needs.
Finally, add the deploy hook to write the environment variable into the JSON file within the mounted directory. The path /app/storage typically corresponds to the storage mount point inside the container:
/storage/variables.json file at runtime using a library like axios or the native fetch API to get the correct API_ENDPOINT for the current environment: