Spinning up a new Ubuntu server is exciting – but also a bit intimidating. The moment it's online, it’s visible to the internet, and that means it's vulnerable.

I remember my first time: within hours, bots were already knocking at my SSH door.

That’s why properly preparing your server from day one is so important. It’s not just about installing software – it’s about setting the stage for security, stability, and performance.

A few smart tweaks early on can help your server run faster, stay safer, and avoid problems down the line.

In this guide, I’ll walk you through the exact steps I take right after deploying a fresh Ubuntu instance. Whether you're setting up a web server, mail server, or anything else, these initial steps will help you.

📬 Newsletter

Get updates from my server administration journey – tips, lessons, and discoveries along the way.

I’m In!

Document Everything (Seriously)

You might not realize it now, but keeping track of what you do – from the tiniest config tweak to major installs – is one of the most valuable habits you can build as a server admin.

I learned this the hard way. The first time I messed with SSH configs and accidentally locked myself out, I couldn’t remember what I had changed – or why.

Ever since then, I document everything: the exact commands I run, what I was trying to do, and the results.

Even small changes matter. Things like:

  • Editing sshd_config
  • Installing packages or services
  • Adjusting firewall rules
  • Creating users or groups

I also note the date, time, and a quick summary of my intention (e.g., "disabled password login for root").

You don’t need a fancy setup to start – just open a plain text file on your local machine and jot things down. Later, you can explore more structured tools.

Pro Tip: Good documentation isn’t just for debugging – it’s also a huge win if you ever rebuild, automate, or hand off your setup later.

Logging In as Root

The first step is getting into your server – and for that, you'll need two things:

  • The server’s IP address
  • The root password

Many providers allow you to set the root password during server creation on their dashboard or send it to you via email with the server details, as Hetzner does.

Keep in mind that the root password provided by providers like Hetzner is often temporary. Once you access your server, you'll need to change it.

👉
New to Hetzner? Use my link to get free credits!

Once you’ve got your credentials, fire up your terminal and run:

ssh root@your.server.ip

You’ll be prompted for the root password. Type it in, and you’re in!

💡
Tip: Run passwd right away to set a new root password (or update any user’s password later). It’s a quick, essential first move.

Running Updates

Once you're logged in, your server might greet you with a message like:

X packages can be updated.
Y of these updates are security updates.

Don't ignore it.

Running outdated software is one of the easiest ways to expose your server to known vulnerabilities. So, before you do anything else, let’s bring your server up to date.

Begin by updating the package list on your server with the following command:

apt update

It doesn’t install anything yet – it just tells your server what’s new in the package repositories.

Now, install the updates:

apt upgrade

You’ll be prompted to confirm – just type yes and hit ENTER.

These updates aren’t just about bug fixes – they include critical security patches, performance improvements, and stability fixes that keep your server healthy from the start.

Personal Tip: Some immediately reboot after updating, but I prefer waiting until the server setup is complete to ensure all changes apply.

Adding a Non-Root User

The root user is powerful – it has full control over your server and can run any command without restriction.

But with great power comes great risk: a single typo or wrong command run as root can break your server or open security holes.

That’s why it’s best practice to create a non-root user for your daily work. This user will have limited permissions by default and will require you to prefix admin commands with sudo – which adds a protective layer by prompting for your password before critical actions.

Run this command, replacing username with your chosen username:

adduser username

You’ll be asked to create a password and fill in some optional details.

💡
Tip: Use strong passwords! A password manager can help you generate and store complex passwords safely.

To allow your new user to run admin commands, add them to the sudo group:

usermod -aG sudo username

To check that the new user is good to go, log out with the logout command and access your server again with the new user:

ssh your.new.user@your.server.ip

Try running the apt update command. It should not work directly, as you need to run the command like this: sudo apt update and then enter your password.

That’s it! You’re now set up to work safely on your server without the risks of using root directly.

SSH Keys & Hardening

By default, you log into your server with a password – but there’s a safer method: SSH key authentication.

Instead of typing a password each time, you use a key pair:

  • The public key goes on the server.
  • The private key stays safely on your local machine.

