DEV Community

Cover image for Building a Multi-Environment Web App on App Platform
Peace Sandy
Peace Sandy

Posted on

Building a Multi-Environment Web App on App Platform

Deploying straight to production is one of the most common mistakes developers make early in their careers. One environment, one URL, and one quiet hope that nothing will break. It works until it doesn't.

A single bad push on a Friday afternoon can leave a client's homepage blank, with no staging environment to catch the issue and no safe place to roll back. Deploying without a safety net isn't a workflow; it's a risk.

Many developers stay in this pattern longer than they should. A single live environment feels faster to maintain. But as applications scale, the approach becomes fragile. Bugs reach users before they are caught.

Multi-Environment architecture solves this. By separating your application into distinct staging and production deployments, you create a safe layer where changes are validated before they affect real users.

Each environment runs the same codebase with different configurations, so what you test in staging is exactly what ships to production, no surprises.

In this tutorial, you will build a Next.js application and deploy it across two fully independent environments on DigitalOcean App Platform, a managed cloud service that builds and deploys apps directly from a GitHub repository.

You will configure environment variables to control how the app behaves in each environment, set up a Git branch strategy that maps staging and production to separate deployments, and enable autodeploy so that every push automatically triggers a rebuild.

By the end, you will have a working multi-environment setup and a repeatable promotion workflow that lets you ship with confidence.

Prerequisites

To complete this tutorial, you will need:

  • Node.js v18 or higher is installed on your machine, including npm, which comes bundled with it. You can check your versions by running node -v and npm -v in your terminal. If you need to install Node.js, follow How To Install Node.js and Create a Local Development Environment for your system.

  • Git is installed on your local machine. Run git --versionto check. If you need to install it, follow How To Install Git and set it up on your machine before continuing.

  • A GitHub account with a new empty repository named multi-env-app. App Platform deploys directly from GitHub, so your code must be hosted there before you can connect it to DigitalOcean. You can sign up for free at github.

  • A DigitalOcean account with access to App Platform. If you are new to DigitalOcean, you can sign up at DigitalOcean and follow the App Platform getting started documentation before proceeding.

  • Familiarity with Next.js and React, specifically what components and pages are and how they relate to each other. If you need to build your foundational knowledge first, follow How To Create a Next.js App before starting this tutorial.

Key Takeaways:

  • A multi-environment setup separates your application into distinct deployments, typically staging and production, allowing you to test changes safely before they affect real users.

  • DigitalOcean App Platform deploys directly from a GitHub repository, automatically rebuilding and redeploying your app every time you push to a connected branch.

  • Environment variables in Next.js prefixed with NEXT_PUBLIC_ are embedded into the client bundle at build time. They are publicly visible, while variables without the prefix remain server-side only and should be used for secrets.

  • Each App Platform deployment maintains its own set of environment variables, meaning your staging and production apps can point to different APIs and configurations while running identical code.

  • A Git branch-based promotion workflow where the staging branch maps to the staging environment and the main branch maps to production gives you a reliable, repeatable process for shipping changes safely.

  • Keeping .env.local out of version control by adding it to .gitignore and committing only .env.example as a reference template is a critical security practice that prevents secrets from being accidentally exposed on GitHub.

What is Multi-Environment?

A multi-environment setup means running separate, isolated versions of the same application, each with its own configuration, URL, and purpose.

Rather than maintaining one live deployment that everyone shares, you maintain distinct environments that represent different stages of your development workflow.

Most teams work with three environments:

  • Local is where development happens. It runs on your machine, points to local APIs, and is never visible to anyone else. You can break things freely here without consequence.

  • Staging is a production-like environment used for testing and review. It runs the same code and infrastructure as production but uses test data and non-critical API endpoints. Think of it as a dress rehearsal before the real show.

  • Production is the live environment where real users interact. Changes here have real consequences, which is why nothing should reach it without first passing through staging.

What makes this work is that each environment runs the same codebase with different configuration values. There is no separate "staging version" of your code.

The same application reads its environment variables at build time and behaves accordingly, which is exactly what you will see in action throughout this tutorial.

