This is a collection of Docker Compose files to make Rails development easier.
These files can be combined to add services such as databases and memory caches to your development environment.
There are two Dockerfiles Dockerfile
and Dockerfile-Node
. The latter adds
Node and Yarn to the configurations, like webpack, that need them.
- PostgreSQ - docker-compose-postgres.yml
- MySQL - docker-compose-mysql.yml
- MongoDB - docker-compose-mongo.yml
- Redis - docker-compose-redis.yml
- Memcached - docker-compose-memcached.yml
- Sidkiq - docker-compose-sidekiq.yml - Requires docker-compose-redis.yml
- ngrok - docker-compose-ngrok.yml - Configure ngrok to access your app with
DNS and SSL. Creates an SSL to your development environment. Requires
two variables to be set in the .env file. NGROKSUBDOMAIN
sets the first part of the tunnel's URL,
NGROK_SUBDOMAIN=example
will set the URL to https://example.ngrok.io. The value of NGROK_AUTH is the value _authtoken in ~/.ngrok2/ngrok.yml. - Webpack - docker-compose-webpack.yml - Requires Dockerfile-Node
- Tailwind - docker-compose-tailwindcss.yml - Watches and complies Tailwindcss files.
Copy Dockerfile and docker-compose.yml to your Rails project along with the Compose files for any services you need. For example, if you will be using PostgreSQL, copy docker-compose-postgres.yml.
Note: Newer versions of Rails generate a production Dockerfile, if you have one, move it to Dockerfile.production first. Obviously, if you're using that Dockerfile to deploy, you'll need to make some changes.
cp Dockerfile docker-compose.yml docker-compose-postgres.yml /path/to/my/project
cd
to your project directory and create (or edit) file called .env, and add a
line which reads:
COMPOSE_FILE=docker-compose.yml:docker-compose-postgres.yml
Then edit Dockerfile and change the line that reads:
FROM ruby
to
FROM ruby:X.Y.Z
Where X.Y.Z matches the Ruby version in your Gemfile e.g. "3.2.2".
Then run:
docker compose build
Using these configurations, it's possible to create a new Rail app without having Ruby or any dependencies installed locally.
Create a new directory and copy Dockerfile, docker-compose.yml, and Compose files for any services you need. Copy Gemfile.bootstrap into Gemfile.
cp Dockerfile docker-compose.yml docker-compose-postgres.yml /path/to/my/new/project
cp Gemfile.bootstrap /path/to/my/new/project/Gemfile
cd
to the new directory and run:
docker compose build
docker compose run --rm app bundle exec rails new . --force --database=postgresql
You can pass any other options you need to the new command, for example --api
, and swap out the
database type (swapping to matching Compose file as well). Be sure to leave the
--force
as that allows Rails to replace the bootstrap Gemfile with a real one.
Once rails new
completes, create/edit a .env file and add:
COMPOSE_FILE=docker-compose.yml:docker-compose-postgres.yml
Newer versions of Rails generate a production Dockerfile, move that to Dockerfile.production and copy back the development version:
mv Dockerfile Dockerfile.production
cp /path/to/rails-on-docker/Dockerfile .
then edit Dockerfile to pin the Ruby version to the one in your Gemfile
e.g. FROM ruby
-> FROM ruby:3.2.2
.
Run:
docker compose up
then in another window run:
docker compose exec app ./bin/rails db:setup
You will get a warning that "db/schema.rb doesn't exist yet", that's normal as you don't have any migrations yet.
docker compose up
Your app should be accessible at http://localhost:3000 as usual. Edit files as
you normally would. When you are finished, run docker compose down
in another
window.
Because Rails lives inside Docker, you need to use docker compose exec
to run
commands:
- Open the Rails console -
docker compose exec app ./bin/rails c
- Adding Gems -
docker compose exec app bundle add GEM_NAME
(or add the gem manually to the Gemfile and rundocker compose exec app bundle install
. - Creating migrations -
docker compose exec app ./bin/rails g migration NAME ...
. - Running migrations -
docker compose exec app ./bin/rails db:migrate
. - Running a shell -
docker compose exec app bash
.
Debug, Pry, and Byebug can be a bit tricky. You need to "attach" to Docker first. This can be done by running the following in it's own window:
docker attach `docker compose ls -q`-app-1
The when a debugger/byebug/pry statement is reached, you're good to go.
However, there's a catch, if you hit Control-C in the attached window, you will shutdown the App's Docker container.
You can just always leave it attached or type the disconnect sequence Control-P Control-Q.
These aliases can make it a little easy to work Rails and Docker Compose
alias dc='docker compose'
alais dcb='dc exec app bundle'
alias dcr='dcb exec rails
alias dcs='dcb exec rspec'
With these you can start and stop with dc up
, and dc down
and use dcr console
to get the Rails console or dcb add GEMNAME
to add a gem.
If you are all in with Docker Compose you could take it a step further with:
alias dc='docker compose'
alias bundle='dc exec app bundle'
alias rails='bundle exec rails'
alias rspec='bundle exec rspec'
Note: There is a dc command on most *nix systems, including macOS, a "arbitrary-precision decimal reverse-Polish notation calculator". If you happen to use it, you might want a different name for your alias.
Bug reports and pull requests are welcome on GitHub at https://github.com/spikex/rails-on-docker. This project is intended to be a safe, welcoming space for collaboration