Skip to content

Static Website

Static websites are websites that consist of HTML, JavaScript, CSS, and other files that are ready to be sent directly to a user's browser, similar to downloading files from cloud storage. Some static websites can be developed without additional frameworks (simply by writing HTML and JavaScript), while others can be generated using static site generators based on templates, such as Hugo, Jekyll, or MkDocs (if you're building documentation websites). A full list of static site generators can be found at Awesome Static Web Site Generators. Regardless of how you create the static website, you'll need a web server to make it accessible online.

In this example, we will deploy a static website in two different ways:

  • Using Caddy (a proxy server used throughout this handbook) without containers. This is the lightest and fastest way to deploy a static website on a cloud server, offering automated HTTPS, custom domains, and automatic restart in case the server reboots.
  • Using containers and Docker. This option requires more resources but works better when you need multiple environments or want to host many websites on a single server.

Both options provide a way to deploy with a single command from a local repository, ensuring that your setup remains reliable and scalable (scalability depends on your cloud provider).

Prerequisites for Both Options

  • A server with a public IP address, running Ubuntu 22.04, and SSH access. You can use any cloud provider, but we recommend those listed in the "Getting a Cloud Server, Setting Backups" chapter. The IP address used in this example is 151.115.51.131—be sure to replace it with the IP of your server.
  • A domain or subdomain with an A record pointing to your server's IPv4 address. If you don’t know how to add an A record, check the chapter "Where to Buy Domains and How to Connect Them to Servers". In this example, I will use demo-static.turbocloud.dev.

Deploy a Static Website Without Containers

Deployment Steps

This is the simplest way to deploy a static website, requiring only one service on your server: Caddy Server. Let’s walk through the steps to deploy a static website.

  • Upload the website folder to your server (replace "folder_with_website" and "151.115.51.131" with your actual folder and server IP):
cd folder_with_website
scp -r . root@151.115.51.131:website 
  • SSH into the server (replace "151.115.51.131" with your server's IP):
ssh root@151.115.51.131
  • Check the uploaded website files:
ls -la

You should see the "website" folder.

  • Install Caddy (this service will act as a web server to serve your static files and handle HTTPS certificates):
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
  • Create a Caddy configuration file to serve the website you uploaded, telling Caddy to respond to all requests to your domain with your website content:
rm /etc/caddy/Caddyfile
sudo echo -e "demo-static.turbocloud.dev {\nroot * /root/website\nencode gzip\nfile_server \n{        hide .git/n    }\n}" >> /etc/caddy/Caddyfile
caddy reload -c /etc/caddy/Caddyfile
  • Verify that your website is live. After 30 seconds, visit your domain (e.g., https://demo-static.turbocloud.dev).

How to Update the Website

To update the website, simply upload the new files (run commands below on your development machine):

cd folder_with_website
scp -r . root@151.115.51.131:website 

Then, verify the updates by visiting your domain in the browser.

How to Add a New Domain

  • Add an A record in DNS, pointing to your server's IPv4 address.
  • Update the Caddy configuration:
sudo echo -e "new-domain.com {\nroot * /root/website\nencode gzip\n}" >> /etc/caddy/Caddyfile
caddy reload -c /etc/caddy/Caddyfile

Deploy a Static Website with Docker

Deploying with Docker involves more steps and requires additional server resources, but it is ideal for hosting multiple websites or handling high traffic. This option also provides better security by isolating environments.

  • Create a Dockerfile in the local repository with your website:
cd folder_with_website
echo -e "FROM joseluisq/static-web-server:2-alpine\nCOPY ./ public/" >> Dockerfile
  • Upload the website folder (replace "folder_with_website" and "151.115.51.131" with the actual folder and server IP):
scp -r . root@151.115.51.131:website 
  • SSH into the server (replace "151.115.51.131" with your server IP):
ssh root@151.115.51.131
  • Install Caddy:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
  • Install Docker:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  • Build and start a Docker container using the Dockerfile you created:
sudo docker image rm website
sudo docker build website -t website
sudo docker container rm website --force

sudo docker run -it -d --restart unless-stopped -p 5000:80 website
  • Create a Caddy configuration file to reverse-proxy requests to your Docker container:
rm /etc/caddy/Caddyfile
sudo echo -e "demo-static.turbocloud.dev {\nreverse_proxy * localhost:5000\n}" >> /etc/caddy/Caddyfile
caddy reload -c /etc/caddy/Caddyfile
  • Verify your website. After 20–30 seconds, open your domain (e.g., https://demo-static.turbocloud.dev) to ensure it’s working.