Ship It, 2009
The word was coined in 2009; the job is older than that. This era gives you one server to operate end to end: systemd units, deployments and rollbacks, users and permissions, disks, logs and the network underneath.
Infrastructure and operations track · 34 missions · boss mission, written exam and certificate · free, no signup. Everything below runs in the browser terminal on the SERVBG home page.
What you will do
- read the systemd unit file for the app service
cat /etc/systemd/system/app.serviceA unit file has three sections: [Unit] (metadata/ordering), [Service] (how to run it), [Install] (how it hooks into boot targets). systemd replaced SysVinit in most distros around 2011-2015.
- check whether the app service is currently running
systemctl status appA unit file existing on disk means nothing until systemd loads and starts it — "inactive (dead)" is the honest default state of anything you haven't started yet.
- start the service right now
systemctl start appstart affects only THIS boot. It says nothing about what happens after a reboot — that is a separate, deliberate decision (see the next mission).
- confirm the service is now active (running)
systemctl status appActive/enabled are two independent axes: a service can be running-but-not-enabled (won't survive reboot) or enabled-but-not-running (will start on the NEXT boot only). Always check both.
- make the service start automatically on every future boot
systemctl enable appenable just drops a symlink into a systemd target's .wants/ directory — no daemon reload of its own logic, just "start me when this target is reached."
- audit every service unit currently running on the host
systemctl list-units --type=serviceEvery running service is attack surface and a maintenance burden. Real ops teams audit the running list, since the installed list alone hides what is actually live.
- view the existing cron schedule
crontab -lcron's five-field syntax (minute hour day month weekday) has been unchanged since 1975 — one of the oldest still-live interfaces in computing.
- install a nightly backup cron job
crontab -e-e opens your crontab in $EDITOR; saving atomically installs the whole file. There is no "append one line" — you always edit the complete schedule.
- confirm the new job actually took
crontab -lNever trust that an edit worked — verify. A typo'd cron schedule fails silently at 2am with nobody watching; reading it back is the whole safety net.
- read the reverse-proxy site config
cat /etc/nginx/sites-enabled/app.confnginx (Igor Sysoev, 2004) popularized sites-available/sites-enabled: configs live in one dir, a symlink in the other turns them on — enable/disable a site without deleting its config.
- find which port nginx is listening on
grep listen /etc/nginx/sites-enabled/app.confgrep a config instead of eyeballing it — the habit scales from a 10-line site.conf to a 10,000-line one identically.
- find the backend nginx is forwarding requests to
grep proxy_pass /etc/nginx/sites-enabled/app.confproxy_pass is the whole reverse-proxy pattern in one directive: nginx is the public-facing door, the app process behind it never touches the internet directly.
- validate the config syntax before ever reloading it
nginx -tnginx -t before every reload is the single habit that prevents the most common self-inflicted outage: a typo'd config taking down a working server.
- generate a deploy keypair for CI/CD
ssh-keygen -t ed25519Ed25519 (2013) keys are shorter and faster to verify than RSA-4096 at equivalent security — the modern default whenever the remote end supports it.
- view the public half of the key you just generated
cat ~/.ssh/id_ed25519.pubThe .pub file is meant to be shared freely — it is what you paste into a server's authorized_keys or a Git host's settings. The private half never leaves this machine.
- check which public keys this host already trusts for login
cat ~/.ssh/authorized_keysauthorized_keys is the whole of SSH public-key auth on the server side: any private key matching a line in this file can log in as this account — no password needed.
- see the releases directory and the "current" symlink
ls -la /opt/releasesSymlink-swap deploys (popularized by Capistrano, ~2008) are the classic pattern: unpack a new release into its own directory, then repoint one symlink. The switch is atomic.
- check disk space before you ship anything
df -hA full disk breaks deploys, crashes databases mid-write, and fills logs with cascading errors that hide the real problem. Cheapest check that prevents a 2am page.
- see how much space old releases are eating
du -sh /opt/releasesKeep N releases, prune the rest — the same symlink pattern that makes rollback instant also quietly fills a disk if nobody ever cleans up.
- list every release this app's deploy tool knows about
deploy listFrom here on, "deploy" is this host's own small release tool — same symlink-swap idea as the ls above, wrapped so a human (or CI) never has to touch the symlink by hand.
- see the current live release and its health, before touching anything
deploy statusStatus-first is the ops equivalent of "look both ways" — know what state you're starting from before you change it.
- ship a normal, healthy release
deploy release v1.4This is the boring, uneventful path most deploys should be. Remember what "normal" looks like — it makes the abnormal easy to spot later.
- confirm v1.4 is actually healthy after shipping it
deploy healthAlways verify after you ship. "The deploy script didn't error" and "the service actually works" are two different claims — only one of them matters to users.
- preview infrastructure changes before applying them
terraform planTerraform (HashiCorp, 2014) is declarative IaC: you describe the desired end state, and plan shows the diff between that and reality — a dry run for infrastructure.
- apply the planned infrastructure change
terraform applyIdempotency is the whole promise of IaC: re-running apply against unchanged config converges to "no changes" rather than creating duplicate resources. Try it again later — it will say exactly that.
- run a configuration-management playbook
ansible-playbook site.ymlAnsible (Michael DeHaan, 2012) tasks are meant to be idempotent too: "changed" means the task actually did something this run, "ok" means it checked and the system already matched — same playbook, safe to run daily.
- create the service account that owns the app and its home directory
useradd -m deployA dedicated service account instead of running everything as root applies least-privilege to daemons the same as humans. If the app is compromised, it isn't root.
- grant deploy just enough privilege to manage the service
usermod -aG sudo deploy-aG APPENDS to a user's groups. Drop the -a by mistake and plain -G REPLACES every group membership the user had — a classic footgun that silently kicks someone out of every other group.
- ship the big one — release v2.0
deploy release v2.0Shipping is the easy part. Everything from here is the actual job: noticing it broke, finding out why, and fixing it without panic.
- see the failure reflected in deploy status
deploy statusstatus is the fastest lie-detector you have: it will tell you plainly whether "deployed" and "working" are the same thing right now. Here, they are not.
- read the application logs to find out WHY it is failing
deploy logsLogs are ground truth; guessing is not. A missing environment variable crashing the process on boot is one of the most common real-world "it deployed but it's down" causes.
- rule out nginx itself — confirm the config is syntactically fine
nginx -tLayered diagnosis: nginx is what users SEE fail (502), but that doesn't mean nginx is at fault. Its config is fine — the process it proxies to isn't running. Don't fix the wrong layer.
- ROLL BACK to the last known-good release
deploy rollbackRollback is a legitimate first response, not an admission of failure: restore service now with a release you already know works, root-cause the broken one after, with nobody waiting on you.
- Boss missionFINAL — verify health is actually restored after the rollback
deploy healthThe full incident loop, once: ship, detect, diagnose, roll back, verify. Every real production incident is some version of exactly these five steps, in exactly this order.
Certificate
This track is certifiable. Clear the boss mission in the terminal, then run EXAM DEVOPS for the written paper: 20 server-graded questions drawn from our own bank, pass mark 14 of 20. The certificate is issued once both are done, and it carries a verification code.
Independently developed; not affiliated with, endorsed by, or sponsored by the Linux Foundation. Content is aligned to the Linux Foundation’s publicly published exam objectives for the Linux Foundation Certified Systems Administrator (LFCS) exam.