Linux Administration: Why You Should Avoid Root for Deployments and Use Deployer Instead
Why You Should Avoid Using Root for Deployments
In many server deployments, it’s tempting to SSH as root because you avoid permission issues. But directly using root poses serious security and operational risks:
- Root has full power: If your SSH key or password leaks, an attacker can do anything.
- No accountability: With multiple people or CI/CD systems using the same root account, it’s impossible to track actions.
- Easy to break the system: Small mistakes (like a mistyped command) can break everything instantly.
- Bypasses best practices: Security principles recommend the least privilege possible for each task.
Why Use a Dedicated Deployer User Instead?
Using a dedicated deployer user minimizes these risks:
Limited scope:
Deployer only has the minimal permissions needed for deployments. If compromised, it can’t destroy your entire system.
Use sudo for root-level actions:deployer can still restart services or copy to protected directories using sudo, but only when needed.
Logs and auditing:sudo logs every privileged command, so you know who did what.
Easier to revoke:
If someone leaves the team, you only remove their deployer access—not full root access.
🛠️ Setting Up a Deployer User with Root Privileges
Let’s assume you’re logged in as root:
Create the deployer user:
adduser deployer
Add deployer to the sudo group:
usermod -aG sudo deployer
Allow passwordless sudo for seamless deployments (edit with visudo):
visudo
Add this line:
deployer ALL=(ALL) NOPASSWD:ALL
Now deployer can run any sudo command without a password.
🔐 Configure SSH Access
On your local machine, generate an SSH key if needed:
ssh-keygen -t ed25519 -C "deployer key"
Copy your public key to the server:
ssh-copy-id deployer@your.server.ip
or manually add it to:
/home/deployer/.ssh/authorized_keys
Using deployer Like Root
Now, instead of SSHing as root:
ssh root@server
You connect as deployer:
ssh deployer@server
For privileged commands (like installing packages or restarting services):
sudo apt update
sudo systemctl reload nginx
No password needed because of the NOPASSWD config.
Example: Transition from Root-based to Deployer-based Deployment
Here’s a sample CI/CD script for root:
ssh root@server <<'EOF'
cd /var/www/myapp
git pull origin main
npm ci
npm run build
systemctl reload nginx
EOF
Updated script for deployer:
ssh deployer@server <<'EOF'
cd ~/myapp
git pull origin main
npm ci
npm run build
sudo cp -r build/* /var/www/myapp/
sudo systemctl reload nginx
EOF
Key Points in the Updated Flow:
SSH as deployer, not root.
Use sudo only for tasks that truly require it (like copying to /var/www or reloading nginx).
All logs show deployer as the actor, improving auditability.
Final Thoughts
Security: Using deployer limits potential damage if credentials leak.
Best practice: Principle of Least Privilege—use the smallest set of permissions needed.
Scalable: Works smoothly with CI/CD tools like GitHub Actions, Jenkins, or GitLab CI.
Sample SSH Deployment Flow in GitHub Actions
- name: Deploy to production
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.VPS_IP }}
username: deployer
key: ${{ secrets.DEPLOYER_SSH_KEY }}
script: |
cd ~/myapp
git pull origin main
npm ci
npm run build
sudo cp -r build/* /var/www/myapp/
sudo systemctl reload nginx
Summary of Commands to Transition from Root to Deployer:
Create deployer:
adduser deployer
usermod -aG sudo deployer
Allow passwordless sudo (visudo):
deployer ALL=(ALL) NOPASSWD:ALL
Copy your SSH key to deployer.
SSH as deployer, use sudo for privileged tasks only.
Done! You’re now following best practices for secure deployments.