provision-nixos-server
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseProvision NixOS Server
部署NixOS服务器
Workflow Overview
工作流概述
- Gather requirements from user
- Create Proxmox container
- Set up SSH access
- Create Colmena init configuration
- Deploy init config and update to static IP
- Copy infrastructure key for SOPS
- Configure application (if applicable)
- Deploy full configuration
- 收集用户需求
- 创建Proxmox容器
- 配置SSH访问
- 创建Colmena初始化配置
- 部署初始化配置并更新为静态IP
- 复制基础设施密钥用于SOPS
- 配置应用(如适用)
- 部署完整配置
Step 1: Gather Requirements
步骤1:收集需求
Ask user for:
- Hostname: Server name (e.g., )
woodpecker - Container ID: Proxmox container ID (e.g., )
122 - Proxmox server: Target Proxmox host (e.g., )
thrall - Storage: (fast) or
local-lvm(distributed, slower)cephpool1 - Memory: RAM in MB (default: )
4096 - Disk size: In GB (default: )
100 - Application: What will run on this server
Verify soft-secrets exist for the new host (, etc.) or ask user to create them.
host.<hostname>.admin_ip_address向用户收集以下信息:
- 主机名:服务器名称(例如:)
woodpecker - 容器ID:Proxmox容器ID(例如:)
122 - Proxmox服务器:目标Proxmox主机(例如:)
thrall - 存储:(高速)或
local-lvm(分布式,低速)cephpool1 - 内存:内存大小(MB,默认值:)
4096 - 磁盘大小:磁盘容量(GB,默认值:)
100 - 应用:该服务器将运行的应用
验证新主机的软密钥是否存在(如等),或要求用户创建这些密钥。
host.<hostname>.admin_ip_addressStep 2: Create Proxmox Container
步骤2:创建Proxmox容器
bash
PROXMOX_SERVER=<server>
HOSTNAME=<hostname>
CONTAINER_ID=<id>
STORAGE=local-lvm
MEMORY=4096
DISK_SIZE_IN_GB=100
ssh $PROXMOX_SERVER "pct create $CONTAINER_ID \
--arch amd64 local:vztmpl/nixos-system-x86_64-linux.tar.xz \
--ostype unmanaged \
--description nixos \
--hostname $HOSTNAME \
--net0 name=eth0,bridge=vmbr3,ip=dhcp,firewall=1 \
--storage $STORAGE \
--memory $MEMORY \
--rootfs $STORAGE:$DISK_SIZE_IN_GB \
--unprivileged 1 \
--features nesting=1 \
--cmode console \
--onboot 1 \
--start 1"Timeout note: Use longer timeouts (5+ minutes) for storage.
cephpool1bash
PROXMOX_SERVER=<server>
HOSTNAME=<hostname>
CONTAINER_ID=<id>
STORAGE=local-lvm
MEMORY=4096
DISK_SIZE_IN_GB=100
ssh $PROXMOX_SERVER "pct create $CONTAINER_ID \
--arch amd64 local:vztmpl/nixos-system-x86_64-linux.tar.xz \
--ostype unmanaged \
--description nixos \
--hostname $HOSTNAME \
--net0 name=eth0,bridge=vmbr3,ip=dhcp,firewall=1 \
--storage $STORAGE \
--memory $MEMORY \
--rootfs $STORAGE:$DISK_SIZE_IN_GB \
--unprivileged 1 \
--features nesting=1 \
--cmode console \
--onboot 1 \
--start 1"超时说明: 使用存储时,需设置更长超时时间(5分钟以上)。
cephpool1Step 3: Set Up SSH Access
步骤3:配置SSH访问
Fresh NixOS containers require full paths. Run via :
pct execbash
ssh $PROXMOX_SERVER "pct exec $CONTAINER_ID -- /run/current-system/sw/bin/bash -c '\
mkdir -p ~/.ssh && \
curl -s https://github.com/fred-drake.keys > ~/.ssh/authorized_keys && \
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys'"Get DHCP IP address:
bash
ssh $PROXMOX_SERVER "pct exec $CONTAINER_ID -- /run/current-system/sw/bin/ip addr show eth0 | grep 'inet '"全新的NixOS容器需要使用完整路径。通过运行以下命令:
pct execbash
ssh $PROXMOX_SERVER "pct exec $CONTAINER_ID -- /run/current-system/sw/bin/bash -c '\
mkdir -p ~/.ssh && \
curl -s https://github.com/fred-drake.keys > ~/.ssh/authorized_keys && \
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys'"获取DHCP IP地址:
bash
ssh $PROXMOX_SERVER "pct exec $CONTAINER_ID -- /run/current-system/sw/bin/ip addr show eth0 | grep 'inet '"Step 4: Create Colmena Init Configuration
步骤4:创建Colmena初始化配置
Create these files (see references/colmena-host-template.md and references/nixos-config-template.md):
mkdir -p modules/nixos/host/<hostname>- Create
modules/nixos/host/<hostname>/configuration.nix - Create
colmena/hosts/<hostname>.nix - Update with imports
colmena/default.nix
Initial deploy config: Use DHCP IP and user:
rootnix
deployment = {
targetHost = "<DHCP_IP>";
targetUser = "root";
};Stage files and build:
bash
git add colmena/hosts/<hostname>.nix modules/nixos/host/<hostname>/ colmena/default.nix
colmena build --impure --on <hostname>-init创建以下文件(参考references/colmena-host-template.md和references/nixos-config-template.md):
mkdir -p modules/nixos/host/<hostname>- 创建
modules/nixos/host/<hostname>/configuration.nix - 创建
colmena/hosts/<hostname>.nix - 更新添加导入配置
colmena/default.nix
初始部署配置: 使用DHCP IP和用户:
rootnix
deployment = {
targetHost = "<DHCP_IP>";
targetUser = "root";
};暂存文件并构建:
bash
git add colmena/hosts/<hostname>.nix modules/nixos/host/<hostname>/ colmena/default.nix
colmena build --impure --on <hostname>-initStep 5: Deploy Init and Update IP
步骤5:部署初始化配置并更新IP
Deploy (will hang when network restarts due to IP change):
bash
colmena apply --impure --on <hostname>-initKill the hanging command, then update :
colmena/hosts/<hostname>.nixnix
deployment = {
targetHost = soft-secrets.host.<hostname>.admin_ip_address;
targetUser = "default";
};Verify with another deploy:
bash
colmena apply --impure --on <hostname>-init部署(网络因IP变更重启时,命令会挂起):
bash
colmena apply --impure --on <hostname>-init终止挂起的命令,然后更新:
colmena/hosts/<hostname>.nixnix
deployment = {
targetHost = soft-secrets.host.<hostname>.admin_ip_address;
targetUser = "default";
};通过再次部署验证配置:
bash
colmena apply --impure --on <hostname>-initStep 6: Copy Infrastructure Key
步骤6:复制基础设施密钥
Required for SOPS secret decryption:
bash
ssh default@<NEW_IP> "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
scp ~/.ssh/id_infrastructure default@<NEW_IP>:~/id_infrastructure
ssh default@<NEW_IP> "chmod 600 ~/id_infrastructure"Age public key (for .sops.yaml):
age1rnarwmx5yqfhr3hxvnnw2rxg3xytjea7dhtg00h72t26dn6csdxqvsryg5If secrets fail to decrypt, user needs to add this key to and run on the secret files.
.sops.yamlsops updatekeys该密钥用于SOPS密钥解密:
bash
ssh default@<NEW_IP> "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
scp ~/.ssh/id_infrastructure default@<NEW_IP>:~/id_infrastructure
ssh default@<NEW_IP> "chmod 600 ~/id_infrastructure"Age公钥(用于.sops.yaml):
age1rnarwmx5yqfhr3hxvnnw2rxg3xytjea7dhtg00h72t26dn6csdxqvsryg5如果密钥解密失败,用户需要将此密钥添加到并对密钥文件执行。
.sops.yamlsops updatekeysStep 7: Configure Application
步骤7:配置应用
See references/app-templates.md for patterns.
参考references/app-templates.md中的配置模板。
Add Container Images
添加容器镜像
- Edit
apps/fetcher/containers.toml - Run
just update-container-digests - Stage:
git add apps/fetcher/containers.toml apps/fetcher/containers-sha.nix
- 编辑
apps/fetcher/containers.toml - 运行
just update-container-digests - 暂存文件:
git add apps/fetcher/containers.toml apps/fetcher/containers-sha.nix
Create Application Config
创建应用配置
Create with:
apps/<appname>.nix- Nginx proxy with SSL (if web-facing)
- PostgreSQL container (if database needed)
- Application container(s)
- tmpfiles rules for data directories
创建,包含以下内容:
apps/<appname>.nix- 带SSL的Nginx反向代理(如果是Web应用)
- PostgreSQL容器(如果需要数据库)
- 应用容器
- 数据目录的tmpfiles规则
Create Secrets Config
创建密钥配置
Create referencing SOPS files.
modules/secrets/<hostname>.nixUser must create SOPS files in secrets repo with:
- (POSTGRES_PASSWORD, POSTGRES_USER, POSTGRES_DB)
postgresql-env.sops - (app-specific secrets)
<appname>-env.sops
创建,关联SOPS文件。
modules/secrets/<hostname>.nix用户必须在密钥仓库中创建以下SOPS文件:
- (包含POSTGRES_PASSWORD、POSTGRES_USER、POSTGRES_DB)
postgresql-env.sops - (应用专属密钥)
<appname>-env.sops
Update Colmena Full Config
更新Colmena完整配置
In , add to full configuration imports:
colmena/hosts/<hostname>.nixnix
../../modules/secrets/<hostname>.nix
../../apps/<appname>.nix在中,将以下内容添加到完整配置的导入项:
colmena/hosts/<hostname>.nixnix
../../modules/secrets/<hostname>.nix
../../apps/<appname>.nixStep 8: Deploy Full Configuration
步骤8:部署完整配置
bash
just update-secrets # Get latest secrets
git add <all-new-files>
colmena apply --impure --on <hostname>bash
just update-secrets # 获取最新密钥
git add <all-new-files>
colmena apply --impure --on <hostname>Common Issues
常见问题
SOPS decrypt fails: Age key not in .sops.yaml - user must add key and re-encrypt
Nginx duplicate directive: Don't add when using
proxy_http_versionproxyWebsockets = truePostgreSQL 18 fails: Mount at not
/var/lib/postgresql/var/lib/postgresql/dataContainer can't reach postgres: Use for port binding, in connection string
0.0.0.0:5432:5432host.containers.internalSOPS解密失败: Age密钥未添加到.sops.yaml中 - 用户必须添加密钥并重新加密
Nginx重复指令: 当设置时,请勿添加
proxyWebsockets = trueproxy_http_versionPostgreSQL 18启动失败: 挂载路径应为而非
/var/lib/postgresql/var/lib/postgresql/data容器无法连接PostgreSQL: 端口绑定使用,连接字符串中使用
0.0.0.0:5432:5432host.containers.internal