� Back to Documentation

Deploy to Hetzner VPS

For those who prefer full control, deploy on a Hetzner VPS with Nginx configured to serve your launchpage for ANY domain pointing to your server. Perfect for managing multiple domains from a single server.

Why Hetzner VPS?

Prerequisites

Step 1: Set Up the Server

First, SSH into your server and install the required software:

# SSH into your server
ssh root@your-server-ip

# Update system packages
apt update && apt upgrade -y

# Install Nginx and Git
apt install nginx git -y

# Install Certbot for SSL certificates
apt install certbot python3-certbot-nginx -y

Step 2: Clone the Repository

Deploy Launchpage.xyz to your web directory:

# Create web directory
mkdir -p /var/www/launchpage

# Navigate to the directory
cd /var/www/launchpage

# Clone the repository
git clone https://github.com/simplebytes-com/launchpage.xyz.git .

# Set proper permissions
chown -R www-data:www-data /var/www/launchpage
chmod -R 755 /var/www/launchpage

Step 3: Configure Nginx (Catch-All for Any Domain)

Create an Nginx configuration that serves the launchpage for ANY domain pointing to your server:

# Create Nginx configuration file
nano /etc/nginx/sites-available/launchpage

Add this configuration:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # Catch all server names (ANY domain)
    server_name _;

    root /var/www/launchpage;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    # Serve static files with caching
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }
}
Key Configuration: The server_name _; directive is the magic here - it makes Nginx serve your launchpage for ANY domain pointing to this server's IP!

Step 4: Enable the Configuration

# Remove default Nginx configuration
rm /etc/nginx/sites-enabled/default

# Enable our launchpage configuration
ln -s /etc/nginx/sites-available/launchpage /etc/nginx/sites-enabled/

# Test Nginx configuration for syntax errors
nginx -t

# If test passes, restart Nginx
systemctl restart nginx

# Enable Nginx to start on boot
systemctl enable nginx

Step 5: Point Your Domains

For each domain you want to use with your launchpage:

  1. Go to your domain registrar's DNS settings
  2. Add an A record:
    • Type: A
    • Name: @ (for root domain like example.com)
    • Value: Your server IP address (e.g., 157.245.16.45)
    • TTL: 300 (5 minutes) or default
  3. Optionally, add a www subdomain:
    • Type: A
    • Name: www
    • Value: Your server IP address
  4. Wait for DNS propagation (typically 5-30 minutes)

Once DNS propagates, visiting your domain will show the launchpage!

Step 6: Add SSL Certificates (Recommended)

Secure your domains with free Let's Encrypt SSL certificates:

For Specific Domains

If you have specific domains, add SSL for each:

# For a single domain
certbot --nginx -d example.com -d www.example.com

# Follow the prompts:
# - Enter your email address
# - Agree to Terms of Service
# - Choose whether to redirect HTTP to HTTPS (recommended: yes)

This will automatically update your Nginx configuration with SSL settings.

Updated Nginx Config with SSL

After running Certbot, your configuration will look like this:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # SSL certificates (managed by Certbot)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/launchpage;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    # Static file caching
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }
}

Certificate Auto-Renewal

Certbot automatically sets up certificate renewal. Test it with:

# Test renewal process
certbot renew --dry-run

# View renewal timer status
systemctl status certbot.timer

Adding Additional Domains

To add more domains to the same server:

  1. Point the new domain's A record to your server IP
  2. For HTTP only: No additional configuration needed (catch-all works automatically)
  3. For HTTPS: Run Certbot for the new domain:
    certbot --nginx -d newdomain.com -d www.newdomain.com

Updating Your Launchpage

To update to the latest version of Launchpage.xyz:

# Navigate to launchpage directory
cd /var/www/launchpage

# Pull latest changes from Git
git pull origin main

# Reload Nginx to ensure changes are served
systemctl reload nginx

Monitoring and Maintenance

Check Nginx Status

# Check if Nginx is running
systemctl status nginx

# View Nginx error logs
tail -f /var/log/nginx/error.log

# View access logs
tail -f /var/log/nginx/access.log

Firewall Configuration

If using UFW (Ubuntu Firewall), allow HTTP and HTTPS:

# Allow Nginx through firewall
ufw allow 'Nginx Full'

# Check firewall status
ufw status

Collect Emails/Waitlist

To collect email submissions from your launchpage, you'll need to set up a Cloudflare Worker. This allows you to store and access visitor submissions.

Follow our complete guide: Collect Emails/Waitlist →

After setting up the Worker, update the form action in your index.html before deploying to your Hetzner VPS:

<form class="email-form" id="emailForm" method="POST"
      action="https://YOUR-WORKER-URL.workers.dev">

Troubleshooting

Domain not showing launchpage?

SSL certificate not working?

Nginx won't start?

Pro Tip: The catch-all configuration means you can point UNLIMITED domains to your server, and they'll all automatically show the launchpage. Perfect for managing a portfolio of domains!

Performance Optimization

Enable Gzip Compression

Add to your Nginx configuration:

gzip on;
gzip_vary on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;

Add Security Headers

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

Other Deployment Platforms


Need help? Open an issue on GitHub or check the Hetzner documentation.

� Back to Documentation