Starting a Rails app using vscode containers

imiked

Miguel Alfredo

Posted on August 30, 2020

Starting a Rails app using vscode containers

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

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 .
Enter fullscreen mode Exit fullscreen mode

On the editor, press ctrl+shift+p. This will open the command panel. Look for the "Add Development Container Configuration Files.." option.

Add dev container

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).

Rails dev configuration

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.

Reopen Folder

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
Enter fullscreen mode Exit fullscreen mode

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",
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 } %>
Enter fullscreen mode Exit fullscreen mode

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.
Rails S
Alt Text

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.

💖 💪 🙅 🚩
imiked
Miguel Alfredo

Posted on August 30, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related