Hugo 进阶:集成 Google Analytics 4 与站点收录优化

完成网站搭建后,下一步便是集成 Google Analytics (GA4) 以及优化搜索引擎收录。对于我来说,这不仅仅是技术配置,更是将以前域名的冗余资源清理掉,赋予这个站点一个干净、纯粹的起点。 1. 集成 Google Analytics 统计分析 在 FixIt 主题中,集成统计分析需要配置 Hugo 的内置服务与主题插件。 在 hugo.toml 文件中进行如下配置: # 1. 开启 Hugo 内置的 Google Analytics 服务 [services] [services.googleAnalytics] ID = 'G-XXXXXXXXXX' # 替换为您在 GA4 获取的“衡量 ID” # 2. 配置 FixIt 主题的分析插件 [params] [params.analytics] enable = true type = "google" # 指定类型为 google [params.analytics.google] id = "G-XXXXXXXXXX" async = true # 开启异步加载,避免统计代码影响网页首屏加载速度 站长提示:配置完成后,建议在本地运行 hugo server 并使用 F12 检查网络请求,确认是否有来自 google-analytics.com 的数据上报。 2. 提交 Sitemap 与清理旧资源 为了让 Google 更好地爬取新内容,并彻底告别过去,我们需要通过 Google Search Console 进行以下操作。 ...

2026-01-02 · 1 min · Eagle

Hugo 进阶:FixIt 主题深度配置(目录结构、多级菜单与 Logo)

在完成第一篇文章的发布后,趁热打铁记录下 FixIt 主题的深度定制备忘,重点解决内容组织架构与导航体验。 1. 内容目录架构:从逻辑到物理组织 为了方便管理 9 年来的技术沉淀,我决定不依赖 Hugo 的扁平化展示,而是通过文件夹在物理层面进行分类,将其划分为 “项目实战” 与 “技术随笔” 两大板块。 项目实战 (Projects) 在 content/projects/ 目录下,采用“一项目一文件夹”的结构。每个文件夹内放置 _index.md 标识该板块为一个 Section。 路径示例:content/projects/mole-client/_index.md 配置内容: +++ title = "Mole 客户端 (frp管理)" layout = "section" draft = false +++ 注意:在父级 projects/ 下也要放置一个 _index.md 作为项目总列表。 技术随笔 (Posts) 日常记录存放于 content/posts/。不需要 _index.md,直接通过文章开头的 Front Matter 进行分类。 示例 Front Matter: categories: ["deploy"] # 将分类设为 deploy,Hugo 会自动将其归档至对应分类页 2. 导航菜单配置:构建多级下拉菜单 在 hugo.toml 中,通过 identifier 和 parent 的配合,我为“技术笔记”板块设计了下拉菜单,使导航更具条理性。 [menu] # 首页入口 [[menu.main]] identifier = "home" name = "首页" url = "/" pre = '<i class="fa-solid fa-home fa-fw"></i>' weight = 1 # --- 技术笔记下拉菜单 --- # 1. 父级入口:点击不跳转,仅用于展开子项 [[menu.main]] identifier = "notes" name = "技术笔记" url = "#" pre = '<i class="fa-solid fa-book fa-fw"></i>' weight = 2 # 2. 子菜单:小程序 [[menu.main]] parent = "notes" identifier = "mp" name = "小程序" url = "/categories/mp/" pre = '<i class="fa-solid fa-mobile-screen-button fa-fw"></i>' weight = 1 # 3. 子菜单:Go 语言 [[menu.main]] parent = "notes" identifier = "go" name = "Go 语言" url = "/categories/go/" pre = '<i class="fa-brands fa-golang fa-fw"></i>' weight = 2 # 4. 子菜单:Rust 语言 [[menu.main]] parent = "notes" identifier = "rust" name = "Rust 语言" url = "/categories/rust/" pre = '<i class="fa-brands fa-rust fa-fw"></i>' weight = 3 # 5. 子菜单:部署运维 [[menu.main]] parent = "notes" identifier = "deploy" name = "部署实战" url = "/categories/deploy/" pre = '<i class="fa-solid fa-cloud-arrow-up fa-fw"></i>' weight = 4 # --- 其他一级菜单 --- [[menu.main]] identifier = "projects" name = "项目实战" url = "/projects/" pre = '<i class="fa-solid fa-layer-group fa-fw"></i>' weight = 10 [[menu.main]] identifier = "about" name = "关于我" url = "/about/" pre = '<i class="fa-solid fa-user-circle fa-fw"></i>' weight = 20 3. 视觉识别:更换站点 Logo 作为“ 豆子技术站”的标志,我选择了 Ostrich 图标。 ...

