3 minute read


I recently built a Debian server to host my personal projects, portfolio, and development tools.
This tutorial walks through how to set up a similar environment — complete with a web server, secure file sharing via SFTP, remote desktop access using SSH/RDP, and a private VPN connection using Tailscale.

At the end, you’ll have a fully functional Debian-based home server that’s accessible securely from anywhere without exposing ports to the public Internet.


Requirements

Before we begin, make sure you have:

  • A Debian or Ubuntu-based system (physical or virtual machine)
  • sudo privileges
  • A Tailscale account (https://tailscale.com)
  • Stable Internet connection

Note: This guide assumes you’re familiar with basic Linux commands. If not, take a few minutes to review file permissions, service management (systemctl), and basic networking.


Step 1: System Preparation

Update the system and install essential tools:

sudo apt update && sudo apt upgrade -y
sudo apt install vim curl wget git ufw -y

Enable the firewall and allow SSH access:

sudo ufw allow ssh
sudo ufw enable
sudo ufw status

Check your IP and hostname:

hostnamectl
ip a

Step 2: Web Server Setup

We’ll use Apache and Node.js for hosting websites and APIs.

Install Apache

sudo apt install apache2 -y
sudo systemctl enable apache2
sudo systemctl start apache2

You can verify the web server is running by visiting your server’s IP address in a browser. You should see the default Apache welcome page.

Install Node.js (for backend or API hosting)

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -v
npm -v

Step 3: Secure File Transfer (SFTP)

You can use the built-in SSH server for secure file transfers via SFTP.

Ensure SSH is running:

sudo systemctl enable ssh
sudo systemctl start ssh

To connect securely from another machine:

sftp username@<server-ip>

For example, from macOS or Linux:

sftp wolf@192.168.1.50

Step 4: Remote Access via SSH and RDP

SSH Access

You can remotely manage your Debian server via SSH.

From another device:

ssh username@<server-ip>

RDP (Remote Desktop)

Install xRDP for GUI-based remote access:

sudo apt install xrdp -y
sudo systemctl enable xrdp
sudo systemctl start xrdp

Now you can connect from any RDP client (like Microsoft Remote Desktop) using:

server_ip:3389

Step 5: Private Networking with Tailscale

Tailscale allows you to connect securely to your Debian server from anywhere, without opening firewall ports.

Install Tailscale

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Log in via the URL provided in your terminal. Once authenticated, you can access your server from any other Tailscale-connected device.

Check status:

sudo tailscale status

You’ll see something like:

100.101.102.103   wolf@debian-server   active; relay "syd" (Australia)

Step 6: Network Isolation & NAT Hole Punching

Your server remains isolated from the public Internet — only accessible through your Tailscale network. Tailscale automatically uses NAT traversal (hole punching) to establish peer-to-peer connections, bypassing the need for manual port forwarding.

To verify your server is only reachable via Tailscale:

sudo ufw deny from any to any
sudo ufw allow in on tailscale0
sudo ufw reload

Step 7: Hosting Your Projects

Now you can host your personal projects, websites, or APIs.

Example: Hosting your portfolio at ashenperera.com

Place your files in:

/var/www/html/

Restart Apache:

sudo systemctl restart apache2

Your website should now be live within your Tailscale network or through your public domain (if configured with DNS and HTTPS).


Step 8: Optional – Enable HTTPS with Let’s Encrypt

If your server is public-facing, use Certbot to enable HTTPS:

sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache

Renew certificates automatically:

sudo systemctl enable certbot.timer

Testing & Maintenance

Check that all services are active:

sudo systemctl status apache2
sudo systemctl status ssh
sudo systemctl status xrdp
sudo systemctl status tailscaled

Reboot and confirm everything starts automatically:

sudo reboot

After reboot, reconnect using Tailscale IP:

ssh username@100.x.x.x

Resources