🐳 以 Docker 筑博客平台 #5:增 Dockerfile + 部署至 Clouderized
速记一句:撰 Dockerfile,建镜像,以一git push部署 Clouderized,使 Flask 博客得活,自动 HTTPS,无服务器之劳形.
🔧 既欲始,先论 Blogger 迁徙之 URL 控制
触 Docker 之前,有四则之修,今可为之。
今吾之平台,自文件名构 URL:hey-markdown.md化而为/2026/04/hey-markdown.html。此法适新文,然不契移自 Blogger 之 URL:
| Blogger URL | 基于文件名之 URL |
|---|---|
/2026/03/docker-rootless-on-ubuntu-2026-guide.html |
/2026/03/docker-rootless-ubuntu.html |
吾于前文加之canonical_url,用以二事:
- 此平台实际供文之URL也— 迁徙之文,仍守其 Blogger 之径。
-
<link rel="canonical">—告Google此页之内容与旧Blogger URL无异
更新content/posts/hey-markdown.md:
---
title: "Hey Markdown"
date: 2026-04-25
description: "The first post written in Markdown — no more writing HTML by hand."
tags: [meta, blog]
canonical_url: "https://blog.dtio.app/2026/04/old-markdown.html"
---
此不协乃有意为之:文件名与所供路径可异。
葆助URL之器于 app.py
開 app.py。頂部添此引:
from urllib.parse import urlparse
次於 get_post_path() 之後添此函:parse_post():
def get_post_path(meta):
"""Determine the URL path for a post from its canonical_url."""
if meta.get('canonical_url'):
return urlparse(meta['canonical_url']).path
# Fallback: auto-generate from date + slug
slug = meta.get('slug', 'unknown')
date = meta.get('date', '')
if hasattr(date, 'year'):
return f'/{date.year}/{date.month:02d}/{slug}.html'
return f'/{slug}.html'
此助器取URL之徑於canonical_url,兼以日期+缩略名为备。
更新get_all_posts()
于既有get_all_posts()之函数,增路径之域:
def get_all_posts():
posts = []
posts_dir = 'content/posts'
for filename in os.listdir(posts_dir):
if not filename.endswith('.md'):
continue
filepath = os.path.join(posts_dir, filename)
post = parse_post(filepath)
post['slug'] = filename[:-3]
post['path'] = get_post_path(post)
posts.append(post)
posts.sort(key=lambda p: p.get('date', ''), reverse=True)
return posts
每篇文皆具path之域——即其应服务之确URL。
更新路由
于既有路由中寻之app.py:
@app.route('/<int:year>/<int:month>/<slug>')
def post(year, month, slug):
filepath = f'content/posts/{slug}.md'
if not os.path.exists(filepath):
abort(404)
post = parse_post(filepath)
return render_template('post.html', post=post)
以动态查询替换之:
@app.route('/<int:year>/<int:month>/<path:slug>.html')
def post(year, month, slug):
target_path = f'/{year}/{month:02d}/{slug}.html'
all_posts = get_all_posts()
matching_post = next((p for p in all_posts if p['path'] == target_path), None)
if not matching_post:
abort(404)
post_data = parse_post(f'content/posts/{matching_post["slug"]}.md')
post_data['path'] = matching_post['path']
return render_template('post.html', post=post_data)
此路径匹配.html网址,寻得相应post['path'],载入正确之markdown文件.
更新首页链接
于templates/index.html,更易手所构之URL,以帖之径代之。
<a href="{{ post.path }}">{{ post.title }}</a>
且于"Read more"之链:
<a href="{{ post.path }}" class="text-teal-400 text-sm hover:text-teal-300 font-medium transition-colors duration-200">
Read more →
</a>
增置规范链接标签
于templates/post.html,加诸规范链接之标籤于内<head>,元描述之后:
<meta name="description" content="{{ post.description }}">
{% if post.canonical_url %}
<link rel="canonical" href="{{ post.canonical_url }}">
{% endif %}
{% if %}之卫,使标签于无canonical_url之文可略。
更新前文架构
此乃今后完整之前文架构:
| 字段 | 用于 |
|---|---|
title |
<title>之標籤,<h1>於帖子頁,帖子列表 |
date |
URL生成,排序,顯示 |
description |
<meta name="description">,摘錄於首頁 |
tags |
Tag藥丸於帖子頁,終究標籤頁於Ep12 |
canonical_url |
首頁鏈接+<link rel="canonical">為Blogger遷移(可選) |
遷移帖子時,設canonical_url以合原BloggerURL。
✅ 第一步:验诸事于本地
未及触碰Docker,先验平台URL更易后,犹能运行无碍否
激活汝之venv,运此应用:
$ source venv/bin/activate
$ python app.py
访 http://localhost:8000 并察:
- 首页 — 文章已列,链接指向正确路径
-
文章页面 — 渲染无误,
<link rel="canonical">见于HTML源码(检视源码并搜索canonical) - 标签丸 — 文章页正确显示
一旦本地皆妥,即可容器化之。
次步:立.dockerignore
先撰Dockerfile,而后示Docker何者不宜入图。于项目根目录立.dockerignore:.dockerignore 全屏模式
venv/
__pycache__/
*.pyc
.git/
.gitignore
📄 次步:撰Dockerfile
立Dockerfile 在项目根目录下:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
此序为何要重:
- 先拷贝
requirements.txt以便依赖安装可缓存 - 后拷贝应用代码 使常规代码修改能速重建
🔨 步骤四:构建图像
务必处于项目根目录(即此处)Dockerfile(是)
$ docker build -t tioblog .
既毕,验其图存否。
$ docker images tioblog
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
tioblog:latest 05dbc52b9852 231MB 55.6MB
🚀 第五步:运行之
$ docker run -p 8000:8000 tioblog
游JHSNS_URL_0。博客载入——与往昔无异,然今运行于器中.
📝 步第六:增置.gitignore
推于Clouderized之前,当慎勿使非属库者入于其中。于项目根处,立.gitignore:
venv/
__pycache__/
*.pyc
.env
此令汝之虚拟境、缓存之文、及一切本地之配置,不存于版本控制之列.
🌐 步第七:部署于Clouderized
Clouderized乃此系列之部署目标,盖因其优化于简易容器应用之输送:推于Git,自建,自部署,HTTPS默认开启.
此博客之部署,如是:
$ git init
$ git add .
$ git commit -m "Initial commit for tioblog"
$ git branch -M main
$ git remote add origin https://git.clouderized.com/davidtio/tioblog.git
$ git push -u origin main
https://git.clouderized.com/davidtio/tioblog.git以davidtio为云端化用户名,以tioblog为项目名
于汝之应用,用:
https://git.clouderized.com/<username>/<project>.git
经一时辰,汝之博客即成于:
https://davidtio-tioblog.clouderized.com
同 Dockerfile,今以 HTTPS 公开运行。
添汝自定域名
Clouderized 亦支持自定域名。此博客,生产运行于 blog.dtio.app。
- 往
https://dash.clouderized.com - 启
tioblog应用卡 - 击
Domains - 添汝自定域名(例如
blog.dtio.app) - 复制
cfargotunnel所示之目标,由 Clouderized - 为汝域创建
CNAME记录,并指向cfargotunnel目标
待 DNS 传播既,汝之应用即于自域运行,而 Clouderized 仍主路由与 HTTPS 之事.
小创作者平台所系何在?
- 尔恒持一部署单元(汝之Docker图像)
- 尔可避手维之逆代理与证书之设
- 尔可同Git之工法运内容与应用之变
🧪 步第八:验其鲜活
启尔之瀏览器,验其活URL:
https://davidtio-tioblog.clouderized.com
请确认首页载入,文章已列,且.html链接地址可用。
https://davidtio-tioblog.clouderized.com/2026/04/hey-markdown.html
此合Blogger式URL,以利迁移之顺。
亦验HTTPS之用,且证其牒之效。于Clouderized,此乃自为之,汝可专力於内容与产品之事,而不必忧於基设之劳。
所建何物
tiohub-blog/
├── Dockerfile ← new
├── .dockerignore ← new
├── app.py (get_post_path, post['path'] in get_all_posts, route adds post['path'])
├── requirements.txt
├── static/
│ └── js/
│ ├── tailwind.config.js
│ └── code-blocks.js
├── templates/
│ ├── index.html (links use {{ post.path }} instead of manual URLs)
│ └── post.html (<link rel="canonical"> added)
└── content/
└── posts/
├── hey-markdown.md (canonical_url added to frontmatter)
└── second-post.md
所变何在:
-
canonical_url与post.path今主稳定之後URL - 動態之路解URL之徑至合適之markdown文
- 首頁連結用
{{ post.path }} - 可選之典標籤加
post.html -
Dockerfile.dockerignore與.gitignore增 - ,該應用於容器內運行,需
docker build與docker run - 部署至雲端,以供公眾HTTPS主機服務。
- 自定義域名可於
Domains中對應,DNS指向所供cfargotunnel目標。 - 之部署,本于Git,故发布之务可复,以应将来系列之文
🚀 将至
一弊:每易一文,必重筑其像,乃见其变。是适得其反,无以彰内容之旨
次章:绑定挂载。吾等将挂载之content/ 之文件夹,直纳于容器——更文,刷新页,立见变。无需重构建。
此法有益乎? 分享于众,或留言于下。
搜索引擎元数据
- 标题: 以Docker构建博客平台 #5:增Dockerfile + 部署于Clouderized
- 元描述: 为汝之 Flask 博客撰 Dockerfile,建其像,而布之於 clouderized.com — 推至 git.clouderized.com/davidtio/tioblog,自建,自导,自 HTTPS,於 davidtio-tioblog.clouderized.com。












