How to Manage Environment Variables and Secrets on a VPS

Hardcoding database passwords, API keys, and other secrets directly into application code is a common and serious security mistake. This guide covers proper environment variable management across different deployment approaches.

Why This Matters

  • Hardcoded secrets end up in version control history, even if later removed
  • Different environments (development, staging, production) need different values
  • Separating configuration from code follows standard software deployment practices

Method 1 — .env Files (Most Common for PHP/Node.js/Python Apps)

nano .env
DB_HOST=localhost
DB_PASSWORD=change_me_strong_password
API_KEY=your_api_key_here

Always exclude it from version control:

echo ".env" >> .gitignore

Commit a .env.example with variable names but no real values, so team members know what's required.

Method 2 — System Environment Variables via systemd

For applications run as a systemd service, set variables directly in the unit file:

[Service]
Environment="DB_PASSWORD=change_me"
Environment="API_KEY=your_key"
ExecStart=/usr/bin/node /opt/myapp/index.js

Or reference a separate environment file:

EnvironmentFile=/etc/myapp/myapp.env
ExecStart=/usr/bin/node /opt/myapp/index.js
sudo chmod 600 /etc/myapp/myapp.env

Method 3 — Shell Profile (Not Recommended for Secrets)

Setting variables in ~/.bashrc works for non-sensitive configuration but isn't ideal for secrets, since it's tied to a specific user session rather than the specific service.

Method 4 — Docker/Docker Compose

See Docker Compose .env Files and Environment Variables Explained for the full Docker-specific approach.

Reading Environment Variables in Code

PHP:

$dbPassword = getenv('DB_PASSWORD');

Node.js:

const dbPassword = process.env.DB_PASSWORD;

Python:

import os
db_password = os.environ.get('DB_PASSWORD')

Setting Correct File Permissions on Secret Files

chmod 600 .env
chown deploy:deploy .env

Only the application's own user should be able to read it — never world-readable.

Rotating Secrets

When rotating a compromised or routinely-expiring secret:

  1. Generate the new credential at the source (database, API provider)
  2. Update the .env file or systemd environment configuration
  3. Restart the application to pick up the new value
  4. Revoke the old credential once confirmed working

Common Errors

Variable shows as undefined in the application — confirm the application actually loads the .env file (most frameworks require a library like dotenv for PHP/Node.js), and that the app was restarted after any change.

Secrets accidentally committed to Git — beyond removing the file going forward, the credential should be treated as compromised and rotated immediately, since Git history retains it even after deletion.

Best Practices

  • Never commit real secret values to version control, ever
  • Set restrictive file permissions (600) on any file containing secrets
  • Use different credentials per environment (development, staging, production)
  • Rotate secrets immediately if accidentally exposed

Related Articles

  • Docker Compose .env Files and Environment Variables Explained
  • How to Manage Services with systemd and systemctl
  • VPS Security Checklist for Beginners
  • environment variables, secrets management, dotenv, application security
  • 0 用戶發現這個有用
這篇文章有幫助嗎?

相關文章

How to Install PHP on Ubuntu & Debian (Complete Guide)

PHP powers a huge share of the web, including WordPress, Laravel, and Magento. This guide covers...

How to Install Node.js on Ubuntu & Debian (with NVM)

Node.js is a fast JavaScript runtime for building APIs, web applications, and backend services....

How to Install Python on Ubuntu & Debian

Python powers web frameworks like Django and Flask, automation scripts, and data applications....

How to Install Java (OpenJDK) on Ubuntu & Debian

Java powers enterprise applications, build tools like Maven and Gradle, and platforms like...

How to Install Composer for PHP Dependency Management

Composer is PHP's standard dependency manager, used by virtually every modern PHP framework...