The cost of skipping this setup only becomes clear after something breaks in production. A multi-environment architecture does not prevent bugs, but it ensures they are caught early, when the stakes are low, before they reach the people who depend on your product.

Building a Simple Next.js App

In this section, we are going to build a simple Next.js App

Step 1: Creating the Repository on GitHub

In this step, you will create a GitHub repository to host your project. App Platform deploys directly from GitHub, so your code must be hosted there before you can connect it to DigitalOcean.

Navigate to github and click the "New" button to create a new repository. Fill in the details as follows:

  • Set the Repository name to multi-env-app
  • Set the Visibility to Public
  • Check the box labelled Add a README file

Checking the Add a README file option initializes the repository with a first commit. This means Git treats the repository as having an existing history, so you can clone it to your local machine immediately without running any additional initialization commands.

Click Create repository when you are done. You have created your remote repository on GitHub, and it is ready to receive your project files. In the next step, you will clone it to your local machine and open it in your code editor.

Step 2: Cloning the Repository and Opening It in VS Code

In this step, you will clone the repository to your local machine and open it in VS Code so you have a working local copy ready for development.

Run the following command in your terminal to clone the repository, replacing YOUR_USERNAME with your actual GitHub username:

git clone https://github.com/YOUR_USERNAME/multi-env-app.git
Enter fullscreen mode Exit fullscreen mode

This command downloads the repository from GitHub and creates a local copy of it in a folder named multi-env-app on your machine.

Move into the project directory:

cd multi-env-app
Enter fullscreen mode Exit fullscreen mode

Then open the folder in VS Code:

code.
Enter fullscreen mode Exit fullscreen mode

The code. command launches VS Code with the current directory open as the project workspace. If this command is not recognized in your terminal, follow the VS Code Shell Command installation guide to enable it.

At this point, your project contains only the README.md file that GitHub created. In the next step, you will scaffold the Next.js application inside this directory.

Step 3: Scaffolding the Next.js Application

In this step, you will scaffold a new Next.js application directly into your existing project directory. This generates all the files and folders you need to start building your app.

Run the following command to create the Next.js application inside the current directory:

npx create-next-app@latest .
Enter fullscreen mode Exit fullscreen mode

The dot (.) tells the scaffolding tool to use the current directory instead of creating a new nested folder.

Without it, the tool would create a multi-env-app folder inside your existing multi-env-app folder, which would break your repository structure.

The tool will prompt you with a series of configuration questions. Answer them exactly as follows:

Would you like to use TypeScript?             No
Would you like to use ESLint?                 Yes
Would you like to use Tailwind CSS?           Yes
Would you like your code inside a src/ dir?   No
Would you like to use App Router?             Yes
Would you like to use Turbopack?              No
Would you like to customize the import alias? No
Enter fullscreen mode Exit fullscreen mode

Here is why each choice matters for this tutorial:

  • TypeScript: No — This tutorial uses JavaScript to keep the code accessible to a wider audience. The concepts apply equally to TypeScript projects.

  • ESLint: Yes — ESLint catches common code errors during development and is a standard part of most production Next.js setups.

  • Tailwind CSS: Yes — You will use Tailwind utility classes to style the environment banner directly in your JSX, without creating any separate CSS files.

  • App Router: Yes — The App Router is the current recommended routing system in Next.js and is built around this tutorial.

  • src/ directory, Turbopack, import alias: No—These are not needed for this tutorial and would add unnecessary complexity.

Once the prompts are complete, create-next-app will install all dependencies and automatically generate your project files.

You now have a fully scaffolded Next.js application in your project directory. In the next step, you will create the environment variable files that allow your app to behave differently depending on where it is deployed.

Step 4: Creating the Environment Variable Files

In this step, you will create environment variable files that allow your app to read different configuration values depending on where it runs. You will also update your .gitignore file to ensure that secrets are never committed to GitHub.

Open your editor and create a new file named .env.local in the root of your project. Add the following content:

NEXT_PUBLIC_APP_ENV=local
NEXT_PUBLIC_API_URL=http://localhost:3000/api

