WIP! A BB-style forum, on the ATmosphere!
We're still working... we'll be back soon when we have something to show off!
node
typescript
hono
htmx
atproto
1{ pkgs, ... }:
2
3{
4 languages.javascript = {
5 enable = true;
6 corepack.enable = true;
7 };
8
9 packages = [
10 pkgs.turbo
11 pkgs.nginx
12 ];
13
14 # PostgreSQL is enabled by default for development.
15 # To use SQLite instead, create devenv.local.nix with:
16 # { ... }: { services.postgres.enable = false; }
17 # Then set DATABASE_URL=file:./data/atbb.db in your .env file.
18 services.postgres = {
19 enable = pkgs.lib.mkDefault true;
20 package = pkgs.postgresql_17;
21 listen_addresses = "127.0.0.1";
22 port = 5432;
23 initialDatabases = [
24 { name = "atbb"; }
25 ];
26 initialScript = ''
27 CREATE USER atbb WITH PASSWORD 'atbb';
28 GRANT ALL PRIVILEGES ON DATABASE atbb TO atbb;
29 ALTER DATABASE atbb OWNER TO atbb;
30 '';
31 };
32
33 processes =
34 let
35 # Inline nginx config using Nix store paths so it works in the Nix
36 # environment (no /etc/nginx/mime.types). Mirrors production nginx.conf
37 # but listens on port 8080 (no root required) and uses a tmp working dir.
38 nginxConf = pkgs.writeText "atbb-nginx-dev.conf" ''
39 pid /tmp/atbb-nginx-dev.pid;
40 error_log /dev/stderr;
41
42 events {
43 worker_connections 1024;
44 }
45
46 http {
47 include ${pkgs.nginx}/conf/mime.types;
48 default_type application/octet-stream;
49
50 access_log /dev/stdout;
51
52 client_max_body_size 10M;
53 proxy_connect_timeout 60s;
54 proxy_send_timeout 60s;
55 proxy_read_timeout 60s;
56
57 server {
58 listen 8080;
59
60 # OAuth client metadata → appview
61 # AT Protocol fetches {client_id}/.well-known/oauth-client-metadata
62 # to validate the OAuth client. OAUTH_PUBLIC_URL should be set to
63 # http://localhost:8080 so this route serves the correct document.
64 location /.well-known/ {
65 proxy_pass http://localhost:3000;
66 proxy_set_header Host $host;
67 proxy_set_header X-Real-IP $remote_addr;
68 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
69 proxy_set_header X-Forwarded-Proto $scheme;
70 }
71
72 # API routes → appview
73 location /api/ {
74 proxy_pass http://localhost:3000;
75 proxy_set_header Host $host;
76 proxy_set_header X-Real-IP $remote_addr;
77 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
78 proxy_set_header X-Forwarded-Proto $scheme;
79 }
80
81 # Web UI → web
82 location / {
83 proxy_pass http://localhost:3001;
84 proxy_set_header Host $host;
85 proxy_set_header X-Real-IP $remote_addr;
86 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
87 proxy_set_header X-Forwarded-Proto $scheme;
88 }
89 }
90 }
91 '';
92 in
93 {
94 appview.exec = "pnpm --filter @atbb/appview dev";
95 web.exec = "pnpm --filter @atbb/web dev";
96 nginx.exec = "${pkgs.nginx}/bin/nginx -c ${nginxConf} -p /tmp/atbb-nginx-dev -g 'daemon off;'";
97 };
98}