Openstatus www.openstatus.dev

Automate the dev environment with Devbox (#1169)

* chore: git-ignore openstatus-dev.db

* chore: make the db seed script idempotent

* chore: configure Devbox

This requires https://github.com/jetpack-io/devbox to be installed. Then
all that is needed is to run "devbox services up" in the project root.

* chore: Remove unnecessary commands in Devbox setup

* chore: add a workaround to tell corepack to download pnpm

This is needed because corepack prompts the user before downloading
pnpm.

* docs: Document how to get started with Devbox

authored by

Mike and committed by
GitHub
73cc277b f888abb0

+307 -11
+1
.gitignore
··· 60 60 .wrangler 61 61 apps/web/.env.dev 62 62 packages/db/.env.dev 63 + openstatus-dev.db 63 64 openstatus-dev.db-wal 64 65 openstatus-dev.db-shm 65 66 apps/ingest-worker/.production.vars
+15
README.md
··· 84 84 85 85 ## Getting Started 🚀 86 86 87 + ### With Devbox 88 + 89 + You can use [Devbox](https://www.jetify.com/devbox/) and get started with the following commands: 90 + 91 + 1. Install Devbox 92 + ```sh 93 + curl -fsSL https://get.jetify.com/devbox | bash 94 + ``` 95 + 2. Install project dependencies, build and start services 96 + ```sh 97 + devbox services up 98 + ``` 99 + 100 + Alternatively, follow the instructions below. 101 + 87 102 ### Requirements 88 103 89 104 - [Node.js](https://nodejs.org/en/) >= 20.0.0
+10
devbox.json
··· 1 + { 2 + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.10.6/.schema/devbox.schema.json", 3 + "packages": ["turso-cli@latest", "nodejs@20", "bun@latest", "sqld@latest"], 4 + "env": { 5 + "DEVBOX_COREPACK_ENABLED": "true" 6 + }, 7 + "shell": { 8 + "init_hook": ["yes | pnpm -v &> /dev/null"] 9 + } 10 + }
+214
devbox.lock
··· 1 + { 2 + "lockfile_version": "1", 3 + "packages": { 4 + "bun@latest": { 5 + "last_modified": "2025-01-13T08:04:02Z", 6 + "resolved": "github:NixOS/nixpkgs/ef56e777fedaa4da8c66a150081523c5de1e0171#bun", 7 + "source": "devbox-search", 8 + "version": "1.1.43", 9 + "systems": { 10 + "aarch64-darwin": { 11 + "outputs": [ 12 + { 13 + "name": "out", 14 + "path": "/nix/store/wg9x0cb4rl5jrvmkak6ihljdxl811h62-bun-1.1.43", 15 + "default": true 16 + } 17 + ], 18 + "store_path": "/nix/store/wg9x0cb4rl5jrvmkak6ihljdxl811h62-bun-1.1.43" 19 + }, 20 + "aarch64-linux": { 21 + "outputs": [ 22 + { 23 + "name": "out", 24 + "path": "/nix/store/6yszhl10ah05n17lf35kpnyzrqlsg3hl-bun-1.1.43", 25 + "default": true 26 + } 27 + ], 28 + "store_path": "/nix/store/6yszhl10ah05n17lf35kpnyzrqlsg3hl-bun-1.1.43" 29 + }, 30 + "x86_64-darwin": { 31 + "outputs": [ 32 + { 33 + "name": "out", 34 + "path": "/nix/store/4rjyabjj3fj3qd01sv6aii0qcnxb6jyx-bun-1.1.43", 35 + "default": true 36 + } 37 + ], 38 + "store_path": "/nix/store/4rjyabjj3fj3qd01sv6aii0qcnxb6jyx-bun-1.1.43" 39 + }, 40 + "x86_64-linux": { 41 + "outputs": [ 42 + { 43 + "name": "out", 44 + "path": "/nix/store/k8yj5s89swbhlh1i8lp25ha2hw9171yr-bun-1.1.43", 45 + "default": true 46 + } 47 + ], 48 + "store_path": "/nix/store/k8yj5s89swbhlh1i8lp25ha2hw9171yr-bun-1.1.43" 49 + } 50 + } 51 + }, 52 + "nodejs@20": { 53 + "last_modified": "2024-05-03T15:42:32Z", 54 + "plugin_version": "0.0.2", 55 + "resolved": "github:NixOS/nixpkgs/5fd8536a9a5932d4ae8de52b7dc08d92041237fc#nodejs_20", 56 + "source": "devbox-search", 57 + "version": "20.12.2", 58 + "systems": { 59 + "aarch64-darwin": { 60 + "outputs": [ 61 + { 62 + "name": "out", 63 + "path": "/nix/store/844n9zrm2sindml9hvla57shgwavwyjn-nodejs-20.12.2", 64 + "default": true 65 + }, 66 + { 67 + "name": "libv8", 68 + "path": "/nix/store/zsss2v62ff4wxbbv6zizjk6zmlhkqjzh-nodejs-20.12.2-libv8" 69 + } 70 + ], 71 + "store_path": "/nix/store/844n9zrm2sindml9hvla57shgwavwyjn-nodejs-20.12.2" 72 + }, 73 + "aarch64-linux": { 74 + "outputs": [ 75 + { 76 + "name": "out", 77 + "path": "/nix/store/4lpbv14w1bhh1z2v3sjhv9xcp05pgn2d-nodejs-20.12.2", 78 + "default": true 79 + }, 80 + { 81 + "name": "libv8", 82 + "path": "/nix/store/lhiqlp28jmnhqibsr550yf6fqbx5c9c7-nodejs-20.12.2-libv8" 83 + } 84 + ], 85 + "store_path": "/nix/store/4lpbv14w1bhh1z2v3sjhv9xcp05pgn2d-nodejs-20.12.2" 86 + }, 87 + "x86_64-darwin": { 88 + "outputs": [ 89 + { 90 + "name": "out", 91 + "path": "/nix/store/49d07knzwmlaggcq86d98fpzqa70a2ya-nodejs-20.12.2", 92 + "default": true 93 + }, 94 + { 95 + "name": "libv8", 96 + "path": "/nix/store/idmhy1hnfndv43ncd6yy60vdwin1nyfa-nodejs-20.12.2-libv8" 97 + } 98 + ], 99 + "store_path": "/nix/store/49d07knzwmlaggcq86d98fpzqa70a2ya-nodejs-20.12.2" 100 + }, 101 + "x86_64-linux": { 102 + "outputs": [ 103 + { 104 + "name": "out", 105 + "path": "/nix/store/71r8n7ckcpvav9qwshlr12hjd5nlchds-nodejs-20.12.2", 106 + "default": true 107 + }, 108 + { 109 + "name": "libv8", 110 + "path": "/nix/store/zyp86pvn1l7fsw0s7kgv5iwmn14z0vg7-nodejs-20.12.2-libv8" 111 + } 112 + ], 113 + "store_path": "/nix/store/71r8n7ckcpvav9qwshlr12hjd5nlchds-nodejs-20.12.2" 114 + } 115 + } 116 + }, 117 + "sqld@latest": { 118 + "last_modified": "2024-12-03T12:40:06Z", 119 + "resolved": "github:NixOS/nixpkgs/566e53c2ad750c84f6d31f9ccb9d00f823165550#sqld", 120 + "source": "devbox-search", 121 + "version": "0.24.18", 122 + "systems": { 123 + "aarch64-darwin": { 124 + "outputs": [ 125 + { 126 + "name": "out", 127 + "path": "/nix/store/znd6nm9kkpkdwk4db7h6j7fkk5p5k6wa-sqld-0.24.18", 128 + "default": true 129 + } 130 + ], 131 + "store_path": "/nix/store/znd6nm9kkpkdwk4db7h6j7fkk5p5k6wa-sqld-0.24.18" 132 + }, 133 + "aarch64-linux": { 134 + "outputs": [ 135 + { 136 + "name": "out", 137 + "path": "/nix/store/dm4jsc4acixxznds5xdpxg1isd2scg8a-sqld-0.24.18", 138 + "default": true 139 + } 140 + ], 141 + "store_path": "/nix/store/dm4jsc4acixxznds5xdpxg1isd2scg8a-sqld-0.24.18" 142 + }, 143 + "x86_64-darwin": { 144 + "outputs": [ 145 + { 146 + "name": "out", 147 + "path": "/nix/store/rsvrgk3b71b149a0d5hxf7zhcn42d7qm-sqld-0.24.18", 148 + "default": true 149 + } 150 + ], 151 + "store_path": "/nix/store/rsvrgk3b71b149a0d5hxf7zhcn42d7qm-sqld-0.24.18" 152 + }, 153 + "x86_64-linux": { 154 + "outputs": [ 155 + { 156 + "name": "out", 157 + "path": "/nix/store/gfxfxqnj208jhld4m56zab3byhhq63dc-sqld-0.24.18", 158 + "default": true 159 + } 160 + ], 161 + "store_path": "/nix/store/gfxfxqnj208jhld4m56zab3byhhq63dc-sqld-0.24.18" 162 + } 163 + } 164 + }, 165 + "turso-cli@latest": { 166 + "last_modified": "2024-12-23T21:10:33Z", 167 + "resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#turso-cli", 168 + "source": "devbox-search", 169 + "version": "0.97.2", 170 + "systems": { 171 + "aarch64-darwin": { 172 + "outputs": [ 173 + { 174 + "name": "out", 175 + "path": "/nix/store/0lddbdg4y9fyiqvvlp82zblmmcrnji3c-turso-cli-0.97.2", 176 + "default": true 177 + } 178 + ], 179 + "store_path": "/nix/store/0lddbdg4y9fyiqvvlp82zblmmcrnji3c-turso-cli-0.97.2" 180 + }, 181 + "aarch64-linux": { 182 + "outputs": [ 183 + { 184 + "name": "out", 185 + "path": "/nix/store/dyfpmyx65n26c44dvw6h80aa66s5cabf-turso-cli-0.97.2", 186 + "default": true 187 + } 188 + ], 189 + "store_path": "/nix/store/dyfpmyx65n26c44dvw6h80aa66s5cabf-turso-cli-0.97.2" 190 + }, 191 + "x86_64-darwin": { 192 + "outputs": [ 193 + { 194 + "name": "out", 195 + "path": "/nix/store/b6k6gkc2np7dhlrd6r2347pd2zgp7dg5-turso-cli-0.97.2", 196 + "default": true 197 + } 198 + ], 199 + "store_path": "/nix/store/b6k6gkc2np7dhlrd6r2347pd2zgp7dg5-turso-cli-0.97.2" 200 + }, 201 + "x86_64-linux": { 202 + "outputs": [ 203 + { 204 + "name": "out", 205 + "path": "/nix/store/fxgjr95908fmpysl9wamziaa6lq50kws-turso-cli-0.97.2", 206 + "default": true 207 + } 208 + ], 209 + "store_path": "/nix/store/fxgjr95908fmpysl9wamziaa6lq50kws-turso-cli-0.97.2" 210 + } 211 + } 212 + } 213 + } 214 + }
+33 -11
packages/db/src/seed.mts
··· 49 49 paidUntil: null, 50 50 }, 51 51 ]) 52 + .onConflictDoNothing() 52 53 .run(); 53 54 54 55 await db ··· 91 92 body: '{"hello":"world"}', 92 93 }, 93 94 ]) 95 + .onConflictDoNothing() 94 96 .run(); 95 97 96 98 await db ··· 105 107 customDomain: "", 106 108 published: true, 107 109 }) 110 + .onConflictDoNothing() 108 111 .run(); 109 112 110 113 await db ··· 117 120 email: "ping@openstatus.dev", 118 121 photoUrl: "", 119 122 }) 123 + .onConflictDoNothing() 120 124 .run(); 121 125 await db 122 126 .insert(usersToWorkspaces) 123 127 .values({ workspaceId: 1, userId: 1 }) 128 + .onConflictDoNothing() 124 129 .run(); 125 130 126 - await db.insert(monitorsToPages).values({ monitorId: 1, pageId: 1 }).run(); 131 + await db 132 + .insert(monitorsToPages) 133 + .values({ monitorId: 1, pageId: 1 }) 134 + .onConflictDoNothing() 135 + .run(); 127 136 await db 128 137 .insert(notification) 129 138 .values({ ··· 133 142 data: '{"email":"ping@openstatus.dev"}', 134 143 workspaceId: 1, 135 144 }) 145 + .onConflictDoNothing() 136 146 .run(); 137 147 await db 138 148 .insert(notificationsToMonitors) 139 149 .values({ monitorId: 1, notificationId: 1 }) 150 + .onConflictDoNothing() 140 151 .run(); 141 152 142 153 await db ··· 149 160 status: "investigating", 150 161 updatedAt: new Date(), 151 162 }) 163 + .onConflictDoNothing() 152 164 .run(); 153 165 154 166 await db ··· 160 172 message: "Message", 161 173 date: new Date(), 162 174 }) 175 + .onConflictDoNothing() 163 176 .run(); 164 177 165 178 await db ··· 172 185 status: "investigating", 173 186 updatedAt: new Date(), 174 187 }) 188 + .onConflictDoNothing() 175 189 .run(); 176 190 177 191 await db ··· 183 197 message: "Message", 184 198 date: new Date(), 185 199 }) 200 + .onConflictDoNothing() 186 201 .run(); 187 202 188 - await db.insert(monitorsToStatusReport).values([ 189 - { 190 - monitorId: 1, 191 - statusReportId: 2, 192 - }, 193 - { 194 - monitorId: 2, 195 - statusReportId: 2, 196 - }, 197 - ]); 203 + await db 204 + .insert(monitorsToStatusReport) 205 + .values([ 206 + { 207 + monitorId: 1, 208 + statusReportId: 2, 209 + }, 210 + { 211 + monitorId: 2, 212 + statusReportId: 2, 213 + }, 214 + ]) 215 + .onConflictDoNothing() 216 + .run(); 198 217 199 218 await db 200 219 .insert(incidentTable) ··· 205 224 createdAt: new Date(), 206 225 startedAt: new Date(), 207 226 }) 227 + .onConflictDoNothing() 208 228 .run(); 209 229 210 230 await db ··· 216 236 createdAt: new Date(), 217 237 startedAt: new Date(Date.now() + 1000), 218 238 }) 239 + .onConflictDoNothing() 219 240 .run(); 220 241 // on status update 221 242 await db ··· 231 252 message: "test", 232 253 date: new Date(), 233 254 }) 255 + .onConflictDoNothing() 234 256 .run(); 235 257 process.exit(0); 236 258 }
+34
process-compose.yaml
··· 1 + version: "0.5" 2 + is_strict: true 3 + processes: 4 + init_dependencies: 5 + namespace: init 6 + command: | 7 + pnpm install 8 + is_tty: true 9 + init_turso: 10 + namespace: init 11 + command: | 12 + turso dev --db-file openstatus-dev.db 13 + is_tty: true 14 + availability: 15 + restart: "no" 16 + init_dx: 17 + namespace: init 18 + command: | 19 + pnpm dx 20 + kill $(pgrep -f "turso dev") 21 + is_tty: true 22 + depends_on: 23 + init_dependencies: 24 + condition: process_completed_successfully 25 + init_turso: 26 + condition: process_started 27 + dev: 28 + namespace: dev 29 + command: | 30 + pnpm dev:web 31 + is_tty: true 32 + depends_on: 33 + init_dx: 34 + condition: process_completed_successfully