Run an application

Create a service and reverse proxy

Run the application with systemd and let Nginx handle public HTTP and HTTPS while forwarding to the private local port.

8 minute lesson

~~~

Systemd should own the application process. It starts the app after boot, records output in the journal, applies the service user, and restarts unexpected failures.

Create /etc/systemd/system/notes-app.service:

[Unit]
Description=Notes application
After=network.target

[Service]
Type=simple
User=notes-app
Group=notes-app
WorkingDirectory=/srv/notes-app/current
EnvironmentFile=/etc/notes-app.env
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s

[Install]
WantedBy=multi-user.target

Use the real absolute runtime path from command -v node and the application’s real entry file. A service does not inherit your interactive shell setup.

Validate, load, and start it:

sudo systemd-analyze verify /etc/systemd/system/notes-app.service
sudo systemctl daemon-reload
sudo systemctl enable --now notes-app
sudo systemctl status notes-app --no-pager
sudo journalctl -u notes-app -n 50 --no-pager
curl --fail http://127.0.0.1:3000/health

The unit should be enabled and active. The local health request must succeed before Nginx is involved.

Now replace the static location / in the Nginx server block:

location / {
  proxy_pass http://127.0.0.1:3000;
  proxy_http_version 1.1;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
}

Validate and reload:

sudo nginx -t
sudo systemctl reload nginx
curl -I https://notes.example.com

A 502 Bad Gateway means Nginx could not get a usable response from the upstream. Check systemctl status notes-app, the journal, ss -lntp, and the configured port. Do not open port 3000 in UFW as a workaround.

For a code rollback, point /srv/notes-app/current at the previous tested release and restart notes-app. For a unit or Nginx rollback, restore the last working file, validate it, then reload or restart.

Your action is to reboot the Droplet during a safe learning window. After reconnecting, verify the service is active and the public HTTPS health endpoint still works.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →