Skip to content

Checklist

What a server needs before it holds production traffic.

Kamal will happily deploy to a box with password logins on, no firewall and no backups. This is the list that closes that gap. KamalCloud applies all of it; the list works just as well by hand, which is why the whole thing is on this page.

17 items. All of it on this page, no form in the way.

The firewall

  • Turn on the host firewall

    ufw denies inbound by default. Do this before opening anything, not after.

    ufw --force enable
  • Allow SSH, HTTP and HTTPS through it

    22, 80 and 443. Anything else your app publishes has to be named explicitly.

    ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp
  • Attach the provider's own firewall too

    The cloud firewall stops traffic before it reaches the machine, so a misconfigured ufw is not the only thing between the internet and your app.

SSH

  • Turn off password logins

    Keys only. This single line removes the entire brute-force category.

    sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
  • Limit root to key logins

    prohibit-password, not no: deploys still need root over a key.

    sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
  • Keep sessions alive

    A dropped connection in the middle of a long deploy is its own kind of outage.

    ClientAliveInterval 60

Brute force

  • Install fail2ban

    Bans an address after repeated failures, without you reading a single auth log.

    apt-get install -y fail2ban
  • Turn on the aggressive SSH mode

    Catches the scanners that never get as far as a password prompt.

Updates and capacity

  • Turn on automatic security updates

    The patch you keep meaning to apply is the one that gets used.

    apt-get install -y unattended-upgrades
  • Bring packages up to date once, now

    A new machine is not a patched machine.

    apt-get update && apt-get upgrade -y
  • Add swap

    A gigabyte or two. It is the difference between a slow minute and an OOM kill during a build.

  • Prepare a storage directory

    One predictable path for volumes and database data, so a rebuild does not hunt for it.

The part everyone leaves until later

  • Back up every database on a schedule

    To storage you control, off the machine being backed up.

  • Restore one, to a different machine

    A backup nobody has restored is a hypothesis. This is the only item on the list that proves itself.

  • Give each teammate their own access

    A shared key is one leaver away from a problem, and nobody can tell you afterwards who used it.

  • Keep staging and production genuinely apart

    Different machines, different secrets, or at minimum different Kamal destinations.

  • Know what the machines cost

    Per server, per month. The number nobody looks at until the card is declined.

Connect a server. Start with staging.

Register a machine you already have, or provision a new one. Nothing is touched that you have not chosen.

Sign-ups are paused while the app is in maintenance.