Why use Docker
First of all, why should I use Docker in a development environment when it’s better to build it directly on my local system?
Using Docker in a development environment provides the following benefits.
- Solidify the development environment into a configuration file, which makes it easy for new developers to start.
- Isolating system dependencies across projects to avoid interactions.
- Make the development environment as close to the production environment as possible to avoid potential problems due to system inconsistencies.
The more projects you manage, the more you will appreciate the benefits of containerizing your development environment.
Introduction to Docker Compose
For projects like Rails, in addition to dependencies on the operating system, there are usually external services like PostgreSQL and Redis. A single Docker container is not enough to manage all development dependencies, so Docker Compose is needed.
💡 Docker’s best practice is to run one process per container to easily manage container state and logging.
Docker Compose is a tool that comes with Docker Desktop that defines multiple services needed by an application via YAML configuration files, and then builds and starts them together.
Using Docker Compose is divided into about three steps.
- Write the project’s
Dockerfilefor building the project image.
- Write the project’s
docker-compose.ymlconfiguration, which defines the services needed to start the project.
- Start the application with the
docker compose upcommand.
The contents of
docker-compose.yml look like this.
As you can see from the above example, the Compose file can define multiple services, each corresponding to a container. service content includes the image to be used, the open ports and the local directory to be mounted, etc. The detailed syntax of
docker-compose.yml can be found in the official documentation.
Build a Rails application development environment
The following shows how to build a Rails development environment with Docker Compose.
💡 Here’s the chicken or the egg question. Our goal is to put all our dependencies in Docker, but how do we create a Rails project if we don’t have Ruby installed on our local system? rails/) provides a bootstrap approach, building an initial image, starting the container to create the project, and then rebuilding the image.
I chose a different approach: first open a temporary Ruby container, create the project inside the container, and later build the image needed for development.
Create a new project
In order to create a Rails project, start a temporary Ruby container first.
To install the Rails gem inside the container.
Then create the project.
--skip-bundle argument is used here because this is only a temporary container and the
bundle will be executed later in the development container.
Now that the temporary container has completed its mission, press
ctrl-d or type
exit to exit the container.
Adding a Dockerfile
Dockerfile file to the project directory and enter the following.
This is a minimalist image of the Rails development environment, and you can use
apt-get to install other system dependencies if needed.
You don’t need to build the image yet, we’ll build it together later with the
docker compose command.
docker-compose.yml file to the project directory and enter the following.
Here web and postgres services are defined. web service builds an image based on the Dockerfile file in the current directory and mounts the current directory to the
/app directory in the container, releasing port 3000 and adding a startup dependency on the postgres servcie. postgres service will use the postgres image and set the initial password via environment variables.
Build the image
Execute the following command.
Docker Compose will read the configuration in
docker-compose.yml and build the image accordingly.
You have to re-execute this command every time you modify
Go to the command line
Execute the following command.
This will start the web service container and open a bash shell where we can execute the commands we need to execute for local development, such as
bin/rails g, and so on.
Any later operations that need to be performed inside the container will be executed through this shell.
First execute the following command inside the container.
This command sets the bundle installation directory to the
vendor/bundle directory under the project. This is because I don’t want to have to rebuild the image every time I update the Gemfile during development.
❗️ Remember to add
Preparing the database
Before creating the database, you need to modify the database settings of the Rails project, because in the environment built by Docker Compose, PostgreSQL and Rails processes run in different containers, similar to different hosts, and the service name is their respective network name.
database.yml and add the following to the
Then execute the following command.
After that, the corresponding database will be created.
Start the web service
After the above preparations, it is time to start the web service. Open another terminal and enter the following command.
Once the launch is complete, request
http://localhost:3000/ and you will see the Rails launch page.
ctrl-c to close the servcie.