Sunday, July 20, 2025

Reusing the same Next.js Docker image with runtime CDN assetPrefix

Recently, while investigating a production issue, I needed to deploy the production Docker image locally for debugging purposes. However, I encountered a significant architectural constraint that highlighted a fundamental deployment challenge requiring both architectural and DevOps expertise to resolve.

The Challenge: CDN Configuration

Next.js provides assetPrefix configuration to specify CDN or custom domains for static asset delivery, enabling faster content delivery through geographically distributed networks. However, this configuration presents a critical architectural constraint: it's a build-time setting that gets permanently embedded into static pages and CSS assets.

This limitation creates substantial operational challenges when reusing a Docker image:

  • Multiple Environments: Different environments like QA, stage, and production use different CDN domains.
  • Regional CDNs: Production environments could use different regional CDN domains.

The traditional approach would require building separate Docker images for each environment, violating the fundamental DevOps principle of "build once, deploy anywhere."

Architectural Solution: Runtime Asset Prefix Injection

Through careful analysis of Next.js's asset handling mechanisms and strategic use of text replacement techniques, I developed a solution that maintains build-time optimization while enabling runtime CDN configuration.

Configuration Architecture

The solution begins with environment-aware configuration that handles both basePath and assetPrefix dynamically:

Docker Build Strategy

During the Docker image creation process, we set placeholder values that will be replaced at runtime, along with a custom entrypoint script:

Runtime Replacement Logic

The entrypoint script performs intelligent text replacement, substituting placeholder values with environment-specific configurations at container startup:

Addressing Image Security Constraints

During implementation, I encountered an additional architectural challenge: Next.js image optimization returns cryptic 404 errors when serving images from CDN domains. Investigation into the Next.js source code revealed this is a security feature that only allows pre-approved domains for image serving.

The error message "url parameter is not allowed" provides insufficient context for troubleshooting, but the root cause is Next.js's domain whitelist mechanism. This requires configuring images.remotePatterns to explicitly allow CDN domains.

Advanced Runtime Configuration

The most sophisticated aspect of this solution involves dynamically updating the remotePatterns configuration at runtime. Since we're performing text replacements on configuration files, I leveraged Node.js's command-line execution capabilities to add intelligent remotePatterns generation for CDN domain whitelisting.

This approach ensures that:

  • Security policies remain enforced through domain whitelisting
  • Runtime flexibility is maintained for multi-environment deployments
  • Performance optimization continues through proper CDN utilization
  • Operational efficiency is achieved through single-image deployment

Key Architectural Benefits

This solution delivers several critical advantages:

  • Single Image Deployment: One Docker image serves all environments, reducing build complexity and storage requirements
  • Runtime Flexibility: CDN configurations adapt to deployment context without rebuild cycles
  • Performance Preservation: Static page optimization remains intact while enabling dynamic asset serving
  • Security Compliance: Domain whitelisting ensures controlled image processing
  • Operational Simplicity: Environment-specific configurations are managed through standard environment variables

Implementation Considerations

When implementing this approach, consider these architectural factors:

  • Text replacement scope: Ensure replacements target only intended configuration values
  • Environment variable validation: Implement proper fallbacks for missing or invalid CDN configurations
  • Security boundaries: Maintain strict domain whitelisting for image processing
  • Performance monitoring: Verify that runtime replacements don't impact application startup time

Conclusion

With some architectural creativity, we can resolve platform limitations while maintaining operational best practices. By combining Next.js's build-time optimizations with runtime configuration flexibility, we achieve the ideal balance of performance and deployment efficiency.

The approach enables teams to leverage CDN benefits across multiple environments while adhering to containerization principles, ultimately delivering both technical excellence and operational simplicity. For organizations deploying Next.js applications across diverse environments, this pattern provides a production-ready solution that scales with architectural complexity while maintaining deployment consistency.

No comments:

Reusing the same Next.js Docker image with runtime CDN assetPrefix

Recently, while investigating a production issue, I needed to deploy the production Docker image locally for debugging purposes. However, I ...