Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automating Environment Configuration Selection Based on ServerEnvironment Enum #249

Open
rsaz opened this issue Apr 3, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@rsaz
Copy link
Member

rsaz commented Apr 3, 2024

Description

We aim to enhance the current system for managing environment configurations in our application by automatically selecting the appropriate .env file (env.prod for production or env.local for local development) based on a ServerEnvironment enum. This will streamline the setup process for different environments, reducing manual intervention and potential human error. Additionally, we seek suggestions for modernizing our approach to environment configuration management, ensuring our system is robust, flexible, and easy to maintain.

Current Approach

The application currently loads .env.local explicitly within the EnvironmentProvider class, without considering the environment context (Production, Development, etc.) dynamically. Here is the simplified current implementation:

async function bootstrap() {
    const app = await AppFactory.create(container, App);
    await app.listen(3000, ServerEnvironment.Production);
}

@provide(EnvironmentProvider)
export class EnvironmentProvider {
    async load(): Promise<void> {
        try {
            const fs = import("fs");
            const configPath = ".env.local";
            if ((await fs).existsSync(configPath)) {
                const local = (await import("dotenv")).config({
                    path: configPath,
                });
                process.env = {
                    ...process.env,
                    ...local.parsed,
                };
            }
        } catch {}
    }
}

Objective

Automate .env File Selection: Based on the ServerEnvironment enum passed during the application bootstrap process, automatically determine and load the corresponding .env file (env.prod or env.local).
Modernize Configuration Management: Explore and suggest modern approaches or tools that could offer a more flexible, secure, and maintainable way to manage environment configurations.

Requirements

Dynamic Environment Configuration
Implement logic to dynamically select the .env file based on the ServerEnvironment enum.
Ensure seamless transition between environments without manual file swapping or code changes.

Error Handling and Logging
Improve error handling around environment file loading to ensure clarity and traceability of issues.
Enhance logging to provide clear feedback on which environment configuration is loaded.
Exploration of Modern Tools and Practices:

Research and suggest modern tools or libraries that could improve environment configuration management (e.g., support for .env file encryption, advanced parsing capabilities).
Consider adopting a library or framework that natively supports different environment configurations without manual intervention.

Examples

// Assuming ServerEnvironment is accessible and used to determine the environment
const environmentConfig = {
    [ServerEnvironment.Production]: '.env.prod',
    [ServerEnvironment.Development]: '.env.local',
    // Add other environments as needed
};

const configPath = environmentConfig[process.env.NODE_ENV] || '.env.local'; // Default to local

// Load the appropriate .env file based on the current environment
const dotenv = require('dotenv');
dotenv.config({ path: configPath });

Modern Approaches

Centralized Configuration Service
For applications running in microservices or requiring dynamic configuration across multiple environments, consider using a centralized configuration service like Spring Cloud Config, Consul, or etcd. These tools can serve environment-specific configurations at runtime, reducing the need for local .env files and enabling real-time configuration changes without redeployment.

Environment Variables Management Tools
Tools like HashiCorp Vault or AWS Secrets Manager offer more secure ways to manage environment variables, especially secrets. They provide encryption, access control, and audit logs, which are particularly useful for production environments.

Containers and Orchestration
If your application runs in containers, consider using Docker or Kubernetes for environment configuration. Both allow you to manage environment variables securely and flexibly through container orchestration, supporting different environments without changing the codebase.

For Docker, you might use docker-compose with environment-specific override files (docker-compose.prod.yml, docker-compose.dev.yml) to define and manage environment variables.

Utilize Modern Frameworks or Libraries
Some newer frameworks or libraries are designed with environment management in mind. For example, Next.js (for React applications) automatically loads .env.local or .env.[environment] files based on the NODE_ENV value, without additional setup. Exploring such options can provide out-of-the-box solutions for environment configuration management.

Suggestions

Take in consideration of the new built-in .env file in node v21
https://nodejs.org/en/blog/release/v20.6.0

Also, look at how .net core applications deals with multiple environment.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-8.0

@juliano-soares juliano-soares self-assigned this Apr 4, 2024
@rsaz rsaz added the enhancement New feature or request label Apr 4, 2024
@rsaz
Copy link
Member Author

rsaz commented Apr 8, 2024

@juliano-soares link to a project example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: 💻 In Development
Development

When branches are created from issues, their pull requests are automatically linked.

2 participants