Enter fullscreen mode Exit fullscreen mode

This file holds the configuration values for your local development environment. Next.js loads .env.localautomatically when you run the development server, so these values will be available to your app without any additional setup.

Next, create a second file named .env.example in the same root location and add the following:

NEXT_PUBLIC_APP_ENV=
NEXT_PUBLIC_API_URL=

Enter fullscreen mode Exit fullscreen mode

Unlike .env.local, this file contains the variable names but no values. It acts as a reference template for anyone who clones the repository, showing them exactly which variables they need to configure without exposing any real values.

Now open the .gitignorefile that Next.js generated automatically and locate the following line:
.env *

This wildcard pattern tells Git to ignore all files that begin with .env, which correctly prevents .env.local from being committed to GitHub. However, it also ignores .env.example, which you do want to commit so other developers can reference it. Add the following line directly below it:

.env*
!.env.example
Enter fullscreen mode Exit fullscreen mode

The exclamation mark creates an exception to the wildcard rule, telling Git to track .env.example, even though all other .env files are ignored. With this change in place, your local secrets stay protected while the reference template remains visible in the repository.

You have set up your environment variable files and secured your .gitignore. In the next step, you will build the environment banner component that reads these values and displays them visually in the browser.

Step 5: Building the Environment Banner Component

In this step, you will create a React component that reads your environment variables and displays them as a colored banner at the top of the page. This makes it immediately clear which environment you are looking at whenever you open the app in a browser.

Create a new folder named components in the root of your project. Inside it, create a new file named EnvBanner.js:

mkdir components && touch components/EnvBanner.js
Enter fullscreen mode Exit fullscreen mode

Open components/EnvBanner.js in your editor and add the following code:

