VPS DeploymentBeginner 11 min Lesson 6 of 30

Creating a Deploy User

Set up a personal sudo account and a dedicated application account, and stop doing everything as root.

VPS Deployment · Lesson 6 of 30
0/30 done(0%)

What is it? #

Working as root means every command runs with unlimited power, every mistake is unrecoverable, and every log line says "root" rather than who actually did it.

The standard arrangement has two kinds of account. A personal account with sudo, for administration. A service account with no login shell, for running the application.

This is the second thing you do on a new server, after connecting. Everything afterwards happens as the non-root user.

The setup takes two minutes and removes an entire category of future problems.

Think of it like this #

A workshop where the master key opens everything, including the chemical store and the fuse box.

Most work needs neither. Carrying a normal key and fetching the master one when genuinely required means a distracted moment cannot destroy something important.

Simple example #

You create deploy for yourself with sudo and your SSH key, and appuser with no shell to run the application. Root login is then disabled entirely.

Code #

BASH
# As root, on the new server

# 1. Your personal administration account
adduser deploy                        # prompts for a password (used for sudo)
usermod -aG sudo deploy               # Debian/Ubuntu. On RHEL: -aG wheel

# 2. Give it your SSH key
mkdir -p /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/    # reuse the key you connected with
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

# 3. The application service account — no login, no password
useradd --system --home-dir /srv/app --shell /usr/sbin/nologin appuser
mkdir -p /srv/app
chown -R appuser:appuser /srv/app
BASH
# 4. Test the new account from a NEW terminal, keeping this one open
ssh [email protected]
sudo whoami                 # should print: root
BASH
# 5. Only after that works, disable root login
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sudo sshd -t && sudo systemctl reload sshd
TEXT
Who should own what

/srv/app              appuser:appuser     the application code and data
/srv/app/.env         appuser:appuser 600 secrets, readable only by the app
/etc/nginx/*          root                system configuration
/var/log/myapp        appuser:appuser     the app writes its own logs

deploy runs deployments with sudo where needed; the application itself
never runs as root and never needs a password.
TEXT
Optional: passwordless sudo for a deployment account

/etc/sudoers.d/deploy-restart
  deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp, /bin/systemctl reload nginx

Edit with: sudo visudo -f /etc/sudoers.d/deploy-restart
visudo validates the syntax — a broken sudoers file locks out sudo entirely.
Grant specific commands, not blanket NOPASSWD.

How it works #

adduser creates the account, home directory and matching group, and prompts for a password. That password is used for sudo, not for SSH login, since password authentication will be disabled.

Copying authorized_keys from root gives the new account the key you are already using, so you can log in immediately without generating anything new.

The permissions on .ssh matter: 700 on the directory and 600 on the file, or SSH refuses the key with a generic permission denied.

The service account uses --system and nologin. It exists to own files and run a process, not to be logged into, and there is no password to guess.

Testing from a second terminal before disabling root is the step that prevents lockouts. If something is wrong with the new account, the original session is still open to fix it.

The sudoers snippet allows a deployment script to restart the service without an interactive password, restricted to specific commands. visudo validates the file before saving, which matters because a syntax error in sudoers can remove your ability to use sudo at all.

Real-world use #

Every professional server setup separates administration accounts from service accounts. It is a five-minute task that appears in every hardening checklist for good reason.

Automated deployments use a dedicated account with a dedicated key, so access can be revoked without affecting people.

Shared logins destroy accountability. When several people use one account, the audit trail tells you nothing about who restarted the service at 2am.

Running the application as a non-root user is what limits the damage of an application vulnerability. A compromised process that cannot write outside its own directory is a contained incident.

When someone leaves the team, removing their account and their key is a single, obvious action — which is only true if accounts are personal in the first place.

Common mistakes #

  • Continuing to do everything as root because it is fewer keystrokes.
  • Disabling root login before testing the new account from a separate session.
  • Wrong permissions on ~/.ssh, causing a confusing authentication failure.
  • Giving the service account a real login shell it does not need.
  • Blanket passwordless sudo instead of specific allowed commands.

Practice #

On a fresh server, create a personal sudo account with your SSH key and a service account with no login shell. Verify the new account works from a separate terminal, then disable root login. Finally, add a sudoers rule permitting only the service restart command.

Quick quiz

  1. 1. Why create a personal account instead of using root?

  2. 2. What should you do before disabling root login?

  3. 3. Why does the application account use nologin?

  4. 4. What permissions does ~/.ssh need?

  5. 5. Why use visudo to edit sudoers files?

Summary

  • Use a personal sudo account for administration and a service account for the app.
  • Copy your SSH key to the new account and fix the permissions.
  • Test the new account from a second session before disabling root.
  • The application account needs no shell and no password.
  • Grant specific passwordless sudo commands, never blanket access.