2026-01-01 · 2 min · Eagle

从零到一:Hugo 项目部署 Cloudflare Pages 避坑指南

今天“ 豆子技术站”正式上线了!虽然部署过程只用了几个小时,但中间踩了不少坑。为了让大家少走弯路,我把这段折腾经历记录下来。 为什么选择 Hugo + GitHub + Cloudflare? 我有自己的服务器,最初想用 mdBook。但 mdBook 适合书籍展示,格式太固定,不适合折腾。最终我选择了 Hugo —— 虽有一段时间没用,但基础还在。 在主题选型上我花了不少时间,从花哨的 Blowfish 转向了更严谨的 FixIt。虽然我的重心正转向 Go 和 Rust,但 2026 年初的首要任务是搭建好这个支持中英双语的“根据地”。 站长忠告:切忌心急。 很多弯路其实是因为没读懂 Cloudflare 的英文提示就直接上手导致的。 避坑指南:我踩过的六个坑 1. 误判服务:Workers 还是 Pages? 这是最尴尬的一个坑。我一直在 Cloudflare Workers 里折腾,结果页面永远显示 Hello World。AI 告诉我是配置文件没生效,我折腾半天无果,最后通过 Google 搜索才发现:我要部署的是静态站(Pages),而不是函数脚本(Workers)。换成 Pages 服务后,一遍过。 2. DNS 托管的“心理障碍” Cloudflare 的免费计划要求将 DNS 托管给它。起初我很抗拒,因为我还有阿里云的子域名(如小程序后端 mp)在运行,担心影响原有业务。 解决方法:在域名注册商后台将 DNS 服务器换成 Cloudflare 提供的地址。 关键点:激活后,记得把原来的解析记录在 Cloudflare 重新添加一遍。以后新增解析都在 Cloudflare 完成。 3. 页面样式“裸奔”:baseURL 没填对 部署完成后,网站能打开但没有样式(CSS 加载失败)。 原因:F12 检查发现 URL 地址不对。 解决:在 hugo.toml 中将 baseURL 修改为你的自定义域名。 进阶:在 Cloudflare 构建命令中使用 hugo -b $CF_PAGES_URL,系统会自动处理域名。 4. CNAME 无法直接生效 我起初打算在原域名商处使用 CNAME,但死活打不开。事实证明,为了享受 Cloudflare 的全套防护和证书服务,DNS 托管是最高效的选择。 ...

2026-01-01 · 1 min · Eagle

自签名证书无法在网盘cloudreve使用S3通过https协议连接Minio

Cloudreve是一个自托管文件管理与共享系统,支持多存储提供商。我们需要集成Minio的S3服务。现在碰到了问题,在填写参数后,无法在客户端上传文件。 我们的Minio服务使用自签名证书。排查发现应该是证书问题。现在需要在系统中安装证书。 我们已经解决,具体步骤如下: 1,检查证书是否PEM格式? 检查方法: cat public.crt 如果开头是 —–BEGIN CERTIFICATE—–,则是 PEM 格式。 如果是一堆乱码,则是 DER 格式。需要转换为PEM格式:openssl x509 -inform der -in public.crt -out public.pem 2,放置证书 在CentOS Linux中,需要将证书文件放在/etc/pki/ca-trust/source/anchors/目录下,并且后缀必须为.crt。如果文件名为public.pem,需要改为public.crt。 确认文件是否放置正确? ls /etc/pki/ca-trust/source/anchors/ 输出中应包含我们的证书。 3,激活证书 执行以下命令激活,依次执行: update-ca-trust extract update-ca-trust 4,验证证书是否激活成功 tail -n 20 /etc/pki/tls/certs/ca-bundle.crt 查看是否是自己的证书,如果还没有成功,执行命令追加: cat public.crt | sudo tee -a /etc/pki/tls/certs/ca-bundle.crt 最后,使用 grep 搜索证书中关键的信息 grep -i "域名信息" /etc/pki/tls/certs/ca-bundle.crt 这个时候应该可以搜索了。 5,验证在系统中使用证书 我们使用命令检验Minio是否可以使用自签名证书 curl -v https://yourdomain.com:9000 如果输出SSL证书信息,并显示Access 相关信息,则成功了。如果没有,则需要再次检查证书生成信息是否正确?例如,是否包含了正确的域名? 6,重启Cloudreve网盘服务 最后一定要重启Cloudreve网盘,只有重启之后才能加载系统自定义证书。

