A lightweight project management app for teams who want clarity without clutter. Organize work into projects, group tasks in to-do lists, and check things off — nothing extra.
Built with Rails 8, SQLite, Tailwind CSS v4, and Vite. Authentication uses Devise with optional Google and GitHub sign-in.
- Create and manage projects with optional notes
- Add multiple to-do lists per project (e.g. “This week”, “Launch checklist”)
- Add to-dos with optional due dates; mark complete with one click
- Sign up with email/password or OAuth
- Edit your profile at
/profile
| Layer | Technology |
|---|---|
| Backend | Ruby 3.4.7, Rails 8.1 |
| Database | SQLite 3 |
| Frontend | ERB, Hotwire (Turbo), Tailwind CSS v4 |
| Assets | Vite, Propshaft |
| Auth | Devise, OmniAuth (Google, GitHub) |
| Jobs / cache / cable | Solid Queue, Solid Cache, Solid Cable |
| Deploy | Docker, Kamal |
Install these before you begin:
| Tool | Version | Notes |
|---|---|---|
| Ruby | 3.4.7 | Use rbenv, mise, or chruby |
| Node.js | 22.21.1 | See .node-version |
| Yarn | 1.22+ | npm install -g yarn if needed |
| Git | any recent | — |
Optional but recommended for local dev:
For deployment:
- A Linux server with Docker (SSH access)
- A container registry (Docker Hub, GHCR, DigitalOcean, etc.)
- Kamal — included in the Gemfile (
bundle exec kamal)
git clone <your-repo-url> flowbase
cd flowbase# If you use rbenv:
rbenv install -s 3.4.7
rbenv local 3.4.7
# If you use nvm or similar:
nvm install # reads .node-version (22.21.1)bundle install
yarn installCopy the example env file and fill in what you need:
cp .env.example .env| Variable | Required | Purpose |
|---|---|---|
GOOGLE_CLIENT_ID |
For Google login | OAuth client ID |
GOOGLE_CLIENT_SECRET |
For Google login | OAuth client secret |
GITHUB_CLIENT_ID |
For GitHub login | OAuth app client ID |
GITHUB_CLIENT_SECRET |
For GitHub login | OAuth app client secret |
Email/password sign-up works without OAuth. Leave OAuth variables blank if you do not need social login.
OAuth redirect URIs (development):
- Google:
http://localhost:3000/users/auth/google_oauth2/callback - GitHub:
http://localhost:3000/users/auth/github/callback
Database files are created under storage/ automatically. Run:
bin/rails db:prepareOr use the setup script (installs deps, prepares DB, and can start the server):
bin/setupTo reset the database from scratch:
bin/rails db:resetbin/devThis starts:
- Rails on http://localhost:3000
- Vite for CSS/JS hot reload
Open http://localhost:3000 in your browser. Use localhost (not 127.0.0.1) so Vite and Rails share the same host.
Run processes separately (if you prefer):
# Terminal 1
bin/rails server -p 3000
# Terminal 2
bin/vite dev- Visit http://localhost:3000
- Click Get started or Sign up
- After sign-in you land on Your projects — create a project and add to-do lists
bin/rails console # Rails console
bin/rails db:migrate # Run pending migrations
bin/rails db:migrate:status
bin/rails routes # List routes
bin/rubocop # Lint Ruby
bin/brakeman # Security scan
yarn run check # TypeScript check (Inertia pages)Health check endpoint: GET /up (used by load balancers and Kamal).
app/
controllers/ # Projects, todos, profiles, Devise/OAuth
models/ # User, Project, TodoList, Todo
views/ # ERB templates (Tailwind v4 utility classes)
javascript/ # Vite entrypoints, Stimulus, Inertia (example page)
config/
deploy.yml # Kamal deployment config
database.yml # SQLite (dev/test/prod)
storage/ # SQLite database files (gitignored)
db/
migrate/ # Schema migrations
Production deployment uses Docker and Kamal. The repo includes a Dockerfile and config/deploy.yml.
flowchart LR
Dev[Your machine] -->|kamal setup / deploy| Server[Linux server]
Dev -->|docker push| Registry[Container registry]
Registry --> Server
Server --> DB[(SQLite on volume)]
- Ubuntu 22.04+ or similar Linux with Docker installed
- SSH access as a user with Docker permissions (often
rootor a deploy user) - Open ports 80 and 443 (if using Kamal’s built-in SSL proxy)
- Persistent storage for SQLite files (Kamal mounts
flowbase_storage:/rails/storageby default)
The app uses separate SQLite files under storage/ (see config/database.yml):
production.sqlite3— primary app dataproduction_cache.sqlite3— Solid Cacheproduction_queue.sqlite3— Solid Queueproduction_cable.sqlite3— Solid Cable
No external database server is required. Ensure the Kamal volume for /rails/storage is enabled so data survives deploys.
Edit config/deploy.yml:
-
Servers — replace
192.168.0.1with your server IP or hostname:servers: web: - 203.0.113.10
-
Registry — point to your image registry:
registry: server: ghcr.io # or docker.io, registry.digitalocean.com, etc. username: your-username password: - KAMAL_REGISTRY_PASSWORD
-
Image name — use a namespaced image, e.g.
ghcr.io/your-org/flowbase -
SSL (recommended) — uncomment and set your domain:
proxy: ssl: true host: app.yourdomain.com
Then enable in
config/environments/production.rb:config.assume_ssl = true config.force_ssl = true
Never commit config/master.key. Configure .kamal/secrets to load:
| Secret | Purpose |
|---|---|
RAILS_MASTER_KEY |
Decrypts Rails credentials (config/master.key) |
KAMAL_REGISTRY_PASSWORD |
Registry login (if private images) |
Example .kamal/secrets (already partially set up):
RAILS_MASTER_KEY=$(cat config/master.key)
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORDExport registry password before deploy:
export KAMAL_REGISTRY_PASSWORD="your-registry-token"Add production OAuth and DB secrets via Kamal env / env/secret in deploy.yml as needed.
From your machine (with SSH access to the server):
# Install Kamal CLI if needed (or use bundler)
bundle exec kamal setupkamal setup installs Docker on the server (if needed), pushes the image, and boots the app.
Subsequent releases:
bundle exec kamal deployOther helpful commands:
bundle exec kamal logs # Tail application logs
bundle exec kamal app exec -i "bin/rails console"
bundle exec kamal dbc # Database console (alias in deploy.yml)
bundle exec kamal rollback # Roll back to previous image- Open
https://app.yourdomain.com(orhttp://your-server-ip) - Confirm health:
curl https://app.yourdomain.com/up→200 - Sign up and create a test project
For a single container on any host with Docker:
docker build -t flowbase .
docker run -d \
-p 80:80 \
-e RAILS_MASTER_KEY="$(cat config/master.key)" \
-v flowbase_storage:/rails/storage \
--name flowbase \
flowbaseThe entrypoint runs db:prepare on boot when starting the Rails server.
| Variable | Required | Description |
|---|---|---|
RAILS_MASTER_KEY |
Yes | Rails credentials key |
RAILS_LOG_LEVEL |
No | Default info |
SOLID_QUEUE_IN_PUMA |
No | Set true to run jobs in Puma (default in deploy.yml) |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET |
For OAuth | Production OAuth callbacks |
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET |
For OAuth | Production OAuth callbacks |
Update OAuth provider callback URLs to your production domain, e.g.
https://app.yourdomain.com/users/auth/google_oauth2/callback
Cannot apply unknown utility class (Tailwind)
Custom components must not @apply other custom classes in Tailwind v4 — only built-in utilities. See app/javascript/entrypoints/application.css.
Vite assets not loading
Use http://localhost:3000, not 127.0.0.1. The app redirects 127.0.0.1 to localhost for this reason.
Database connection errors
Confirm storage/ exists and is writable. Run bin/rails db:prepare. On deploy, ensure the /rails/storage volume is mounted.
OAuth fails in development
Confirm .env values, callback URLs, and that buttons use data: { turbo: false } (already set in Devise views).
Kamal deploy fails
Verify SSH (ssh user@server), Docker on the server, registry credentials, and RAILS_MASTER_KEY. Inspect logs with kamal logs.
Private / all rights reserved unless otherwise specified by the repository owner.