flake
This commit is contained in:
parent
8a76cca5fb
commit
7eb4977b99
6 changed files with 537 additions and 5 deletions
204
NIX.md
Normal file
204
NIX.md
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
# NixOS Deployment
|
||||
|
||||
## Flake outputs
|
||||
|
||||
| Output | Description |
|
||||
|---|---|
|
||||
| `packages.default` | The `crypto-alert-bot` binary |
|
||||
| `devShells.default` | Dev shell with Go toolchain, gopls, golangci-lint, go-migrate |
|
||||
| `nixosModules.default` | NixOS module that runs the bot as a systemd service |
|
||||
|
||||
---
|
||||
|
||||
## NixOS module
|
||||
|
||||
The module handles all infrastructure automatically:
|
||||
|
||||
- Enables and configures `services.postgresql`
|
||||
- Creates the `crypto-alert-bot` database and PostgreSQL role
|
||||
- Connects via Unix socket using peer authentication (no password)
|
||||
- Creates a dedicated system user `crypto-alert-bot`
|
||||
- Runs the bot as a hardened systemd service
|
||||
|
||||
The only secret you need to supply is the Telegram bot token, via a file path.
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `enable` | bool | `false` | Enable the service |
|
||||
| `package` | package | flake default | Override the binary package |
|
||||
| `telegramTokenFile` | path | — | **Required.** Path to a file containing the bot token |
|
||||
| `dbName` | string | `"crypto-alert-bot"` | PostgreSQL database name |
|
||||
| `logLevel` | `debug\|info\|warn\|error` | `"info"` | Log verbosity |
|
||||
| `logEncoding` | `console\|json` | `"json"` | Log format |
|
||||
| `logServiceName` | string | `"alert-bot"` | Service name field in log output |
|
||||
| `bybitBaseUrl` | string | `"https://api.bybit.com"` | Bybit REST API base URL |
|
||||
|
||||
### Minimal configuration
|
||||
|
||||
```nix
|
||||
# flake.nix of your NixOS config
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
crypto-alert-bot.url = "github:youruser/crypto_alert_bot";
|
||||
agenix.url = "github:ryantm/agenix";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, crypto-alert-bot, agenix, ... }: {
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
modules = [
|
||||
crypto-alert-bot.nixosModules.default
|
||||
agenix.nixosModules.default
|
||||
./configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
```nix
|
||||
# configuration.nix
|
||||
services.crypto-alert-bot = {
|
||||
enable = true;
|
||||
telegramTokenFile = config.age.secrets.telegram-token.path;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Encrypting the Telegram token with agenix
|
||||
|
||||
[agenix](https://github.com/ryantm/agenix) encrypts secrets with [age](https://github.com/FiloSottile/age)
|
||||
and decrypts them at boot using SSH host keys already present on the machine.
|
||||
Encrypted secret files are safe to commit to your NixOS config repository.
|
||||
|
||||
### 1. Install age and agenix
|
||||
|
||||
```bash
|
||||
# age — encryption tool
|
||||
nix shell nixpkgs#age
|
||||
|
||||
# agenix CLI — manages encrypted secret files
|
||||
nix shell github:ryantm/agenix
|
||||
```
|
||||
|
||||
### 2. Collect recipient public keys
|
||||
|
||||
agenix encrypts each secret for one or more recipients. Typical recipients:
|
||||
|
||||
- **SSH host key** of the target machine (used for decryption at boot)
|
||||
- **Your personal SSH key** (used so you can re-encrypt or rotate secrets from your workstation)
|
||||
|
||||
```bash
|
||||
# Get the host's SSH public key (run on the target machine or from your config)
|
||||
cat /etc/ssh/ssh_host_ed25519_key.pub
|
||||
|
||||
# Get your personal SSH public key
|
||||
cat ~/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
### 3. Create secrets.nix
|
||||
|
||||
In the root of your NixOS config repository, create `secrets/secrets.nix`.
|
||||
This file declares which keys can decrypt each secret — it is **not** sensitive
|
||||
and should be committed.
|
||||
|
||||
```nix
|
||||
# secrets/secrets.nix
|
||||
let
|
||||
# SSH public key of the target host
|
||||
host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... root@myhost";
|
||||
|
||||
# Your personal SSH public key (for re-encryption from your workstation)
|
||||
me = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@workstation";
|
||||
in
|
||||
{
|
||||
"telegram-token.age".publicKeys = [ host me ];
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Encrypt the token
|
||||
|
||||
```bash
|
||||
cd secrets/
|
||||
|
||||
# agenix will open $EDITOR so you can type the token, then encrypt on save
|
||||
agenix -e telegram-token.age
|
||||
```
|
||||
|
||||
Type (or paste) the raw token value — just the token string, no quotes, no newline:
|
||||
|
||||
```
|
||||
1234567890:ABCdefGHIjklMNOpqrSTUvwxYZ
|
||||
```
|
||||
|
||||
Save and close the editor. agenix writes `telegram-token.age` — this encrypted
|
||||
file is safe to commit.
|
||||
|
||||
### 5. Wire the secret into your NixOS config
|
||||
|
||||
```nix
|
||||
# configuration.nix
|
||||
{ config, ... }:
|
||||
{
|
||||
# Declare the secret; agenix decrypts it at boot to /run/agenix/telegram-token
|
||||
age.secrets.telegram-token = {
|
||||
file = ./secrets/telegram-token.age;
|
||||
# The service user must be able to read the decrypted file
|
||||
owner = "crypto-alert-bot";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
services.crypto-alert-bot = {
|
||||
enable = true;
|
||||
telegramTokenFile = config.age.secrets.telegram-token.path;
|
||||
# Optionally tune logging:
|
||||
# logLevel = "debug";
|
||||
# logEncoding = "console";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Deploy
|
||||
|
||||
```bash
|
||||
nixos-rebuild switch --flake .#myhost
|
||||
```
|
||||
|
||||
At boot, agenix decrypts `telegram-token.age` using the host's SSH private key
|
||||
and places the plaintext at `/run/agenix/telegram-token` (mode 0400, owned by
|
||||
`crypto-alert-bot`). The bot service reads the token from that path at start time.
|
||||
|
||||
### Rotating the token
|
||||
|
||||
Edit the encrypted file from your workstation with your personal SSH key:
|
||||
|
||||
```bash
|
||||
cd secrets/
|
||||
agenix -e telegram-token.age # opens $EDITOR with decrypted content
|
||||
# change the value, save, close
|
||||
git add telegram-token.age && git commit -m "rotate telegram token"
|
||||
```
|
||||
|
||||
Then redeploy:
|
||||
|
||||
```bash
|
||||
nixos-rebuild switch --flake .#myhost
|
||||
systemctl restart crypto-alert-bot
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Development shell
|
||||
|
||||
```bash
|
||||
nix develop
|
||||
|
||||
# Start the database locally (Docker or Podman)
|
||||
docker compose up -d
|
||||
|
||||
# Run the bot
|
||||
CONFIG_PATH=./internal/config/local.yml go run ./cmd/app/main.go
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue