Consolidated 16+ top-level categories into 8 clear functional groups (AI, Development, Home-Automation, Infrastructure, Lifestyle, PKM, Professional, Backup). Merged duplicate files (OpenRouter.md, Github.md) and archived originals. This simplifies navigation and improves long-term maintainability. (vault changes by Claude Code)
9.0 KiB
Executable File
Install
debian 13
vps provider debian 10 install
default root:
8txlD7djkkKk
Good catch 👍 — you’re right.
Debian 11 Bullseye moved from the main mirrors to the Debian archive repository after its LTS phase ended in 2026. That means:
-
You can still upgrade from Debian 10 → 11 → 12 → 13,
-
But for Debian 11 you’ll need to point your
sources.listto the archive.debian.org service, since the normaldeb.debian.orgno longer carries Bullseye.
🔧 How to Handle Missing Debian 11 (Bullseye) Repos
When upgrading Debian 10 → 11, change your /etc/apt/sources.list to use the archive:
sed -i 's|deb.debian.org|archive.debian.org|g' /etc/apt/sources.list
sed -i 's|security.debian.org|archive.debian.org|g' /etc/apt/sources.list
Then explicitly set it to Bullseye:
deb http://archive.debian.org/debian bullseye main contrib non-free
deb http://archive.debian.org/debian-security bullseye-security main contrib non-free
⚠️ Important: you also need to disable Valid-Until checks (since archive metadata is old). Add this to /etc/apt/apt.conf.d/99no-check-valid-until:
Acquire::Check-Valid-Until "false";
After that, apt update will work again for Debian 11 packages.
🔄 Recommended Path
-
Debian 10 → Debian 11 (Bullseye)
usingarchive.debian.org -
Debian 11 → Debian 12 (Bookworm)
switch back todeb.debian.org -
Debian 12 → Debian 13 (Trixie)
upgrade normally from main repos
⚠️ Alternative Approach (Skip Hop?)
Some admins reinstall instead of multi-hop upgrades when they’re more than 2 releases behind.
It’s often faster and cleaner to install Debian 13 fresh and migrate configs/data.
👉 Do you want me to prepare the exact sources.list entries for each step (10 → 11, 11 → 12, 12 → 13), so you can just copy-paste them before each upgrade?
traefik
services: 10:47:35 [24/1240]
traefik:
image: traefik:v3.4
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks: [traefik]
ports:
- "80:80"
- "443:443"
- "8080:8080" # dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
- ./dynamic:/dynamic:ro
command:
# Entrypoints
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
# Providers
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik"
- "--providers.file.directory=/dynamic"
- "--providers.file.watch=true"
# Let's Encrypt (ACME)
- "--certificatesresolvers.letsencrypt.acme.email=admin@windy.me"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
# Dashboard
- "--api.dashboard=true"
- "--api.insecure=false"
# Logging
- "--log.level=INFO"
- "--accesslog=true"
# Metrics (optional)
- "--metrics.prometheus=true"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`npm.chans.xyz`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$wrhTVUaG$$tcchNFj..."
networks:
traefik:
external: true
dashboard user and pass
Ahku+eRei_chu3ah
htpasswd -nb windy "Ahku+eRei_chu3ah"
windy:$apr1$wrhTVUaG$tcchNFj.yyA3OpK8f9XnA.
一步改成 MASTER
执行以下命令即可统一切换类型:
docker compose exec -T db psql -U pdns -d pdns -c "UPDATE domains SET type='MASTER';"
执行完,再确认:
docker compose exec -T db psql -U pdns -d pdns -c "SELECT id, name, type FROM domains ORDER BY name;"
应输出:
id | name | type ----+-----------+--------- 7 | chans.xyz | MASTER 9 | windy.me | MASTER 8 | wsvc.info | MASTER (3 rows)
✅ 一、明确两种元数据的作用
| kind | 作用 | 主节点是否需要 |
|---|---|---|
PRESIGNED |
表示该 zone 的 DNSSEC 已经签好,不需要 PowerDNS 重新签名 | ✅ 需要保留 |
AXFR-MASTER-TSIG |
从节点用来验证上游 master(旧主)的 TSIG 密钥 | ❌ 主节点不需要 |
🧹 二、删除无用的 AXFR-MASTER-TSIG 记录
执行:
docker compose exec -T db psql -U pdns -d pdns -c "DELETE FROM domainmetadata WHERE kind='AXFR-MASTER-TSIG';"
验证删除结果:
docker compose exec -T db psql -U pdns -d pdns -c "SELECT domain_id, kind, content FROM domainmetadata;"
应该只剩:
domain_id | kind | content
------------+------------+---------
7 | PRESIGNED | 1
8 | PRESIGNED | 1
9 | PRESIGNED | 1
(3 rows)
🧩 三、保留 PRESIGNED(不要删)
这三条 PRESIGNED 的存在说明你的 zone 已经是“预签名区”,
也就是在数据库里已经有 DNSKEY、RRSIG、NSEC/NSEC3 等签名记录,
PowerDNS 不会去重新签名,非常正确 ✅
🧰 四、确保 supermasters 已清空(如果还没执行)
docker compose exec -T db psql -U pdns -d pdns -c "TRUNCATE TABLE supermasters;"
🚀 五、重启 PDNS 并验证主节点状态
docker compose exec auth pdnsutil list-all-zones
docker compose exec auth pdnsutil check-all-zones
预期输出:
Zone "chans.xyz." (MASTER)
Zone "windy.me." (MASTER)
Zone "wsvc.info." (MASTER)
All zones OK
✅ 六、总结(当前应保留状态)
| 表 | 应保留内容 | 已处理状态 |
|---|---|---|
| domains | type=MASTER | ✅ |
| domainmetadata | 仅 PRESIGNED |
🧹 已清理 |
| supermasters | 空表 | ✅ |
| records / cryptokeys / tsigkeys | 原样保留 | ✅ |
如果你愿意,我可以帮你生成一个命令脚本,一次性完成:
-
把所有域设为 MASTER
-
删除 AXFR/MASTER 相关 metadata
-
清空 supermasters
-
验证 zone 状态
你只需执行一条命令即可让任何副节点快照变主节点。是否要我生成?
docker compose exec auth pdnsutil metadata set wsvc.info ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set windy.me ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set chans.xyz ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set wsvc.info TSIG-ALLOW-AXFR "mykey."
Set 'wsvc.info' meta TSIG-ALLOW-AXFR = mykey.
docker compose exec auth pdnsutil metadata set windy.me TSIG-ALLOW-AXFR "mykey."
Set 'windy.me' meta TSIG-ALLOW-AXFR = mykey.
docker compose exec auth pdnsutil metadata set chans.xyz TSIG-ALLOW-AXFR "mykey."
Set 'chans.xyz' meta TSIG-ALLOW-AXFR = mykey.
docker compose exec auth pdns_control notify windy.me
docker compose exec auth pdns_control notify chans.xyz
docker compose exec auth pdns_control notify wsvc.info
db-init/01-init.sh
#!/bin/bash
set -e
echo "🔧 Creating PowerDNS role and databases..."
psql -v ON_ERROR_STOP=1 --username "$PGUSER" <<-'EOSQL'
DO $$
BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'pdns') THEN
CREATE USER pdns WITH PASSWORD 'windyboy';
END IF;
END
$$;
EOSQL
for dbname in pdns pdnsadmin; do
if ! psql -tAc "SELECT 1 FROM pg_database WHERE datname='${dbname}'" | grep -q 1; then
echo "🆕 Creating database ${dbname} owned by pdns"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" -c "CREATE DATABASE ${dbname} OWNER pdns;"
else
echo "✅ Database ${dbname} already exists"
fi
done
echo "✅ Initialization finished."
for z in windy.me chans.xyz wsvc.info; do
docker compose exec auth pdnsutil zone unset-presigned $z
docker compose exec auth pdnsutil zone secure $z
docker compose exec auth pdnsutil zone rectify $z
done
docker compose exec auth pdnsutil zone list-all | while read z; do
docker compose exec auth pdnsutil zone list "$z" > "auth/export/$z.zone"
done
labels:
- "traefik.enable=true"
- "traefik.http.routers.pgweb.rule=Host(`pgweb.wsvc.info`)"
- "traefik.http.routers.pgweb.entrypoints=websecure"
- "traefik.http.routers.pgweb.tls.certresolver=letsencrypt"
- "traefik.http.services.pgweb.loadbalancer.server.port=8081"