How to Set Environment Variables in systemd Service Units: A Complete Guide for Linux Developers


3 views

When working with systemd services, environment variables play a crucial role in configuring application behavior. Unlike shell scripts where you can simply use export VAR=value, systemd requires specific configuration approaches.

The simplest approach is to add the Environment directive in your service file:

[Unit]
Description=My Daemon

[Service]
Environment="MY_VAR=some_value"
Environment="ANOTHER_VAR=123"
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

For multiple variables or sensitive data, consider using an environment file:

[Service]
EnvironmentFile=/etc/myapp/env.conf
ExecStart=/bin/myforegroundcmd

Your /etc/myapp/env.conf would contain:

DB_HOST=localhost
DB_PORT=5432
API_KEY=your_secret_key_here

To inherit variables from the system environment:

[Service]
PassEnvironment=DISPLAY PATH DB_HOST
ExecStart=/bin/myforegroundcmd

Multiple Environment Files

You can specify multiple environment files:

[Service]
EnvironmentFile=/etc/myapp/base.conf
EnvironmentFile=/etc/myapp/secrets.conf
ExecStart=/bin/myforegroundcmd

Conditional Variables

Use ExecStartPre for complex variable logic:

[Service]
ExecStartPre=/bin/sh -c 'export DEBUG_LEVEL=$(calculate_debug_level)'
ExecStart=/bin/myforegroundcmd

To check if variables are properly set:

systemctl show myservice.service --property Environment
systemctl show myservice.service --property EnvironmentFile
  • Always reload systemd after changes: systemctl daemon-reload
  • Variables are case-sensitive
  • Whitespace matters in environment files
  • Special characters should be properly escaped

For sensitive data:

[Service]
LoadCredential=db_password:/etc/secrets/db_password
ExecStart=/bin/myforegroundcmd

Access the credential at $CREDENTIALS_DIRECTORY/db_password


When working with systemd services, environment variables play a crucial role in configuring application behavior. Unlike traditional init systems, systemd provides multiple approaches to set environment variables, each with different scopes and use cases.

The simplest way is to specify environment variables directly in the [Service] section of your unit file:

[Service]
Environment="MY_VAR=some_value"
Environment="ANOTHER_VAR=123"
ExecStart=/bin/myforegroundcmd

For multiple variables or when you need to keep configurations separate:

[Service]
EnvironmentFile=/etc/myapp/env.conf
ExecStart=/bin/myforegroundcmd

Where /etc/myapp/env.conf contains:

DB_HOST=localhost
DB_PORT=5432
APP_DEBUG=false

For variables needed across multiple services, consider setting them in /etc/environment or using systemctl set-environment:

# Set temporarily
sudo systemctl set-environment MY_GLOBAL_VAR=value

# Make permanent by adding to:
# /etc/systemd/system.conf
# or /etc/systemd/user.conf
DefaultEnvironment="MY_GLOBAL_VAR=value"

For dynamic environment variables, you can use ExecStartPre to set them before service execution:

[Service]
ExecStartPre=/bin/bash -c 'echo "DYNAMIC_VAR=$(date +%s)" > /tmp/envvars'
EnvironmentFile=/tmp/envvars
ExecStart=/bin/myforegroundcmd

To check what environment variables your service sees:

systemctl show myservice.service --property=Environment
systemctl show myservice.service --property=EnvironmentFile
  • Use EnvironmentFile for production deployments
  • Keep sensitive variables in separate files with proper permissions
  • Remember to reload systemd after changes: systemctl daemon-reload
  • Test variable inheritance with systemd-analyze verify

Common issues include:

# Check service logs for environment-related errors
journalctl -u myservice.service -b

# Verify variable expansion
systemd-escape "your$var"