KAHIBARO
Discord Login Register

23.3. Linux Server Setup

Why Linux For Backend Servers

Most production backends run on Linux. It is free, stable, scriptable, and most server tools are built for it first.

As a backend developer you do not need to become a full Linux administrator, but you must be comfortable enough to:

This chapter focuses on what you actually do when you get a fresh Linux server for deployment.

Goal of this chapter
After this chapter you should be able to log into a new Linux VPS, perform basic setup, and prepare it to run a backend application.

Choosing a Linux Distribution

For servers you almost always use a distribution like:

FamilyExamplesPackage managerTypical usage
Debian-basedUbuntu Server, DebianaptVery common for web apps and VPS
RHEL-basedCentOS Stream, Rocky, Almadnf / yumEnterprise data centers
OthersArch, openSUSEVariousLess common for beginners on servers

For this course, you can assume Ubuntu Server LTS on a cloud VPS, because:

If you see examples using dnf or yum, you can usually translate them:

ActionUbuntu / DebianRHEL family
Update packagessudo apt updatesudo dnf update
Upgrade systemsudo apt upgradesudo dnf upgrade
Install packagesudo apt install nginxsudo dnf install nginx
Remove packagesudo apt remove nginxsudo dnf remove nginx

Connecting To Your Server With SSH

You normally access a remote Linux server using SSH (Secure Shell).

Creating an SSH key

On your local machine (Linux, macOS, or WSL on Windows):

bash
ssh-keygen -t ed25519 -C "your_email@example.com"

You will be asked:

This creates two files:

FileDescription
~/.ssh/id_ed25519Private key, keep it secret
~/.ssh/id_ed25519.pubPublic key, safe to share

Important
Never share your private key (id_ed25519 or id_rsa). Share only the .pub file.

View your public key:

bash
cat ~/.ssh/id_ed25519.pub

Copy this line. You will add it to the server.

Adding your SSH key to the server

Most cloud providers (DigitalOcean, AWS, etc.) let you paste your SSH public key during server creation. They put it into /home/youruser/.ssh/authorized_keys for you.

If you only have password access initially, you can:

  1. Connect with password:
bash
ssh root@YOUR_SERVER_IP
  1. On the server, create the .ssh directory for your user:
bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
  1. Edit authorized_keys and paste your public key:
bash
nano ~/.ssh/authorized_keys
# paste the content of your .pub key
chmod 600 ~/.ssh/authorized_keys

After that, you can log in with your key.

Logging in via SSH

From your local machine:

bash
ssh youruser@YOUR_SERVER_IP

If you are using the default root user (not recommended long term):

bash
ssh root@YOUR_SERVER_IP

You will see a shell prompt like:

text
youruser@server-name:~$

You are now working on the remote server.

Creating a Non-Root User

Running everything as root is dangerous. A safer pattern:

  1. Create a regular user.
  2. Give it sudo permissions.

As root on the server:

bash
adduser deploy
# follow prompts for password and info

Add the user to the sudo group (on Ubuntu):

bash
usermod -aG sudo deploy

Switch to that user:

bash
su - deploy

Now test sudo:

bash
sudo ls /root

It should ask for deploy's password and then show the directory listing.

Next, copy your SSH authorized keys from root to deploy (if the provider added them to root):

bash
rsync --archive --chown=deploy:deploy /root/.ssh /home/deploy

Now you can exit and reconnect as deploy:

bash
exit  # leave root
ssh deploy@YOUR_SERVER_IP

From now on, use this non-root user with sudo for administration.

Basic File System Navigation

When you log in you are in your home directory, for example /home/deploy.

Useful paths on a server:

PathPurpose
/home/userUser home directories
/var/wwwOften used for web app code
/etcConfiguration files for services
/var/logLog files
/usr/binSystem binaries
/tmpTemporary files

Basic commands:

bash
pwd              # show current directory
ls               # list files
ls -la           # list with details and hidden files
cd /var/www      # change directory
cd ~             # go back to home
mkdir myapp      # create directory
rm file.txt      # remove file
rm -r dir        # remove directory recursively

Example session:

bash
cd /var
ls
cd www
sudo mkdir myapp
sudo chown deploy:deploy myapp
cd myapp
pwd   # /var/www/myapp

Installing System Packages

On Ubuntu and similar:

  1. Update package index:
bash
sudo apt update
  1. Upgrade installed packages:
bash
sudo apt upgrade
  1. Install a package, for example Git:
bash
sudo apt install git
  1. Remove a package:
bash
sudo apt remove git
  1. Search for packages:
bash
apt search postgres

Some typical packages for backend servers:

PurposePackage examples
Web servernginx
Database clientpostgresql-client, mysql-client
VCSgit
Basic toolscurl, wget, htop, zip
Pythonpython3, python3-venv, python3-pip

System Users, Groups, and Permissions

Linux has users and groups. Each file has an owner, a group, and three sets of permissions:

See file details:

bash
ls -l

You might see:

text
-rw-r--r-- 1 deploy deploy  1234 Aug 28 12:00 config.json
drwxr-xr-x 2 deploy deploy  4096 Aug 28 12:01 logs

Breakdown of the first line:

PartMeaning
-rw-r--r--File type and permissions
deployOwner
deployGroup

Permissions are in order r (read), w (write), x (execute):

Change owner:

bash
sudo chown deploy:deploy /var/www/myapp

Change permissions:

bash
chmod 640 config.json   # owner rw, group r, others none
chmod 755 scripts.sh    # typical for executable scripts

