/user/kayd @ devops :~$ cat ubuntu-terminal.md

Ubuntu Terminal Cheatsheet Ubuntu Terminal Cheatsheet

QR Code linking to: Ubuntu Terminal Cheatsheet
Karandeep Singh
Karandeep Singh
• 6 minutes

Summary

The Ubuntu server commands I reach for daily. Covers apt/dpkg/snap package management, systemd, ufw, user management, networking, and upgrades.

Most of the fleet I manage runs Ubuntu LTS, and the same twenty commands cover 90% of the day-to-day: patching with apt, poking services with systemctl, reading journalctl, opening a port in ufw. This is that reference. I run nearly all of it inside a tmux session so a dropped SSH connection doesn’t kill an upgrade (see my tmux Cheatsheet).

apt - Package Management

Docs: apt(8) on Ubuntu manpages

sudo apt update                      # refresh package index (always first)
sudo apt upgrade                     # upgrade installed packages
sudo apt full-upgrade                # upgrade, allowing removals (kernel etc.)
apt list --upgradable                # what would upgrade
sudo apt install nginx               # install
sudo apt install nginx=1.24.0-2ubuntu7   # install a specific version
sudo apt remove nginx                # remove package, keep config
sudo apt purge nginx                 # remove package AND config files
sudo apt autoremove --purge          # remove orphaned dependencies
sudo apt install -y --no-install-recommends jq   # lean install for servers/CI

Inspecting packages:

apt show nginx                       # metadata: version, deps, description
apt-cache policy nginx               # installed vs candidate version, origin
apt search "reverse proxy"           # search descriptions
apt list --installed | grep nginx    # what's installed
sudo apt-mark hold linux-image-generic   # pin a package (unhold to release)

Repositories:

sudo add-apt-repository ppa:ondrej/php    # add a PPA (runs apt update on modern Ubuntu)
sudo add-apt-repository --remove ppa:ondrej/php
# modern keyring pattern for third-party repos:
curl -fsSL https://example.com/key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg
echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://repo.example.com stable main" \
  | sudo tee /etc/apt/sources.list.d/example.list

Unattended security updates:

sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
# config: /etc/apt/apt.conf.d/50unattended-upgrades
sudo unattended-upgrade --dry-run -d      # test what it would do

dpkg Basics

Docs: dpkg(1) on Ubuntu manpages

sudo dpkg -i package.deb             # install a local .deb
sudo apt install ./package.deb       # better: resolves dependencies too
dpkg -l | grep nginx                 # list installed packages
dpkg -L nginx                        # files a package installed
dpkg -S /usr/sbin/nginx              # which package owns this file
sudo dpkg --configure -a             # fix interrupted installs
sudo apt --fix-broken install        # fix broken dependencies

snap Basics

Docs: Snap documentation on snapcraft.io

snap list                            # installed snaps
snap find kubectl                    # search the store
sudo snap install kubectl --classic  # classic = no sandbox confinement
sudo snap refresh                    # update all snaps
sudo snap remove --purge kubectl     # remove including snapshots
snap info kubectl                    # channels and versions

systemd - Services

Docs: systemctl(1) on man7.org

systemctl status nginx               # state, PID, recent log lines
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx          # reload config without dropping connections
sudo systemctl enable --now nginx    # start now AND on boot
sudo systemctl disable nginx
systemctl is-active nginx            # scripting-friendly: active/inactive
systemctl list-units --type=service --state=failed
sudo systemctl daemon-reload         # after editing unit files
sudo systemctl edit nginx            # override unit via drop-in file

journalctl - Logs

Docs: journalctl(1) on man7.org

journalctl -u nginx                  # logs for one unit
journalctl -u nginx -f               # follow (like tail -f)
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx --since "2026-07-22 09:00" --until "2026-07-22 10:00"
journalctl -u nginx -n 100 --no-pager
journalctl -p err -b                 # errors since last boot
journalctl --disk-usage              # how much space logs use
sudo journalctl --vacuum-size=500M   # trim the journal

ufw - Firewall

Docs: UFW on the Ubuntu Community Help Wiki

sudo ufw status verbose
sudo ufw allow OpenSSH               # ALWAYS before enabling, or you lock yourself out
sudo ufw enable
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 10.0.0.0/8 to any port 5432 proto tcp   # scoped rule
sudo ufw limit ssh                   # rate-limit brute force
sudo ufw status numbered
sudo ufw delete 3                    # delete rule by number
sudo ufw default deny incoming
sudo ufw default allow outgoing

