1. Home
  2. Deploy Rails App on Docker with Gitlab CI
Deploy Rails App on Docker with Gitlab CI

Prepare

We want to deploy our rails app to a doker container and do this automatically with gitlab-ci, so let's start.

First we pre-build a docker image, that we would use for our rails container.
We also include nodejs and yarn. as our rails app has Javascript components written in Js

Dockerfile

FROM ruby:3.0

RUN apt-get update -y

RUN gem install bundler
RUN gem install rake

RUN apt-get install -y sudo curl wget git
RUN curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
RUN apt-get install -y nodejs
RUN npm install -g yarn

RUN apt-get install -y zlib1g-dev libpng-dev libssl-dev

RUN ruby -v

VOLUME ["/app"]
WORKDIR /app

and now let's build an image with docker build -t rails:1 .

Prepare Docker

first create a docker-compose.yml with our container config

services:
  rails-app:
    user: ${CURRENT_UID}
    build: .
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    volumes:
      - /docker/volumes/rails-app:/app
    command:
      - ./docker-run.sh

docker-run.sh is our entry script. In the project - the name of the file is docker-run-raw.sh, later on we would rename it. We should do this because of executable flags.

here docker-run-raw.sh:

#!/bin/sh
set -e

# YARN, Precompile
yarn install --network-concurrency 1
NODE_ENV=production RAILS_ENV=production bundle exec rake assets:precompile

# Start the web server
echo "rm PID"
rm -f tmp/pids/server.pid
echo "starting service"
rails s -p 3000 -b '0.0.0.0' -e production

And we need a Dokerfile, wich we use by the deployment

FROM rails:1

ENV SECRET_KEY_BASE=some_key_here_or_from_environment

COPY . /app
WORKDIR /app
EXPOSE 3000

RUN bundle install

lets deploy it with CI

First we would copy/rsync project to the final destination, give docker-run.sh executable mode and then build our container. Here is the a .gitlab-ci.yaml for this pipeline

variables:
  docker_app_root: '/docker/volumes/app'
  GIT_STRATEGY: clone

stages:
  - deploy

prod-deploy:
  stage: deploy
  script:
    - mkdir -p $docker_app_root
    - docker-compose stop
    - rsync -r --delete `pwd`/* $docker_app_root
    - cd $docker_app_root
    - /bin/cp -rf docker-run-raw.sh docker-run.sh
    - chmod +x ./docker-run.sh
    - CURRENT_UID=$(id -u):$(id -g) docker-compose up --build -d

so now, running a pipeline we habe a working container running on Port 3000 with our Rails Application. Yeha! :))