zerobyte/app/server/index.ts
James Brink 5cb092f130 feat: add pure NixOS flake with bun2nix
Adds a complete Nix flake for NixOS integration:

Package:
- Pure reproducible builds using bun2nix (no network during build)
- Bundles restic, rclone, shoutrrr, and other runtime dependencies
- Supports x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin
- Version read from package.json to avoid drift

NixOS Module:
- Systemd service with security hardening
- FUSE support for remote mounts (NFS, SMB, WebDAV)
- Configurable options: port, dataDir, user/group, timezone, etc.
- protectHome option for backing up home directories
- CAP_DAC_READ_SEARCH capability when protectHome=false
- PORT env var properly passed to server

Development:
- devShell with bun, node, biome, typescript, and runtime tools
- bun2nix CLI for regenerating bun.nix after dependency changes

Also includes:
- Overlay exposing zerobyte and shoutrrr packages
- NixOS VM integration tests
- Experimental darwin module (requires TCC permissions for home dirs)
- Configurable MIGRATIONS_PATH and PORT for Nix store compatibility

Note: package.json includes additional peer dependencies (@standard-community/*,
@standard-schema/spec, openapi-types, quansync, react-is) required by bun2nix
for pure builds - bun requires all transitive peer deps to be satisfied.
2025-12-27 00:01:46 -07:00

46 lines
1.3 KiB
TypeScript

import { createHonoServer } from "react-router-hono-server/bun";
import { runDbMigrations } from "./db/db";
import { startup } from "./modules/lifecycle/startup";
import { migrateToShortIds } from "./modules/lifecycle/migration";
import { logger } from "./utils/logger";
import { shutdown } from "./modules/lifecycle/shutdown";
import { REQUIRED_MIGRATIONS } from "./core/constants";
import { validateRequiredMigrations } from "./modules/lifecycle/checkpoint";
import { createApp } from "./app";
import { config } from "./core/config";
const app = createApp();
runDbMigrations();
await migrateToShortIds();
await validateRequiredMigrations(REQUIRED_MIGRATIONS);
startup();
logger.info(`Server is running at http://localhost:${config.port}`);
export type AppType = typeof app;
process.on("SIGTERM", async () => {
logger.info("SIGTERM received, starting graceful shutdown...");
await shutdown();
process.exit(0);
});
process.on("SIGINT", async () => {
logger.info("SIGINT received, starting graceful shutdown...");
await shutdown();
process.exit(0);
});
export default await createHonoServer({
app,
port: config.port,
customBunServer: {
idleTimeout: config.serverIdleTimeout,
error(err) {
logger.error(`[Bun.serve] Server error: ${err.message}`);
},
},
});