A full-stack web application template using SQLite, Express, React, and Node.js with Docker Compose for easy deployment. This template is designed for small-scale self-hosted projects and such uses SQLite.
- React - UI library
- TypeScript - Type safety
- Vite - Build tool and dev server
- CSS - Styling with dark/light mode support
- Node.js - Runtime environment
- Express - Web framework
- TypeScript - Type safety
- SQLite - Embedded database
- sqlite3 - Database driver
- Docker - Containerization
- Docker Compose - Multi-container orchestration
- sqlite-web - Web-based SQLite database viewer
.
├── backend/ # Express API server
│ ├── src/
│ │ └── index.ts # Main server file
│ ├── dist/ # Compiled output
│ └── package.json
├── frontend/ # React application
│ ├── src/
│ │ ├── App.tsx # Main app component
│ │ ├── App.css # Styles
│ │ └── main.tsx # Entry point
│ ├── dist/ # Build output
│ └── package.json
├── data/ # SQLite database storage (gitignored)
├── docker-compose.yml # Docker services configuration
├── Dockerfile # Multi-stage build for production
└── package.json # Root package with scripts
- Docker: 20.10+ or later
- Docker Compose: 2.0+ or later (v2 CLI)
- Node.js: 20.x or later
- Yarn: 4.x (Berry) via Corepack
- Enable with:
corepack enable - Corepack comes bundled with Node.js 16.10+
- Enable with:
- Git: Any recent version
- SQLite CLI: For manual database inspection (not required - sqlite-web provides a UI)
Ensure you have the required versions listed in the Requirements section above.
-
Start the application:
docker compose up --build
-
Access the services:
- Frontend + API: http://localhost:8080
- SQLite Web Viewer: http://localhost:8081
-
Stop the application:
docker compose down
-
Enable Yarn 4 (first time setup):
corepack enable -
Install dependencies:
yarn install
-
Start backend (Terminal 1):
yarn dev-backend
-
Start frontend (Terminal 2):
yarn dev-frontend
-
Access the application:
- Frontend: http://localhost:5173 (Vite dev server with HMR)
- API: http://localhost:8080
| Command | Shorthand | Description |
|---|---|---|
docker compose up |
yarn up |
Start containers with existing images |
docker compose up --build |
yarn up-build |
Start containers and rebuild if needed |
docker compose down |
yarn down |
Stop and remove containers |
docker compose down -v && docker system prune -f |
yarn clean |
Remove containers, volumes, and clean Docker system |
docker compose down && docker compose build --no-cache && docker compose up |
yarn rebuild |
Full clean rebuild (no cache) |
docker compose logs -f |
yarn logs |
Follow container logs in real-time |
docker compose restart |
yarn restart |
Restart all containers |
| Command | Description |
|---|---|
yarn dev-frontend |
Run frontend dev server with HMR |
yarn dev-backend |
Run backend in development mode |
GET /api/usersResponse:
[
{
"id": 1,
"name": "John Doe"
}
]POST /api/users
Content-Type: application/json
{
"name": "Jane Doe"
}Response:
{
"id": 2,
"name": "Jane Doe"
}| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
Server port |
NODE_ENV |
production |
Environment mode |
DB_PATH |
/data/db.sqlite |
SQLite database path |
TZ |
Australia/Brisbane |
Timezone |
- Port: 8080:8080
- Purpose: Serves both frontend and backend API
- Volume:
./data:/data- Persistent database storage - Restart: unless-stopped
- Port: 8081:8081
- Purpose: Web-based SQLite database viewer
- Volume:
./data:/data- Access to application database - Restart: unless-stopped
-
Frontend changes:
- Edit files in
frontend/src/ - Changes are reflected immediately with HMR in dev mode
- For Docker:
docker compose up --build
- Edit files in
-
Backend changes:
- Edit files in
backend/src/ - For Docker:
docker compose up --build
- Edit files in
-
Dependency changes:
- Update package.json in respective folder
- Run
docker compose down && docker compose build --no-cache && docker compose upfor clean Docker build
Access http://localhost:8081 to view and query your SQLite database using the web interface.
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL
);- Full-stack TypeScript support
- Hot Module Replacement (HMR) in development
- Multi-stage Docker builds for optimized production images
- Multi-architecture support (AMD64, ARM64, x86)
- Persistent SQLite database with web viewer
- Dark/Light mode support in UI
- RESTful API design
- Containerized development and production environments
This project is designed to work seamlessly across different CPU architectures:
- AMD64/x86_64 - Intel/AMD processors (most common)
- ARM64/aarch64 - Apple Silicon (M1/M2/M3), AWS Graviton, Raspberry Pi 4+
- x86 - Older 32-bit systems (via emulation)
- Base Images: Uses official
node:20-alpinemulti-arch images - Native Compilation: sqlite3 module is compiled from source during build for the target architecture
- Platform Detection: Docker automatically detects your system architecture and builds accordingly
- Cross-Platform Compatible: The same
docker-compose.ymlworks on all architectures
Simply run on any supported platform:
docker compose up --buildDocker will automatically:
- Pull the correct base images for your architecture
- Compile native dependencies (sqlite3) for your platform
- Build an optimized container that runs natively
- sqlite-web: Uses linux/amd64 with emulation on ARM (slight performance impact, but works fine)
- Performance: Native builds provide best performance on all platforms
- Apple Silicon: Fully supported - no Rosetta needed for the main app
If ports 8080 or 8081 are in use, either:
- Stop the conflicting service
- Modify ports in
docker-compose.yml
If you get "database is locked" errors:
- Stop all containers:
docker compose down - Remove volumes:
docker compose down -v && docker system prune -f - Restart:
docker compose up --build
If you encounter issues after dependency changes:
docker compose down && docker compose build --no-cache && docker compose upThis performs a complete rebuild without cache.
MIT
Vibed by Claude and quality checked by Nick Brown