Self-Hosting Your Website in 2026: Complete Guide (VPS, Docker, HTTPS)
2026 technical guide to self-hosting on a VPS: choosing plans, Docker setup, Let's Encrypt HTTPS, security, and real costs. Compare self-hosting vs. cloud.
Hosting your own website in 2026 is no longer reserved for sysadmin experts or geeks with symmetric fiber connections. With the maturity of containerization tools, the democratization of free SSL certificates, and the drop in cloud infrastructure costs, the barrier to entry has decreased significantly. Yet, the temptation of the “click-and-go” SaaS platforms (Wix, Shopify, WordPress.com) remains strong.
This guide does not aim to convince you to become a full-time system administrator, but to provide a precise technical roadmap to regain control of your data, bandwidth, and long-term costs. We will deconstruct the process of installing a site (static, WordPress, or web application) on a VPS (Virtual Private Server), emphasizing robustness, security, and reproducibility via Docker.
Before diving into terminal commands, it is crucial to understand the arena you are entering. Physical self-hosting at home and VPS self-hosting are two distinct paradigms, with very different technical and financial trade-offs.
Self-hosting vs VPS: The technical duel
The first decision to make is hardware-related. Do you have a PC running 24/7 in your living room, or will you rent a remote server?
Physical self-hosting (Home Lab)
This is the “old-school” option. You use an old laptop, a Raspberry Pi, or a mini-PC as a server.
- Advantages: One-time hardware cost (often already amortized), no dependency on a cloud provider for immediate availability, total control over hardware.
- Major drawbacks: Upload bandwidth is rarely symmetric (often 10-20 Mbps upload for a consumer connection), making the site slow for distant visitors. Furthermore, Internet Service Providers (ISPs) often block incoming ports 80 and 443, requiring complex tunneling solutions (Cloudflare Tunnel, Tailscale). Reliability depends on your electricity and connection.
- Verdict: Ideal for internal projects, media (Jellyfin), or learning, but not recommended for a critical public site requiring high availability and low global latency.
VPS (Virtual Private Server)
A VPS is a dedicated virtual machine rented from a host (Hetzner, OVH, DigitalOcean, AWS Lightsail).
- Advantages: Public fixed IP, high and symmetric bandwidth, guaranteed availability (SLA), remote reboot possible, data geographically close to your audience.
- Drawbacks: Recurring monthly cost. Security responsibility (firewall, OS updates) rests entirely on you.
- Verdict: The industrial standard for hosting a public site. It is the rational choice for performance, network simplicity, and professionalizing your infrastructure.
For the rest of this tutorial, we will assume you have opted for a VPS. It is the most reliable way to ensure your site stays online, fast, and secure without having to manage the noise of your fan at 3 AM.
Step 1: Choosing the right VPS offer
The VPS market in 2026 is saturated, but quality varies. Avoid generalist consumer hosts that sell “cloud” at rock-bottom prices but with poor disk I/O performance. Prefer hosts specialized in infrastructure.
Benchmarks and real costs
Here is a comparative analysis based on the average needs of a modern website in 2026.
| Criterion | Entry-level (Blog/Static) | Mid-range (WordPress/DB) | High Performance (App/API) |
|---|---|---|---|
| CPU | 1 vCPU (e.g., AMD EPYC) | 2 vCPU | 4+ vCPU |
| RAM | 1 GB - 2 GB | 4 GB | 8 GB+ |
| Storage | 20 GB NVMe SSD | 50 GB NVMe SSD | 100 GB+ NVMe |
| Bandwidth | 1-2 TB/month | 2-5 TB/month | Unlimited or very high |
| Monthly Cost | ~€3 - €5 | ~€8 - €15 | ~€20 - €40 |
| Host Types | Hetzner Cloud, DigitalOcean | Hetzner, OVH, Linode | AWS, GCP, DigitalOcean |
Technical Analysis: For a WordPress site with a local database, 1 GB of RAM is often too tight if you don’t do aggressive tuning. The MySQL/MariaDB engine consumes a lot of memory. 4 GB is the comfortable floor to avoid swap (which kills disk performance). For a static site (Hugo, Jekyll) or a lightweight Node.js app, 1 GB is more than enough.
Our recommendation: Start small. It is always possible to scale up on most modern cloud platforms without migrating your data. Choose a host that allows easy disk or snapshot migration.
Step 2: Initial server hardening
Once your VPS is provisioned, you receive an IP address and a root password via email. Do not connect directly with root via password for the rest of the process. The first thing to do is to harden SSH access.
-
Create a dedicated user:
adduser monuser usermod -aG sudo monuser -
Configure SSH keys: Generate an SSH key on your local machine (
ssh-keygen) and copy it to the server (ssh-copy-id monuser@IP_OF_VPS). -
Disable root login and password login: Edit
/etc/ssh/sshd_config:PermitRootLogin no PasswordAuthentication noRestart the SSH service (
systemctl restart sshd). -
Configure the firewall (UFW): Enable the firewall and allow only necessary traffic.
sudo ufw allow OpenSSH sudo ufw allow 80/tcp # HTTP sudo ufw allow 443/tcp # HTTPS sudo ufw enable
These steps eliminate 90% of automated attacks (brute force) that plague servers exposed to the public internet.
Step 3: Installing Docker and Docker Compose
Forget manual installation of Nginx, PHP, MySQL, or Node.js on the filesystem. In 2026, the standard is container isolation. Docker allows you to deploy your web stack in a reproducible, clean, and easy-to-update manner.
Installing Docker
The safest method is to use the official installation script or the packages from the Docker repository.
# System update
sudo apt update && sudo apt upgrade -y
# Install dependencies
sudo apt install ca-certificates curl gnupg
# Add the official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Verify the installation:
sudo docker run hello-world
sudo docker compose version
Project structure
Create a directory for your site. For example, for a WordPress site or static app, the file structure will be crucial for maintenance.
/home/monuser/web-app/
├── docker-compose.yml
├── .env
├── nginx/
│ └── nginx.conf
├── app/
│ └── (your source code here)
└── data/
└── (for databases or uploads)
Step 4: Deploying a site (Concrete cases)
Case A: Static Site (HTML/CSS/JS or generator)
This is the simplest and most performant case. You only need an Nginx container serving static files.
Create a docker-compose.yml file:
version: '3.8'
services:
web:
image: nginx:alpine
container_name: mon_site_statique
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./app:/usr/share/nginx/html:ro
- ./nginx/conf.d:/etc/nginx/conf.d
- ./certs:/etc/nginx/certs
depends_on:
- certbot
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./certs:/etc/letsencrypt
- ./webroot:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
Note: This simplified approach uses a shared volume for certificates. For robust production, it is better to use a dedicated reverse proxy (see below).
Case B: WordPress with Docker
WordPress is more complex as it requires a database. Let’s use MariaDB and PHP-FPM via Nginx.
version: '3.8'
services:
db:
image: mariadb:10.6
container_name: wp_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
MYSQL_DATABASE: wordpress
MYSQL_USER: wp_user
MYSQL_PASSWORD: ${DB_PASS}
volumes:
- db_data:/var/lib/mysql
networks:
- wp_network
wordpress:
image: wordpress:php8.2-fpm
container_name: wp_app
restart: always
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: ${DB_PASS}
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
networks:
- wp_network
nginx:
image: nginx:alpine
container_name: wp_nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- wp_data:/var/www/html
- ./certs:/etc/nginx/certs
depends_on:
- wordpress
networks:
- wp_network
volumes:
db_data:
wp_data:
networks:
wp_network:
In this scenario, you must configure an nginx.conf file in the nginx/conf.d/ folder to proxy_pass to the PHP-FPM container (wordpress:9000). This is the standard method for running PHP in Docker.
Step 5: HTTPS and Let’s Encrypt Certificates
Having a site over HTTP in 2026 is unacceptable. Browsers mark insecure sites as “Not Secure,” which affects SEO and user trust.
The most reliable method is not to generate certificates inside each container, but to use a Reverse Proxy or an external tool that handles automatic renewal.
Recommended approach: Traefik or Nginx Proxy Manager
To keep things simple and without heavy external dependencies, we will use a standard Nginx configuration coupled with Certbot, but in a secure manner.
However, the current best practice is to use Cloudflare Tunnel (if you use Cloudflare) or to configure Certbot in standalone or webroot mode.
Here is how to obtain a valid SSL certificate for your domain monsite.com:
-
Install Certbot on the host (not in a container to simplify port 80/443 management):
sudo apt install certbot -
Stop Nginx if you installed it manually, or ensure it is not listening on 80/443 yet.
-
Obtain the certificate:
sudo certbot certonly --standalone -d monsite.com -d www.monsite.com -
Configure Nginx (in your container or host) to serve files from the
/etc/letsencrypt/live/monsite.com/folder. -
Automate renewal: Certificates expire every 90 days. Create a cron job on the server:
sudo crontab -e # Add this line to check every day at midnight 0 0 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl restart nginx"
If you use Docker, the cleanest way is to use the certbot/certbot image in a dedicated container that mounts certificate volumes, as shown in the static example above.
Step 6: Backups and Recovery
A server without backups is a server waiting for disaster. In self-hosting, you are your own disaster recovery team.
3-2-1 Strategy
- 3 copies of your data.
- 2 different storage media (the VPS disk + an external cloud).
- 1 off-site copy.
Technical implementation
For a VPS, critical data includes:
- Your application files (
app/,wp-content/uploads). - The database.
- Configurations (
docker-compose.yml, Nginx configs, SSH keys).
Simple backup script (backup.sh):
#!/bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="/home/monuser/backups"
REMOTE_DIR="user@remote-server:/backups"
# 1. Database backup (MySQL example)
docker exec wp_db mysqldump -u root -p${DB_ROOT_PASS} wordpress > $BACKUP_DIR/db_$DATE.sql
# 2. Archive files
tar -czf $BACKUP_DIR/files_$DATE.tar.gz /home/monuser/web-app/app
# 3. Upload to remote storage (SCP or Rclone to S3/Backblaze)
scp $BACKUP_DIR/* $REMOTE_DIR/
# 4. Local cleanup (keep only 7 days)
find $BACKUP_DIR -type f -mtime +7 -delete
Make this script executable and schedule it via crontab (e.g., every day at 2 AM). Sending to object storage (S3 compatible) is highly recommended as it is immutable and inexpensive.
Which choice for your profile?
We have seen the technical steps. But technology is just a means. Here is how to choose your approach based on your reality.
Profile 1: The Curious Beginner
- Goal: Learn, host a simple blog.
- Choice: Entry-level VPS (€3-5/month).
- Stack: Docker Compose + Static Site (Hugo/Jekyll) or pre-configured WordPress.
- Why? Less maintenance, fewer security risks related to misconfigured PHP/MySQL. Static is indestructible.
Profile 2: The Developer / Freelancer
- Goal: Host your own apps, dynamic portfolios, APIs.
- Choice: Mid-range VPS (€8-15/month).
- Stack: Advanced Docker Compose, Reverse Proxy (Traefik/Nginx), Monitoring (Prometheus/Grafana or Uptime Kuma).
- Why? You have the skills to manage updates and security. You want the flexibility to deploy any language.
Profile 3: The Enterprise / Critical Site
- Goal: High availability, high traffic, compliance.
- Choice: High-performance VPS or Managed Cloud (Kubernetes, AWS).
- Stack: Infrastructure as Code (Terraform), CI/CD (GitHub Actions), Managed Database (Neon, AWS RDS) to delegate DB management.
- Why? The time spent managing a “home” VPS is too costly compared to the revenue generated. Outsource infrastructure complexity.
FAQ: Frequently Asked Questions
Can I migrate from WordPress.com to my own VPS?
Yes, but be aware of the complexity. WordPress.com (SaaS) handles updates, security, and caching. On your VPS, you have to do everything yourself. Use WordPress’s native export/import tool to retrieve your posts and media. Think about configuring a fast cache (Redis or Varnish) and a CDN (Cloudflare) to compensate for the performance loss of the SaaS.
How long does the initial setup take?
If you are a beginner, count 4 to 8 hours for the first installation, including understanding Docker, SSL configuration, and SSH hardening. Once the base is in place, deploying a new site takes 15 minutes. The learning curve is steep at first, then flattens out.
Is Docker mandatory?
No, but it is highly recommended. You could install Nginx and PHP directly on the OS (apt install nginx php-fpm). However, this creates a “snowflake server” (a unique and hard-to-reproduce server). If the server crashes, you have to reinstall everything manually. With Docker, you restore your server by recreating containers from a docker-compose.yml file. It is a matter of reproducibility and cleanliness.
What if my VPS is hacked?
Prevention is key (OS updates, fail2ban, SSH keys). If the worst happens, do not try to “clean” the server. Start from a clean image (snapshot), restore your data from the last known good backup, and rebuild the infrastructure. Reinstallation is often faster and safer than detoxifying a compromised system.
Conclusion
Hosting your own website in 2026 is a rewarding technical exercise that offers total control over your data and costs. Going through a VPS and Docker represents the current standard for combining performance, security, and ease of maintenance.
Do not underestimate the initial hardening phase and the setup of backups. These two pillars distinguish an unorganized hobbyist from a professional self-hosting practitioner. Start small, document your procedures, and do not hesitate to iterate. Your infrastructure is your code; treat it with the same rigor.