Users & Permissions

Docs: Ubuntu Server documentation

sudo adduser deploy                  # interactive: home dir, password, shell
sudo usermod -aG sudo deploy         # add to sudo group (-a is critical!)
sudo usermod -aG docker deploy       # docker without sudo (log out/in to apply)
groups deploy                        # check memberships
sudo deluser deploy --remove-home
sudo passwd -l deploy                # lock an account
sudo visudo                          # edit sudoers safely (syntax-checked)
# passwordless sudo for one command, via a drop-in:
echo 'deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp' \
  | sudo tee /etc/sudoers.d/deploy-restart

chmod / chown recap:

CommandEffect
chmod 644 filerw-r–r– (configs, regular files)
chmod 755 dirrwxr-xr-x (directories, scripts)
chmod 600 key.pemrw——- (private keys; SSH refuses looser)
chmod +x script.shAdd execute bit
chmod -R g+w shared/Recursive group write
chown deploy:deploy fileChange owner and group
chown -R www-data: /var/wwwRecursive; empty group = user’s group

Networking

Docs: Netplan documentation

ip a                                 # interfaces and addresses
ip r                                 # routing table (default gateway)
ss -tulpn                            # listening sockets + owning process
ss -tn state established             # current TCP connections
resolvectl status                    # DNS config (systemd-resolved)
ping -c 4 1.1.1.1
curl -sI https://karandeepsingh.ca | head -5

Netplan (Ubuntu’s network config since 18.04): YAML in /etc/netplan/*.yaml, applied with sudo netplan apply. On cloud instances the file is usually generated by cloud-init, so override via /etc/cloud/cloud.cfg.d/ rather than editing the generated file, or your changes vanish on reboot. sudo netplan try applies with an auto-rollback timer, which is the safe option over SSH.

Release & Version Info

Docs: Ubuntu Server docs on ubuntu.com

lsb_release -a                       # Ubuntu version and codename
cat /etc/os-release                  # same info, script-friendly
uname -r                             # kernel version
sudo do-release-upgrade              # upgrade to next LTS (take a snapshot first)
sudo do-release-upgrade -d           # upgrade to development release
# /etc/update-manager/release-upgrades: Prompt=lts|normal|never

update-alternatives

Docs: update-alternatives(1) on Ubuntu manpages

Manage multiple versions of the same tool:

update-alternatives --list editor
sudo update-alternatives --config editor      # interactive pick
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1
sudo update-alternatives --set editor /usr/bin/vim.basic

Common Paths

PathWhat lives there
/etc/apt/sources.list.d/Third-party apt repo definitions
/etc/apt/apt.conf.d/apt behaviour incl. unattended-upgrades config
/etc/apt/keyrings/Repo signing keys (modern location)
/etc/netplan/Network configuration YAML
/etc/systemd/system/Custom and overridden unit files
/var/log/syslogGeneral system log
/var/log/auth.logLogins, sudo usage, SSH attempts
/var/log/unattended-upgrades/Automatic update history
/var/log/nginx/nginx access and error logs
/etc/sudoers.d/Drop-in sudo rules (use with visudo)
/etc/cron.d/, /etc/cron.daily/System cron jobs

If your servers are EC2 instances running Amazon Linux instead, most of this maps over with yum in place of apt. The differences are in my Amazon Linux 2 Terminal Cheatsheet.

0
  • Amazon Linux 2 Terminal: the yum/EC2 counterpart, covering extras repos, SSM Session Manager, IMDSv2, and cloud-init logs
  • tmux: how I keep do-release-upgrade and other long jobs alive through dropped SSH sessions
  • Jenkins: for when you stop running these commands by hand and codify them as pipeline stages

More terminal sheets in the Terminal group; the full cheatsheet library has everything else.

Similar Articles

More from devops

tmux Cheatsheet

Quick-reference tmux cheatsheet: sessions, windows, panes, copy mode, synchronize-panes, .tmux.conf …

Jenkins Cheatsheet

Jenkins cheatsheet with declarative pipeline syntax, credentials, parameters, parallel stages, …

Docker Cheatsheet

Docker cheatsheet with the commands I use daily as a DevOps engineer: image builds, run flags, …

Bash Basics Cheatsheet

Quick-reference Bash basics cheatsheet: variables, parameter expansion, conditionals, loops, arrays, …