Hugo vs Jekyll Comparison
| Hugo | Jekyll |
|---|---|
| Written in Go | Written in Ruby |
| Extremely fast builds (<1ms/page) | Mature ecosystem, many plugins |
| Single binary, no dependencies | Requires Ruby environment |
| Built-in asset pipeline | Liquid templating engine |
| Best for: Large sites, frequent builds | Best 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
Connect and Update Server
Connect to your VPS and update the system packages:
ssh root@your-server-ip
# Update system packages
apt update && apt upgrade -y
# Install essential tools
apt install -y git curl wget unzip build-essentialCreate a Non-Root User
Create a non-root user for daily operations (recommended):
# Create user with sudo privileges
adduser webadmin
usermod -aG sudo webadmin
# Switch to new user
su - webadminPart 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.
Install Hugo
Install Hugo using the official releases for the latest version:
# 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 versionWhy Hugo Extended? The extended version includes SCSS/SASS processing and WebP image encoding capabilities. Most modern Hugo themes require these features.
Create a Hugo Site
Create a new Hugo site and add a theme:
# 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.tomlConfigure Hugo
Edit the hugo.toml configuration file:
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']Build Hugo Site
Build the site for production:
# 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.
Install Ruby and Jekyll
Jekyll requires Ruby 2.7 or higher. We'll use rbenv for Ruby version management:
# 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.2Install Jekyll and Bundler:
# Install Jekyll
gem install jekyll bundler
# Verify installation
jekyll -v
bundler -vCreate a Jekyll Site
Create a new Jekyll site:
cd /var/www
# Create new Jekyll site
jekyll new myblog
cd myblog
# Install dependencies
bundle installConfigure Jekyll
Edit the _config.yml configuration file:
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-sitemapBuild Jekyll Site
Build the site for production:
# 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
Option A: Nginx Configuration
Install and configure Nginx for optimal static file serving:
# Install Nginx
sudo apt install -y nginx
# Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginxCreate an optimized Nginx configuration:
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 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 nginxOption B: Caddy Configuration
Caddy automatically handles HTTPS certificates and provides a simpler configuration syntax:
# 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 caddyCreate a Caddyfile configuration:
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.
SSL with Nginx (Certbot)
If using Nginx, install Certbot for free SSL certificates:
# 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-runPart 4: Deployment Automation
Git Hook Deployment
Set up a bare Git repository with a post-receive 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-receiveAdd the remote to your local repository:
# On your local machine
git remote add production ssh://user@your-server-ip/var/repo/site.git
# Deploy by pushing
git push production mainGitHub Actions Deployment
Create a GitHub Actions workflow for automated deployment:
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
Security Best Practices
Secure your static site deployment:
# 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/publicMonitoring & Maintenance
Set up basic monitoring and log rotation:
# 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
htopPro 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
