How to set up Rails, Redis, and Postgres with docker-compose in 2023
Many developers don’t like to install everything on their own machines. When using docker you can avoid it, also, with the new rails-docker-image you can configure it with just a few steps.
Prerequisites
- Docker needs to be installed and running on your computer.
- Docker basic background.
Setting up docker-compose
Create a new rails project
First of all, we need to create a rails project. We will use the docked image which has rails inside it. So, before creating it you have to execute the following commands:
docker volume create ruby-bundle-cache
alias docked='docker run --rm -it -v ${PWD}:/rails -v ruby-bundle-cache:/bundle ghcr.io/rails/cli'
In the docker volume, we will store our bundle data and the alias is just a way to avoid writing too many instructions after each command.
After creating the volume and the alias we have to execute the following commands:
docked rails new rails-project --database=postgresql
cd rails-project
Don’t forget to add the host and the username in your config/database.yml with the following inside the default: &default:
host: db
username: postgres
As you can see, using the alias we are creating a new project called rails-project and we are accessing it. On the other hand, if you want to execute any rails command you have to use docked at the beginning. So, for example, if you want to execute rails migrations:
docked rails db:migrate
If you want to trigger the rails console:
docked rails c
And so on…
Create the docker-compose file
In this file, we are going to configure 3 services: Rails, Redis and Postgres.
To create the docker-compose file we have to execute the following command:
touch docker-compose.yml
After that, you can access it by using code/vim or etc. and you have to add the following to configure the base file:
version: '3.4'
services:
As you can see, we are adding the docker-compose version and the key services that we know that are going to be 3.
Configuring rails service
To configure rails we are going to add the following commands below the previous commands:
web:
image: "ghcr.io/rails/cli:latest"
command: /bin/bash -c "rm -f /tmp/server.pid && bundle exec rails server -b 0.0.0.0 -P /tmp/server.pid"
env_file: .env
ports:
- 3000:3000
depends_on:
- db
- redis
volumes:
- .:/rails
- ruby-bundle-cache:/bundle
This is the explanation of each instruction:
- web: means that we are adding a service called “web”.
- image: means that we are using some docker image. In this case, we are using the latest rails image.
- command: means that after loading this image we are going to execute that value into the console. In this case, we are starting a new rails server.
- env_file: means that we are specifying that we are going to use an env file called .env in our root folder.
- ports: means that our host_port is the same that our container_port. In other words, we are going to be able to access the container port from the outside without the necessity to access the Docker image.
- depends_on: means that our web service is going to be started after “db” and “redis” services finished their load.
- volumes: means that we are going to use 2 volumes. “.:/rails” means that in our root folder, we are going to load the container “rails” folder. “ruby-bundle-cache:/bundle” means that in our ruby-bundle-cache volume, we are going to load the container “bundle” folder.
So, after clarifying that we can proceed with configuring the last 2 services.
Configuring Redis service
To configure Redis we have to add the following commands below the previous commands:
redis:
image: "redis:7-alpine"
ports:
- 6379
volumes:
- ./tmp/redis_data:/var/lib/redis/data
This is the explanation of each instruction:
- redis: means that we are adding a new service called “redis”.
- image: means that we are using the Redis 7-alphine image from the DockerHub.
- ports: means that our host_port is the same that our container_port. In other words, we are going to be able to access the container port from the outside without the necessity to access the Docker image.
- volumes: means that in our local route “./tmp/redis_data” we are storing the container data located in the container route “/var/lib/redis/data”.
Configuring Postgres service
To configure Postgres we have to add the following commands below the previous commands:
db:
image: postgres
restart: always
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
ports:
- 5432:5432
volumes:
- ./tmp/postgres_data:/var/lib/postgresql/data
This is the explanation of each instruction:
- db: means that we are adding a new service called “db”.
- image: means that we are loading an image called “postgres”.
- ports: means that our host_port is the same that our container_port. In other words, we are going to be able to access the container port from the outside without the necessity to access the Docker image.
- volumes: means that in our local route “./tmp/postgres_data” we are storing the container data located in the container route “/var/lib/postgresql/data”.
Configuring our external volume
Finally, to let docker knows that we are going to use our external volume called ruby-bundle-cache, we just have to add the following at the end of our file:
volumes:
ruby-bundle-cache:
external: true
Final result
The docker-compose file should look like the following:
version: '3.4'
services:
web:
image: "ghcr.io/rails/cli:latest"
command: /bin/bash -c "rm -f /tmp/server.pid && bundle exec rails server -b 0.0.0.0 -P /tmp/server.pid"
env_file: .env
ports:
- 3000:3000
depends_on:
- db
- redis
volumes:
- .:/rails
- ruby-bundle-cache:/bundle
redis:
image: "redis:7-alpine"
ports:
- 6379
volumes:
- ./tmp/redis_data:/var/lib/redis/data
db:
image: postgres
restart: always
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
ports:
- 5432:5432
volumes:
- ./tmp/postgres_data:/var/lib/postgresql/data
volumes:
ruby-bundle-cache:
external: true
Building your project
So, if you want to init your Rails project with Postgres and Redis you should first execute the following command:
docker-compose build
That command is going to download the docker images and is going to set up everything needed. After that, you should install your dependencies:
docked bundle install
Finally, to init your entire project with its services you should execute the following command:
docker-compose up
To be able to execute rails without any problem, don’t forget to create your database with the following command:
docker-compose run web rails db:create
That’s it, you are going to be able to access your rails application using the route http://localhost:3000 and to use Redis and Postgres without the necessity to install them directly on your machine!.
Example code repository
This is an example where you only have to create a .env file with the information that’s inside the .env.example:
https://github.com/ginzunza/docker_compose
📥 Thanks For Reading! 📥
If you have any questions or suggestions please let me know