When you try to connect, the server checks if you have the matching private key. If you do, you're in.

This is far more secure than using passwords, and it protects against brute-force login attempts.

Check for Existing Keys

First, check if you already have an SSH key pair on your local machine:

ls -l ~/.ssh

If the directory is empty (or only contains known_hosts), you're good to go. If you see existing keys like id_rsa or id_ed25519, consider backing them up before continuing.

Generate a New SSH Key Pair

To create a secure key pair, run:

ssh-keygen -b 4096

You’ll be prompted to choose a file path for saving the key – press ENTER to accept the default or enter a custom path to avoid overwriting any existing key.

You’ll also be asked to enter a passphrase. While optional, using a passphrase adds another layer of security and is strongly recommended.

Once done, two files will be created in your ~/.ssh directory:

  • id_ed25519 – your private key
  • id_ed25519.pub – your public key
Keep the private key safe and never share it.

Copy the Public Key to the Non-Root User

If you copy the public key for the root user, only root will be able to log in with it. If you copy it for another user, only that user can use key-based login.

Since we’re using a non-root user, we’ll copy the key for that user instead.

To enable key-based access for your non-root user, copy the public key to the server using:

ssh-copy-id -i ~/.ssh/id_ed25519.pub your.non.root.user@your.server.ip

Replace your.non.root.user and your.server.ip with your actual values. Enter the user’s password when prompted.

After this, you’ll be able to log in without a password – your key will handle the authentication.

Disable Password and Root Logins

Now that key-based authentication is working, let’s lock things down even further.

We’ll disable password logins entirely and prevent root from logging in over SSH.

Open the SSH configuration file:

sudo vim /etc/ssh/sshd_config

