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"