DEV Community

Cover image for Overcoming NEXT_PUBLIC_ Environment Variable Limitations in Next.js with Docker
Ajay
Ajay

Posted on

Overcoming NEXT_PUBLIC_ Environment Variable Limitations in Next.js with Docker

When deploying a Next.js application in a Docker container, managing environment variables can be a real challenge β€” especially when it comes to client-side variables prefixed with NEXT_PUBLIC_. This is crucial for services like Google reCAPTCHA and analytics tools like PostHog, which require these variables at runtime.

The Issue: NEXT_PUBLIC_ Environment Variables and Docker

Imagine you've successfully built your Next.js app locally, only to run into a wall when you try to deploy it in a Docker container. The problem arises because NEXT_PUBLIC_ environment variables must be defined at build time. When you run the next build command, Next.js inlines these values into the generated JavaScript, making them inaccessible at runtime.

In a typical setup where the same Docker image is used across multiple environments (dev, staging, production), this means you would need to create separate images for each environment just to accommodate different values for NEXT_PUBLIC_. This approach leads to:

  • Increased complexity in your CI/CD pipeline.
  • Longer deployment times.
  • A higher chance of introducing errors with each build.

For example, I encountered significant challenges when integrating PostHog for analytics, as I needed to provide the NEXT_PUBLIC_POSTHOG_KEY in different environments without rebuilding the Docker image. Similarly, handling Google reCAPTCHA keys posed a similar issue.

The Solution: Dynamic Environment Variables with next-runtime-env

Fortunately, there's a way to avoid these headaches: using the next-runtime-env package. This package allows you to inject environment variables into your Next.js application at runtime, enabling you to build your Docker image once and deploy it across different environments without needing to rebuild.

How to Get Started

  1. Install next-runtime-env: Add the package to your project:
   npm install next-runtime-env
Enter fullscreen mode Exit fullscreen mode
  1. Update Your Layout: In your app/layout.tsx, include the PublicEnvScript component to expose your NEXT_PUBLIC_ variables:
// app/layout.tsx
import { PublicEnvScript } from 'next-runtime-env';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <PublicEnvScript />
      </head>
      <body>
        {children}
      </body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode
  1. Access Your Variables: Now you can access your environment variables within your components:
// app/client-page.tsx
'use client';
import { env } from 'next-runtime-env';
import posthog from 'posthog-js';
import { PostHogProvider } from 'posthog-js/react';
import React from 'react';

if (typeof window !== "undefined") {
  posthog.init(env("NEXT_PUBLIC_POSTHOG_KEY") || "", {
    api_host: "/ingest",
    ui_host: "https://us.posthog.com",
    person_profiles: "always",
  });
}

export function CSPostHogProvider({ children }: { children: React.ReactNode }) {
  return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
}
Enter fullscreen mode Exit fullscreen mode

Benefits of This Approach

  • One Image, Many Environments: With next-runtime-env, you can use a single Docker image across different environments, significantly simplifying your deployment strategy.

  • Faster Deployments: Since you're not rebuilding images, your deployments are quicker and less prone to errors.

  • Easier Maintenance: You'll spend less time managing multiple builds, allowing you to focus on developing new features.

Conclusion

If you've ever faced the challenge of managing NEXT_PUBLIC_,environment variables in a Dockerized Next.js application, you know how frustrating it can be. By leveraging next-runtime-env, you can manage these variables dynamically at runtime, ensuring a smooth and efficient deployment process.

This solution keeps your Docker strategy simple, maintainable, and effective across all your environments β€” whether you're handling analytics tools like PostHog or integrating Google reCAPTCHA.

May your code be bug-free!

Top comments (0)