2025-01-13 · 1 min · Eagle

Netstat 常用命令

查询本机 IP 连接 netstat -an 查看网络 TCP 连接状态数量 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 查看 8080 端口有多少个 TCP 连接 netstat -ant |grep 8080|wc -l 查看当前 TCP 连接状态为 ESTABLISHED 的数量 netstat -ant|grep 8080|grep ESTABLISHED|wc -l 查看 TCP 连接 netstat -ant 过滤某个 TCP 端口 netstat -ant |grep 端口号 查看 UDP 连接 netstat -anu 过滤某个 UDP 端口 netstat -anu |grep 端口号 实时监控 UDP 连接信息,每隔 2 秒自动更新一次 watch -n 2 'netstat -anu' 使用 ss 或 netstat 关联进程和端口 ...

2025-01-01 · 2 min · Eagle

Asterisk 常见错误

Asterisk 是第一套以开放源代码软件实现的 用户交换机 (PBX) 系统。Asterisk 由 Digium 的创办人马克·史宾瑟(Mark Spencer)于 1999 年他还在奥本大学念书时所开发。与其他的用户交换机系统相同,Asterisk 同样支持电话拨打另一只分机,和拨打到公共交换电话网与 IP 电话系统。Asterisk 这个名称源自于星号 “*"。 网址:https://www.asterisk.org/ Asterisk 常见错误 403 登录失败 解决:等待 1 分钟,等超时之后重新连接即可。一般是切换 IP 时或者换软电话登录会碰到。 401 登录失败 解决:检查账户和密码是否正确?检查连接地址是否正确?检查 Asterisk 是否启动?检查防火墙端口是否打开? 408 连接超时 解决:一般是 Asterisk 服务不通,检查 Asterisk 服务是否启动,检查防火墙是否打开? 可以拨通,没有声音? 一般是 NAT 造成,配置这三个参数:rtp_symmetric,force_rport,rewrite_contact。 SIP 客户端没有自动挂机? 一般是没有设置 stun 造成的,在 SIP 客户端,设置 stun 即可。如果没有 stun server,可以设置这个stun.l.google.com:19302 AGI 脚本返回状态 4,正常应该为 0? 查看网上资料,是 AGI 脚本中调用 Hangup 导致,将脚本中的 Hangup 去掉,放在拨号计划配置文件中执行 Hangup,可以解决这个问题。 AGI Script agidemo completed, returning 0 解决 asterisk 没有声音的问题 在配置好 asterisk 之后,拨打 8000 没有听到声音。 ...

2025-01-01 · 1 min · Eagle

Bash 常用命令

