190 lines
4.8 KiB
Markdown
190 lines
4.8 KiB
Markdown
+++
|
||
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](https://www.getzola.org/) 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](https://caddyserver.com/) 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](https://system76.com/cosmic/).
|
||
2. **A domain name** pointing to your server – I use [Cloudflare](https://www.cloudflare.com/).
|
||
3. **A reverse proxy** – [Caddy](https://caddyserver.com/) handles this role.
|
||
4. **A CI/CD platform** – I use [Gitea](/blog/gitea-open-source-github-alternative) for automated deployments.
|
||
5. **A privacy-focused analytics tool** – I use [Plausible](https://plausible.io/).
|
||
|
||
## Installation
|
||
|
||
### Step 1: Install Zola
|
||
|
||
Since there is no precompiled package for Pop!_OS 24.04 LTS alpha, we will install Zola from source:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
zola init blog
|
||
cd blog
|
||
git init
|
||
echo "public" > .gitignore
|
||
```
|
||
|
||
### Step 3: Install a Zola Theme
|
||
|
||
I use the [tabi](https://github.com/welpo/tabi.git) theme. To install it:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```toml
|
||
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`:
|
||
|
||
```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`:
|
||
|
||
```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!
|
||
|