跳转到正文
LimoBlog
返回

Linux 服务器

基于 Debian + Docker,结合 Nginx + Cloudflare Tunnel 的服务器,用于部署 Astro 静态博客。

在家中的闲置 Win10 旧笔记本上重装了 Debian Linux 系统,用于搭建家庭轻量级服务器,并在新购域名下重新构建与部署了个人的 Astro 博客。

目录

目录

架构

手头有一台闲置的戴尔游匣 14 7000,虽然性能不再适合日常高负载,但用于运行轻量级家庭服务依旧绰绰有余。

Debian:底层操作系统。我安装了 XFCE 桌面。

Docker:多阶段容器化隔离。统一管理 Nginx、Cloudflare Tunnel 等组件。

Nginx:静态资源反向代理服务器。承接容器内的 HTTP 请求,分发静态文件。

Cloudflare Tunnel:内网穿透通道。与 Cloudflare 边缘节点连接,避免内网端口暴露到公网。

Astro:静态站点生成框架(SSG)。采用“群岛架构(Islands Architecture)”。

整套方案不依赖公网 IP、不修改光猫与家庭路由器配置,兼顾了自建基础设施的灵活性与边缘网络的安全保护,赞。

一、底层系统初始化

1. 准备

前往 Debian 官网下载Debian。

下载并使用 Rufus,选择下载的 debian-xxx.iso,

分区方案选 GPT,目标系统选 UEFI,点击开始写入 U盘。

2. BIOS

在开机界面连续按下 F12 以跳转到 Boot Mode 界面,选择 BIOS Setup,

SATA Controller / Operation Mode 切换为 AHCI,

Secure Boot 切换为 Disable,

插入 启动U盘 后,保存并退出。

3. 系统安装

按照引导菜单自行选择,

Root password 留空,

如果想保留 window10 系统,给磁盘分区,

安装XFCE桌面,

勾选 SSH server 和 standard system utilities,

完成后拔出 U盘,重启电脑。

4. 禁用合盖休眠

打开终端,执行以下命令:

sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

别忘了按需配置基础环境,但这里就略过了。

二、 Astro

在已有基于 Astro 的本地项目的情况下,

将 Astro 项目送入容器打包前,

我遇到了以下问题:

现象原因解决方案
CSS/JS 失效设置了 base: '/Limo_Blog',导致生成的资源链接失效在 astro.config.mjs 中修改为 base: '/'
Prefetch 拦截site 写成了 http://,HTTPS 网页严禁调用 HTTP 资源修正为 https://,在 Cloudflare 开启 Always Use HTTPS
特定图片失效源码组件中残留了我手写的硬编码路径(/Limo_Blog/images/)修正为绝对路径 /images/即可

配置检查完毕后,在项目根目录创建 .dockerignore:

node_modules
.git
dist
.vscode

三、 容器化多阶段工程

1. 编写 Nginx 站点配置

在项目根目录新建 nginx.conf,启用 Gzip 压缩与长效缓存策略:

server {
    listen 80;
    server_name localhost;

    root /usr/share/nginx/html;
    index index.html;

    gzip on;
    gzip_types text/plain text/css application/javascript application/json image/svg+xml;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|svg|woff2?)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}

2. 编写多阶段构建 Dockerfile

针对跨境镜像拉取不稳定的情况,先拉取国内镜像源打标:

docker pull m.daocloud.io/docker.io/library/node:22-alpine
docker tag m.daocloud.io/docker.io/library/node:22-alpine node:22-alpine

docker pull m.daocloud.io/docker.io/library/nginx:alpine
docker tag m.daocloud.io/docker.io/library/nginx:alpine nginx:alpine

在项目根目录新建 Dockerfile:

# 第一阶段:编译静态文件
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 第二阶段:装配静态分发容器,丢弃构建依赖
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

四、 网络发布

1. 域名与 DNS

注册域名后,前往 Cloudflare 控制台 点击Add a site输入域名。

进入域名注册商后台,将 Name Server 记录修改为 Cloudflare 分配的两条权威服务器地址(*.ns.cloudflare.com),等待解析生效。

2. 创建 Cloudflare Tunnel

前往 Cloudflare Zero Trust 控制台。

在左侧导航栏依次选择Networks -> Tunnels,点击Create a tunnel,

选择Cloudflared部署方式并命名。

在配置页面选择Docker环境,复制命令中附带的专属 TUNNEL_TOKEN。

在博客项目根目录下创建 docker-compose.yml:

services:
  astro-blog:
    build: .
    container_name: astro-blog
    restart: always

  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: always
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=你的Cloudflare_Tunnel_Token
    depends_on:
      - astro-blog

在终端执行一键启动命令:

docker compose up -d --build

3. 映射 Public Hostname

回到 Cloudflare Zero Trust 控制台 的 Tunnel 配置页,切换至Public Hostname标签:

点击Add a public hostname;

Subdomain:按需输入子域名(如 blog,主域则留空);

Domain:选择你在第一步绑定的域名;

Type:选择 HTTP;

URL:填写 astro-blog:80(直接使用 Compose 服务名解析,无需暴露宿主机端口)。

保存配置后,Cloudflare 会自动完成全球 CDN 节点与本地笔记本容器的端到端安全连接。

五、 博客更新流程图

[ 开发端 ]
   │  1. 本地修改代码/更新文章
   │  2. git add .
   │  3. git commit -m ""
   │  4. git push origin main
   ▼
[ GitHub 仓库 ]
   │  5. 推送至 GitHub 仓库
   ▼
[ 服务器 ]
   │  6. cd ~/.../LimoBlog
   │  7. git pull --rebase origin main
   ▼
[ Docker ]
   │  8. docker compose up -d --build
   │  9. docker image prune -f
   ▼
[ 公网(https://limovane.top)]

## 结语 除此之外,我还做了三件事:

Tailscale:

为服务器与开发端建立了安全的 P2P 加密隧道,实现 SSH 与 xrdp 远程桌面控制;

GParted:

从盘中划出 154GB 的独立 ext4 分区挂载为 /data,将 Docker 的存储中枢(data-root)完整平移。

Autocutsel:

由于 Linux 历史遗留的双重剪贴板机制,我无法跨系统剪贴,这个工具通过让 Linux 双剪贴板同步,解决了应用层粘贴阻抗的问题。

不过受限于篇幅,就不作过多展开了。

收工。

整个工程闭环比我预期的更为流畅,

前后仅耗费一天半。



上一篇
智能体 & 工作流