Environment Variables in systemd Services

Master environment variable configuration in systemd unit files. Compare inline Environment= vs EnvironmentFile=, learn variable precedence, and best practices for secrets management.

Operational Guides

Detailed Explanation

Configuring Services with Environment Variables

Environment variables are the standard way to configure Linux services. Systemd provides two directives for setting them: Environment= for inline values and EnvironmentFile= for loading from a file.

Inline Variables with Environment=

[Service]
Environment="NODE_ENV=production"
Environment="PORT=3000"
Environment="DB_HOST=localhost"
Environment="DB_PORT=5432"

Each Environment= line sets one or more variables. The value must be quoted if it contains spaces. Multiple variables can be set on one line:

Environment="NODE_ENV=production" "PORT=3000"

Loading from Files with EnvironmentFile=

For many variables or sensitive values, use a file:

[Service]
EnvironmentFile=/etc/myapp/env
EnvironmentFile=-/etc/myapp/env.local

The file format is simple KEY=VALUE, one per line:

# /etc/myapp/env
NODE_ENV=production
PORT=3000
DB_HOST=localhost
DB_PASSWORD=secretvalue

The - prefix makes the file optional — the service still starts if the file doesn't exist.

Variable Precedence

When the same variable is defined in multiple places:

  1. Environment= in the unit file (highest priority)
  2. EnvironmentFile= (later files override earlier ones)
  3. System environment inherited from PID 1

Security Considerations

Inline Environment= values are visible to anyone who can read the unit file or run systemctl show:

systemctl show myapp.service -p Environment
# Environment=NODE_ENV=production DB_PASSWORD=secret123

EnvironmentFile= values are NOT exposed through systemctl show. This makes it the preferred method for secrets:

# Set restrictive permissions on the env file
chmod 600 /etc/myapp/env
chown root:root /etc/myapp/env

Dynamic Environment

For values that change at runtime, use a generator script:

[Service]
ExecStartPre=/opt/scripts/generate-env.sh
EnvironmentFile=/run/myapp/dynamic.env
ExecStart=/usr/local/bin/myapp

The ExecStartPre= script generates the environment file before the main process starts.

Template Variables

Systemd provides built-in specifiers that can be used in unit files:

Specifier Meaning
%n Full unit name
%i Instance name (for template units)
%H Hostname
%t Runtime directory (/run)
%S State directory (/var/lib)
Environment="HOSTNAME=%H"
Environment="SERVICE_NAME=%n"

Use Case

Managing configuration for a service that needs both public settings (port, log level) and secrets (database passwords, API keys) with proper security isolation between them.

Try It — Systemd Unit File Generator

Open full tool