Skip to content

Host a static website on Quake AI

Tutorial · Updated Jun 2026
Before this

Host a static website on Quake AI

In this tutorial, we deploy a static website served by Nginx on a Quake AI instance. By the end, you will have a publicly accessible web page served from your own cloud server, with a public IP you can share or point a domain name to.

What you will learn:

  • How to configure an instance for web hosting
  • How to install and configure Nginx as a web server
  • How to deploy static HTML content
  • How security groups control which ports are accessible from the internet
  • How to verify your website is publicly accessible
VisitorPublic IP(PublicEphemeral)Security groupSSH, HTTP, HTTPSUbuntu instanceNginx + HTML HTTP/HTTPS
Click to zoom
What you'll build: visitor traffic reaches Nginx on an Ubuntu instance via its PublicEphemeral public IP, gated by a security group

Prerequisites#

You need:

  • A Quake AI account with an active project
  • An SSH key pair uploaded to Quake AI (the OpenStack name is your key pair name)
  • Completed the Quickstart

The PublicEphemeral network assigns a public IP to the instance at boot, so this tutorial needs no private network, router, or floating IP. We use the OpenStack CLI so you can reproduce every step from your terminal.

Follow Generate app credentials to create and download your credentials file.

Source the file to load credentials into your shell session:

bash
source ~/path/to/openrc.sh

Substitute these placeholders in the commands: YOUR_KEYPAIR_NAME for your uploaded key pair, and UBUNTU_22_IMAGE_NAME from openstack image list for Ubuntu 22.04 (names vary by region, for example Ubuntu 22.04 or Ubuntu-22.04).

Step 1: Create a security group for SSH, HTTP, and HTTPS#

Security groups filter traffic to instance ports. Without ingress rules for 22, 80, and 443, clients cannot reach SSH or Nginx from the internet. We use a dedicated group so the rules stay organized and auditable.

bash
openstack security group create tutorial-static-web \
  --description "SSH, HTTP, and HTTPS for static site tutorial"
openstack security group rule create \
  --protocol tcp --dst-port 22 --remote-ip 0.0.0.0/0 \
  tutorial-static-web
openstack security group rule create \
  --protocol tcp --dst-port 80 --remote-ip 0.0.0.0/0 \
  tutorial-static-web
openstack security group rule create \
  --protocol tcp --dst-port 443 --remote-ip 0.0.0.0/0 \
  tutorial-static-web

We use 0.0.0.0/0 so any client can reach the tutorial instance. In production, narrow SSH sources and put a self-managed reverse proxy in front of HTTP services.

Step 2: Launch an Ubuntu 22.04 instance#

We attach the instance to PublicEphemeral, which assigns a public IP at boot, and combine default and tutorial-static-web so baseline project behavior stays in place while our rules open the web ports.

bash
openstack server create \
  --flavor s1a.micro \
  --image UBUNTU_22_IMAGE_NAME \
  --network PublicEphemeral \
  --key-name YOUR_KEYPAIR_NAME \
  --security-group default \
  --security-group tutorial-static-web \
  --wait \
  tutorial-web-vm

The command returns when the server reaches ACTIVE.

Step 3: Find the instance public IP#

PublicEphemeral assigns the public address at boot, so there is no floating IP to allocate. Read the address from the instance and save it for the SSH and browser checks:

bash
INSTANCE_IP=$(openstack server show tutorial-web-vm -f value -c addresses | sed 's/.*=//')
echo "$INSTANCE_IP"

Step 4: SSH into the instance#

Ubuntu cloud images use the ubuntu user. Connect with the private key that matches YOUR_KEYPAIR_NAME:

bash
ssh -i /path/to/YOUR_PRIVATE_KEY ubuntu@$INSTANCE_IP

Accept the host key the first time you connect.

Step 5: Install Nginx#

Nginx is a small, efficient choice for static files.

bash
sudo apt update
sudo apt install -y nginx

If apt cannot resolve the archives, your subnet is missing DNS resolvers. Run the DNS check in Prerequisites before you retry.

Step 6: Add a simple HTML page#

Ubuntu's default document root is /var/www/html/. Replace the stock page:

bash
sudo tee /var/www/html/index.html > /dev/null <<'EOF'
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hosted on Quake AI</title></head>
<body><h1>Hello from Quake AI</h1><p>Static HTML served by Nginx.</p></body>
</html>
EOF

