https://github.com/codemonument/example-bun-sqlite-hosting
Example repository to develop scaffolding for using Bun + SQLite with deployment on Railway.
https://github.com/codemonument/example-bun-sqlite-hosting
Last synced: 8 months ago
JSON representation
Example repository to develop scaffolding for using Bun + SQLite with deployment on Railway.
- Host: GitHub
- URL: https://github.com/codemonument/example-bun-sqlite-hosting
- Owner: codemonument
- Created: 2025-10-15T15:23:29.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-10-26T10:59:26.000Z (8 months ago)
- Last Synced: 2025-10-26T12:29:49.193Z (8 months ago)
- Language: TypeScript
- Size: 41 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# example-bun-sqlite-hosting
Example repository to develop scaffolding for using Bun + SQLite with deployment
on Railway.
If running you can find it:
- at railway: https://example-bun-sqlite-railway-production.up.railway.app/
- at fly.io: https://example-bun-sqlite-hosting.fly.dev
- at sevalla: https://example-bun-sqlite-hosting-sc13n.sevalla.app/todos
## Features
- **Pure Bun** - No external frameworks, uses Bun.serve and built-in SQLite
- **TypeScript Throughout** - Both frontend and backend use TypeScript
- **RESTful API** - Complete CRUD operations for todos
- **Persistent Storage** - SQLite database with proper Railway volume setup
- **Production Ready** - Health checks, restart policies, and proper error
handling
## Tech Stack
- **Runtime**: Bun
- **Database**: SQLite (via `bun:sqlite`)
- **Frontend**: Vanilla HTML + TypeScript
- **Backend**: Bun.serve with TypeScript
- **Deployments**:
- Railway with Volume storage
- Fly.io with Volume storage
## Project Structure
```
.
├── src/
│ ├── index.ts # Main server + SQLite setup + API routes
│ ├── client/ # Frontend files
│ │ ├── about.html # About page
│ │ ├── todos.html # Todo app page
│ │ └── assets/
│ │ ├── todos.ts # Frontend TypeScript
│ │ └── styles.css # Minimal styling
│ └── db.ts # Database setup and queries
├── data/ # SQLite storage (gitignored)
│ └── .keep
├── railway.toml # Railway deployment config
├── fly.toml # Fly.io deployment config
├── package.json # Scripts and dependencies
└── README.md
```
## API Endpoints
- `GET /` - Redirects to `/todos`
- `GET /todos` - Todo list page
- `GET /about` - About page
- `GET /healthz` - Health check endpoint
- `GET /api/todos` - List all todos
- `POST /api/todos` - Create a new todo
- `GET /api/todos/:id` - Get a single todo
- `PATCH /api/todos/:id` - Update a todo
- `DELETE /api/todos/:id` - Delete a todo
## Local Development
### Prerequisites
- [Bun](https://bun.sh) installed
### Setup
1. Clone the repository
2. Install dependencies:
```bash
bun install
```
3. Start the development server with hot reload:
```bash
bun run dev
```
4. Open [http://localhost:3000](http://localhost:3000)
The SQLite database will be created at `data/app.sqlite`.
### Available Scripts
```bash
# Development with hot reload
bun run dev
# Development with file watching
bun run dev-watch
# Production mode
bun run start
# Build for production
bun run build
# Railway setup (requires Railway CLI)
bun run railway:setup # Setup volume + env var
bun run railway:volume # Add volume only
bun run railway:env # Set env var only
```
## Railway Deployment
### Prerequisites
- GitHub account
- [Railway account](https://railway.app)
- [Railway CLI](https://docs.railway.app/guides/cli) (optional, for automated
setup)
### Deployment Steps
### Railway CLI Setup (Automated)
1. **Install Railway CLI**
```bash
# macOS/Linux
curl -fsSL https://railway.app/install.sh | sh
# Or with npm
npm i -g @railway/cli
```
2. **Login & Link Project**
```bash
railway login
railway link # Link to existing project or create new one
```
3. **Setup Volume & Environment (One Command)**
```bash
bun run railway:setup
```
Or run individually:
```bash
# Add volume
bun run railway:volume
# Set environment variable
bun run railway:env
```
4. **Deploy** (optional via CLI)
```bash
railway up
```
### Environment Variables
- `PORT` - Set automatically by Railway
- `DB_PATH` - Path to SQLite database (set to `/data/app.sqlite` on Railway)
### Railway Configuration
The [railway.toml](railway.toml) file configures:
- **Builder**: Nixpacks (auto-detects Bun)
- **Start Command**: `bun src/index.ts`
- **Health Check**: `/healthz` endpoint with 10s timeout
- **Restart Policy**: ON_FAILURE with max 3 retries
---
# Deployment Insights gathered
## uncloud: 2025-10-26 on paas2
- machine setup: see "systems/server/paas2" - running on hetzner
- Setup a volume: "uc volume create example-bun-sqlite-hosting_data"
Use command "uc deploy": `uc deploy`
```bash
❯ uc deploy --help
Deploy services from a Compose file.
Usage:
uc deploy [FLAGS] [SERVICE...] [flags]
Flags:
-c, --context string Name of the cluster context to deploy to (default is the current context)
-f, --file strings One or more Compose files to deploy services from. (default compose.yaml)
-h, --help help for deploy
-n, --no-build Do not build images before deploying services. (default false)
-p, --profile strings One or more Compose profiles to enable.
--recreate Recreate containers even if their configuration and image haven't changed.
-y, --yes Auto-confirm deployment plan. Should be explicitly set when running non-interactively,
e.g., in CI/CD pipelines. [$UNCLOUD_AUTO_CONFIRM]
Global Flags:
--connect string Connect to a remote cluster machine without using the Uncloud configuration file. [$UNCLOUD_CONNECT]
Format: [ssh://]user@host[:port] or tcp://host:port
--uncloud-config string Path to the Uncloud configuration file. [$UNCLOUD_CONFIG] (default "~/.config/uncloud/config.yaml")
```
## Sevalla 2025-10-15: really solid ui, but no Infra as code again!
For Deployment:
- added env var PORT=8080 to be aligned with the default expectation
- Not added env var DB_PATH, default is data/app.sqlite
- Update: added DB_PATH=/data/app.sqlite, since the default path might be
wrong, dependning on the workdir configuration in the final docker image!
- added "Disk" in ui, basically the same as a volume
- redeployed
=> worked flawlessly => builds with nixpacks like railway and uses dockerfile
under the hood
## Northflank 2025-10-15: has infrastructure as code, but in a weird way
AFAIK:
- you can create templates
- these templates can be synced with another git repo, different to the one you
deploying your app from (?!? - why tf)
## Fly.io 2025-10-15: works ok, coldstart is extremely slow
- some issues with the initial deployment, the automatic detection got some
things wrong as i gave the git repo to fly.io
- Good: volume was created and mounted correctly
- Question: Does scaling the volume via fly.toml work?
- Bad: Cold Start time is really bad (initial request did fail due to
coldstart!)
## Railway 2025-10-15: good, but needs manual volume setup
- Good: volume was created and mounted correctly
- Question: Does scaling the volume via railway.toml work? => no, volume
management is completely manual, via dashboard
---
# Dev Info
## Database Schema
```sql
CREATE TABLE todos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT NOT NULL,
completed INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TRIGGER todos_updated_at
AFTER UPDATE ON todos
BEGIN
UPDATE todos SET updated_at = datetime('now') WHERE id = NEW.id;
END;
```
## Todo App Features
- ✅ Add new todos
- ✅ Mark todos as complete/incomplete
- ✅ Edit todo text (double-click)
- ✅ Delete todos
- ✅ Persistent storage
## Architecture
### Backend (index.ts)
- Bun.serve for HTTP handling
- SQLite database with prepared statements
- RESTful API with proper error handling
- Static file serving for HTML/CSS/TS
### Frontend (todos.ts)
- TypeScript with DOM manipulation
- Fetch API for backend communication
- Simple, responsive UI
### Deployments - see above
- Volume-mounted persistent storage
- Health check monitoring
- Automatic restarts on failure
- Environment-based configuration
- strict Infrastructure as Code, as far as possible
## Contributing
This is a template/scaffolding project. Feel free to:
- Fork and modify for your needs
- Add features (authentication, pagination, etc.)
- Improve the UI/UX
- Add tests
## License
MIT