Services (.service)

Pass environment variables to a systemd service

3 min · updated June 15, 2026

Apps configured by environment variables (12-factor style) read them from the service’s environment. systemd gives you two ways to set it.

Inline, in the unit

[Service]
Environment=NODE_ENV=production
Environment=PORT=8080 LOG_LEVEL=info
ExecStart=/opt/app/server

Multiple Environment= lines accumulate; you can also put several KEY=value pairs on one line.

From a file (keep secrets out of the unit)

[Service]
EnvironmentFile=/etc/myapp/env
ExecStart=/opt/app/server

/etc/myapp/env is plain KEY=value lines (no export, no shell):

DATABASE_URL=postgres://app:s3cret@db.internal/app
API_TOKEN=abcdef123456
PORT=8080

Lock it down so only root (and the service user) can read the secrets:

sudo chmod 600 /etc/myapp/env
sudo chown root:myapp /etc/myapp/env   # if the service runs as myapp, use 640

Prefix the path with - (EnvironmentFile=-/etc/myapp/env) to make a missing file non-fatal.

Apply and confirm

sudo systemctl daemon-reload
sudo systemctl restart myapp.service
# Dump the exact environment systemd will give the unit:
systemctl show myapp.service -p Environment

Gotchas: values in EnvironmentFile are not shell-expanded — FOO=$BAR is the literal string $BAR. Quotes are mostly passed through literally too, so avoid wrapping values in quotes unless your app expects them. For real secrets, prefer LoadCredential=/systemd-creds over env files, since environment variables are visible in /proc/<pid>/environ.

← All recipes