blog/content/blog/2025-03-12-self-hosting-a-blog-in-2025.md
2025-03-12 18:45:23 +00:00

4.8 KiB
Raw Blame History

+++ title = "Self-Hosting a Website in 2025" description = "A step-by-step guide to hosting your own website using Zola, Caddy, and Gitea." date = 2025-03-12 updated = 2025-03-12

[taxonomies] tags = ["Self-Hosting", "CI/CD", "Linux", "Caddy", "Zola"]

[extra] social_media_card = "img/social_cards/blog_self_hosting_a_blog_in_2025.jpg" +++

Introduction

Zola is a static site generator written in Rust that is fast, simple, and easy to use. This blog is built using Zola and hosted on a Linux server with Caddy as the web server.

This guide will walk you through setting up Zola and Caddy to self-host your website efficiently.

Prerequisites

Before starting, ensure you have the following:

  1. A Linux server I am using Pop!_OS 24.04 LTS alpha.
  2. A domain name pointing to your server I use Cloudflare.
  3. A reverse proxy Caddy handles this role.
  4. A CI/CD platform I use Gitea for automated deployments.
  5. A privacy-focused analytics tool I use Plausible.

Installation

Step 1: Install Zola

Since there is no precompiled package for Pop!_OS 24.04 LTS alpha, we will install Zola from source:

git clone https://github.com/getzola/zola.git
cd zola
cargo install --path . --locked
zola --version

Step 2: Create a New Site

Initialize a new Zola site:

zola init blog
cd blog
git init
echo "public" > .gitignore

Step 3: Install a Zola Theme

I use the tabi theme. To install it:

git submodule add https://github.com/welpo/tabi.git themes/tabi

Step 4: Configure Zola & Tabi

Zola uses a config.toml file for configuration. Below is a sample configuration:

base_url = "https://www.aldofunes.com"
title = "Aldo Funes"
description = "Human being in the making"
default_language = "en"
theme = "tabi"
compile_sass = false
minify_html = true
author = "Aldo Funes"
taxonomies = [{ name = "tags" }, { name = "categories" }]
build_search_index = true

[markdown]
highlight_code = true
highlight_theme = "css"
highlight_themes_css = [{ theme = "dracula", filename = "css/syntax.css" }]
render_emoji = true
external_links_class = "external"
external_links_target_blank = true
smart_punctuation = true

[search]
index_format = "elasticlunr_json"

[extra]
stylesheets = ["css/syntax.css"]
remote_repository_url = "https://gitea.funes.me/aldo/blog"
remote_repository_git_platform = "gitea"
mermaid = true
show_previous_next_article_links = true
toc = true
favicon_emoji = "👾"

Step 5: Add Content

Zola uses Markdown for content creation, and its directory structure is intuitive. Use your favorite text editor to start writing articles.

Step 6: Deploy Your Site

To serve the site with Caddy, place the generated files in /www/blog and configure Caddy with the following Caddyfile:

aldofunes.com, www.aldofunes.com {
    tls {
        dns cloudflare __CLOUDFLARE_TOKEN__
        resolvers 1.1.1.1
    }
    root * /www/blog
    file_server
    handle_errors {
        rewrite * /{err.status_code}.html
        file_server
    }
    header           Cache-Control max-age=3600
    header /static/* Cache-Control max-age=31536000
}

Step 7 (Optional): Set Up a CDN

Using Cloudflare as a CDN improves performance and security. Configure a DNS record and enable Cloudflare proxying to benefit from caching and DDoS protection.

Step 8: Automate Deployment with CI/CD

To automate deployments with Gitea, create .gitea/workflows/deploy.yaml:

name: Deploy
on:
  push:
    branches:
      - main

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository code
        uses: actions/checkout@v4
        with:
          submodules: true

      - name: Check 🔍
        uses: zolacti/on@check
        with:
          drafts: true

      - name: Build 🛠
        uses: zolacti/on@build

      - name: Deploy 🚀
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ vars.ATLAS_SSH_HOST }}
          username: ${{ vars.ATLAS_SSH_USERNAME }}
          key: ${{ secrets.ATLAS_SSH_KEY }}
          port: ${{ vars.ATLAS_SSH_PORT }}
          source: public
          target: /www/blog
          rm: true
          overwrite: true
          strip_components: 1

Set these environment variables in Gitea Actions:

  • ATLAS_SSH_HOST
  • ATLAS_SSH_USERNAME
  • ATLAS_SSH_PORT

And add the secret key:

  • ATLAS_SSH_KEY

These credentials enable secure deployment via SCP.

Conclusion

You now have a fully self-hosted website powered by Zola and Caddy. With automated CI/CD using Gitea, you can focus on writing content while Gitea handles deployment. Enjoy your self-hosted blog!