A tool to parse, normalize, and manage recipes from spreadsheets and websites. Built with modern Rails.
- Ruby 3.4.8
- Rails 8.1 with Hotwire (Turbo + Stimulus), Importmaps, Propshaft
- PostgreSQL for the database
- Tailwind CSS via
tailwindcss-rails - Docker for containerized development and deployment
No secondary JavaScript frameworks — all UI is built with native Rails tech.
- Ruby 3.4.8 (recommended: install via rbenv)
- PostgreSQL 14+
- Or just Docker and Docker Compose
# Install Ruby dependencies
bundle install
# Create and migrate the database
bin/rails db:prepare
# Start the development server
bin/devThe app will be available at http://localhost:3000.
# Build and start all services
docker compose up --build
# In a separate terminal, create the database (first time only)
docker compose exec web bin/rails db:prepareThe app will be available at http://localhost:3000.
bin/rails test
bin/rails test:systembin/rubocopThe app is deployed on Fly.io with Neon for PostgreSQL.
Live app: https://quick-recipe-parser.fly.dev
| Service | Purpose | Plan |
|---|---|---|
| Fly.io | App hosting (Docker containers) | Free tier (shared CPU, 1GB RAM) |
| Neon | PostgreSQL database | Free tier |
If you ever need to recreate this deployment, here are the full steps:
curl -L https://fly.io/install.sh | shSign up at fly.io, then create the app:
fly apps create quick-recipe-parser- Sign up at neon.tech (free tier, no credit card required)
- Create a new project (e.g. name:
quick-recipe-parser, region:US East) - Copy the connection string — it looks like:
postgresql://<user>:<password>@<host>.neon.tech/<dbname>?sslmode=require
Set the two required secrets (these are stored encrypted on Fly.io, never in source code):
# The Rails master key (from config/master.key, gitignored)
fly secrets set RAILS_MASTER_KEY=<value from config/master.key> -a quick-recipe-parser
# The Neon PostgreSQL connection string
fly secrets set DATABASE_URL=<your-neon-connection-string> -a quick-recipe-parser| Secret | Description | Where to find it |
|---|---|---|
RAILS_MASTER_KEY |
Decrypts Rails encrypted credentials | config/master.key (gitignored) |
DATABASE_URL |
Neon PostgreSQL connection string | Neon dashboard → project → Connection Details |
The fly.toml in the repo root configures the app. Key settings:
HTTP_PORT = '8080'— Thruster (Rails HTTP proxy) listens on 8080 because the container runs as a non-root user and can't bind to port 80internal_port = 8080— Fly.io routes traffic to this port inside the containerauto_stop_machines = 'stop'— Machines spin down when idle to save resourcesrelease_command = './bin/rails db:prepare'— Runs migrations automatically on each deploy
fly deployThis builds the Docker image (using the repo's Dockerfile), pushes it to Fly.io's registry, runs the release command (db:prepare), and starts the app.
After the initial setup, future deploys are just:
fly deployfly status -a quick-recipe-parser # App status and machine info
fly logs -a quick-recipe-parser # Tail production logs
fly secrets list -a quick-recipe-parser # List configured secrets (names only)
fly ssh console -a quick-recipe-parser # SSH into a running machine
fly apps open -a quick-recipe-parser # Open the app in your browserGitHub Actions runs on every PR and push to main:
- Security scans: Brakeman (static analysis) and bundler-audit (dependency vulnerabilities)
- Lint: RuboCop with Rails Omakase style
- Tests: Unit and system tests against PostgreSQL