added a how to website med
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
+++
|
||||
title = "About"
|
||||
date = 2025-10-09
|
||||
+++
|
||||
|
||||
# Who is Raphael?
|
||||
|
41
src/content/meditations/self-hosting/_index.md
Normal file
41
src/content/meditations/self-hosting/_index.md
Normal file
@@ -0,0 +1,41 @@
|
||||
+++
|
||||
title = 'How to Host a Website using Docker and Cloudflared'
|
||||
draft = false
|
||||
sort_by = "weight"
|
||||
|
||||
[extra]
|
||||
date = 2025-10-16
|
||||
+++
|
||||
|
||||
# How to Host a Website using Docker and Cloudflared
|
||||
|
||||
In today's world you may find yourself wanting to host a website for various purposes, whether it be a personal portfolio, business, or just a side project. I'm going to show you how to host three different kinds of websites using Docker: a WordPress site, a static Hugo site, and a Python Django site in a series of articles.
|
||||
|
||||
This series will teach you how to self-host websites from your own hardware using Docker for containerization and Cloudflare Tunnel (Cloudflared) to securely expose your sites to the internet without opening ports or needing a static IP address. Best of all, this setup is completely free for personal use.
|
||||
|
||||
## What You'll Learn in This Series
|
||||
|
||||
**Part 1 (This Article): Environment Setup**
|
||||
- Installing Docker and Docker Compose
|
||||
- Setting up Cloudflare Tunnel (Cloudflared)
|
||||
- Understanding basic Docker networking
|
||||
- Configuring your domain with Cloudflare
|
||||
|
||||
**Part 2: WordPress Site (Beginner)**
|
||||
- Deploying WordPress with Docker
|
||||
- Setting up MySQL database
|
||||
- Configuring persistent storage
|
||||
|
||||
**Part 3: Static Hugo/Zola Site (Intermediate)**
|
||||
- Building and serving a Hugo site
|
||||
- Optimizing static content delivery
|
||||
|
||||
**Part 4: Python Django Site (Advanced)**
|
||||
- Containerizing a Django application
|
||||
- Setting up PostgreSQL
|
||||
- Managing migrations and static files
|
||||
|
||||
**Part 5: Using a Spare Android Phone (Advanced)**
|
||||
- Setting up Termux to host a static Hugo site
|
||||
- Using Cloudflared to host that site on the public internet
|
||||
- Setting up SSH so you can do all this without having to type on a tiny screen
|
8
src/content/meditations/self-hosting/part-five.md
Normal file
8
src/content/meditations/self-hosting/part-five.md
Normal file
@@ -0,0 +1,8 @@
|
||||
+++
|
||||
title = 'Part 5: Using a Spare Android Phone (Advanced)'
|
||||
date = 2025-10-16
|
||||
draft = false
|
||||
weight = 5
|
||||
+++
|
||||
|
||||
Android, at its core, is Linux. The kernel is forked from Linux and the system is built on top of it. Through a userland tool called Termux we can get an isolated terminal environment where we can run Hugo or Zola as well as Cloudflared. This section is marked as advanced not because it is inherently difficult but because it is quite different to anything else you might have done. But considering how cheap a solid Android phone can come it is an affordable way to self-host a basic static site (or even more complex things if you really want to try).
|
6
src/content/meditations/self-hosting/part-four.md
Normal file
6
src/content/meditations/self-hosting/part-four.md
Normal file
@@ -0,0 +1,6 @@
|
||||
+++
|
||||
title = 'Part 4: Python Django Site (Advanced)'
|
||||
date = 2025-10-16
|
||||
draft = false
|
||||
weight = 4
|
||||
+++
|
23
src/content/meditations/self-hosting/part-one.md
Normal file
23
src/content/meditations/self-hosting/part-one.md
Normal file
@@ -0,0 +1,23 @@
|
||||
+++
|
||||
title = 'Part 1: Environment Setup'
|
||||
date = 2025-10-16
|
||||
draft = false
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
## Prerequisites
|
||||
|
||||
**Hardware:**
|
||||
- A spare computer (Windows, macOS, or Linux)
|
||||
- Minimum 4GB RAM, 20GB free storage
|
||||
- Stable internet connection
|
||||
|
||||
**Software:**
|
||||
- Windows 10/11, macOS 10.15 or newer, or Linux kernel 5.10+
|
||||
- Basic command line familiarity
|
||||
|
||||
**Accounts & Domain:**
|
||||
- Free Cloudflare account
|
||||
- A domain name (you can get one free from Freenom, or purchase from Namecheap, Google Domains, etc., though I reccomend just buying one from Cloudflare to simplify the process since they sell them at-cost)
|
||||
|
||||
**Skill Level:** Beginner to intermediate - I'll explain each step as we go.
|
12
src/content/meditations/self-hosting/part-three.md
Normal file
12
src/content/meditations/self-hosting/part-three.md
Normal file
@@ -0,0 +1,12 @@
|
||||
+++
|
||||
title = 'Part 3: Static Hugo/Zola Site (Intermediate)'
|
||||
date = 2025-10-16
|
||||
draft = false
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
For this section, you're in luck, I've already done most of the work for you through this site. I host this site using a custom Docker container and compose that runs Zola, Nginx, and Cloudflared. We'll be taking a look at the repository and structure so that you can adapt it to your needs.
|
||||
|
||||
## Who this is For
|
||||
|
||||
A static site is not for everyone. It is simple, very secure, not at all resource intensive, but that comes with some tradeoffs.
|
6
src/content/meditations/self-hosting/part-two.md
Normal file
6
src/content/meditations/self-hosting/part-two.md
Normal file
@@ -0,0 +1,6 @@
|
||||
+++
|
||||
title = 'Part 2: WordPress Site (Beginner)'
|
||||
date = 2025-10-16
|
||||
draft = false
|
||||
weight = 2
|
||||
+++
|
74
src/templates/section.html
Normal file
74
src/templates/section.html
Normal file
@@ -0,0 +1,74 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{%- block title -%}
|
||||
{{ section.title }} | {{ config.title }}
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block description -%}
|
||||
{%- if section.description %}
|
||||
<meta name="description" content="{{ section.description | markdown(inline=true) | striptags | safe }}">
|
||||
{%- elif config.description %}
|
||||
<meta name="description" content="{{ config.description | safe }}">
|
||||
{%- endif %}
|
||||
{%- endblock -%}
|
||||
|
||||
{%- block main -%}
|
||||
{%- filter indent -%}{%- filter indent -%}
|
||||
{%- if section.content -%}
|
||||
<header class="content {%- if section.extra.framed %} framed{%- endif -%}">
|
||||
{{ section.content | indent | safe }}
|
||||
</header>
|
||||
{% endif -%}
|
||||
|
||||
{% for path in section.subsections -%}
|
||||
{%- set subsection = get_section(path=path) -%}
|
||||
<article class="post">
|
||||
<header>
|
||||
<h2 class="post-title">
|
||||
<a href="{{ subsection.permalink | safe }}">{{ subsection.title }}</a>
|
||||
</h2>
|
||||
<ul class="post-meta">
|
||||
{%- if subsection.extra.date %}
|
||||
<li title="Published on {{ subsection.extra.date }}">
|
||||
<time datetime="{{ subsection.extra.date }}">{{ subsection.extra.date | date(format="%Y.%m.%d") }}</time>
|
||||
</li>
|
||||
{%- endif %}
|
||||
|
||||
{%- if config.author and config.extra.show_default_author %}
|
||||
<li role="separator" aria-hidden="true">::</li>
|
||||
<li title="Author">{{ config.author }}</li>
|
||||
{%- endif %}
|
||||
|
||||
{%- if subsection.word_count %}
|
||||
<li role="separator" aria-hidden="true">::</li>
|
||||
{%- set reading_time = subsection.reading_time ~ " min" | replace(from="0 min", to="<1 min") -%}
|
||||
{%- set word_count = [subsection.word_count ~ " word", subsection.word_count | pluralize] | join %}
|
||||
<li title="{{ word_count }}"><time datetime="PT{{ subsection.reading_time }}M">{{ reading_time }}</time> read</li>
|
||||
{%- endif %}
|
||||
</ul>
|
||||
</header>
|
||||
{%- if subsection.description %}
|
||||
<p>{{ subsection.description | markdown(inline=true) | safe }}</p>
|
||||
{%- endif %}
|
||||
<a class="read-more" href="{{ subsection.permalink | safe }}" aria-label="Read more about {{ subsection.title }}">read more →</a>
|
||||
</article>
|
||||
{% endfor -%}
|
||||
|
||||
{% for page in paginator.pages | default(value=section.pages) -%}
|
||||
{{ post_macros::excerpt(page=page) }}
|
||||
{% endfor -%}
|
||||
|
||||
{%- if paginator and paginator.number_pagers > 1 %}
|
||||
<nav class="pagination">
|
||||
<ul>
|
||||
{%- if paginator.previous %}
|
||||
<li><a rel="prev" href="{{ paginator.previous | safe }}" aria-label="newer posts">< [newer posts]</a></li>
|
||||
{%- endif %}
|
||||
{%- if paginator.next %}
|
||||
<li><a rel="next" href="{{ paginator.next | safe }}" aria-label="older posts">[older posts] ></a></li>
|
||||
{%- endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{%- endif %}
|
||||
{% endfilter %}{% endfilter %}
|
||||
{%- endblock -%}
|
Reference in New Issue
Block a user