Initialise Rails API backend and VueJS App Frontend in Docker for development

Here I create a ruby on rails api backend with VueJS frontend project with help of docker-compose for development on any machine without installing any extra software.

Initialise Rails API backend and VueJS App Frontend in Docker for development

Some systems don’t support development especially Ruby on Rails development environment is quite difficult in WindowsOS. So by docker we can do development in any machine. The difficulty is initialising the project.

Install docker

You can install docker by going to docker hub. The settings I use for docker are 8 GB RAM.

Init Project

Create a folder named todo in your working directory. And create a file named docker-compose.yml in the folder.

Init Rails

Define the project

Create a folder in todo folder named api and create a file named Dockerfile and put the following content there:

todo/api/Dockerfile:

FROM ruby:2.6.6
RUN apt-get update -qq && apt-get install -y postgresql-client
RUN mkdir /api
WORKDIR /api
COPY Gemfile /api/Gemfile
COPY Gemfile.lock /api/Gemfile.lock
RUN mkdir -p /api/log && touch /api/log/development.log
RUN gem install bundler
RUN bundle install
COPY . /api
RUN gem install foreman

What this file will do:

In this file we are telling docker to use image of ruby 2.6.6 and then add postgresql-client that we will be using in the project. Then will create a folder in image name api and then copy Gemfile and Gemfile.lock in the folder and logs as well the run bundle install and then install foreman that we will be using.

Now create another file in api folder named Gemfile and add the following content:

todo/api/Gemfile:

source 'https://rubygems.org'
gem 'rails', '~> 6.0', '>= 6.0.3.1'

What this file will do:

Creates a bootstrap Gemfile which just loads Rails. It’ll be overwritten in a moment by rails new.

Also create a file named Gemfile.lock in the same folder.

Now create a file named Procfile in the same folder with contents:

todo/api/Procfile:

web: bundle exec rails s -b 0.0.0.0 -p ${PORT}
logger: tail -f log/development.log

Now in main to-do folder create a file named docker-compose.yml with following content:

todo/docker-compose.yml:

version: "3"
services:

  db:
    image: postgres
    volumes:
      - db:/var/lib/postgresql/data
    ports:
      - "5491:5432" # use port that you want to in your local instead of 5491
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust

  api:
    build: ./api
    command: bash -c "rm -f /api/tmp/pids/server.pid && foreman start -f /api/Procfile"
    environment:
      - PORT=3000
    volumes:
      - ./api:/api
      - rails_log:/api/log
    ports:
      - "3091:3000" # use port that you want to in your local instead of 3091
    depends_on:
      - db

volumes:
  db:
  rails_log:

Build the project

With those files in place, you can now generate the Rails skeleton app using docker-compose run:

docker-compose run api rails new . --api -T --force --no-deps --database=postgresql

This will initialise the rails app. Now update a database.yml file in newly created app with following:

todo/api/config/database.yml:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db # add this host
  username: postgres
  password:
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

Now we can boot up the project by going to your working-directory/todo/ in terminal:

docker-compose up -d --build

Then run:

docker-compose run api rails db:create

Now open the url in browser http://localhost:3091, and hopefully, you will see this image or please don't hesitate to comment.

All other commands in rails can be called by initialising with docker-compose run api ....

Init VueJS

Create a new folder named todo/front. Run the following command in terminal:

cd front && docker run --rm -v "${PWD}:/$(basename `pwd`)" -w "/$(basename `pwd`)" -it node:14.4-alpine sh -c "yarn global add @vue/cli && vue create ."

Then go through options and that will create new vue app according to your options.

Now in front folder create a file named Dockerfile and fill with following contents:

todo/front/Dockerfile:

FROM node:14.4-alpine
WORKDIR /front
COPY package*.json ./
RUN yarn install
COPY . .
CMD ["yarn", "serve"]

Then update the docker-compose.yml file in main folder so that final file becomes:

todo/docker-compose.yml:

version: "3"
services:

  db:
    image: postgres
    volumes:
      - db:/var/lib/postgresql/data
    ports:
      - "5491:5432" # use port that you want to in your local instead of 5491
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust

  api:
    build: ./api
    command: bash -c "rm -f /api/tmp/pids/server.pid && foreman start -f /api/Procfile"
    environment:
      - PORT=3000
    volumes:
      - ./api:/api
      - rails_log:/api/log
    ports:
      - "3091:3000" # use port that you want to in your local instead of 3091
    depends_on:
      - db

  front:
    build: ./front
    ports:
      - "8091:8080" # use port that you want to in your local instead of 8091
    volumes:
      - ./front:/front
      - front_node_modules:/front/node_modules

volumes:
  db:
  rails_log:
  front_node_modules:

Now in terminal run:

docker-compose down -v

docker-compose up -d --build

docker-compose run api rails db:create

Run http://localhost:3091 and http://localhost:8091 and rails will be running on port 3091 and vuejs front app at 8091.


Happy Coding!