Static Site Generators

    Hugo & Jekyll on RamNode VPS

    Static site generators transform plain text content into fast, secure, and easily deployable websites. Combined with RamNode's reliable VPS hosting, you get blazing-fast static site delivery.

    Ubuntu 22.04/24.04 LTS
    Nginx or Caddy
    ⏱️ 15-20 minutes

    Hugo vs Jekyll Comparison

    HugoJekyll
    Written in GoWritten in Ruby
    Extremely fast builds (<1ms/page)Mature ecosystem, many plugins
    Single binary, no dependenciesRequires Ruby environment
    Built-in asset pipelineLiquid templating engine
    Best for: Large sites, frequent buildsBest for: Blogs, GitHub Pages users

    Why Static Sites on RamNode VPS? RamNode VPS instances provide the perfect environment for static sites: full root access for custom configurations, SSD storage for blazing-fast file serving, generous bandwidth allocations, and the flexibility to run your own web server optimized for static content delivery.

    Prerequisites

    Before You Begin

    • A RamNode VPS with Ubuntu 22.04 or 24.04 LTS (1GB RAM minimum)
    • SSH access with root or sudo privileges
    • A domain name pointed to your VPS IP address (optional but recommended)
    • Basic familiarity with the Linux command line
    • Git installed on your local machine for content management

    Initial Server Setup

    1

    Connect and Update Server

    Connect to your VPS and update the system packages:

    SSH Connection
    ssh root@your-server-ip
    
    # Update system packages
    apt update && apt upgrade -y
    
    # Install essential tools
    apt install -y git curl wget unzip build-essential
    2

    Create a Non-Root User

    Create a non-root user for daily operations (recommended):

    Create User
    # Create user with sudo privileges
    adduser webadmin
    usermod -aG sudo webadmin
    
    # Switch to new user
    su - webadmin

    Part 1: Hugo Deployment

    Hugo is renowned for its exceptional build speed and simplicity. As a single binary with no external dependencies, it's incredibly easy to install and maintain.

    3

    Install Hugo

    Install Hugo using the official releases for the latest version:

    Install Hugo
    # Download the latest Hugo extended version
    HUGO_VERSION=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep tag_name | cut -d '"' -f4 | sed 's/v//')
    
    wget https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    
    # Install Hugo
    sudo dpkg -i hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    
    # Verify installation
    hugo version

    Why Hugo Extended? The extended version includes SCSS/SASS processing and WebP image encoding capabilities. Most modern Hugo themes require these features.

    4

    Create a Hugo Site

    Create a new Hugo site and add a theme:

    Create Hugo Site
    # Create site directory
    mkdir -p /var/www
    cd /var/www
    
    # Create new Hugo site
    hugo new site mysite
    cd mysite
    
    # Initialize git and add a theme (using PaperMod as example)
    git init
    git submodule add https://github.com/adityatelange/hugo-PaperMod themes/PaperMod
    
    # Configure the theme
    echo 'theme = "PaperMod"' >> hugo.toml
    5

    Configure Hugo

    Edit the hugo.toml configuration file:

    /var/www/mysite/hugo.toml
    baseURL = 'https://yourdomain.com/'
    languageCode = 'en-us'
    title = 'My Hugo Site'
    theme = 'PaperMod'
    
    [params]
      description = 'A fast static site hosted on RamNode'
      author = 'Your Name'
    
    [outputs]
      home = ['HTML', 'RSS', 'JSON']
    6

    Build Hugo Site

    Build the site for production:

    Build Site
    # Build with production settings
    hugo --minify
    
    # Output will be in the 'public' directory
    ls -la public/

    Part 2: Jekyll Deployment

    Jekyll offers a mature ecosystem with extensive plugin support and seamless GitHub Pages integration. It's particularly well-suited for blogs and documentation.

    7

    Install Ruby and Jekyll

    Jekyll requires Ruby 2.7 or higher. We'll use rbenv for Ruby version management:

    Install Ruby
    # Install Ruby dependencies
    sudo apt install -y ruby-full ruby-bundler zlib1g-dev
    
    # Or use rbenv for better version control
    git clone https://github.com/rbenv/rbenv.git ~/.rbenv
    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
    echo 'eval "$(rbenv init -)"' >> ~/.bashrc
    source ~/.bashrc
    
    # Install ruby-build plugin
    git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
    
    # Install Ruby
    rbenv install 3.2.2
    rbenv global 3.2.2

    Install Jekyll and Bundler:

    Install Jekyll
    # Install Jekyll
    gem install jekyll bundler
    
    # Verify installation
    jekyll -v
    bundler -v
    8

    Create a Jekyll Site

    Create a new Jekyll site:

    Create Jekyll Site
    cd /var/www
    
    # Create new Jekyll site
    jekyll new myblog
    cd myblog
    
    # Install dependencies
    bundle install
    9

    Configure Jekyll

    Edit the _config.yml configuration file:

    /var/www/myblog/_config.yml
    title: My Jekyll Blog
    description: A modern blog hosted on RamNode VPS
    baseurl: ""
    url: "https://yourdomain.com"
    
    # Build settings
    markdown: kramdown
    theme: minima
    
    # Performance
    sass:
      style: compressed
    
    # Plugins
    plugins:
      - jekyll-feed
      - jekyll-seo-tag
      - jekyll-sitemap
    10

    Build Jekyll Site

    Build the site for production:

    Build Site
    # Build with production environment
    JEKYLL_ENV=production bundle exec jekyll build
    
    # Output will be in the '_site' directory
    ls -la _site/

    Part 3: Web Server Configuration

    11

    Option A: Nginx Configuration

    Install and configure Nginx for optimal static file serving:

    Install Nginx
    # Install Nginx
    sudo apt install -y nginx
    
    # Start and enable Nginx
    sudo systemctl start nginx
    sudo systemctl enable nginx

    Create an optimized Nginx configuration:

    /etc/nginx/sites-available/staticsite
    server {
        listen 80;
        listen [::]:80;
        server_name yourdomain.com www.yourdomain.com;
    
        # For Hugo sites:
        root /var/www/mysite/public;
        # For Jekyll sites:
        # root /var/www/myblog/_site;
    
        index index.html;
    
        # Enable gzip compression
        gzip on;
        gzip_types text/plain text/css application/json
                   application/javascript text/xml application/xml;
    
        # Cache static assets
        location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    
        # Handle clean URLs
        location / {
            try_files $uri $uri/ $uri.html =404;
        }
    
        # Security headers
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
    }

    Enable the site and reload Nginx:

    Enable Site
    # Enable the site
    sudo ln -s /etc/nginx/sites-available/staticsite /etc/nginx/sites-enabled/
    
    # Remove default site
    sudo rm /etc/nginx/sites-enabled/default
    
    # Test configuration
    sudo nginx -t
    
    # Reload Nginx
    sudo systemctl reload nginx
    12

    Option B: Caddy Configuration

    Caddy automatically handles HTTPS certificates and provides a simpler configuration syntax:

    Install Caddy
    # Install Caddy
    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
    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 Caddyfile configuration:

    /etc/caddy/Caddyfile
    yourdomain.com {
        # For Hugo:
        root * /var/www/mysite/public
        # For Jekyll:
        # root * /var/www/myblog/_site
    
        # Enable compression
        encode gzip
    
        # Serve static files
        file_server
    
        # Handle clean URLs
        try_files {path} {path}.html {path}/ =404
    
        # Cache headers for assets
        @static {
            path *.css *.js *.ico *.gif *.jpg *.jpeg *.png *.svg *.woff *.woff2
        }
        header @static Cache-Control "public, max-age=31536000, immutable"
    }

    Automatic HTTPS: Caddy automatically provisions and renews SSL certificates from Let's Encrypt. Simply ensure your domain's DNS A record points to your VPS IP address.

    13

    SSL with Nginx (Certbot)

    If using Nginx, install Certbot for free SSL certificates:

    Install Certbot
    # Install Certbot
    sudo apt install -y certbot python3-certbot-nginx
    
    # Obtain and install certificate
    sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
    
    # Test automatic renewal
    sudo certbot renew --dry-run

    Part 4: Deployment Automation

    14

    Git Hook Deployment

    Set up a bare Git repository with a post-receive hook:

    Create Git Hook
    # Create bare repository
    mkdir -p /var/repo/site.git
    cd /var/repo/site.git
    git init --bare
    
    # Create post-receive hook
    cat > hooks/post-receive << 'EOF'
    #!/bin/bash
    TARGET="/var/www/mysite"
    GIT_DIR="/var/repo/site.git"
    BRANCH="main"
    
    while read oldrev newrev ref
    do
        if [[ $ref = refs/heads/$BRANCH ]]; then
            echo "Deploying $BRANCH..."
            git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
            cd $TARGET
            hugo --minify  # For Hugo
            # JEKYLL_ENV=production bundle exec jekyll build  # For Jekyll
            echo "Deployment complete!"
        fi
    done
    EOF
    
    chmod +x hooks/post-receive

    Add the remote to your local repository:

    Deploy via Git
    # On your local machine
    git remote add production ssh://user@your-server-ip/var/repo/site.git
    
    # Deploy by pushing
    git push production main
    15

    GitHub Actions Deployment

    Create a GitHub Actions workflow for automated deployment:

    .github/workflows/deploy.yml
    name: Deploy to RamNode VPS
    
    on:
      push:
        branches: [main]
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
            with:
              submodules: true
    
          - name: Setup Hugo
            uses: peaceiris/actions-hugo@v2
            with:
              hugo-version: 'latest'
              extended: true
    
          - name: Build
            run: hugo --minify
    
          - name: Deploy via rsync
            uses: burnett01/rsync-deployments@5.2
            with:
              switches: -avzr --delete
              path: public/
              remote_path: /var/www/mysite/public/
              remote_host: ${{ secrets.SSH_HOST }}
              remote_user: ${{ secrets.SSH_USER }}
              remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

    Part 5: Performance & Security

    Performance Optimization

    • Enable Brotli compression (more efficient than gzip for text content)
    • Implement HTTP/2 for multiplexed requests
    • Use immutable caching for versioned assets
    • Optimize images with WebP format and lazy loading
    • Minify HTML, CSS, and JavaScript during build
    16

    Security Best Practices

    Secure your static site deployment:

    Security Configuration
    # Configure UFW firewall
    sudo ufw allow OpenSSH
    sudo ufw allow 'Nginx Full'  # or 'Caddy'
    sudo ufw enable
    
    # Disable root SSH login
    sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
    sudo systemctl restart sshd
    
    # Set proper file permissions
    sudo chown -R www-data:www-data /var/www/mysite/public
    sudo chmod -R 755 /var/www/mysite/public
    17

    Monitoring & Maintenance

    Set up basic monitoring and log rotation:

    Monitoring Setup
    # Install fail2ban for SSH protection
    sudo apt install -y fail2ban
    sudo systemctl enable fail2ban
    
    # Monitor Nginx access logs
    sudo tail -f /var/log/nginx/access.log
    
    # Check disk usage
    df -h
    
    # View system resources
    htop

    Pro Tip: Consider using a free uptime monitoring service like UptimeRobot or Better Stack to receive alerts if your site goes down.

    Troubleshooting

    Hugo build fails with theme errors

    Ensure submodules are initialized: git submodule update --init --recursive

    Jekyll bundle install fails

    Install build dependencies: sudo apt install build-essential libffi-dev

    Nginx returns 403 Forbidden

    Check file permissions and ensure index.html exists in the root directory.

    SSL certificate errors

    Verify DNS propagation has completed and ports 80/443 are open in firewall.

    Changes not reflecting after deployment

    Clear browser cache or check that the correct directory is being served.

    Next Steps

    With your static site deployed on RamNode VPS, consider these enhancements:

    • Add a CDN like Cloudflare for global edge caching
    • Implement a contact form using serverless functions
    • Set up analytics with privacy-respecting tools like Plausible or Umami
    • Configure automated backups of your site content

    Need Help?

    Contact RamNode support at support@ramnode.com

    Visit ramnode.com for VPS plans and documentation