本人最初购买 VPS 的理由就是想搭建一个 docker 应用——memos(闪念记录软件),这篇文章也以这个应用为例。就是通过在浏览器上输入一串网址就能访问自己的服务,这么一个简单的操作,里面的坑真的不少,这篇文章将尽可能详细地记录如何构建 docker 应用并绑定域名。

本文仅在 ubuntu 系统上试验

写在前面

首先我们需要有一个 VPS,如何购买请参考这篇文章,如何初始化设置请看这篇文章

购买域名

如果自己不想给域名花大价钱,也不在乎后缀是什么,可以在 cloudflare 上购买域名,有些域名很便宜,一年就五六十块。购买域名之后,点击 cloudflare profile ➔ API Tokens ➔ Create Token ➔ Edit zone DNS ➔ 选择对应的区域继续即可,最终会得到一个 token,请保存。

域名解析

假如我们想把 memos 部署在memos.<domain>中,需要在 cloudflare ➔ 自己的域名 ➔ DNS Record ➔ 添加 A 记录 ➔ 子域名写入 memos ➔ IP 写 VPS 的 IP ➔ 保存即可。

安装 docker

按照官方教程,执行以下命令即可

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt-get update
sudo apt-get 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
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world

安装 npm

为了让域名能正确解析到 memos 上,需要搭建一个反代服务,这里选择新手友好的 npm(nginx proxy manager)
首先给 npm 创建一个文件夹

mkdir -p ~/npm
cd ~/npm
docker network create proxy
vim docker-compose.yml

写入以下内容

services:
app:
image: jc21/nginx-proxy-manager:latest
container_name: npm
restart: unless-stopped
networks:
- proxy
ports:
- 80:80
- 81:81
- 443:443
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt

networks:
proxy:
external: True

编辑完成,用以下命令创建 npm

docker compose up -d

安装 memos

首先给 memos 创建一个文件夹

mkdir -p ~/memos
cd ~/memos
vim docker-compose.yml

写入以下内容

services:
app:
image: neosmemo/memos:stable
container_name: memos
restart: unless-stopped
networks:
- proxy
ports:
- 127.0.0.1:5230:5230
volumes:
- ./memos:/var/opt/memos

networks:
proxy:
external: True

注意,这里连接的网络要和上面 npm 创建的网络相同才行,按照上面的创建方式,网络名称应该叫做npm_deafult。以后每次创建应用,如果要绑定域名,都需要将应用连接到npm_default网络中,写法如上。如果觉得麻烦,也可以使用docker0网桥,这里不做陈述。
运行以下命令安装 memos

docker compose up -d

反向代理配置

防火墙开放 81 端口(在外部防火墙关闭且 ufw 开启的状态下,关于这部分内容,可以参考这篇文章

ufw allow 81

通过http://<ip>:81>的方式访问 npm,初始用户名admin@example.com,初始密码changeme,登录后改成自己的密码。
点击 SSL Certificates 选项卡 ➔ Add SSL Certificates ➔ Lets Encrypt ➔ DomainName 填入<your_domain>*.<your_domain> ➔ 点击 Use a DNS Challenge ➔ Provider 选择 CloudFlare ➔ 将 token 替换为上面申请到的 token ➔ 点击 save 即可
点击 Hosts 选项卡 ➔ Add Proxy Host ➔ domain-name 填入memos.<your_domain>,scheme 选择 http,Forward Hostname / IP 填入 memos(与 memos 的 container_name 一致),端口选择 5230,选择 Block Common Exploits 和 Websockets Support ➔ 点击 SSL 选择刚刚申请的证书,下面的四个可以都勾选上 ➔ 点击 Save 即可
为了安全考虑,在配置完成之后,关闭 81 端口

ufw delete allow 81

这样就能通过域名访问 memos 应用了!