🚀 零公网 IP 实现内网穿透:Tailscale 安装与多端互联异地访问指南
🚀 零公网 IP 实现内网穿透:Tailscale 安装与多端互联异地访问指南📡 什么是 Tailscale?在日常折腾 HomeLab、NAS 或者远程办公时,我们经常需要在外网访问家里的设备。传统的方案要么需要运营商提供公网 IP(配合 DDNS),要么需要使用带有中心服务器的内网穿透工具(如 Frp、Nps),但这两种方案要么门槛高,要么受限于中心服务器的带宽。 Tailscale 是一种基于 Mesh(网状)拓扑结构的虚拟私人网络(VPN)工具。它能让你分散在各地的设备(手机、电脑、服务器、路由器)无视复杂的网络环境(如大内网、双重路由、NAT 限制),安全地连接在同一个虚拟局域网内。 Tailscale 的核心优势: 去中心化(P2P 连接):虽然有控制服务器协调连接,但设备之间的数据传输是端到端(Peer-to-Peer)的。一旦打洞成功,流量直接在两台设备间传输,速度取决于你的宽带上限,不限速。 无感接入:设备加入网络后,会获得一个固定的内网 IP(100.x.x.x 网段),无论你身处何地,直接访问这个 IP 就能连接设备。 极其简单的配置:无需折腾复杂的证书...
在 Next.js 16 (Turbopack) 中集成 RDKit.js 渲染 SMILES 的工程实践与踩坑指南
在 Next.js 16 (Turbopack) 中集成 RDKit.js 渲染 SMILES 的工程实践与踩坑指南前言在生物制药数字化(AIDD、LIMS 等系统)的前端开发中,SMILES(简化分子线性输入规范)是表示分子结构最常用的文本格式。为了在前端实现“输入文本,实时预览 2D 分子结构”,我们需要引入化学信息学界的工业级开源工具包:RDKit.js。 由于 RDKit.js 底层依赖重型的 WebAssembly (Wasm) 编译产物,当它遇到 Next.js 16 默认的 Turbopack 构建流以及 SSR(服务端预渲染) 架构时,会引发一系列经典的打包与运行时崩溃。 本文将完整记录基于 Next.js 16 + Bun + TypeScript 栈集成 RDKit.js 的踩坑心路历程,并分享最终的离线化解决方案。 一、 初次尝试与经典的 “fs” 编译炸弹按照常规的前端模块化思维,我们首先会通过 Bun 安装依赖: 1bun add @rdkit/rdkit 然后在一个标准的 Client Component 中尝试动态加载: 12// 尝试通过全局或动...
🚀 玩转 Homelab:使用 Helm 在 K3s 中部署 Gitea,并接入外部 PostgreSQL
🚀 玩转 Homelab:使用 Helm 在 K3s 中部署 Gitea,并接入外部 PostgreSQL在自己的内网(Homelab)环境里,拥有一个轻量、好用、全加密(HTTPS)的代码托管系统是每个开发者的梦想。今天这篇博客就带大家复盘,如何利用 K3s、Traefik 网关以及外部自建的 PostgreSQL 数据库,一步步搭建属于自己的 Gitea。 我们将摒弃复杂的理论,用最纯粹的实战步骤,带你避开内网部署中的那些“隐藏大坑”。 🏗️ 整体架构一览为了让整个系统足够轻量且好维护,我们采用了以下设计方案: flowchart TB subgraph Client ["开发者环境 (Client)"] Browser["浏览器 (HTTPS)"] GitCli["Git 客户端 (SSH)"] end subgraph K3S ["K3s 集群边界 (K3s Cluster)"] direction TB subgraph Net ["网络与路由 (Ingres...
从零开始:在 K3s 中部署 CloudNativePG 并成功实现外部直连(全流程实战)
前言本文是在我的Homelab 单节点 K3s(IP: 192.168.0.103)上部署 CloudNativePG (CNPG) 1.29 版本。 123kubectl get nodesNAME STATUS ROLES AGE VERSIONearzer Ready control-plane 53d v1.35.4+k3s1 过程安装 kubectl-cnpg 插件(强烈推荐)CloudNativePG 提供了一个非常强大的 kubectl 插件,可以帮助你轻松查看数据库状态、进行主备切换、查看日志等。 在你的控制端(或 K3s 节点上)运行以下命令安装: 1curl -sSfL https://github.com/cloudnative-pg/cloudnative-pg/raw/main/hack/install-cnpg-plugin.sh | sudo sh -s -- -b /usr/local/bin 如果你是中国用户,你可以使用gh-proxy来加速 1curl -sSfL https://gh-...
🚀 记一次本地 Homelab 环境 Gitea 升级迁移与 Actions (CI/CD) 完美集成实战
🚀 记一次本地 Homelab 环境 Gitea 升级迁移与 Actions (CI/CD) 完美集成实战📌 前言最近对本地 Homelab 服务器的私有代码托管平台 Gitea 进行了一次大版本升级迁移(升级至 v1.26)。原本以为只是一次简单的 docker compose up,没想到中间经历了数据库连错库、旧运行器残留、以及 Gitea Actions (Act Runner) 容器网络隔离等一连串经典的暗坑。 本文将完整记录这次迁移过程、踩坑原因以及最终如何完美集成兼容 GitHub Actions 语法的 Gitea Actions 并成功跑通 Go 自动化编译 的全案。 🛠️ 第一阶段:大版本迁移与数据库踩坑在新的服务器上,我准备好了原有的数据卷 ./data 并编写了新的 docker-compose.yaml。然而初次启动后,发现网页端一片空白,原有的代码仓库、组织和用户全都不见了! 🔍 踩坑原因检查 docker-compose.yaml 发现,在环境变量中误指定了一个全新的数据库名: 12- GITEA__database__NAME=...
2026年5月8号面试总结
前言2026年5月8号有一场面试,是对方架构师来面试的我。总的来说,面试的效果不是很好。面试的岗位是前端岗位,但是问的很多是后端架构的设计,我认为我的准备不是很好,我需要继续努力补全自己。 问题Java的虚拟线程问题:Java的虚拟线程是什么,怎么创建? 回答如下: 在Java 21中,引入了虚拟线程(Virtual Threads)来简化和增强并发性,这使得在Java中编程并发程序更容易、更高效。 虚拟线程,也称为“用户模式线程(user-mode threads)”或“纤程(fibers)”。该功能旨在简化并发编程并提供更好的可扩展性。虚拟线程是轻量级的,这意味着它们可以比传统线程创建更多数量,并且开销要少得多。这使得在自己的线程中运行单独任务或请求变得更加实用,即使在高吞吐量的程序中也是如此。 在Java 21中创建和使用虚拟线程有多种方法: 1. 使用静态构建器方法Thread.startVirtualThread方法将可运行对象作为参数来创建,并立即启动虚拟线程,具体如下代码: 123456Runnable runnable = () -> { S...
2026年5月7号面试总结
前言2026年5月7号有两场面试,本文记录了自己预先准备面试题和面试中遇到的问题。 笔试防抖 (Debounce)原理:在事件被触发 $n$ 秒后再执行回调,如果在这 $n$ 秒内又被触发,则重新计时。适用于:搜索框输入、窗口大小调整 1234567891011121314function debounce<T extends (...args: any[]) => void>( func: T, wait: number): (...args: Parameters<T>) => void { let timeout: ReturnType<typeof setTimeout> | null = null; return function (this: any, ...args: Parameters<T>) { if (timeout) clearTimeout(timeout); timeout = setTimeout(() => { func.a...
使用 Resend + Golang 发送邮件的完整踩坑与解决方案
使用 Resend + Golang 发送邮件的完整踩坑与解决方案在实际开发中,我尝试使用 Resend 的 SMTP 服务结合 Golang 发送邮件(用于重置密码等场景),过程中踩了多个典型坑。本文从 错误现象 → 原因分析 → 最终正确方案 进行完整总结。 一、背景目标: 使用 Golang 发送 HTML 邮件 接入 Resend SMTP 支持自定义域名发信(提升送达率) 二、Resend SMTP 基本认知(关键)Resend 的 SMTP 和传统 SMTP 有一个重要区别: 类型 含义 示例 SMTP Username 登录用户名 resend(固定) SMTP Password API Key re_xxx From(发件人) 邮件发送地址 noreply@xxx.com 👉 重点:Username ≠ From 三、踩坑记录(按时间顺序) ❌ 问题 1:501 Bad sender address syntax1501 Error: Bad sender address syntax 原因1auth := smtp.Plai...
无 Docker Desktop + Colima + Docker Compose v2 标准化方案
无 Docker Desktop + 纯 CLI + Colima + Docker Compose v2 标准化方案一、背景在 macOS 环境中,Docker Desktop 虽然开箱即用,但存在以下问题: 资源占用高(CPU / 内存) 启动慢 商业使用存在许可限制 与开发环境(如 k8s / 自定义 runtime)耦合较重 因此,采用以下组合替代: Colima + Docker CLI + Compose v2 Plugin 目标是实现: 轻量级 Docker 运行环境 完整 CLI 操作体验 原生支持 docker compose(v2) 二、整体架构1234567891011121314151617docker CLI ↓docker context (colima) ↓unix socket (~/.colima/default/docker.sock) ↓Colima VM (container runtime)````---## 三、环境安装### 1. 安装基础工具```bashbrew install doc...
优雅实现 Git 多账号切换:基于 SSH Config 与 includeIf 的环境隔离方案
优雅实现 Git 多账号切换:基于 SSH Config 与 includeIf 的环境隔离方案在日常开发中,我们经常需要在一台电脑上同时处理个人开源项目和公司业务项目。最核心的痛点有两个: SSH Key 冲突:GitHub 默认只识别一对密钥,多账号如何无感切换? 提交身份混淆:如何在公司项目中自动使用公司邮箱,在个人项目中自动使用个人邮箱? 本文分享一种“一次配置,永久生效”的自动化方案。 1. 目录结构规划首先,建议按用途将项目存放在不同的父目录下,这是自动化切换的前提。 123Workspaces/├── personal/ # 存放个人项目└── company/ # 存放公司项目 2. 生成独立的 SSH 密钥为每个账号生成专属的密钥对,不要覆盖默认的 id_ed25519。 12345# 生成个人账号密钥ssh-keygen -t ed25519 -C "personal@email.com" -f ~/.ssh/id_ed25519_personal# 生成公司账号密钥ssh-keygen -t ed25519 -C "...
