Docker container can be used effectively as a rails development environment. Lets create new rails application with Docker and docker-compose.
We are going to see following in this blog
- Create new rails application
- Persisting Postgres data
- Persisting installed gems
- Commands
Dockerfile will have the image definition and docker-compose file will contains container configuration.
- Create new rails application
FROM ruby:2.3.3 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp
We are pulling ruby 2.3.3 image and installing nodejs. Directory /myapp will be created inside container.
Next step would be creating docker-compose file to define and links container.
version: '3' services: db: image: postgres web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000" depends_on: - db
First line indicate the version of docker-compose file. Version 3 has lots of functionality added on it.
Docker compose file contains two services web and db, for web image will be build from Dockerfile and for db postgres image will be pulled from registry.
Current directory will be shared inside container’s /myapp directory and container’s port 3000 will be shared exposed outside to host machine. So that the application will be accessible.
depents_on tag will create link between db and web, so that web can access the db service. We are done with configuration, lets create new rails application.
$ docker-compose build $ docker-compose run web rails new . --force --database=postgresql
This will create new rails application and the files will be available in current working directory.
Lets modify the database.yml to connect with db.
default: &default adapter: postgresql encoding: unicode host: db username: postgres password: pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: * default database: myapp_development
Note the host, its contain name of db service. Since we used depends_on, host db will be accessible.
Lets create the db and launch the application.
$ docker-compose run web bundle exec rake db:create $ docker-compose up
Navigate to browser to see the welcome page http://localhost:3000
Now lets try to stop and down the container and start the app again.
CTL +C to stop $ docker-compose down $ docker-compose up
Now lets try to navigate the url http://localhost:3000,
It will show the FATAL error. Because db container was stopped and all data reset. To solve this problem lets share the container volume to host to persists the db information.
2. Persisting Postgres data
Lets share the db volume to host
version: '3' services: db: image: postgres volumes: - /usr/data/volumes/pgdata/etc:/etc/postgresql - /usr/data/volumes/pgdata/log:/var/log/postgresql - /usr/data/volumes/pgdata/data:/var/lib/postgresql/data web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000" depends_on: - db
db volumes are shared in /usr/data/volumes/pgdata directory. Now the data will be persist.
3. Persisting installed gems
Similarly bundle install will be running every time on container restart. Lets share the volume of bundle.
version: '3' services: db: image: postgres volumes: - /usr/data/volumes/pgdata/etc:/etc/postgresql - /usr/data/volumes/pgdata/log:/var/log/postgresql - /usr/data/volumes/pgdata/data:/var/lib/postgresql/data web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp - /usr/data/volumes/bundle:/bundle ports: - "3000:3000" environment: - BUNDLE_PATH=/bundle depends_on: - db
Note the environment variable BUNDLE_PATH= /bundle. Gems will be installed in /bundle directory and that will be shared to /usr/data/volumes/bundle.
4. Commands
Create migration
$ docker-compose run web bundle exec rails g migration add_column_to_table
Precompile assets
$ docker-compose run web bundle exec rake assets:precompile
Bundle install
$ docker-compose run web bundle install
To know more on running rails application with web server, click https://medium.com/@sivakumarvadivelu/build-and-run-rails-application-with-docker-and-docker-compose-8c3601af2765