Loading... # 一、背景与目标 ## 1. 项目背景 ### A. 业务场景 作者维护个人基础设施已超过十年,自托管服务包括邮件服务器、博客、IRC 服务器、图片托管、RSS 阅读器等。原有部署方式混乱,有的使用容器,有的直接使用 nginx 托管静态文件,有的则是从 Debian 包管理器安装的二进制文件,缺乏统一管理。 ### B. 痛点分析 - 部署方式不一致,难以维护 - 服务分散在各个位置,缺乏统一管理 - 家庭网络 ISP 使用 NAT,难以直接暴露服务到公网 ## 2. 设计目标 ### A. 功能目标 - 在本地家庭网络托管个人基础设施和服务 - 支持内部服务和面向互联网的服务 - 统一容器化部署方案 ### B. 非功能目标 - 易于部署和配置 - 尽可能自托管,愿意牺牲部分便利性 - 可靠性强,无需频繁维护 # 二、硬件资源 ## 1. 设备清单 - **NAS 服务器**:2×8 TB 磁盘,2012 年硬件 - **Intel NUC(byggmester)**:Intel i5-6260U,16 GB RAM,2015 年 - **AMD NUC(amd)**:AMD Ryzen 7 8745HS,64 GB RAM,购自 AliExpress - **路由器**:OpenWRT One ## 2. 网络架构 家庭网络采用扁平化设计,所有设备在同一网段。 ```mermaid graph LR Internet[互联网] -->|WireGuard 隧道| VPS[VPS 服务器] VPS --> byggmester[Intel NUC<br/>byggmester] byggmester --> amd[AMD NUC<br/>amd] byggmester --> NAS[NAS 服务器] amd --> Router[OpenWRT One] Router --> Clients[客户端设备] ```  # 三、容器化平台:Incus ## 1. Incus 简介 Incus(原 LXD)是一个容器管理器,支持 LXC 容器、QEMU 虚拟机和 OCI 容器。作者已使用多年,具有高度可靠性,版本间更新不会突然破坏功能。 ## 2. 集群配置 Incus 集群包含两个节点: - amd:https://10.100.100.3:8443 - byggmester:https://10.100.100.2:8443 ## 3. 网络配置 两个节点都创建了名为 br0 的网桥设备,所有容器使用桥接网络获取本地 IP,路由器提供域名解析。 systemd-networkd 配置示例: ``` # /etc/systemd/network/20-wired.network [Match] Name=en* [Network] Bridge=br0 # /etc/systemd/network/50-br0.netdev [NetDev] Name=br0 Kind=bridge # /etc/systemd/network/50-br0.network [Match] Name=br0 [Network] Address=192.168.1.2/24 Gateway=192.168.1.1 DNS=192.168.1.1 ``` Incus 默认配置: ``` # incus profile show default description: Default Incus profile devices: eth0: nictype: bridged parent: br0 type: nic root: path: / pool: default type: disk name: default ``` ## 4. OCI 容器支持 Incus 支持从容器镜像仓库直接拉取 OCI 容器。例如启动 Valkey 容器: ```bash incus remote add docker https://docker.io/ --protocol=oci --public incus launch docker:valkey/valkey valkey ``` 容器启动后可直接通过本地域名访问: ```bash ping valkey.local # PING valkey.local (192.168.1.148) 56(84) bytes of data. ``` # 四、基础设施即代码:OpenTofu ## 1. OpenTofu 简介 OpenTofu(Terraform 的开源替代品)通过声明式配置管理 Incus 资源,将所有持久化数据存储在 NAS 上,实现基础设施的可重现部署。 ## 2. 项目管理 所有服务按项目分类,每个项目共享通用模板,包括权限、网络和默认配置。OpenTofu 模块结构: - project 模块:所有其他模块的基础模板 - 各服务模块:从 project 模块派生 ## 3. 项目列表 当前运行的项目: | 项目名称 | 描述 | 容器数量 | |---------|------|---------| | ca | CA 项目 | 4 | | default | 默认项目 | 48 | | dns | DNS 项目 | 7 | | immich | Immich 项目 | 14 | | mediaserver | 媒体服务器项目 | 18 | | miniflux | Miniflux 项目 | 6 | | syncthing | Syncthing 项目 | 3 | | test | 测试项目 | 2 | | user-1000 | 用户受限项目 | 2 | ## 4. Immich 部署示例 Immich 项目包含 7 个容器: - auto-album-jpg - auto-album-raw - database - immich - immich-machine-learning - redis OpenTofu 配置示例: ``` resource "incus_image" "redis" { project = incus_project.immich.name alias { name = "redis" } source_image = { remote = "docker" name = "valkey/valkey:8-bookworm" } } resource "incus_instance" "immich_redis" { name = "redis" image = incus_image.redis.fingerprint project = incus_project.immich.name target = "amd" config = { "boot.autorestart" = true } } ``` # 五、网络暴露方案 ## 1. WireGuard 反向隧道 由于家庭 ISP 使用 NAT,无法直接暴露服务到公网。解决方案是在具有静态 IPv4 和 IPv6 的 VPS 上建立 WireGuard 点对点 VPN 隧道。 ```mermaid sequenceDiagram participant Internet as 互联网用户 participant VPS as VPS 服务器<br/>静态 IP participant WG as WireGuard 隧道 participant byggmester as Intel NUC<br/>byggmester participant Incus as Incus 容器 Internet->>VPS: HTTPS 请求 VPS->>WG: 转发流量 WG->>byggmester: 隧道传输 byggmester->>Incus: 反向代理 Incus->>byggmester: 返回内容 byggmester->>WG: 隧道传输 WG->>VPS: 转发响应 VPS->>Internet: HTTPS 响应 ```  ## 2. Nginx 反向代理 在 byggmester 节点上运行 nginx,将需要对外暴露的服务反向代理到内部 Incus 容器。使用内部 DNS 服务器解析域名,避免在 nginx 配置中硬编码 IP。 nginx-acme 插件自动处理 TLS 证书,无需手动运行 certbot。 nginx 配置示例: ``` # /etc/nginx/nginx.d/10-acme.conf acme_issuer letsencrypt { uri https://acme-v02.api.letsencrypt.org/directory; contact root@linderud.dev; state_path /var/lib/nginx/acme; accept_terms_of_service; } acme_shared_zone zone=ngx_acme_shared:1M; server { listen 80; location / { return 404; } } # /etc/nginx/snippets/acme.conf acme_certificate letsencrypt; ssl_certificate $acme_certificate; ssl_certificate_key $acme_certificate_key; ssl_certificate_cache max=2; # /etc/nginx/nginx.d/30-bilder.linderud.dev.conf server { listen 443 ssl; listen [::]:443 ssl; server_name bilder.linderud.dev; access_log /var/log/nginx/bilder.linderud.dev/access.log; error_log /var/log/nginx/bilder.linderud.dev/error.log; include snippets/acme.conf; include snippets/sslsettings.conf; client_max_body_size 50000M; resolver 192.168.1.1 ipv6=off; location / { set $immich immich.local; proxy_pass http://$immich:2283; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; } } ``` # 六、静态网站部署 ## 1. Syncthing 同步方案 对于静态网站(如博客),作者使用 Syncthing 将构建后的文件同步到 Web 服务器,避免了复杂的 CI/CD 流程。 ## 2. 部署流程 ```mermaid graph LR Local[本地计算机] -->|Hugo 构建| Build[构建输出] Build -->|Syncthing| Sync[同步目录] Sync -->|/srv/linderud.dev/blog| Web[Web 服务器] ```  服务器目录结构: ``` /srv/linderud.dev/ ├── blog # 博客 ├── coredns01 # DNS 服务器配置 └── pub # 公共共享文件 ``` 部署命令: ```bash hugo build -d /srv/linderud.dev/blog/ ``` 优点: - 无服务依赖 - 无需 CI/CD 设置 - 无需 GitHub Actions - 无需 Ansible Playbooks # 七、网络管理:OpenWRT One ## 1. 硬件设备 OpenWRT One 是面向 OpenWRT 开发者的路由器,购自 AliExpress。 ## 2. 配置管理 作者编写了 OpenTofu provider 管理路由器配置,实现了基础设施即代码的网络管理。 ## 3. 未来规划 计划添加支持 OpenWRT 的交换机,实现 VLAN 网络分段。 # 八、运维工具 ## 1. USB KVM 在 38C3 活动中购买的 USB KVM 设备,通过 HDMI 和 USB-C 线缆连接到各个小计算机,简化了多设备管理。 # 九、技术总结 ## 1. 核心技术栈 - **容器平台**:Incus(LXC 容器 + QEMU 虚拟机 + OCI 容器) - **基础设施即代码**:OpenTofu - **网络暴露**:WireGuard + nginx - **文件同步**:Syncthing - **路由器**:OpenWRT One ## 2. 架构优势 - 统一容器化部署 - 声明式配置管理 - 简化的网络暴露方案 - 无依赖的静态网站部署 ## 3. 设计理念 - 简单性优于复杂性 - 自托管优于云服务 - 可靠性优于功能丰富 *** ## 参考资料 1. [Personal infrastructure setup 2026](https://linderud.dev/blog/personal-infrastructure-setup-2026/) 2. [Locally hosting an internet-connected server](https://mjg59.dreamwidth.org/70948.html) 最后修改:2026 年 01 月 24 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