前言 / Intro
最近终于下定决心,把原来一直在用的 Windows Server 2016 备份过后,宣布彻底弃用了。之所以之前用 Windows Server,是因为最开始部署博客的时候我还玩不明白满是命令行的 Linux。随着时间的推移,慢慢地变得能够上手了,同时也发现 Linux 有不少优点,比如系统占用小啦,开源社区生态越来越完善啦等等等等。于是的现在,我全面投入了 Linux 的拥抱。因为感觉一众发行版之中 Ubuntu 的生态相对更完善,上手操作简单方便,且通常云服务器提供商也必定会提供 Ubuntu 的镜像,所以光速重装了系统。本以为会花很长时间,结果是几秒钟的时间迅速重装好了。想想也是,毕竟是托管主机,内部更换镜像秒秒钟的事。选择的也是目前我用的云服务商(腾讯云)能够安装到的最新长期维护稳定发行版:Ubuntu Server 22.04 LTS.
其实一开始挣扎了好久,到底要不要安装桌面环境,毕竟 GUI 操作直观流畅,全敲命令行实在是有点恼人。一番纠结过后,还是没有选择安装桌面环境。考虑到我的服务器性能本来就不高,安装桌面环境之后怕不是又跟原来 Windows Server 一样动不动飙升高占用了,而且也想稍微逼自己一把用一用终端,也能巩固一下常用命令的记忆。
敬请注意 / WARNING
这篇折腾日志可能包含先部署再 排错 / 升级 / 修改 等非一次性部署好的情况,几乎只是用来记录我走过的路程的,所以算不上一份标准的教程。你可以先向后阅读,根据潜在的说明或者自行分析,尽可能避免复现不必要的步骤。
前置准备
重装系统!
访问云服务器管理商,通常都会有预制好的镜像,不论是新装还是重装都是即点即用。就不过多赘述啦。
端口放行
如果你是第一次购买服务器,记得去放行端口,常用的有80、8080、443 (HTTP / HTTPS)、22、1022 (SSH)、3389 (RDP远程桌面) 等,其他的根据你自己的需要灵活调节。主流云服务商都很贴心地在面板里给出了一键放行,直接点就可以。
解析域名
如果你已经拥有了域名并且要绑定,接下来转到 DNS 面板,依旧是大快人心的一键添加解析记录。
要是暂时还没有域名,只用 IP 地址来访问的话也不是不可以,但向公网暴露真实 IP 地址有很多弊端,很容易被攻击 ( 虽说一般我们这种小站几乎是无人在意吧,但也正巧是容易被什么恶意爬虫当成下手的对象 ( 所以建议还是准备一个域名。
做完了这些前置工作,就可以连接到我们的 Ubuntu 主机啦~
配置环境
连接到终端
使用任意 SSH 工具,连接到我们主机的命令终端。这里我是用习惯了 XShell,因为操作简单而且重要的是很美观 (颜狗上线
全新启动 & 安装 Docker
Linux 启动第一步,当然是先更新一下。
sudo apt update
sudo apt upgrade
因为我个人喜欢用容器对每个程序进行隔离化管理,所以接下来安装 Docker。
内容可能有时效性。
参阅:Docker 官方文档 - https://docs.docker.com/engine/install/ubuntu
首先执行一下完全卸载命令,确保服务器内没有安装过旧版本,防止引起冲突。
sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc | cut -f1)
如果是新装,机器里什么都没有,那大概可以跳过这一步。当然以防万一也可以运行一下。
此时直接执行安装命令大概是无效的。要先设置一下 Docker 的仓库。
# 添加 Docker 官方 GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# 将仓库写入 Apt 源:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
# 添加完仓库地址,再次执行更新来获取仓库源
sudo apt update
现在可以执行安装命令了。
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
查看一下 Docker 状态,确认是否安装完成并运行:
sudo systemctl status docker
如果没有运行,手动启动一下。
sudo systemctl start docker
安装 Portainer
现在我们已经拥有了 Docker 容器环境,可以拉取并部署各种程序了。虽然直接就这么用也不是不行,但对于我个人而言,我更喜欢可视化一点的操作,而且日后有想要修改的内容不用一遍遍敲命令去操作(比如搜索、停用以及删除)容器,也不用大费周章地改动之前的命令再去完整输入新命令,所以我还要再安装一个 Portainer。
内容可能有时效性。
参阅:Portainer 官方文档 - https://docs.portainer.io/start/install-ce/server/docker/linux
直接执行部署命令,系统识别到本地没有镜像会先自动拉取:
docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:lts
如果你要部署为 HTTPS 或自行导入 SSL 证书,将其中的端口更换为 -p 8000:8000 -p 9443:9443 即可。
使用你的 IP 地址或域名加你的访问端口来访问 Portainer 面板。能成功登入即可。
安装 Typecho 和 数据库
TIPS
插一句,其实这里一开始我想使用 Portainer 内置的 Stacks 来部署 docker-compose 的,但是部署时发现,Stacks 指定文件夹必须使用绝对路径,但是我又想用较为优雅的 ./ 相对路径,如果强制使用相对路径在 Stacks 内部署,就会自动部署到 /data/compose/1/typecho 类似这样的主机根目录,所以我还是选择了官方 docker-compose 手段。
综上所述,那么我们还是按照传统的方式:
首先创建文件夹:
mkdir -p my_blog && cd $_
启动编辑器:
nano docker-compose.yml
编辑 docker-compose:
services:
typecho:
image: joyqi/typecho:1.3.0-php8.2-apache
container_name: typecho
restart: always
environment:
- TIMEZONE=Asia/Shanghai
volumes:
- ./typecho/usr:/app/usr
depends_on:
- db
db:
image: mariadb:10.6
container_name: typecho-db
restart: always
environment:
- MYSQL_ROOT_PASSWORD=Root-Pwd-1234
- MYSQL_DATABASE=my_blog
- MYSQL_USER=username
- MYSQL_PASSWORD=Pwd-1234 # 用户名密码按需修改
- TZ=Asia/Shanghai
volumes:
- ./db:/var/lib/mysql
两个愿望 一次满足 嘿嘿 docker-compose 真好用 (
这里一定要记好我们设置的所有名称、用户名和密码。最后会用到。
- 此外,如果你不想使用独立的数据库容器,想用 Typecho 内置的 SQLite,那么可以把
depends_on:之后有关独立数据库容器的部署内容全部删除。
写好配置文件,然后部署镜像:
docker compose up -d
这里我拉取镜像使用 typecho:1.3.0-php8.2-apache 指定了具体版本。因为有一些国内镜像源可能包含的不是最新镜像仓库,指定具体版本后如果报错,可以帮助我们具体定位问题,从而考虑尝试换源解决。
另外,Typecho 时区我使用了完整参数名 - TIMEZONE=Asia/Shanghai 。这是因为第一次我用的简写 - TZ=Asia/Shanghai 居然对我的 Typecho 不生效,不知是不是版本原因。如果你用完整参数反而无效了,可以考虑进 Portainer 更换这一项,亦或者重新 docker-compose 部署。
部署好之后,我再加了一条映射:
- ./typecho/config.inc.php:/app/config.inc.php
这是因为 config.inc.php 是一个日后可能频繁修改的配置文件,所以我们要挂载出来。
姑且以防万一有萌新第一次操作写个提醒,冒号前相对路径是宿主机真实路径 (host),而后者是容器内路径 (container)。通过 Portainer 添加可能会用到。
TIPS
或许有的小伙伴要问,为什么还要大费周折在部署好之后才添加这条路径映射呢?有两个原因:
- 如果我们一开始就挂载这个文件,有可能会因为系统找不到这个路径,就会默认优先使用该名称自动创建成一个空文件夹,从而导致 Typecho 找不到这个文件;
- 我第一次尝试先手动创建空文件,再进行挂载时,发现 Typecho 无法进入欢迎界面,也无法显示正常的博客页面。排查发现是因为系统检测到有这个配置文件了,所以以为我们的博客已经部署好了,就直接进入博客页面。但实际上又没有被部署,所以就会出现 bug。
所以,我会让程序先自行创建初始 config.inc.php 配置文件,而后再给它挂载出来。
- 以上单纯是我发现的一些小问题。如果你发现我的步骤是不必要,或者还有更好的办法,欢迎留言告诉我。
注意,此时我们还暂时不能访问博客页面。因为我们还没有放行 80 端口投放在公网访问。同样地,如果你选择直接将容器 80 端口映射到宿主机也不是不行 —— 还是请先不要着急添加端口映射,因为我们要使用一项更为优秀的方案:添加 Nginx 反代理。
安装 Nginx (NPM)
NPM,全称 Nginx Proxy Manager,是一项可视化 Nginx 反代理面板。
创建并进入文件夹:
mkdir -p npm && cd $_
启动编辑器:
nano docker-compose.yml
还是 docker-compose:
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- default
- my_blog_net # 按需自定义这里和后面的 Docker 网络名称
networks:
my_blog_net:
external: true
name: my_blog_default
部署镜像:
docker compose up -d
访问 IP地址 / 域名:81 进入我们的 NPM 面板。
如图,新建一个代理服务,域名处填写我们的域名(废话)。
因为我们是在 Docker 内网环境下部署的,所以要转发的主机按照 Docker 内的地址写。
协议 https ,转发主机名建议填写你设置的容器名称,例如 typecho ,这样如果我们日后对容器有修改、更新时,不受内网 IP 地址变动的影响。端口填写 Typecho 内网端口 80 .
可以打开下面的两项常用功能,“缓存资源”和“阻止常见攻击”。
如果你不需要使用自定义 SSL 证书,还可以转到 SSL 选项卡,为我们的域名申请一个免费的 LetsEncrypt,再打开“强制使用 SSL”。操作很简单,就不放图了。
设置完毕,点击“保存”。
配置并访问博客
前置工作都准备完毕,接下来终于可以访问我们的博客页面了。
输入域名,第一次会启动欢迎页面引导向导。输入用户名、邮箱,以及我们之前设置过的数据库信息即可。如果忘了,回头看看我们刚才设置过的 Typecho 的 docker-compose.yml 文件。
注意“数据库地址”不要填 IP,填你在 yaml 中定义的数据库服务名(例如我们刚才设置的 db)即可,Docker 内网的 DNS 会自动寻址。
- 如果你选择的是没有单独部署 SQL 数据库,欲使用 Typecho 内置的 SQLite,那么我们直接下拉菜单,选择 “Pdo 驱动 SQLite 适配器” 即可只需输入数据库名称和路径,完成简化设置。
转到下一步,设置我们的邮箱(会和 Gravatar 头像服务相关联)、用户名和密码。再一路继续。
大功告成!
博客的部署就到这里结束了。如果你想个性化你的博客,安装主题、插件等等,可以在互联网上搜索,款式各种各样。至于我自己在用的一些设置,留到日后看情况写吧。
作者信息:Wwk-Kevin版权声明:任何形式的转载请先联系作者获得授权,并标明出处。