查看内存占用 ps aux | grep soffice | grep -v grep | awk '{print $6/1024 " MB"}' 查看日志 查询 IP 信息,查找某条请求记录,然后打印出 IP 那一列,进行排序,再去重。可以得出请求的 IP 信息。 cat golog/20240905_ad.log |grep 'ad'|awk '{print $9}'|sort|uniq 从 IP 归属地库查询省份城市信息 cat ip.merge.txt |grep '河南省'|awk -v FS="|" '{print $5}'|sort|uniq 将行记录变成一行,并以逗号分割。 cat ip.merge.txt |grep '河南省'|awk -v FS="|" '{print $5}'|sort|uniq|paste -s -d "," Awk awk 是一种处理文本文件的语言,是一个强大的文本分析工具。 使用分隔符指定列: awk -F',' '{print $1, $2}' file 打印满足条件的行数: awk '/pattern/ {print NR, $0}' file SCP 正则匹配复制文件 scp 可以使用正则复制文件,一次复制多个文件 scp -P 2222 \*.mp4 root@host:/data/upfile/ scp 还可以复制文件夹,使用-r 属性,递归复制,例如下面的格式: ...

2025-01-01 · 2 min · Eagle

Curl 用法

cURL(Client URL)是一个功能强大的命令行工具,用于通过 URL 传输数据,支持多种协议(如 HTTP/HTTPS、FTP、SFTP、SCP 等)。它广泛用于 API 测试、文件传输、数据提交等场景。 安装 Linux (Debian/Ubuntu) sudo apt-get install curl macOS brew install curl # 通过Homebrew安装/更新 Windows 从官网下载二进制文件 或使用 Chocolatey: choco install curl 基本用法 发起 GET 请求 curl https://example.com 保存响应到文件 curl -o custom_filename.html https://example.com # 自定义文件名 curl -O https://example.com/file.zip # 使用远程文件名 常用选项 选项 说明 -v 显示详细日志(请求头、响应头、SSL 信息) -L 自动跟随重定向 -s 静默模式(隐藏进度条和错误信息) -i 显示响应头 + 响应体 -I 仅显示响应头(发送 HEAD 请求) -k 跳过 SSL 证书验证(不安全,谨慎使用) -A 设置 User-Agent,如 -A "Mozilla/5.0" HTTP 方法 POST 请求(表单数据) curl -X POST https://api.example.com/data -d "name=John&age=30" POST 请求(JSON 数据) curl -X POST -H "Content-Type: application/json" \ -d '{"name":"John", "age":30}' https://api.example.com/data PUT/DELETE 请求 curl -X PUT https://api.example.com/item/1 -d "data=example" curl -X DELETE https://api.example.com/item/1 处理 HTTP 头 查看响应头 curl -I https://example.com 发送自定义头 curl -H "Authorization: Bearer token123" \ -H "X-Custom-Header: value" https://api.example.com 文件传输 上传文件(表单) curl -F "file=@/path/to/file.txt" https://example.com/upload 上传文件(FTP) curl -T file.txt ftp://example.com/upload/ 断点续传 curl -C - -O https://example.com/large-file.zip 认证 基本认证(Basic Auth) curl -u username:password https://example.com Cookie 管理 curl -c cookies.txt https://example.com/login # 保存Cookie curl -b cookies.txt https://example.com/dashboard # 发送Cookie 高级功能 限速下载(100KB/s) curl --limit-rate 100K -O https://example.com/large-file.zip 使用代理 curl -x http://proxy-server:8080 https://example.com 调试请求 curl --trace-ascii debug.txt https://example.com 实际示例 下载 GitHub 仓库 curl -L -O https://github.com/user/repo/archive/master.zip 模拟浏览器访问 curl -A "Mozilla/5.0" -H "Accept-Language: en-US" https://example.com 调试 HTTPS 请求 curl -v -k https://example.com # 查看SSL握手过程(忽略证书错误) 注意事项 敏感数据:避免在命令行中直接暴露密码,推荐使用--netrc或环境变量。 HTTPS 安全:生产环境中尽量不使用-k(跳过证书验证)。 命令顺序:组合选项时注意顺序(如-L -O需先重定向再保存文件)。 速率限制:使用--limit-rate避免占用过多带宽。

2025-01-01 · 2 min · Eagle

Docker 常用命令