Typical app dir permissions

  • Application code: deploy:deploy, 755 directories, 644 files
  • Configuration files with secrets: 600 or 640, owner-only or owner+group

Process Management and Services

You will need to:

Checking processes

Use ps or htop:

bash
ps aux | grep python

This lists running processes. htop (if installed) is interactive:

bash
sudo apt install htop
htop

systemd services

Most modern distributions use systemd with systemctl to manage services.

Common commands:

bash
# Check service status
sudo systemctl status nginx
# Start / stop / restart
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
# Enable service on boot
sudo systemctl enable nginx
# Disable on boot
sudo systemctl disable nginx

Shortcut to see if a service is running:

bash
systemctl is-active nginx
# prints: active, inactive, failed, etc.

Opening, Editing, and Viewing Files

You must be able to edit configuration files on the server.

Useful tools:

ToolTypeUsage
catViewerPrint a file
lessPagerScroll through a file
nanoText editor, easyGood for beginners
vimAdvanced editorPowerful but steeper learning curve

Examples:

bash
cat /etc/os-release       # view OS info
less /var/log/syslog      # scroll system log
nano /etc/nginx/nginx.conf  # edit nginx config

In nano:

Basic Networking on the Server

You often need to:

Checking the IP address

bash
ip a

Look for something like inet 203.0.113.10/24 on a non-loopback interface, that is your server IP.

Testing connectivity

To check if you can reach a host:

bash
ping google.com
# Ctrl+C to stop

To fetch a URL from the server:

bash
curl https://example.com

Checking listening ports

To see which ports your server is listening on, use ss:

bash
sudo ss -tulnp

Options:

Typical output line:

text
LISTEN 0 128 0.0.0.0:80  0.0.0.0:*  users:(("nginx",pid=1234,fd=6))

This means nginx is listening on port 80 on all network interfaces.

Firewalls and Basic Security

On Ubuntu, a simple firewall tool is UFW (Uncomplicated Firewall).

Basic UFW usage

Install (if not present):

bash
sudo apt install ufw

Check status:

bash
sudo ufw status

Allow SSH and HTTP/HTTPS:

bash
sudo ufw allow OpenSSH
sudo ufw allow http
sudo ufw allow https

Enable firewall:

bash
sudo ufw enable

List rules:

bash
sudo ufw status numbered

Delete a rule:

bash
sudo ufw delete 1   # deletes rule number 1 from the list

Careful with firewalls
Always ensure SSH is allowed before enabling the firewall, or you can lock yourself out:
sudo ufw allow OpenSSH first, then sudo ufw enable.

Installing Runtime Environments

You will install your app runtime, for example Python or Node.js. The exact details belong to other chapters, but the general server-side pattern is similar.

Example: Python runtime on Ubuntu

Install Python and tools:

bash
sudo apt update
sudo apt install python3 python3-venv python3-pip

Verify:

bash
python3 --version
pip3 --version

Create a directory for your app:

bash
sudo mkdir -p /var/www/myapp
sudo chown deploy:deploy /var/www/myapp
cd /var/www/myapp

Create a virtual environment:

bash
python3 -m venv venv
source venv/bin/activate
pip install fastapi uvicorn[standard]

You now have a Python environment dedicated to this app.

Running Your Application as a Service

Running your app in a terminal with uvicorn main:app is not enough for production. You want:

On systemd systems you create a service unit.

Example systemd service for a FastAPI app

Assume:

Create a service file:

bash
sudo nano /etc/systemd/system/myapp.service

Contents:

ini
[Unit]
Description=My FastAPI Application
After=network.target
[Service]
User=deploy
Group=deploy
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
ExecStart=/var/www/myapp/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target

Save and exit.

Reload systemd:

bash
sudo systemctl daemon-reload

Start and enable:

bash
sudo systemctl start myapp
sudo systemctl enable myapp

Check status:

bash
sudo systemctl status myapp

You can now stop / start / restart your app via:

bash
sudo systemctl restart myapp

Logs:

bash
journalctl -u myapp -f

-f follows logs in real time, like tail -f.

Logs and Monitoring Basics

Logs help you debug issues on a live server.

Common log locations:

TypeLocation examples
System logs/var/log/syslog, /var/log/messages
Auth logs/var/log/auth.log
Nginx logs/var/log/nginx/access.log, error.log
App logsCustom, often under /var/www/myapp/logs

View logs:

bash
sudo tail -n 100 /var/log/syslog
sudo tail -f /var/log/nginx/error.log

For systemd services:

bash
journalctl -u myapp -n 50     # last 50 lines
journalctl -u myapp -f        # follow

Learning to read logs is critical for troubleshooting in production.

Simple Troubleshooting Workflow

When your backend is "not working" on a Linux server, use a systematic approach.

Example checklist:

  1. Is the app service running?
bash
sudo systemctl status myapp
  1. Any recent errors in app logs?
bash
journalctl -u myapp -n 50
  1. Is the app listening on the expected port?
bash
sudo ss -tulnp | grep 8000
  1. Can the server itself reach the app?
bash
curl http://127.0.0.1:8000/health
  1. Is the firewall letting traffic through?
bash
sudo ufw status
  1. If behind Nginx or another reverse proxy, are its logs clean?
bash
sudo tail -n 100 /var/log/nginx/error.log

As you gain experience, this kind of routine becomes quicker and mostly automatic.

Summary

In this chapter you learned:

These are the core Linux skills you need to prepare a server for production deployment. In the next chapters you will build on this foundation to containerize and deploy your backend applications.

Views: 8

Comments

Please login to add a comment.

Don't have an account? Register now!