Home · About · Services · Industries · Projects · Products · Process · Blog · FAQ · Contact
DevOps checklist for small teams without an ops engineer The ten things a small team without an ops engineer should have in place: account ownership, CI deploys and rollback, secrets, alerts, backups and runbooks.
A developer leaves. Two weeks later the TLS certificate on the main site expires, because the renewal emails went to their inbox. Nobody else has the registrar login, the cloud root account is tied to their phone, and the deploy only ever ran from their laptop. None of this needed an operations engineer to prevent. It needed a list.
The short answer: a team without an ops engineer needs five things in place before anything clever. The organisation owns every account. Deploys run from CI and can be rolled back with one change. Secrets live outside the code. Someone is alerted when the service, disk, certificates or backups fail. And there is a written page for each service explaining how to recover it.
This is the checklist we use when we take over operations for a small team, or hand a system back to one. It is ordered by how much pain each item prevents per hour of work. Do the first section this week, even if you never get to the rest.
1. Ownership and access Most small-team outages we see are not technical. They are access problems that turn a twenty-minute fix into a two-day hunt for a password.
Domains, DNS, cloud, Git hosting and email sending accounts belong to a company address or organisation, not to a person. At least two people can log in to each one, and both have multi-factor authentication turned on. The AWS root user or Azure global administrator is used only for account-level tasks. It has MFA, no access keys, and the recovery details are stored in a shared password manager. Domains are on auto-renew with a valid card, registrar lock is on, and renewal notices go to a shared mailbox. Everyone uses their own named login. Shared accounts make it impossible to remove one person cleanly. There is a leaver process: remove Git, cloud, VPN and server access the same day, and rotate any secret that person could read. Write the inventory down: which accounts exist, who owns them, what they cost each month. It is dull work, and it is the single most useful page you will produce.
2. Source control and the deploy path If production can only be updated from one person's machine, you do not have a deploy process. You have a dependency on that person. The goal is boring: every change goes through a pull request, CI builds it, and the same pipeline deploys it.
Protect the main branch with a ruleset: pull requests required, status checks must pass, no force pushes. Rulesets on private repositories need a paid GitHub plan; on the free plan they apply to public repositories only. Turn on Dependabot alerts and secret scanning with push protection. Both are free for public repositories, and secret scanning on private repositories depends on your GitHub plan. Build artefacts or container images once in CI, tag them with the commit SHA, and promote the same artefact from staging to production. Rolling back is redeploying the previous tag. Test that it works before you need it. Keep database migrations backwards compatible for one release, so the old version still runs against the new schema during a rollback. A minimal GitHub Actions deploy job looks like this. The concurrency group stops two deploys racing each other, and the environment lets you require an approval and keep production secrets separate from everything else.
name: deploy
on:
push:
branches: [main]
concurrency:
group: deploy-production
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v5
- name: Deploy the image built for this commit
run: ./scripts/deploy.sh "${GITHUB_SHA::7}"
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}Where the target is AWS or Azure, prefer OpenID Connect from GitHub Actions to a long-lived access key stored as a secret. The workflow receives short-lived credentials scoped to one role, and there is no key to leak or rotate. The job needs permissions: id-token: write to request the token, and the cloud role should trust only your repository and the production environment.
3. Secrets and server hygiene Secrets in a repository are permanent. Deleting the file does not remove it from history, so treat any committed secret as leaked and rotate it.
Keep secrets in CI secrets, a cloud secret store or a password manager, and inject them at deploy time. Give each application its own database user with only the permissions it needs. Servers accept SSH keys only. Set PasswordAuthentication no and PermitRootLogin no, check that a file in /etc/ssh/sshd_config.d/ is not switching passwords back on (cloud images often ship one), test with sudo sshd -t, and reload the ssh service while you still have a session open. Close every port the public does not need. Reach admin panels, databases and dashboards over a private network such as a Tailscale tailnet or a VPN. Turn on automatic security updates, and schedule a monthly window for reboots and the updates that need a human. On Ubuntu and Debian, unattended security updates take two commands. Check the operating system's support dates while you are there: Ubuntu 20.04 left standard support in May 2025, and 22.04 follows in 2027.
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# confirm what it would do
sudo unattended-upgrade --dry-run --debug4. Monitoring that wakes the right person You do not need a full observability platform to start. You need to know about failures before your customers tell you. Five checks cover most of the outages we see on small systems.
An external uptime check on each public URL, run from outside your own infrastructure, that hits a health endpoint which also touches the database. Disk usage alerts at around 80 per cent on every server and volume. Full disks cause more strange failures than anything else. Certificate expiry alerts. Publicly trusted certificate lifetimes are shrinking: the maximum fell to 200 days in March 2026 and drops to 100 days in March 2027, so renewal must be automated and watched. A backup arrival check that alerts when today's file is missing, not only when a job reports an error. Cloud budget alerts in AWS Budgets or Azure Cost Management, so a forgotten instance or a runaway job shows up within days. Route alerts to a shared channel and to a named person on rota. An alert that goes to everyone is read by nobody. Keep the number of alerts small enough that each one gets acted on; if an alert fires weekly and nobody does anything, fix the cause or delete it.
For certificates on servers using Certbot, check that renewal actually works rather than trusting the timer.
sudo certbot renew --dry-run
systemctl list-timers | grep certbot5. Backups and recovery Back up every database and every uploaded file, copy the backups off the server to storage the server cannot delete from, and restore them on a schedule. A backup that has never been restored is a hope, not a backup. We cover the full routine, including a scheduled restore test, in our post on backups that actually restore.
Also back up what is not data: environment files, reverse proxy configuration, cron entries and the compose or infrastructure files that describe the stack. Keep them in version control where you can, so a new server can be built from the repository rather than from memory.
6. Runbooks and incidents When something breaks at an awkward hour, whoever is on call should not have to reverse-engineer the system. One page per service is enough.
What it does, who uses it, and who owns it. Where it runs, how to get in, and where the logs are. How to deploy, how to roll back, and how to restart it safely. Its dependencies: database, queues, third-party APIs, DNS. How to restore it from backup, with the time the last restore test took. After each incident, write five lines: what happened, how it was noticed, how it was fixed, what would have caught it sooner, and the one change you will make. Then make that change. Small teams improve fastest by fixing the specific thing that hurt them last time.
The checklist, and when to get help Every account is owned by the organisation, with two admins and MFA. Domains auto-renew and renewal notices reach a shared mailbox. Main branch is protected; deploys run from CI only. Rollback is one change and has been tested. No secrets in the repository; cloud access uses OIDC or short-lived credentials. SSH is key-only, unused ports are closed, security updates are automatic. Uptime, disk, certificate, backup and budget alerts reach a named person. Backups are off-server and restored on a schedule. Each service has a one-page runbook. Leavers lose access the same day. If you can tick all ten, you are in better shape than many larger teams. If several boxes stay empty month after month because product work always wins, that is the point to bring in outside help for the setup and decide whether you need ongoing operations cover, rather than waiting for the expired certificate to decide for you.
Infigini IT Services · 11 Kanwali Road, Dehradun 248001, India · info@infigini.com · +91 95684 87789