DOCKER Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 Docker 网址:https://www.docker.com/ Docker 常用命令: docker init # Creates Docker-related starter files docker build -t friendlyname . # Create image using this directory's Dockerfile docker run -p 4000:80 friendlyname # Run "friendlyname" mapping port 4000 to 80 docker run -d -p 4000:80 friendlyname # Same thing, but in detached mode docker exec -it [container-id] bash # Enter a running container docker ps # See a list of all running containers docker stop <hash> # Gracefully stop the specified container docker ps -a # See a list of all containers, even the ones not running docker kill <hash> # Force shutdown of the specified container docker rm <hash> # Remove the specified container from this machine docker rm -f <hash> # Remove force specified container from this machine docker rm $(docker ps -a -q) # Remove all containers from this machine docker images -a # Show all images on this machine docker rmi <imagename> # Remove the specified image from this machine docker rmi $(docker images -q) # Remove all images from this machine docker logs <container-id> -f # Live tail a container's logs docker login # Log in this CLI session using your Docker credentials docker tag <image> username/repository:tag # Tag <image> for upload to registry docker push username/repository:tag # Upload tagged image to registry docker run username/repository:tag # Run image from a registry docker system prune # Remove all unused containers, networks, images (both dangling and unreferenced), and optionally, volumes. (Docker 17.06.1-ce and superior) docker system prune -a # Remove all unused containers, networks, images not just dangling ones (Docker 17.06.1-ce and superior) docker volume prune # Remove all unused local volumes docker network prune # Remove all unused networks DOCKER COMPOSE docker-compose up # Create and start containers docker-compose up -d # Create and start containers in detached mode docker-compose down # Stop and remove containers, networks, images, and volumes docker-compose logs # View output from containers docker-compose restart # Restart all service docker-compose pull # Pull all image service docker-compose build # Build all image service docker-compose config # Validate and view the Compose file docker-compose scale <service_name>=<replica> # Scale special service(s) docker-compose top # Display the running processes docker-compose run -rm -p 2022:22 web bash # Start web service and runs bash as its command, remove old container. DOCKER SERVICES docker service create <options> <image> <command> # Create new service docker service inspect --pretty <service_name> # Display detailed information Service(s) docker service ls # List Services docker service ps # List the tasks of Services docker service scale <service_name>=<replica> # Scale special service(s) docker service update <options> <service_name> # Update Service options DOCKER STACK docker stack ls # List all running applications on this Docker host docker stack deploy -c <composefile> <appname> # Run the specified Compose file docker stack services <appname> # List the services associated with an app docker stack ps <appname> # List the running containers associated with an app docker stack rm <appname> # Tear down an application DOCKER MACHINE docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux) docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10 docker-machine env myvm1 # View basic information about your node docker-machine ssh myvm1 "docker node ls" # List the nodes in your swarm docker-machine ssh myvm1 "docker node inspect <node ID>" # Inspect a node docker-machine ssh myvm1 "docker swarm join-token -q worker" # View join token docker-machine ssh myvm1 # Open an SSH session with the VM; type "exit" to end docker-machine ssh myvm2 "docker swarm leave" # Make the worker leave the swarm docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm docker-machine start myvm1 # Start a VM that is currently not running docker-machine stop $(docker-machine ls -q) # Stop all running VMs docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir docker-machine ssh myvm1 "docker stack deploy -c <file> <app>" # Deploy an app

2025-01-01 · 4 min · Eagle

Firewall-Cmd 常用命令

firewall 是 Linux CentOS 等操作系统的防火墙。 使用 rich rule 封禁 IP firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='222.222.222.222' reject" 单个IP firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='222.222.222.0/24' reject" IP段 firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=192.168.1.2 port port=80 protocol=tcp accept" 单个IP的某个端口 firewall-cmd --list-rich-rules 查看封禁IP 使用 ip set 封禁 IP firewall-cmd --permanent --new-ipset=dog --type=hash:ip 封禁IP firewall-cmd --permanent --ipset=dog --add-entry=ip地址 firewall-cmd --permanent --new-ipset=blacklist --type=hash:net 封禁网段 firewall-cmd --permanent --ipset=blacklist --add-entry=222.222.222.0/24 firewall-cmd --permanent --add-rich-rule='rule source ipset=blacklist drop' 使ipset生效 删除一个 ipset ...

2025-01-01 · 1 min · Eagle