I had been using Docker a lot in my development workflow for a while. Currently, I always start creating a dockerfile with a docker-compose file to start a new project, and this always adds another layer of work before starting a new project.
Recently, VSCode has been improving its docker integration with dev containers, this feature makes the process of working with containers easier and gives a smoother integration between the editor and the workspace inside the container (Improving compatibility with extensions, isolated configurations and easier debugging).
In this post, we are going to start a rails application with a PostgreSQL database using dev containers.
Pre-requisites
- Docker and docker compose installed
- WSL2 installed if you are using windows
- Remote containers extension installed
- VSCode with remote containers extension installed
Let's get started
Open your terminal and add a new folder using the terminal mkdir rails-example
, now cd
into the directory and open the folder with VSCode
cd rails-example
code .
On the editor, press ctrl+shift+p
. This will open the command panel. Look for the "Add Development Container Configuration Files.." option.
This will open another panel, click on the "Show All Definitions" option and select "Ruby on Rails". There are more configurations for other languages, and many more setups in progress (For instance, I've seen an Elixir + Phoenix configuration on a pull request in the Github page of the extension).
This will add two files inside the .devcontainer folder. Inside devcontainer.json there are certain arguments that we can change, such as the ruby and node versions. We can open this folder inside the container with this configuration by pressing ctrl+shift+p
again and selecting the "Reopen in Container" option. Wait a couple of minutes and then the editor should reopen with the Dev container tag at the bottom.
Open your editor terminal and type ruby -v && rails -v
. If the terminal shows both versions you are good, now you have a ruby on rails container with everything you need to start building a rails application... well, almost.PostgreSQL is required for this application, so you need to add your own docker-compose and extend the dev container configuration JSON file. This will allow you to add more services in the future such as Redis or Elasticsearch.
Extending the default configuration
Inside the .devcontainer
folder, add a new file named docker-compose.yml
the following content:
version: '3'
volumes:
postgres_data:
services:
app:
# See https://aka.ms/vscode-remote/containers/non-root for details.
user: vscode
build:
context: ..
dockerfile: .devcontainer/Dockerfile
args:
# Update 'VARIANT' to pick a Ruby version: 2, 2.7, 2.6, 2.5
VARIANT: 2.7
USER_UID: 1000
USER_GID: 1000
NODE_VERSION: lts/*
volumes:
- ..:/workspace:cached
- $HOME/.ssh/:/home/vscode/.ssh/ # Mount the ssh folder to authenticate with github
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
links:
- db
db:
image: postgres
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- 5432:5432
environment:
POSTGRES_PASSWORD: LocalPassword
This docker-compose extends the dev container with PostgreSQL added as a service. Also, there is a volume mount for your .ssh
folder in order to authenticate with Github inside the container.
Now we need to edit the devcontainer.json
file with the following code to connect your docker-compose service:
{
"name": "Ruby on Rails With PostgreSQL",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want to be installed when the container is created.
"extensions": [
"rebornix.Ruby"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3000],
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
}
After adding these files you need to rebuild the image and reopen the folder in the container. Now, when you are inside the dev container, type the following command to create a new rails app:
rails new . -d postgresql
After the generation is completed, edit the config/database.yml
with the credentials of the database service db
:
default: &default
adapter: postgresql
encoding: unicode
host: db
user: postgres
password: LocalPassword
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
After adding these database credentials run rails db:create
to create the database.
Now you are ready to start the rails app with rails s
command, after that visit http://localhost:3000/ to see the rails app running.
Conclusion
This was a little example of how to get started with dev-containers, which is an awesome feature that can be very helpful to start dev environments quickly between members of a team, reducing the amount of work installing libraries and dependencies, working in projects with different versions and more.
This is my first post and I'm not a native English speaker, so I'm open to any feedback and make adequate corrections.
Top comments (3)
Hey, Miguel! Great article! I was able to setup a Rails environment very quickly. Only one thing didn't work properly: the database password was different in the docker-compose.yml (LocalPassword) and in the database.yml (somepassword). I made them both the same and everything worked perfectly.
Thanks for the article!
I will update the article with the correct passwords, thanks for the feedback.
While easy to kick of a new project in VSCode, it’s not quite as detailed as you’re previous article “ Creating a Docker image for a Ruby on Rails application ”
The issues I see with this is when things hit dependencies issues or if troubleshooting needs to happen. The ‘magic’ of VSCode extensions in this instance does not make it easy to figure out what went wrong when things break down if you know what I mean.
Looking forward to your re-visit of the “ Creating a Docker image for a Ruby on Rails application” article.