Linux systemd Basics

By Vishvesh Patel · DevOps EngineerUpdated September 16, 2026

Manage services with systemd. Start vs enable, daemon-reload after every edit, writing a unit file, what Type= controls, and journalctl.

What Is systemd?

systemd is the init system and service manager used by many modern Linux distributions. It is responsible for booting the system, starting services, tracking their state, and managing logs and dependencies.

If you run a server with Nginx, Docker, SSH, or a custom app, systemd often controls whether that service starts at boot and how it behaves.

Understanding Units and Targets

systemd manages objects called units. A unit describes something systemd knows how to manage.

Common unit types include:

  • .service for services
  • .socket for socket activation
  • .mount for mount points
  • .timer for scheduled tasks
  • .target for grouped system states

A target is roughly like a collection of units that represents a system state, such as multi-user mode.

Managing Services with systemctl

systemctl is the main command for working with systemd.

Start a service:

sudo systemctl start nginx

Stop a service:

sudo systemctl stop nginx

Restart a service:

sudo systemctl restart nginx

Check status:

systemctl status nginx

This shows whether the service is active, recent log lines, and the main process ID.

Enabling and Disabling at Boot

A service can be running now without being configured to start at boot.

Enable at boot:

sudo systemctl enable nginx

Disable at boot:

sudo systemctl disable nginx

A common beginner mistake is assuming start and enable mean the same thing. They do not.

  • start affects the current session
  • enable affects future boots

Tip: Many deployment issues happen because a service was started manually but never enabled.

Reading Logs with journalctl

systemd integrates with the system journal, which you can query using journalctl.

Show recent logs:

journalctl

Follow logs in real time:

journalctl -f

View logs for a specific unit:

journalctl -u nginx
journalctl -u sshd -f

Filter by time:

journalctl --since "2026-07-14 09:00:00"
journalctl -u nginx --since "1 hour ago"

This is incredibly useful for diagnosing why a service failed to start.

Writing a Simple Unit File

You can manage your own applications with systemd by creating a unit file.

Example:

[Unit]
Description=Demo Application Service
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/demo-app
ExecStart=/usr/bin/python3 /opt/demo-app/app.py
Restart=on-failure
User=demo
Group=demo

[Install]
WantedBy=multi-user.target

Save it as:

/etc/systemd/system/demo-app.service

Then reload systemd and start the service:

sudo systemctl daemon-reload
sudo systemctl start demo-app
sudo systemctl enable demo-app

Understanding Key Unit Sections

[Unit]

This section describes metadata and dependencies.

[Service]

This section defines how the service starts, under which user, in which directory, and what should happen if it fails.

[Install]

This section describes how the unit is tied into targets when enabled.

Practical Troubleshooting Flow

Suppose your service will not start after deployment.

A useful workflow is:

systemctl status demo-app
journalctl -u demo-app --since "10 minutes ago"

Typical causes include:

  • wrong ExecStart path
  • missing working directory
  • permission problems
  • missing environment variables
  • app crashes during startup

systemd gives you a repeatable place to inspect that behavior.

Test Your Understanding

Exercise 1: Start versus enable

Question: What is the difference between systemctl start nginx and systemctl enable nginx?

Exercise

Exercise 1: Start versus enable

Identify which action affects the current runtime and which affects future boots.

Exercise 2: Filtering the journal

Scenario: A custom app service fails after deployment, and you want only its journal entries from the last 10 minutes.

Question: Which command from the lesson is the best match?

Exercise

Exercise 2: Filtering the journal

Choose the journalctl command that narrows logs to one unit and a recent time window.

Exercise 3: Making systemd notice changes

Question: Why do you run systemctl daemon-reload after creating or editing a unit file in /etc/systemd/system?

Exercise

Exercise 3: Making systemd notice changes

Pick the reason daemon-reload is necessary after unit file changes.


Key takeaways

  • start is now, enable is at boot. They are independent, and forgetting enable is the classic mistake.
  • systemctl enable --now <unit> does both in one command.
  • Edit a unit, then systemctl daemon-reload, or systemd keeps running the old definition.
  • Type= must match how your process behaves. simple for a foreground process, notify for one that signals readiness.
  • journalctl -u <unit> -f is the first command to run when a service misbehaves.
  • Use systemctl edit <unit> for overrides so a package upgrade does not overwrite your changes.
  • Restart=on-failure plus RestartSec turns a crash into a blip instead of an outage.

Frequently Asked Questions

What is the difference between systemctl start and systemctl enable?

start runs the service right now and does nothing about future boots. enable creates the symlink that makes systemd start it at boot and does nothing right now. They are genuinely independent, which is why a service can be running yet absent after a reboot, or configured to boot yet not currently up. systemctl enable --now <unit> does both, and systemctl is-enabled <unit> tells you which state you are actually in.

Why doesn't my unit file change take effect?

systemd caches unit definitions, so it keeps using the old one until you run sudo systemctl daemon-reload. After that, systemctl restart <unit> picks up the new configuration. If a change still seems ignored, check you edited the file systemd is actually reading, systemctl cat <unit> prints the effective definition including any drop-in overrides, which is the quickest way to spot that your edit is being overridden by something in /etc/systemd/system/<unit>.d/.

How do I write a simple systemd service?

Create /etc/systemd/system/myapp.service with three sections: [Unit] for the description and ordering (After=network.target), [Service] for ExecStart, User, WorkingDirectory and Restart=on-failure, and [Install] with WantedBy=multi-user.target so enable knows where to link it. Then daemon-reload and enable --now. Use an absolute path in ExecStart, systemd does not consult your PATH, and remember the service runs as root unless you set User=.

What does Type= mean in a systemd unit?

It tells systemd how to know the service has started. Type=simple assumes readiness the moment the process is forked, which suits anything that stays in the foreground. Type=forking is for daemons that background themselves, and needs PIDFile=. Type=notify waits for the process to signal readiness via sd_notify, which is the most accurate and what dependent units should rely on. Type=oneshot is for a task that runs and exits, often with RemainAfterExit=yes. A mismatch here is why dependencies start too early.

How do I read logs for a single service?

journalctl -u myapp shows that unit's log, -f follows it live, and -n 50 limits it to the last 50 lines. --since "10 minutes ago" narrows by time and -p err by priority. Add -b for the current boot only, or -b -1 for the previous one, which is how you find out why the machine went down. By default the journal may be volatile and lost on reboot. Set Storage=persistent in /etc/systemd/journald.conf if you need history to survive.

How do I override a unit file that came from a package?

sudo systemctl edit <unit> creates a drop-in at /etc/systemd/system/<unit>.d/override.conf containing only your changes, which a package upgrade will not touch. Editing the shipped file under /lib/systemd/system/ risks losing your work on the next update. One quirk worth knowing: to replace a directive that takes a list, such as ExecStart, you must first clear it with an empty assignment (ExecStart=) and then set the new value, or systemd appends rather than replaces.

Continue Learning

Explore Related Topics

Try the Tool

Practise this in the browser

Linux Playground

Practise real shell commands in a simulated terminal.

When it breaks

Related Resources