Step 7: Verify Nginx locally on the instance#

Confirm the service and HTTP response on the instance before testing from the internet.

bash
systemctl is-active nginx
curl -s http://127.0.0.1/ | head -n 5

Expect active and your heading in the curl output.

Step 8: Open the site in your browser#

Open http://$INSTANCE_IP in a browser. If it fails, recheck security group rules, confirm the public address with openstack server show tutorial-web-vm -c addresses, and rule out local port blocking.

Step 9: (optional) self-signed HTTPS for learning#

Self-signed certificates trigger browser warnings; they only demonstrate TLS termination in Nginx before you use a public CA.

bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/nginx-selfsigned.key \
  -out /etc/ssl/certs/nginx-selfsigned.crt \
  -subj "/CN=TUTORIAL_HOSTNAME"
sudo tee /etc/nginx/sites-available/tutorial-tls.conf > /dev/null <<'EOF'
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name _;
    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
    root /var/www/html;
    index index.html;
}
EOF
sudo ln -sf /etc/nginx/sites-available/tutorial-tls.conf /etc/nginx/sites-enabled/tutorial-tls.conf
sudo nginx -t && sudo systemctl reload nginx

Visit https://$INSTANCE_IP and accept the expected certificate warning.

Step 10: (optional) production HTTPS with Let's Encrypt#

For HTTPS with a custom domain and a trusted certificate, install Certbot after pointing your domain's DNS A record to the instance public IP:

bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com

Certbot adds HTTPS configuration to Nginx and sets up automatic certificate renewal. You will need to add an HTTPS rule (TCP port 443) to your tutorial-static-web security group before HTTPS will work, use the same openstack security group rule create pattern as Step 1.

Cloud-init alternative (zero-touch setup)#

If you want to skip Steps 4–6 and have Nginx installed automatically at first boot, save this as cloud-init-nginx.yaml on your local machine:

YAML
#cloud-config
package_update: true
packages:
  - nginx

write_files:
  - path: /var/www/html/index.html
    content: |
      <!doctype html>
      <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>My Quake AI Site</title>
      </head>
      <body>
        <h1>Hello from Quake AI</h1>
        <p>This static site is served by Nginx, configured by cloud-init.</p>
      </body>
      </html>

runcmd:
  - systemctl enable nginx
  - systemctl start nginx

Pass it on openstack server create with --user-data cloud-init-nginx.yaml. Cloud-init takes 1–2 minutes after boot to finish; once the instance is ACTIVE and cloud-init completes, the site is live.

Deploy your own content#

Replace the placeholder page with your site files from your local machine:

bash
scp -r ./my-site/* ubuntu@$INSTANCE_IP:/var/www/html/

Or use rsync for incremental updates:

bash
rsync -avz --delete ./my-site/ ubuntu@$INSTANCE_IP:/var/www/html/

What you learned#

  • Security groups for SSH, HTTP, and HTTPS, and why each port is opened
  • Instance launch with Ubuntu 22.04, flavor s1a.micro, the PublicEphemeral public network, and the web security group
  • Public addressing with the public IP PublicEphemeral assigns at boot
  • Nginx install, static content under /var/www/html/, local and remote checks
  • Optional TLS with a self-signed certificate

Next steps#

Clean up#

Delete the server, then remove the security group. The PublicEphemeral public IP is released with the instance, so there is no floating IP to delete:

bash
openstack server delete tutorial-web-vm
openstack security group delete tutorial-static-web

Confirm openstack server list no longer shows tutorial-web-vm.

Usage Guidelines

The sample code, software libraries, command line tools, proofs of concept, templates, and other related technology on this page (including any of the foregoing that is provided by Quake AI personnel) is provided to you as Quake AI Content under the Quake AI Customer Agreement, or the relevant written agreement between you and Quake AI (whichever applies). Do not use this Quake AI Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the Quake AI Content (such as sample code) as appropriate for production grade use based on your specific quality control practices and standards. Deploying Quake AI Content may incur Quake AI charges for creating or using Quake AI chargeable resources, such as running Compute instances or storing data in Object Storage. Your use is also subject to the Acceptable Use Policy.

For the full policy, see Usage Guidelines.

Last validated: 04.06.2026

Quick answers

Was this page helpful?