jsx
// components/EnvBanner.js
export default function EnvBanner() {
  const env = process.env.NEXT_PUBLIC_APP_ENV;
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  const styles = {
    local:      { bg: "bg-gray-800",  label: "LOCAL" },
    staging:    { bg: "bg-yellow-500", label: "STAGING" },
    production: { bg: "bg-green-600", label: "PRODUCTION" },
  };

const current = styles[env] || { bg: "bg-gray-500", label: env || "UNKNOWN" };

  return (
    <div className={`${current.bg} text-white text-sm font-mono px-4 py-2 text-center`}>
      🌍 Environment: <strong>{current.label}</strong> &nbsp;|&nbsp; API:{" "}
      <code className="bg-black/20 px-1 rounded">{apiUrl}</code>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here is what each part of the component does:

  • process.env.NEXT_PUBLIC_APP_ENV and process.env.NEXT_PUBLIC_API_URL These lines read the two environment variables you defined in .env.local. Next.js makes any variable prefixed with NEXT_PUBLIC_available directly in the browser bundle.

  • styles object — This maps each environment name to a Tailwind background color and a display label. local renders in dark gray, staging in yellow, and production in green, making each environment visually distinct at a glance.

  • current fallback — If NEXT_PUBLIC_APP_ENV is not set or holds an unexpected value, the banner falls back to gray and displays whatever value it finds. This makes misconfigurations immediately visible in the browser rather than failing silently.

  • The returned JSX — Renders a full-width banner using the resolved color and label, with the API URL displayed alongside it for quick reference.

You have built the banner component that will visually reflect your environment configuration. In the next step, you will update the homepage to render this component so it appears at the top of every page.

Step 6: Updating the Homepage

In this step, you will update the homepage to render the environment banner and display a config card showing the current environment variable values. This gives you a single page that makes your entire environment configuration visible at a glance.

Open app/page.js in your editor and replace its entire contents with the following:

jsx
// app/page.js
import EnvBanner from "@/components/EnvBanner";

export default function Home() {
  return (
    <main className="min-h-screen bg-gray-50">
      <EnvBanner />

      <div className="max-w-2xl mx-auto mt-20 px-6 text-center">
        <h1 className="text-4xl font-bold text-gray-800 mb-4">
          Multi-Environment App
        </h1>
        <p className="text-gray-500 text-lg">
          This app reads its configuration from environment variables.
          The banner above changes depending on where this app is deployed.
        </p>

        <div className="mt-10 bg-white rounded-xl shadow p-6 text-left">
          <h2 className="text-sm font-semibold text-gray-400 uppercase mb-3">
            Current Config
          </h2>
          <ul className="space-y-2 font-mono text-sm">
            <li>
              <span className="text-gray-400">APP_ENV: </span>
              <span className="text-indigo-600 font-bold">
                {process.env.NEXT_PUBLIC_APP_ENV || "not set"}
              </span>
            </li>
            <li>
              <span className="text-gray-400">API_URL: </span>
              <span className="text-indigo-600">
                {process.env.NEXT_PUBLIC_API_URL || "not set"}
</span>
            </li>
          </ul>
        </div>
      </div>
    </main>
  );
}


Enter fullscreen mode Exit fullscreen mode

Here is what each part of the updated homepage does:

  • import EnvBanner from@/components/EnvBanner — This imports the banner component you built in the previous step. The @/prefix is an alias for the project root, configured automatically by create-next-app. It lets you import files without writing long relative paths like ../../components/EnvBanner.

  • EnvBanner — Renders the colored environment banner at the very top of the page, before any other content.

  • The config card — Displays the current values of NEXT_PUBLIC_APP_ENV and NEXT_PUBLIC_API_URL directly on the page. If either variable is not set, it falls back to displaying "not set," so misconfigurations are immediately visible.

You have updated the homepage to display both the environment banner and the current configuration values. In the next step, you will run the app locally to confirm everything is working before deploying to App Platform.

Step 7: Running the App Locally

In this step, start the development server and verify that your app is reading environment variables correctly before deploying it to App Platform.

Run the following command to start the development server:

npm run dev
Enter fullscreen mode Exit fullscreen mode

This command compiles your Next.js application and starts a local server that watches for file changes and reloads automatically.

Open your browser and navigate to http://localhost:3000. You should see the following output across the top of the page:

Output
🌍 Environment: LOCAL  |  API: http://localhost:3000/api
Enter fullscreen mode Exit fullscreen mode

The dark gray banner confirms that your app is reading NEXT_PUBLIC_APP_ENV and NEXT_PUBLIC_API_URL directly from your .env.local file. Below the banner, the config card will display the same values, showing that no values are hardcoded into the UI; everything comes from configuration.

This is an important distinction. When you deploy this same codebase to App Platform in the next steps and set NEXT_PUBLIC_APP_ENV=staging, the banner will turn yellow and update automatically without a single line of code changing.

The code remains identical across all environments; only the configuration changes.

You have confirmed that your app is environment-aware and working correctly on your local machine.

In the next step, you will commit your project to GitHub so that App Platform can access it for deployment.

Step 8: Committing and Pushing to GitHub

In this step, you will commit your project files to Git and push them to GitHub so that App Platform can access your code for deployment.

Before staging any files, confirm that .env.local is not going to be committed by running:

git status
Enter fullscreen mode Exit fullscreen mode

You should see output similar to the following:

Output
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .env.example
        components/
        app/
Enter fullscreen mode Exit fullscreen mode

.env.example should appear as an untracked file, but .env.local should not appear anywhere in the output. If .env.local is visible, stop and review your .gitignore before continuing.

Committing it would expose your local configuration to anyone who can view the repository on GitHub.

Once you have confirmed everything looks correct, stage all the files:

git add.
Enter fullscreen mode Exit fullscreen mode

Commit the staged files with a descriptive message:

git commit -m "initial Next.js app with env banner."
Enter fullscreen mode Exit fullscreen mode

Then push the commit to GitHub:

git push origin main
Enter fullscreen mode Exit fullscreen mode

This pushes your code to the main branch of your remote repository on GitHub, which is the branch App Platform will connect to for the production environment.

After the push completes, visit your repository on GitHub and confirm that components/EnvBanner.js, app/page.js, and .env.example are all visible in the file list. The .env.localfile should not appear anywhere in the repository.

You have pushed your project to GitHub and confirmed that your secrets are protected.

In the next step, you will connect your repository to DigitalOcean App Platform and deploy your staging environment.

Creating the Staging Environment

Throughout this tutorial, you will use a simple two-branch strategy that maps directly to your two environments:

  • The main branch represents production. Code on this branch is live, and real users can see it. Nothing should reach main without first being tested on staging.

  • The staging branch represents the staging environment. This is where all new work lands first. It is a safe, production-like environment where you can verify that changes behave correctly before they affect real users.

In practice, the workflow looks like this: you build and test a new feature on the staging branch, confirm it works on the staging URL, and then merge it into main to promote it to production.

App Platform watches both branches independently and redeploys the appropriate environment whenever either one receives a push.

To create the staging branch, run the following in your terminal:

git checkout -b staging
git push origin staging
Enter fullscreen mode Exit fullscreen mode

You now have two branches on GitHub: main and staging, and your repository is ready to be connected to App Platform.

In the next step, you will create two separate App Platform apps, one pointing at each branch, and configure them with their own environment variables.

Create Your First App on App Platform

In this section, we will cover how to deploy the Next.js application you just built to DigitalOcean App Platform with separate staging and production environments.

You will connect to a GitHub repository, configure environment variables for each environment, and verify that each deployment reads the correct values.

By the end, you will have a live staging URL displaying the correct environment banner and a clear process you can repeat for production.

Step 1: Accessing App Platform

In this step, you will log in to your DigitalOcean account and navigate to App Platform, the service that hosts, builds, and deploys your Next.js application directly from GitHub.

Open your browser and go to DigitalOcean.

Enter your email and password, then click Log In. Once you are on the control panel dashboard, click App Platform in the left-hand sidebar.

This opens the App Platform section, which lists all your deployed apps. In the top-right corner of the Apps page, click the blue Create App button.

After clicking Create App, you are taken to a multi-step wizard. The first screen, titled Create App, asks you to choose a source for your code.

In the next step, you will connect your GitHub repository, so App Platform knows where to pull your code from.

DigitalOcean App Platform dashboard showing multiple deployment environments and how to create an app

Step 2: Connecting Your GitHub Repository

In this step, you will link DigitalOcean to your GitHub account and grant it access to the multi-env-app repository.

This connection is what allows App Platform to pull your code and trigger automatic deployments whenever you push a new commit.

The Create App wizard opens on the source selection screen. Under Git Provider, click the GitHub tile. A Connect to GitHub button will appear; click it.

Connect and Select Repository on the App Platform

A GitHub OAuth pop-up window will open. Do not close it. Inside the pop-up, click Authorize DigitalOcean to grant DigitalOcean read access to your GitHub repositories.

GitHub will then ask you to choose which repositories to share. Select only the repositories to limit access to just the repository this tutorial needs.

Use the search box to find multi-env-app, select it, then click Install & Authorize.

The pop-up will close automatically, and you will be returned to the DigitalOcean dashboard with your GitHub account now connected.

In the next step, you will select the branch and configure the repository source settings to specify which branch to deploy from.

Configure the repository source

Configure the repository source

With GitHub connected, you will now configure the repository source settings. Under Repository, open the dropdown and select multi-env-app. Under Branch, select staging.

You are setting up the staging environment first, so all deployments from this app will track the staging branch.

Leave Source Directory set to / since your Next.js project lives in the root of the repository.

Check the Autodeploy checkbox to have App Platform rebuild and redeploy automatically whenever you push a commit to the staging branch.

This is what makes your deployment workflow hands-free once the initial setup is complete.

Click Next to continue to the Resources screen.

Step 3: Configure Your App Resources

In this step, you will review the auto-detected configuration for your Next.js application and select a pricing plan before deploying.

When App Platform scans your repository, it identifies the project type and suggests a default build configuration. You will see one detected component with the following defaults:

Name: multi-env-app (or web)
Type: Web Service
Build Command: npm run build
Run Command: npm start

If either command is missing, click Edit on the component. Enter npm run build in the Build Command field, and npm start in the Run Command field, then click Save.

These commands tell App Platform how to compile your Next.js project and start the production server.

Next, you will select a pricing plan for your web service. Click Edit Plan on the right side of the detected Web Service component.

On the plan selection screen, click Basic to select the Basic plan, which costs $5 per month.

Under Instance Size, select the smallest available option: 512 MB RAM / 1 vCPU is sufficient for testing purposes. Click Back to return to the Resources screen.

Once you have confirmed your resource configuration, click Next to continue.You have configured your app's build settings and selected a pricing plan.

In the next step, you will set up your environment variables so that App Platform can pass the correct configuration values to your application at build time and runtime.

Step 4: Setting Environment Variables

In this step, you will configure the environment variables that define your application's staging environment. Because Next.js reads these values at build time and embeds them directly in the browser bundle, setting them correctly here is the most critical part of this setup.

You should now be on the Environment Variables screen. Click Edit next to your web service component name to begin adding variables.

Start by adding the first variable. Click Add Variable, and a row with two input fields and a checkbox will appear. In the Key field, enter the following:

NEXT_PUBLIC_APP_ENV

In the Value field, enter:

staging

Enter fullscreen mode Exit fullscreen mode

Leave the Encrypt checkbox unchecked. Because this variable uses the NEXT_PUBLIC_ prefix, Next.js intentionally exposes it to the browser, so encryption is not necessary here.

Next, click Add Variable again to create a second row. In the Key field, enter the following:

NEXT_PUBLIC_API_URL
Enter fullscreen mode Exit fullscreen mode

In the Value field, enter your staging API endpoint:

https://staging-api.example.com
Enter fullscreen mode Exit fullscreen mode

Leave Encrypt unchecked for this variable as well, then click Save to confirm both variables.You have configured the environment variables that distinguish your staging deployment from production.

In the next step, you will review your settings and deploy the application to App Platform.

Setting Environment Variables

Never encrypt public variables. Any key prefixed with NEXT_PUBLIC_ is embedded in the compiled JavaScript and sent to every browser that loads the page.

Checking "Encrypt" on these variables will cause the build to fail because Next.js cannot access encrypted values at build time.

Reserve encryption only for server-side secrets such as database passwords.

After saving, you should see a confirmation summary showing both variables:

NEXT_PUBLIC_APP_ENV   =  staging
NEXT_PUBLIC_API_URL   =  https://staging-api.example.com

Enter fullscreen mode Exit fullscreen mode

Click "Next" to continue

Step 5: Name Your App and Choose a Region

In this step, you will give your app an identifiable name and select the data center that will host it.

You should now be on the Info screen. Click inside the App Name field, clear the existing value, and enter the following:

multi-env-staging
Enter fullscreen mode Exit fullscreen mode

Name your project Region

Naming your app this way makes it immediately clear which environment you are looking at in the dashboard, particularly once you have both staging and production apps listed side by side.

Next, open the Region dropdown and select the data center closest to your users. For example, choose New York (NYC) on the US East Coast, Amsterdam (AMS) in Europe, or Singapore (SGP) in the Asia-Pacific. Placing your app geographically close to your users reduces latency and improves response times.

Once you have set the name and region, click Next to continue. You have named your staging app and selected a hosting region. In the next step, you will review your complete configuration before deploying the application.

Step 6: Reviewing and Creating Your App

In this step, you will review your complete configuration and deploy your staging application to App Platform.

The final screen is a summary of all the configurations you have made. Read through it carefully and confirm that each of the following values is correct before proceeding:

  • Source: multi-env-app repository, staging branch
  • Autodeploy: Enabled
  • Type: Web Service (Next.js)
  • Plan: Basic, $5/month
  • Environment Variables: NEXT_PUBLIC_APP_ENV=staging and NEXT_PUBLIC_API_URL set
  • App Name: multi-env-staging

If anything looks incorrect, click Back to return to the relevant screen and correct it before proceeding. Once you are satisfied that all values are correct, click Create Resources to deploy your application.

You have reviewed your configuration and triggered your first deployment. In the next step, you will monitor the build process and verify that your staging environment is running correctly.

Step 7: Monitoring the Deployment

In this step, you will watch the build log to confirm that your application deploys successfully through each stage of the pipeline.

After clicking Create Resources, App Platform immediately begins building and deploying your app. A live log will appear on screen as the process runs. You will see the following stages complete in order:

  • Cloning repository: App Platform pulls the code from the staging branch of the multi-env-app repository on GitHub.

  • Installing dependencies: App Platform runs npm install to install all packages listed in package.json.

  • Building: App Platform runs npm run build, which compiles the Next.js application and embeds your environment variables into the output bundle.

  • Uploading artifact: The compiled build is packaged and stored in preparation for deployment.

  • Deploying: The container starts, and your app begins serving traffic.

If any stage fails, App Platform will log the error. Read the error message carefully; most build failures at this stage are caused by a missing environment variable or an incorrect build command.

If that happens, click Settings to review your configuration, make the necessary correction, and then trigger a new deploy by clicking Actions > Force Rebuild and Deploy.

Once all five stages are completed successfully, App Platform will display a green Live badge next to your app name. You have successfully deployed your staging environment to App Platform.

Building the project

A successful deployment produces output similar to the following at the end of the build log:

The initial deployment typically takes 3 to 5 minutes. The app's status indicator changes from "Building" (yellow) to "Deployed" (green) when it is ready.

If the deployment fails, click on the failed deployment to expand the full build log. Scroll to the first line marked ERROR to find the cause. Common causes are a missing dependency in package.json, a TypeScript type error that fails the build, or an incorrectly named environment variable.

Step 8: Test Your Staging Deployment

In this step, you will open your deployed application in a browser and confirm that it is reading the correct environment variables.

Navigate to the Deployments tab in App Platform and copy your live URL, which will look like the following:

https://multi-env-staging-xxxxx.ondigitalocean.app

Live Site Staging

Paste the URL into your browser and press Enter. Once the page loads, look at the top of the screen and confirm the following:

  • A yellow banner reading Environment: STAGING is visible at the top of the page.

  • The API URL displayed on the page matches https://staging-api.example.com.

If the banner is missing or shows a different environment, your NEXT_PUBLIC_APP_ENVvariable was not set correctly. If the API URL is wrong or absent, check the value you entered for NEXT_PUBLIC_API_URL.

In either case, return to Settings > App-Level Environment Variables, correct the value, and click Actions > Force Rebuild and Deploy to redeploy with the updated configuration.

Yellow Banner Staging

Deployment confirmed. If you see the yellow STAGING banner with the correct API URL, your staging environment is live, and your environment variables are being read correctly by the Next.js application.

In the next step, you will set up your production app using the same process with a separate set of values.

Creating the Production Environment

With staging live and verified, you are ready to deploy production. The setup follows the same wizard you used for staging. This section only covers what is different.

Step 1: Create a New App and Connect the Main Branch

From the App Platform dashboard, click "Create App".

Since you already authorized DigitalOcean to access your GitHub account during the staging setup, you will not need to go through the OAuth flow again.

Under "Service Provider", select GitHub and configure the repository source as follows:

  • Repository: multi-env-app

  • Branch: main

  • Autodeploy: Enabled

Leave "Source Directory" set to / and click "Next".

Repository

Step 2: Set Production Environment Variables

On the "Environment Variables" screen, add both variables exactly as shown:

NEXT_PUBLIC_APP_ENV   =  production
NEXT_PUBLIC_API_URL   =  https://api.example.com
Enter fullscreen mode Exit fullscreen mode

Unlike the staging setup,NEXT_PUBLIC_API_URL here points to your real production API endpoint. Leave "Encrypt" unchecked for both variables for the same reasons covered in the staging setup. Click "Save", then "Next".

Step 3: Name Your App and Review

On the "Info" screen, name the app "multi-env-production" and select the same region you used for staging to keep latency consistent across environments.

On the final review screen, confirm the following before clicking "Create Resources":

  • Source: multi-env-app repository, main branch

  • Autodeploy: Enabled

  • Environment variables: NEXT_PUBLIC_APP_ENV=production and NEXT_PUBLIC_API_URL set

  • App name: multi-env-production

Name Production

Step 4: Verify the Production Deployment

Once the status shows "Deployed", copy the live URL from the Deployments tab and open it in your browser. Confirm the following:

Enivironment Building

  • A green banner reading "Environment: PRODUCTION" is visible at the top of the page
  • The API URL displayed matches https://api.example.com

If you see the green banner with the correct API URL, your production environment is live. You now have two fully independent deployments running identical code, each reading its own configuration.

productionready

Frequently Asked Questions

  • Can I use this same multi-environment setup with an existing Next.js project, or does it only work with a freshly scaffolded app?

Yes, you can apply this setup to any existing Next.js project. The core requirements are that your project has a package.json with build and start scripts, and that your environment variables follow the NEXT_PUBLIC_ prefix convention.

Simply create your .env.localand .env.example files, update your .gitignore, and connect your existing repository to App Platform following the same steps covered in this tutorial.

  • What happens if I accidentally commit .env.local to GitHub?

Remove it immediately. Run git rm --cached .env.local to stop tracking the file without deleting it locally, commit that change, and push it to GitHub.

Then, rotate any exposed values treat them as compromised regardless of whether your repository is public or private. After that, verify your .gitignore contains the .env* pattern with the !.env.example exception before continuing.

  • Will the autodeploy trigger for both staging and production every time I push to any branch?

No. Each App Platform app watches only the branch you connected it to. Pushing to staging triggers a rebuild of your staging app only, and pushing to main triggers a rebuild of production only. The two deployments are fully independent and do not affect each other.

  • Can I add more than two environments, such as a QA or preview environment?

Yes. You can create as many App Platform apps as you need, each connected to a different branch with its own environment variables. Simply create a new branch in your repository, spin up a new App Platform app pointed at that branch, and configure the appropriate variable values. The same workflow applies regardless of how many environments you add.

  • Does this setup work with frameworks other than Next.js?

Yes. App Platform supports a wide range of frameworks, including Remix, Astro, SvelteKit, and plain Node.js applications.

The environment variable strategy described in this tutorial, using platform-level variables to configure deployments without changing code, applies to any framework that reads from process.env at build or runtime.

Check the App Platform documentation for framework-specific build and run command requirements.

Conclusion

You have built and deployed a multi-environment Next.js application on DigitalOcean App Platform. You scaffolded a Next.js project, configured environment variables to control application behavior, and built an environment banner that makes your active configuration immediately visible in the browser.

You then connected your GitHub repository to App Platform and deployed two fully independent environments, staging tracking the staging branch and production tracking main, each reading its own set of environment variables from the same codebase.

You now have a repeatable promotion workflow: build and test on the staging branch, verify the changes on your staging URL, and merge into main to ship to production. Autodeploy handles the rest automatically on every push.

From here, you can extend this setup in several directions. As your application grows, you can add additional NEXT_PUBLIC_variables for feature flags, analytics keys, or third-party service endpoints without touching your application code.

For sensitive server-side values like database passwords or private API keys, revisit your App Platform environment variable settings and use the Encrypt option. These values are never embedded in the browser bundle and are safe to protect this way.

If you want to go further, DigitalOcean's App Platform documentation covers custom domains, alerting, and autoscaling for when your application is ready to grow beyond a basic plan.

You can also explore Next.js's environment variable documentation for a deeper understanding of how build-time and runtime variables differ and when to use each.

Resources

For more information about App Platform and web app deployment, you can check out the following tutorials:

This article is part of the DigitalOcean Ripple Writers program. I received compensation and platform credits for writing this content, but all technical assessments, code, and opinions are my own based on hands-on testing.

Top comments (2)

Collapse
 
uzukwu_michael_91a95b823b profile image
Michael Uzukwu

Hi Peace, great job!

Collapse
 
peacesandy profile image
Peace Sandy

Thank You