Sysadmin Essentials
Files, permissions, processes, and services on Linux servers running Python APIs, workers, and cron jobs - the commands operators reach for before opening a Python debugger.
Search across all documentation pages
Files, permissions, processes, and services on Linux servers running Python APIs, workers, and cron jobs - the commands operators reach for before opening a Python debugger.
ls -la /var/log/myapp/
sudo systemctl status billing-api
sudo journalctl -u billing-api -n 100 --no-pager
df -h && du -sh /var/lib/myapp/*When to reach for this:
# New deploy directory owned by service user
sudo mkdir -p /var/lib/billing-api/uploads
sudo chown billing:billing /var/lib/billing-api/uploads
sudo chmod 750 /var/lib/billing-api/uploads
# Check unit and recent logs
sudo systemctl daemon-reload
sudo systemctl restart billing-api
sudo systemctl is-active billing-api
sudo journalctl -u billing-api -fWhat this demonstrates:
systemctl lifecycle after unit file change-f on journal for live triageExecStart, env, restart policy.| Problem | Commands |
|---|---|
| Permissions | ls -la, namei -l path, chmod, chown |
| Disk | df -h, du -xh --max-depth=1 |
| Service | systemctl status, restart, enable |
| Logs | journalctl -u, /var/log/ tail |
# Find which process holds port 8000
sudo ss -tlnp | grep 8000
# Confirm venv python path in systemd unit
systemctl cat billing-api | grep ExecStart750 and app group./etc/systemd/system/ with version comment.df shows space but writes fail. Fix: df -i.ausearch / aa-status.| Alternative | Use When | Don't Use When |
|---|---|---|
| Docker logs | Containerized Python services | Bare metal systemd VMs |
| Kubernetes kubectl | K8s deploys | Single VM staging |
| Ansible playbooks | Repeatable server setup | One-off SSH debug |
| Cloud SSH session manager | No bastion SSH keys | Air-gapped on-prem |
systemd on modern Linux VMs; supervisord in legacy containers without systemd.
/etc/billing-api/env mode 600 owned root:billing with EnvironmentFile= in unit - not world-readable.
reload if app supports HUP; Python APIs usually need restart after code deploy.
Service unit can set UMask=0027 so new files are not group/world writable.
Sized tmpfs avoids disk fill but data lost on reboot - use for ephemeral scratch only.
timedatectl status - JWT and log correlation break with bad clock.
Raise LimitNOFILE= in unit for high-connection FastAPI behind keep-alive.
find / -perm -4000 2>/dev/null security audit - unrelated to Python but common sysadmin task.
UID/GID mapping must match across nodes - prefer object storage (S3) for uploads.
Mount writable paths explicitly for logs and tmp - common in hardened containers.
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026