Ambientes de Desarrollo Docker (Rails + Postgres)

Vamos a darle vuelta más de tuerca a nuestro ambiente de desarrollo de Ruby on Rails.

Algo más que común, es el uso de una base de datos en una aplicación web. Es algo que en la mayoría de los proyectos vamos a usar.

Como vimos en el post anterior, armamos un ambiente de desarrollo, usando la extension Remote Containers de Visual Studio Code. Pero solo teníamos el container que tiene la aplicación y usábamos SQLite como base de datos.

En este post vamos a ir un paso más y crear un ambiente con múltiples containers. La aplicación y la base de datos. Esto mismo se puede usar en caso que necesitemos Redis, o cualquier otro servicio corriendo en nuestra aplicación.

Al momento de escribir este post hay un pull request en el proyecto de los templates de Remote Containers con una configuración parecida a la que te voy a mostrar.

Probablemente cuando esto se integre al proyecto va a ser más fácil elegir este template en la lista como elegimos el de Ruby on Rails.

Manos a la obra

Para arrancar vamos a necesitar todo lo mismo que les conté en el post anterior.

Ahora, en lugar de elegir el template Ruby on Rails, vamos a elegir Docker from Docker Compose.

Esto nos va a agregar varios archivos, que vamos a cambiar casi todos y borrar algunos.

La carpeta library-scripts la borramos y el resto de los archivos los vamos a modificar.

devcontainer.json

En este archivo lo que cambio es:

  • name: Ponerle un nombre más representativo en este caso Ruby on Rails + Postgres
  • extensions: Poner rebornix.Ruby
  • fowardPorts: Agregar el 3000 que es donde corre Rails.
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.158.0/containers/docker-from-docker-compose
{
"name": "Ruby on Rails + Postgres",
"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 installed when the container is created.
"extensions": [
"rebornix.Ruby"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3000],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "docker –version",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}
view raw devcontainer.json hosted with ❤ by GitHub

Dockerfile

Lo modifico totalmente, uso en su lugar el que se creó cuando armamos el ambiente de Ruby on Rails sin base de datos.

# [Choice] Ruby version: 2, 2.7, 2.6, 2.5
ARG VARIANT=2
FROM mcr.microsoft.com/vscode/devcontainers/ruby:0-${VARIANT}
# Install Rails
RUN gem install rails webdrivers
ARG NODE_VERSION="lts/*"
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install –no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install additional gems.
# RUN gem install <your-gem-names-here>
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
view raw Dockerfile hosted with ❤ by GitHub

docker-compose.yml

En este archivo es donde pasa la magia :).

Vamos a agregar 2 servicios:

  • App: Este es el mismo container que usábamos antes, que está definido en el Dockerfile, acá vamos a correr nuestra aplicación.
  • Db: Este es el container de la base de datos.

Nota: Como te decía más arriba aca podrias poner los servicios que quisieras, Redis, adminer, etc.

version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
VARIANT: "2.7"
NODE_VERSION: "lts/*"
volumes:
# Update this to wherever you want VS Code to mount the folder of your project
..:/workspace:cached
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
# Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
network_mode: service:db
db:
image: postgres:latest
restart: unless-stopped
volumes:
postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
volumes:
postgres-data:
view raw docker-compose.yml hosted with ❤ by GitHub

Turn on the engines

Ahora estamos listos para arrancar los motores, nuevamente buscamos en la opciones de Remote Container, Reopen in Container.

Ahora vamos a crear una aplicación de rails, pero usando postgres

rails new myapp --database=postgresql

En el archivo de configuración de la base de datos (config/database.yml), agregamos el host, user y password a la sección default.

default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: db
user: postgres
password: postgres
view raw database.yml hosted with ❤ by GitHub

Nota: Dentro de Docker para comunicarnos con otros servicios, la URL que usamos es el nombre del servicio. En este caso el host que vamos a usar en nuestra aplicación va a ser db.

Probemos la DB

Para poder probar la base de datos, vamos a crear algo en Rails para usarla. Para eso usamos el generator de Rails, para crear un CRUD, en este caso de Clientes.

rails g scaffold Customer name:string address:string

Ahora si , tenemos migraciones, entonces ejecutamos

rails db:create db:migrate

Ahora si podemos entrar a http://localhost:3000/customers y probar nuestra app, creando, editando y borrando clientes.

Espero que les sirva y lo puedan usar.

Nos leemos!

One thought on “Ambientes de Desarrollo Docker (Rails + Postgres)

Leave a Reply

Your email address will not be published. Required fields are marked *