Context
Follow-up to #561 which added Docker Compose for infrastructure services (PostgreSQL + Redis). As discussed in the review, a fully containerized setup would lower the barrier for new contributors by removing the need to install Ruby, Node, and system dependencies locally.
Goal
Run the entire development stack with a single docker compose up — Rails server, asset watchers, Sidekiq, PostgreSQL, and Redis — while preserving a fast feedback loop (live code reloading, sub-second asset rebuilds).
High-Level Spec
1. Development Dockerfile (docker/dev/Dockerfile)
A multi-stage Dockerfile targeting development:
- Base image: Ruby 3.3.3 on Debian slim
- System dependencies:
build-essential, libpq-dev, libvips (for image_processing gem), ffmpeg (for streamio-ffmpeg), Node.js 20, Yarn
- Ruby layer:
bundle install with Bundler cache mounted as a named volume (avoids reinstalling on every rebuild)
- Node layer:
npm install with node_modules as a named volume
- No asset precompilation at build time — asset watchers handle this at runtime
2. Compose services (docker-compose.yml)
Extend the existing compose file with application services:
| Service |
Image / Build |
Command |
Purpose |
db |
postgres:14 |
(existing) |
PostgreSQL |
redis |
redis:7 |
(existing) |
Redis |
web |
Build from docker/dev/Dockerfile |
bin/rails server -b 0.0.0.0 -p 3000 |
Rails server |
js |
Same image as web |
yarn build --reload |
esbuild watcher |
tailwind |
Same image as web |
bin/rails tailwindcss:watch |
Tailwind CSS watcher |
sidekiq |
Same image as web |
bundle exec sidekiq |
Background jobs |
All app services should:
- Depend on
db (healthy) and redis
- Bind-mount the project root to
/app for live code reloading
- Use named volumes for
node_modules and bundle to avoid overwriting host dirs
- Share a common
x-app anchor (YAML merge key) to avoid config duplication
- Set environment variables:
DB_HOST=db, DB_USERNAME=postgres, DB_PASSWORD=password, REDIS_URL=redis://redis:6379/0
3. Volume strategy
volumes:
qul-postgres-data: # existing
qul-redis-data: # existing
qul-bundle: # gem cache — survives rebuilds
qul-node-modules: # node_modules — avoids platform mismatch with host
The project root is bind-mounted (./:/app) so code edits on the host are reflected immediately. node_modules and bundle are named volumes so native extensions are compiled for the container's Linux arch rather than the host OS.
4. First-run experience
The target developer experience:
git clone git@github.com:TarteelAI/quranic-universal-library.git
cd quranic-universal-library
docker compose up
# wait for build + boot, then visit http://localhost:3000
On first run, the developer needs a single command to set up both databases (create, load the Quranic data dump, and run migrations):
docker compose exec web rails db:setup db:migrate
The db:setup task should handle creating the databases and loading the Quranic data dump (quran_dev), so contributors don't need to manually download and import SQL files as separate steps.
5. Developer workflow commands
Document common workflows:
| Task |
Command |
| Start everything |
docker compose up |
| First-time DB setup (create, load dump, migrate) |
docker compose exec web rails db:setup db:migrate |
| Rails console |
docker compose exec web rails console |
| Run migrations |
docker compose exec web rails db:migrate |
| Install new gem |
docker compose exec web bundle install |
| Install npm package |
docker compose exec web npm install <pkg> |
| RuboCop |
docker compose exec web bundle exec rubocop |
| Rebuild after Gemfile/Dockerfile change |
docker compose up --build |
6. README updates
Add a "Full Docker Setup" section alongside the existing "Quick Start with Docker" and "Manual Setup" sections, covering:
- Prerequisites (Docker + Docker Compose only)
- First-run setup steps
- Common commands reference table above
Acceptance Criteria
Out of scope
- Production Docker images / Kubernetes manifests
- CI/CD Docker builds
.devcontainer / VS Code Dev Container config (could be a future follow-up)
Context
Follow-up to #561 which added Docker Compose for infrastructure services (PostgreSQL + Redis). As discussed in the review, a fully containerized setup would lower the barrier for new contributors by removing the need to install Ruby, Node, and system dependencies locally.
Goal
Run the entire development stack with a single
docker compose up— Rails server, asset watchers, Sidekiq, PostgreSQL, and Redis — while preserving a fast feedback loop (live code reloading, sub-second asset rebuilds).High-Level Spec
1. Development Dockerfile (
docker/dev/Dockerfile)A multi-stage Dockerfile targeting development:
build-essential,libpq-dev,libvips(for image_processing gem),ffmpeg(for streamio-ffmpeg), Node.js 20, Yarnbundle installwith Bundler cache mounted as a named volume (avoids reinstalling on every rebuild)npm installwithnode_modulesas a named volume2. Compose services (
docker-compose.yml)Extend the existing compose file with application services:
dbpostgres:14redisredis:7webdocker/dev/Dockerfilebin/rails server -b 0.0.0.0 -p 3000jswebyarn build --reloadtailwindwebbin/rails tailwindcss:watchsidekiqwebbundle exec sidekiqAll app services should:
db(healthy) andredis/appfor live code reloadingnode_modulesandbundleto avoid overwriting host dirsx-appanchor (YAML merge key) to avoid config duplicationDB_HOST=db,DB_USERNAME=postgres,DB_PASSWORD=password,REDIS_URL=redis://redis:6379/03. Volume strategy
The project root is bind-mounted (
./:/app) so code edits on the host are reflected immediately.node_modulesandbundleare named volumes so native extensions are compiled for the container's Linux arch rather than the host OS.4. First-run experience
The target developer experience:
On first run, the developer needs a single command to set up both databases (create, load the Quranic data dump, and run migrations):
docker compose exec web rails db:setup db:migrateThe
db:setuptask should handle creating the databases and loading the Quranic data dump (quran_dev), so contributors don't need to manually download and import SQL files as separate steps.5. Developer workflow commands
Document common workflows:
docker compose updocker compose exec web rails db:setup db:migratedocker compose exec web rails consoledocker compose exec web rails db:migratedocker compose exec web bundle installdocker compose exec web npm install <pkg>docker compose exec web bundle exec rubocopdocker compose up --build6. README updates
Add a "Full Docker Setup" section alongside the existing "Quick Start with Docker" and "Manual Setup" sections, covering:
Acceptance Criteria
docker compose buildcompletes successfullydocker compose upstarts all 6 services (db, redis, web, js, tailwind, sidekiq)rails db:setup db:migratecreates both databases, loads the Quranic data dump, and runs all migrations in one commandwebcontainerjscontainertailwindcontainerdocker compose exec web rails consoleworksDB_HOST=localhostwith local Ruby) still works unchangedOut of scope
.devcontainer/ VS Code Dev Container config (could be a future follow-up)