Find and update the following lines. If they’re commented out (start with #), remove the # character:

PasswordAuthentication no
PermitRootLogin no

Once you’ve saved and exited the file, reload the SSH service to apply the changes:

sudo systemctl reload ssh
⚠️
Heads up: Some server providers include additional SSH configuration files in /etc/ssh/sshd_config.d/. Be sure to check them so your settings aren’t overridden.

Test Your Setup

Try logging in as root:

ssh root@your.server.ip

You should see:

Permission denied (publickey).

Also, try logging in as your non-root user from a machine that doesn’t have the private key – you’ll be blocked there too.


At this point, your server:

  • Rejects password-based logins
  • Blocks root SSH access
  • Only allows access for your non-root user with SSH key authentication

This is a major win for your server’s security.

Changing Server Hostname

Giving your server a meaningful hostname is like putting a name tag on it – it helps you recognize it at a glance and makes your terminal sessions less error-prone.

Imagine managing multiple servers and accidentally running a destructive command on the wrong one just because they all look the same in the prompt. A clear, unique hostname minimizes that risk.

But beyond convenience, setting the hostname properly is also important for functionality:

  • Some software relies on the server’s hostname to work correctly – especially services that depend on networking or domain resolution.
  • If a server's hostname can't be resolved to an IP address, it can cause communication and networking issues. This may result in timeouts, connection errors, and other unexpected behavior.

To set the hostname, use this command:

sudo hostnamectl set-hostname yourservername.yourdomain.com

Replace yourservername.yourdomain.com with the actual name you want to use. A typical hostname includes two parts:

  • Server name, like web or mail
  • Domain name, like example.com

For instance:

sudo hostnamectl set-hostname mail.example.com

That’s all it takes to update the server’s hostname.

Make sure to add an A record for your hostname.

Setting Up a Firewall

Before adding services or hosting applications, it’s important to lock down your server to prevent unauthorized access. A basic firewall configuration that only allows SSH traffic is a great starting point for a secure setup.

Ubuntu comes with UFW (Uncomplicated Firewall), a user-friendly tool for managing firewall rules. On many cloud providers (like Vultr), it’s already installed – and sometimes even pre-configured to allow SSH.

UFW is typically included in Debian-based distributions, like Ubuntu, but if needed, install it with:

sudo apt install ufw

To check if UFW is already active:

sudo ufw status

If it’s inactive, continue to the next step. If it’s active and you want a clean slate, reset it:

sudo ufw disable
sudo ufw reset
💡
Resetting clears existing rules, which is useful if you’re unsure what’s already in place.

Before enabling UFW, make sure SSH (port 22) is allowed – otherwise, you could lock yourself out:

sudo ufw allow 22/tcp

Now that SSH access is allowed, turn on the firewall:

sudo ufw enable

You’ll see a warning that the connection may be disrupted – but since SSH is allowed, you’re safe to continue.

You now have a basic firewall in place.

Only SSH traffic is allowed in, and all other incoming connections are blocked by default. Outbound traffic remains unrestricted, so your server can still fetch updates and reach the outside world.

When you later install a web server or other services, you can open additional ports as needed:

sudo ufw allow 80/tcp  
sudo ufw allow 443/tcp

These commands allow traffic on the standard ports used for websites – port 80 for unencrypted web traffic and port 443 for secure HTTPS connections. Without opening these, your website won’t be accessible from a browser.

Changing the Timezone

Setting the correct timezone for your server is important because it ensures that all timestamps and scheduled tasks reflect your local time (or the time zone relevant to your server’s purpose).

An incorrect timezone can lead to confusing logs, misfired cron jobs, or mismatched timestamps in applications. Getting it right from the beginning saves you from future debugging headaches.

To see the full list of available timezones, run:

timedatectl list-timezones

This will display all supported timezones (you can scroll or pipe it through less for easier browsing).

Once you’ve found the correct timezone for your location (e.g. Europe/Berlin, America/New_York, Asia/Tokyo), apply it using:

sudo timedatectl set-timezone Your/Timezone

For example:

sudo timedatectl set-timezone Europe/Berlin

Your server’s clock is now aligned with the correct timezone.

Changing the Default Editor

Your server uses a default text editor for system-level tasks like editing crontabs (crontab -e) or secure files with visudo. By default, this editor is often Nano – a simple, beginner-friendly choice.

But if you prefer something more powerful, like Vim, you can easily switch it.

Run the following command:

sudo update-alternatives --config editor

You’ll see a list of installed editors:

There are 4 choices for the alternative editor (providing /usr/bin/editor).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /bin/nano            40        auto mode
  1            /bin/ed             -100       manual mode
  2            /bin/nano            40        manual mode
  3            /usr/bin/vim.basic   30        manual mode
  4            /usr/bin/vim.tiny    15        manual mode

Press <enter> to keep the current choice[*], or type selection number:

Enter the number next to your preferred editor and press ENTER.

🙆‍♂️
I personally use Vim because of its speed and power – but go with whatever makes you comfortable!

Installing Essential Software

Once your server is updated and secure, it’s a good idea to install some essential tools that make daily tasks easier and more efficient.

Depending on what your server is for (web hosting, backups, development, etc.), you might need different tools – but some are useful in almost every setup.

Here’s a go-to list I personally install on all my servers:

sudo apt install git htop curl wget zip unzip net-tools ncdu rsync

Let’s quickly break down what these do:

  • git – Version control for managing code and config files
  • htop – An interactive process viewer (better than top)
  • curlwget – For downloading files and testing web endpoints
  • zipunzip – For compressing and extracting archives
  • net-tools – Includes legacy tools like ifconfig and netstat
  • ncdu – Disk usage analyzer (great for cleaning up space)
  • rsync – Fast, efficient file transfer and sync utility

These are lightweight but powerful tools that make server life a lot smoother. Feel free to expand this list with tools specific to your use case!

Configuring Swap Space

If your server runs out of RAM, it can crash processes or become unresponsive. One way to prevent this is by adding swap space – a portion of disk that acts as backup memory.

The caveat is that it is slower than RAM since data is written to the disk. However, it provides valuable safety against out-of-memory situations.

Personal Tip: I usually configure swap space on servers with SSD or NVMe storage. On older machines, adding more RAM is often the better choice.

First, check if your server already has existing swap space by running:

sudo swapon --show

If you receive no output, it means that swap space has not been added. You can confirm this by using the free -h command.

A common rule of thumb is to allocate swap space equal to your RAM, or double it if you have disk space to spare.

Here's how to create a 1 GB swap file:

sudo fallocate -l 1G /swapfile

Swap files must only be accessible to root. Set the correct permissions:

sudo chmod 600 /swapfile

Next, mark the file for swap usage:

sudo mkswap /swapfile

Then enable it:

sudo swapon /swapfile

Use the free -h command again to check that the swap space is now active.

To keep the swap space active after reboot, add it to the /etc/fstab file:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Your server now has a safety net when memory runs low.

Configuring SMTP Relay

To ensure your server can send important notifications – such as security alerts or upgrade failures – it’s crucial to install Postfix and configure it to use an external SMTP relay.

By relaying email through a trusted SMTP provider, you avoid common pitfalls like blocked ports or blacklisted IPs that can prevent your server from delivering mail reliably.

These notifications are especially valuable for things like:

Without a working mail configuration, you might miss out on critical issues until it's too late.

👉
I’ve written a dedicated guide on configuring Postfix with SMTP2GO, a reliable free SMTP relay that works great with most server setups.

If you're looking for full control over email delivery and want to manage your own SMTP infrastructure, I also have a detailed guide on building your own SMTP server with Postal. You can use Postal as a smart host, letting other servers send email through it securely.

Choose what fits your setup – whether it’s a third-party SMTP provider or a self-hosted solution – but don’t skip this step.

A silent server is a dangerous one.

Applying Changes

Once you've gone through all the setup steps – including updates, user configuration, SSH hardening, firewall rules, swap space, and more – it’s a good idea to reboot your server.

This ensures that all changes are properly applied and any pending updates or configurations take full effect.

Run this command to reboot your server:

sudo reboot

After a few moments, your server will come back online with all configurations in place.

You're now ready to move forward with whatever you’ve planned for your new server.

Planning to Use Docker?

If you're anything like me, Docker is probably one of the first tools you’ll want to install next. I use Docker on almost every server I manage, so I’ve made it a default part of my preparation routine.

Docker lets you run applications inside containers – lightweight, portable, and consistent environments that behave the same across development and production.

To get it installed properly, I recommend using Docker’s official repository rather than the default Ubuntu packages – that way, you get the latest stable releases and important security updates.

👉
I’ve written a dedicated guide that walks you through the entire process: Installing Docker and Docker Compose on Ubuntu

If Docker is part of your workflow – as it is in mine – this guide will help you set it up the right way.

Using the SSH Config File

When managing multiple servers, typing long SSH commands can get repetitive. That’s where the SSH config file comes in – it acts like an address book for your servers, making SSH connections easier and more organized.

Instead of typing the full SSH command every time, you can define shortcuts for each server.

Start by creating the config file on your local machine (not on the server):

touch ~/.ssh/config

Now, open the file with your preferred editor and add a block like this:

Host server1
        HostName 81.41.156.93
        User ivan
        Port 22
        IdentityFile ~/.ssh/id_rsa

In this example:

  • server1 is a nickname for the server.
  • HostName is the server’s IP address.
  • User is the user you use to log in (in this case, ivan).
  • Port is the SSH port (22 is default, so you can skip it unless it’s custom).
  • IdentityFile is the path to your private SSH key.

Without a config file, connecting looks like this:

ssh -p 22 -i ~/.ssh/id_rsa ivan@81.41.156.93

But with the config file set up, all you need is:

ssh server1

Simple, right?

Now, update the values to match your own server details. If you haven’t changed the SSH port, you can skip the Port line entirely.

💡
Tip: Managing multiple servers? Just add a new Host block for each one inside the same config file.

Conclusion and Final Thoughts

🎉 Congratulations – you’ve reached the end of this guide!

By now, you’ve successfully prepared your Ubuntu server for its first use and laid a solid foundation for managing it safely and efficiently.

👉
It’s time to take the security of your server up a notch. You can find my full collection of detailed Linux server security guides here.

💬 Found this guide helpful?

I’d love to hear your thoughts, questions, or suggestions in the discussion section below. Your feedback helps improve future guides and supports others on their server journey.

Prefer a more direct conversation? Feel free to contact me anytime.