Before you log in
Add your SSH public key in the portal before you create the instance, so it is injected at first boot. If you already created it with a password, that is fine: step 3 fixes it. Note the IPv4 address from the instance page. Every command below assumes Debian 12 or Ubuntu 24.04; the RHEL-family lines are given where they differ.
1. Patch everything
Images are built periodically, so there are always a few updates waiting.
sudo apt update && sudo apt full-upgrade -y
# AlmaLinux / Rocky:
sudo dnf upgrade -y
If a kernel was updated, reboot now rather than later. ls /var/run/reboot-required on Debian-family systems tells you if one is pending.
2. Create a working user
Day-to-day work as root makes every typo a system-wide typo. Create a user and give it sudo.
sudo adduser deploy
sudo usermod -aG sudo deploy # Debian/Ubuntu
sudo usermod -aG wheel deploy # AlmaLinux/Rocky
3. Copy your key and test it
sudo mkdir -p /home/deploy/.ssh
sudo cp ~/.ssh/authorized_keys /home/deploy/.ssh/
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh && sudo chmod 600 /home/deploy/.ssh/authorized_keys
Open a second terminal and run ssh [email protected]. Do not close the first session until this works. The SSH hardening guide covers turning off password and root login properly.
4. Set the hostname and timezone
sudo hostnamectl set-hostname api-1
sudo timedatectl set-timezone Europe/London
timedatectl
The last command should show System clock synchronized: yes. If it says no, install and enable systemd-timesyncd or chrony. TLS, TOTP codes and log correlation all break quietly when the clock drifts. Some teams keep servers on UTC and convert in their log tooling; pick one and use it everywhere.
5. Turn on a firewall
Allow SSH and whatever you will serve, drop everything else. The short version for Ubuntu:
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable
sudo ufw status verbose
For a ruleset you can read and version-control, use the nftables guide instead. You can also add rules in the portal's per-VM firewall, which filters before traffic reaches the guest. Running both is reasonable; just keep them consistent.
6. Add a swap file
On Spark and Boost, a 1–2 GB swap file is cheap insurance.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
sudo sysctl vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/90-swap.conf
Check with free -h. A low swappiness means the kernel only uses swap when it has to, which is what you want with fast storage underneath.
7. Automatic security updates
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# AlmaLinux / Rocky:
sudo dnf install -y dnf-automatic
sudo sed -i 's/^upgrade_type.*/upgrade_type = security/' /etc/dnf/automatic.conf
sudo systemctl enable --now dnf-automatic.timer
Unattended upgrades on Debian and Ubuntu default to security pockets only. They will not reboot unless you set Unattended-Upgrade::Automatic-Reboot, which you should only do if your services come back cleanly on their own.
8. Make the journal persistent and bounded
sudo mkdir -p /etc/systemd/journald.conf.d
printf '[Journal]\nStorage=persistent\nSystemMaxUse=500M\n' | sudo tee /etc/systemd/journald.conf.d/size.conf
sudo systemctl restart systemd-journald
Logs that disappear on reboot are useless after a crash. Logs without a cap fill 20 GB disks. This setting gives you both history and a ceiling.
9. Check what is listening
sudo ss -tulpn
On a fresh image you should see sshd on port 22, perhaps a local DNS stub on 127.0.0.53, and little else. Anything bound to 0.0.0.0 that you did not install deserves a look before you go further.
10. Snapshot the clean state
From the portal, take a snapshot now. It is your known-good baseline: patched, hardened, firewalled, with nothing deployed. When an experiment goes wrong next week, restoring it takes minutes instead of repeating this hour. Snapshots are not backups, though; the backups guide explains why.
Common mistakes
- Enabling the firewall before allowing SSH. If it happens, fix it from the browser console.
- Editing
/etc/ssh/sshd_configand restarting without runningsudo sshd -tfirst. A syntax error stops sshd from starting. - Expecting outbound mail on port 25 to work. It is blocked by default; request an unblock in the portal if you genuinely run a mail server, or relay through an authenticated provider on 587.