1. Rails-Inspired (Multiple Dockerfiles)
Create separate Dockerfiles like Dockerfile.dev, Dockerfile.prod.
Clear separation of concerns per environment.
Easy to specify which file to use during build:
bash
docker build -f Dockerfile.dev .
In Docker Compose:
In Docker Compose:
yaml
services:
app:
build:
dockerfile: Dockerfile.dev
Downside: Lots of duplicated code across files. No shared config like Rails' application.rb.
2. Docker-Idiomatic (Multi-Stage Builds)
Use a single Dockerfile with multiple named stages:
Dockerfile
FROM ruby:3.2.2 AS base
WORKDIR /app
COPY . .
RUN bundle install
FROM base AS development
ENV RAILS_ENV=development
CMD ["rails", "server", "-b", "0.0.0.0"]
FROM base AS production
ENV RAILS_ENV=production
RUN bundle exec rake assets:precompile
CMD ["rails", "server", "-b", "0.0.0.0"]
Build with:
bash
docker build --target production -t myapp:prod .
Compose support:
yaml
services:
app:
build:
target: development
Benefits: DRY configuration, single source of truth, easier to maintain.
Tradeoff: More complex, harder to reason about as builds grow.
The best approach depends on:
Complexity of your builds.
How much variation exists between environments.
Your team’s Docker fluency.
If you're revisiting full-stack and cloud-native architecture, this article offers a great lens into balancing clarity vs. maintainability in container workflows. Want help refactoring your own Docker setup or comparing this with Kubernetes manifests or CI/CD pipelines? I’d love to dive deeper with you.
0
5
0