DEV Community

Cover image for The complete guide to setup a CI/CD for Rails 6+ on Gitlab

The complete guide to setup a CI/CD for Rails 6+ on Gitlab

CHADDA Chakib on August 19, 2018

Continuous Integration/Deployment for Rails on Gitlab In this blog post, we will through the necessary steps to setup Gitlab in order ...
Collapse
 
drnic profile image
Dr Nic Williams • Edited

Since my Gemfile already had gem "webdrivers" for local running of rails test:system, I needed to change this to disable webdrivers so as to stop the "Failed to find Chrome binary" error:

gem "webdrivers", require: !ENV['selenium_remote_url']
Enter fullscreen mode Exit fullscreen mode
 
zimski profile image
CHADDA Chakib

Hi Patrik,

When I print /etc/hosts inside a service and the main container, I get:

# Inside a service
2018-12-26T14:48:23.565202452Z 127.0.0.1    localhost
2018-12-26T14:48:23.565246527Z ::1  localhost ip6-localhost ip6-loopback
2018-12-26T14:48:23.565251755Z fe00::0  ip6-localnet
2018-12-26T14:48:23.565256138Z ff00::0  ip6-mcastprefix
2018-12-26T14:48:23.565260449Z ff02::1  ip6-allnodes
2018-12-26T14:48:23.565264704Z ff02::2  ip6-allrouters
2018-12-26T14:48:23.565268770Z 172.17.0.6   cc27ba611b73

# inside the main container
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.5  postgres a35defa95dba runner-a252ce20-project-5796108-concurrent-0-postgres-0
172.17.0.6  runner-a252ce20-project-5796108-concurrent-0

So definitely, the ip of the main container is 172.17.0.6 and it's referenced inside the service but with an other name cc27ba611b73 and it's the container ID. so I cannot find an easy way to fix your issue.

May be you can create a issue in the repo, gitlab is opensource ;)

The chrome is CPU intensive, using it side by side with rails server can make your system test flaky.

Have a good day

Collapse
 
colindresj profile image
JC

Hi, I followed this guide, but I am having problems with Chrome. When CI runs my tests, I get the following error:

Webdrivers::BrowserNotFound: Failed to find Chrome binary.

Any ideas why Chrome can't be found?

Collapse
 
zimski profile image
CHADDA Chakib

Hey,

I know that I have an issue with the latest selenium containers
Can you try with this one:

    - selenium/standalone-chrome:3.14.0-helium

Collapse
 
colindresj profile image
JC

Hi,

I tried with that container version, but I'm still getting the same problem.

Thread Thread
 
zimski profile image
CHADDA Chakib

Are you sure that your system test is trying to connect with the remote chrome hosted inside the selenium container.

I think your issue is that the tests is trying to run in the local container and gets this error because there is no chrome installed in the build container.

Make sure that is used

 driver_options[:url] = ENV['selenium_remote_url'] if ENV['selenium_remote_url']
Thread Thread
 
colindresj profile image
JC

My application_system_test_case.rb looks like this:

require "test_helper"
require "socket"

def prepare_options
  driver_options = {
    desired_capabilities: {
      chromeOptions: {
        args: %w[headless disable-gpu disable-dev-shm-usage] # preserve memory & cpu consumption
      }
    }
  }

  driver_options[:url] = ENV["selenium_remote_url"] if ENV["selenium_remote_url"]

  driver_options
end

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 1400], options: prepare_options
end

And within the configure block ofconfig/environments/test.rb I have:

  net = Socket.ip_address_list.detect{|addr| addr.ipv4_private? }
  ip = net.nil? ? 'localhost' : net.ip_address
  config.domain = ip
  config.action_mailer.default_url_options = { :host => config.domain }

  Capybara.server_port = 8200
  Capybara.server_host = ip
Collapse
 
zimski profile image
CHADDA Chakib

Hello Patrik, thankyou for your comment.

To solve your issue, I will proceed like this:

  1. Find the hostname of the main container that run your rails app in gitlab CI, in the rest of this comment, I will refer to it as [HOSTNAME]

  2. setup a test domain with sub-domains using CNAME ( you can use route53 from aws for this) :

  subdomain1.example-ci.com CNAME [HOSTNAME]
  subdomain2.example-ci.com CNAME [HOSTNAME]
  ...
  1. in your rails app, setup the links generator to use subdomains

The result will be:

  1. Rails will generate domains using *.example-ci.com
  2. Selenium will resolve this domain and get [HOSTNAME] as the first result it will try to resolve [HOSTNAME] a second time and will find the IP because all services and the main container are linked together gitlab service alias
  3. selenium will send the http requests to the right container containing your rails app

Hope this help you

Merry Christmas

Collapse
 
gafemoyano profile image
Felipe Moyano

Hi, thanks for your post! It was very useful. However I'm struggling a bit to get the system tests running.

I don't know if I'm missing something, but I'm getting a lot of errors when initializing Chromedriver.

Did you include it in your docker image? Is there any script you're executing on the build phase to install chromedriver and it's dependencies?

Thanks again for a great post

Felipe

Collapse
 
zimski profile image
CHADDA Chakib

Hey Felipe,

I think the error that you are getting is when the system test is trying to connect to the chrome driver in the separated container and failed.

I think this can help you by updating this file application_system_test_case.rb

require "test_helper"
require "socket"


def prepare_options
  driver_options = {
    desired_capabilities: {
      chromeOptions: {
        args: %w[headless disable-gpu disable-dev-shm-usage]
      }
    }
  }

  driver_options[:url] = ENV['selenium_remote_url'] if ENV['selenium_remote_url']

  driver_options
end

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 1400],
            options: prepare_options
end

Take attention to the code that fetch the selenium_remote_url from the env variable

Collapse
 
gafemoyano profile image
Felipe Moyano

Thanks! That did the trick.

Collapse
 
zimski profile image
CHADDA Chakib

Thank you for your comment, I updated the blog post.