Linux Server Essentials: What Every Developer Should Know (2026)
You deployed your app to a server. Now what? Here's the practical knowledge every developer needs for server management.
SSH: Your Remote Control
# Basic connection
ssh user@192.168.1.100
# Key-based authentication (no passwords!)
# Generate key pair:
ssh-keygen -t ed25519 -C "your@email.com"
# Copy to server:
ssh-copy-id user@server-ip
# Now you can login without password!
# Config file (~/.ssh/config) — Save time with aliases:
Host myserver
HostName 192.168.1.100
User ubuntu
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60 # Keep connection alive
ServerAliveCountMax 3
# Now just: ssh myserver
# Port forwarding (access remote services locally):
# Local port forward: Access remote localhost:3000 via local localhost:8080
ssh -L 8080:localhost:3000 myserver
# Remote port forward: Share your local service to the server
ssh -R 3000:localhost:8080 myserver
# SOCKS proxy (route all traffic through server):
ssh -D 1080 myserver
# Then configure browser to use SOCKS5 proxy at localhost:1080
# Execute command remotely (without interactive session):
ssh myserver "df -h && free -h"
# Copy files:
scp ./file.txt myserver:/home/user/ # Upload
scp myserver:/path/file.txt ./ # Download
scp -r ./folder myserver:/home/user/ # Recursive upload
Process Management
# Finding processes
ps aux | grep node # Find Node processes
ps aux --sort=-%mem | head -10 # Top memory consumers
ps aux --sort=-%cpu | head -10 # Top CPU consumers
pgrep -f "node server" # Get PIDs matching pattern
# Process signals (how to control processes)
kill <pid> # SIGTERM (15) — Graceful shutdown (can handle)
kill -9 <pid> # SIGKILL (9) — Force kill (cannot be caught or ignored)
kill -HUP <pid> # SIGHUP (1) — Reload configuration
kill -USR1 <pid> # Custom signal (if app handles it)
# Common patterns:
pkill -f "node server" # Kill by pattern name
killall node # Kill ALL processes named node
kill $(lsof -t -i :3000) # Kill whatever is using port 3000
# Background & foreground
npm start & # Run in background
jobs # List background jobs
fg %1 # Bring job 1 to foreground
bg %1 # Resume suspended job in background
Ctrl+Z # Suspend current process (pause it)
# nohup — persist after logout
nohup npm start > app.log 2>&1 & # Keeps running even if you disconnect!
# Better alternative: tmux/screen (see below)
System Monitoring
# === Quick Status ===
uptime # Load average + uptime
hostnamectl # System info (OS, kernel, etc.)
whoami && id # Current user + groups
date # Current time (check timezone!)
uname -a # Kernel info
# === Memory ===
free -h # Human-readable memory usage
# Total = used + free + buff/cache
# Available is what's actually available for new processes
cat /proc/meminfo # Detailed memory info
# === Disk ===
df -h # Disk space per filesystem
du -sh * | sort -rh | head -10 # Largest items in current dir
ncdu / # Interactive disk usage analyzer (amazing tool!)
# === Network ===
ss -tlnp # Listening ports (what's running?)
ss -tlnp | grep :80 # What's on port 80?
ip addr show # IP addresses (modern replacement for ifconfig)
curl -s ifconfig.me # Your public IP address
# === Real-time monitoring ===
htop # Interactive process monitor (install it!)
iotop # Disk I/O by process
iftop # Network bandwidth by connection
nethogs # Network bandwidth by process
# One-liner status check:
echo "=== Uptime ===" && uptime \
&& echo "=== Memory ===" && free -h \
&& echo "=== Disk ===" && df -h / \
&& echo "=== Top Processes ===" && ps aux --sort=-%mem | head -6
File Operations You Need Daily
# Searching
find . -name "*.js" -type f # Find by name
find . -mtime -7 -type f # Modified in last 7 days
find . -size +100M # Files larger than 100MB
grep -r "TODO" src/ # Search content recursively
grep -r "functionName" src/ --include="*.ts" # Search only TS files
# Viewing files
less bigfile.log # Pager (scroll, search with /)
tail -f /var/log/nginx/access.log # Follow log in real-time
tail -n 50 error.log # Last 50 lines
head -n 30 config.json # First 30 lines
wc -l file.txt # Line count
# Text processing
sed -i 's/old/new/g' file.txt # Find and replace
awk '{print $1, $3}' data.csv # Extract columns 1 and 3
sort file.txt # Sort lines
uniq # Remove adjacent duplicates
sort | uniq -c | sort -rn # Count occurrences
# Compression
tar -czvf archive.tar.gz folder/ # Create .tar.gz
tar -xzvf archive.tar.gz # Extract .tar.gz
zip -r archive.zip folder/ # Create .zip
unzip archive.zip # Extract .zip
# Permissions (critical!)
chmod +x script.sh # Make executable
chmod 644 file.txt # rw-r--r--
chmod 755 script.sh # rwxr-xr-x
chown user:group file.txt # Change owner
chown -R www-data:www-data /var/www # Recursive ownership change
# Symbolic links
ln -s /path/to/target link-name # Create symlink
readlink link-name # Show target
Users & Permissions
# Who am I?
whoami # Username
id # User ID, group ID, groups
groups # Which groups I'm in
# User management (requires sudo)
sudo adduser deploy # Create user
sudo deluser removeuser # Delete user
sudo usermod -aG sudo deploy # Add user to group
sudo passwd deploy # Change password
# Switching users
su - otheruser # Switch to otheruser (need password)
sudo -u deploy whoami # Run as deploy (with sudo)
# Permission breakdown:
# r = read (4), w = write (2), x = execute (1)
# Owner | Group | Others
# Example: rw-r--r-- = 644
# Example: rwxr-xr-x = 755
# Critical security commands:
sudo visudo # Edit sudoers safely
last # Recent logins
lastb # Failed login attempts
Automation with Cron & Systemd
# Cron jobs (scheduled tasks):
crontab -e # Edit your cron table
# Format: minute hour day-of-month month day-of-week command
# Examples:
0 2 * * * /usr/bin/docker system prune -af > /dev/null 2>&1 # Daily 2 AM cleanup
*/15 * * * * /opt/scripts/health-check.sh # Every 15 minutes
0 9 * * 1-5 /opt/scripts/weekly-report.sh # Weekdays 9 AM
# View cron jobs:
crontab -l # List current jobs
sudo crontab -u otheruser -l # List another user's crons
# Systemd services (for long-running processes):
# Create service file:
sudo vim /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js App
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/app
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=10
Environment=NODE_ENV=production
Environment=PORT=3000
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
# Manage services:
sudo systemctl daemon-reload # After creating/editing service
sudo systemctl start myapp # Start
sudo systemctl stop myapp # Stop
sudo systemctl restart myapp # Restart
sudo systemctl enable myapp # Start on boot
sudo systemctl disable myapp # Don't start on boot
sudo systemctl status myapp # Check status
journalctl -u myapp -f # Follow logs
# tmux (persistent terminal sessions — better than nohup!)
tmux new -s work # New named session
tmux attach -t work # Reconnect to session
# Inside tmux:
# Ctrl+B then D → detach (session keeps running!)
# Ctrl+B then c → create new window
# Ctrl+B then n/p → next/previous window
# Ctrl+B then % → split vertical
# Ctrl+B then " → split horizontal
What's your most-used server command? What server task do you find most intimidating?
Follow @armorbreak for more practical developer guides.
Top comments (0)