I am trying to setup Gitlab CI for my Ruby on Rails project, but ran into an error that I don't know how to fix.
The application is running on Ruby 2.3.1, Rails 5.0 and is using a postgreSQL database.
My current .gitlab.ci.yml file looks like this:
# https://hub.docker.com/r/library/ruby/tags/
image: "ruby:2.3.0"
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service
services:
- redis:latest
- postgres:latest
- node:latest
# This is a basic example for a gem or script which doesn't use
# services such as redis or postgres
before_script:
- gem install bundler # Bundler is not installed with the image
- bundle install -j $(nproc) # Install dependencies
rubocop:
script:
- rubocop
rspec:
script:
- rspec spec
rails:
script:
- rails db:migrate
- rspec spec
So it's supposed to be using NodeJS as runtime. However, I get the following error:
$ rails db:migrate
rails aborted!
Bundler::GemRequireError: There was an error while trying to load the gem 'uglifier'.
Gem Load Error is: Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes.
Backtrace for gem load error is:
/usr/local/bundle/gems/execjs-2.7.0/lib/execjs/runtimes.rb:58:in `autodetect'
/usr/local/bundle/gems/execjs-2.7.0/lib/execjs.rb:5:in `<module:ExecJS>'
/usr/local/bundle/gems/execjs-2.7.0/lib/execjs.rb:4:in `<top (required)>'
/usr/local/bundle/gems/activesupport-5.0.0.rc2/lib/active_support/dependencies.rb:293:in `require'
/usr/local/bundle/gems/activesupport-5.0.0.rc2/lib/active_support/dependencies.rb:293:in `block in require'
/usr/local/bundle/gems/activesupport-5.0.0.rc2/lib/active_support/dependencies.rb:259:in `load_dependency'
/usr/local/bundle/gems/activesupport-5.0.0.rc2/lib/active_support/dependencies.rb:293:in `require'
/usr/local/bundle/gems/uglifier-3.0.0/lib/uglifier.rb:5:in `<top (required)>'
You need to have a javascript runtime (e.g. nodejs). You can install it by using the following command:
For Ubuntu Users
sudo apt-get install nodejs
For CentOS / RedHat Users
sudo yum install nodejs
In case you can't install nodejs you can install and then use therubyracer gem.
Description from repository:
Embed the V8 JavaScript interpreter into Ruby.
Add this line to your Gemfile
gem 'therubyracer', platforms: :ruby
Gitlab-CI can be configured with the file .gitlab-ci.yml in this case:
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
can be used to install nodejs on the setup stage (source).
A complete before_script with jekyll can look like the following code (for instance, this is required for jekyll-minifier):
image: ruby:latest
variables:
JEKYLL_ENV: production
LC_ALL: C.UTF-8
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- ruby -v
- which ruby
- gem install bundler
- bundle install
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
Related
I'm trying to create an environment for developing some Ruby on Rails applications using Docker.
I'm following the official guide for a ruby on rails application on the docker website
The following are my Gemfile, Dockerfile and docker-compose.yml.
source 'https://rubygems.org'
gem 'rails', '~>6'
# syntax=docker/dockerfile:1
FROM ruby:latest
RUN apt-get update -qq && apt-get install -y nodejs
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
version: "3.9"
services:
db:
image: mysql:8
restart: always
ports:
- 3306:3306
volumes:
- dbdata:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: app_db
MYSQL_USER: db_user
MYSQL_PASSWORD: db_user_pass
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
volumes:
dbdata:
The only changes I have made to the guide is to use Rails 6, the latest version of ruby and to use MySQL instead of postgres. When I try to run 'docker-compose build' I get the following error:
ERROR [7/9] RUN bundle install
#17 0.505 /usr/local/lib/ruby/3.0.0/rubygems.rb:281:in `find_spec_for_exe': Could not find 'bundler' (1.17.3) required by your /app/Gemfile.lock. (Gem::GemNotFoundException)
#17 0.505 To update to the latest version installed on your system, run `bundle update --bundler`.
The error message is clear, I don't have the correct version of bundler installed. At the bottom of my Gemfile.lock file I have the following:
RUBY VERSION
ruby 2.5.9p229
BUNDLED WITH
1.17.3
I had assumed that my ruby version would have been the latest version and that my Gemfile would have been bundled with > 2.0. I tried adding 'RUN gem bundle install' in my Dockerfile but that did not fix the issue. Is there a correct way I can specify docker to use the latest version of ruby, rails and bundler that are compatible with each other.
You can add this line before RUN bundle install in your Dockerfile:
ENV BUNDLE_VERSION 1.17.3
RUN gem install bundler --version "$BUNDLE_VERSION"
I am trying to put my rails project on the google cloud engine for the first time and I have a lot of trouble.
I've wanted to upload my project with a custom runtime app.yaml (because I would like yarn to install the dependencies as well), but the deployment command fails with this error:
Error Response: [4] Your deployment has failed to become healthy in the allotted time and therefore was rolled back. If you believe this was an error, try adjusting the 'app_start_timeout_sec' setting in the 'readiness_check' section.
PS: the app runs locally (development and production env).
My app.yaml looks like this:
entrypoint: bundle exec rails s -b '0.0.0.0' --port $PORT
env: flex
runtime: custom
env_variables:
My Environment variables
beta_settings:
cloud_sql_instances: ekoma-app:us-central1:ekoma-db
readiness_check:
path: "/_ah/health"
check_interval_sec: 5
timeout_sec: 4
failure_threshold: 2
success_threshold: 1
app_start_timeout_sec: 120
And my Dockerfile looks like this:
FROM l.gcr.io/google/ruby:latest
RUN apt-get update -qq && apt-get install apt-transport-https
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev imagemagick yarn
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock
RUN gem install pkg-config -v "~> 1.1"
RUN bundle install && npm install
COPY . /app
When deploying with a ruby runtime I realized that the dockerfile generated was much more complex and probably complete and google provide a repo to generate it.
So, I tried to look into the ruby-docker public repo that google shared but I don't know how to use their generated docker images and therefore fix my Dockerfile issue
https://github.com/GoogleCloudPlatform/ruby-docker
Could someone help me figure what's wrong in my setup and how to run these ruby-docker image (seems very useful!)?
Thank you!
The "entrypoint" field in app.yaml is not used when a custom runtime is in play. Instead, set the CMD in your Dockerfile. e.g.:
CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0", "--port", "8080"]
That probably will get your application running. (Remember that environment variables are not interpolated in exec form, so I replaced your $PORT with the hard-coded port 8080, which is the port App Engine expects.)
As an alternative:
It may be possible to use the Ruby runtime images in the ruby-docker repo, and not have to use a custom runtime (i.e. you may not need to write your own Dockerfile), even if you have custom build steps like doing yarn installs. Most of the build process in runtime: ruby is customizable, but it's not well-documented. If you want to try this path, the TL;DR is:
Use runtime: ruby in your app.yaml and don't provide your own Dockerfile. (And reinstate the entrypoint of course.)
If you want to install ubuntu packages not normally present in runtime: ruby, list them in app.yaml under runtime_config:packages. For example:
runtime_config:
packages:
- libgeos-dev
- libproj-dev
If you want to run custom build steps, list them in app.yaml under runtime_config:build. They get executed in the Dockerfile after the bundle install step (which cannot itself be modified). For example:
runtime_config:
build:
- npm install
- bundle exec rake assets:precompile
- bundle exec rake setup_my_stuff
Note that by default, if you don't provide custom build steps, the ruby runtime behaves as if there is one build step: bundle exec rake assets:precompile || true. That is, by default, runtime: ruby will attempt to compile your assets during app engine deployment. If you do modify the build steps and you want to keep this behavior, make sure you include that rake task as part of your custom build steps.
I am using GitLab to host my static page!
every time I am configuring the .gitlab-ci.yml file I am getting the following error: "Could not locate Gemfile"
Here is the output of the cmd
Here id the .gitlab-ci.yml file
image: ruby:2.3
before_script:
- bundle install
job:
script:
- gem install jekyll
- jekyll build
pages:
stage: deploy
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle install
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
In your configuration I see a mixed of different install instructions:
bundle install (in the before_script)
bundle install (again, in the pages deploy script)
gem install jekyll
The Gemfile is required by the bundle command, and it should specify mainly the dependency on jekyll (so again a duplication)
PROPOSED SOLUTION:
I suggest you to try with the configuration in the gitlab pages sample:
gitlab-ci.yml
image: ruby:2.3
variables:
JEKYLL_ENV: production
before_script:
- bundle install
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
Gemfile
source "https://rubygems.org"
ruby RUBY_VERSION
# This will help ensure the proper Jekyll version is running.
gem "jekyll", "3.4.0"
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
I'm trying to move our Rails app over to a Docker deployment, however I can't manage to get bundle to install from a Github reference.
With the below Dockerfile:
FROM ruby:2.3.0-slim
MAINTAINER Chris Jewell <chrisjohnjewell#gmail.com>
# Install dependencies:
# - build-essential: To ensure certain gems can be compiled
# - nodejs: Compile assets
# - libpq-dev: Communicate with postgres through the postgres gem
# - postgresql-client-9.4: In case you want to talk directly to postgres
RUN apt-get update && apt-get install -qq -y build-essential nodejs libpq-dev postgresql-client-9.4 --fix-missing --no-install-recommends
# Set an environment variable to store where the app is installed to inside
# of the Docker image.
ENV INSTALL_PATH /ventbackend
RUN mkdir -p $INSTALL_PATH
# This sets the context of where commands will be ran in and is documented
# on Docker's website extensively.
WORKDIR $INSTALL_PATH
# Ensure gems are cached and only get updated when they change. This will
# drastically increase build times when your gems do not change.
COPY Gemfile Gemfile
RUN bundle install
# Copy in the application code from your work station at the current directory
# over to the working directory.
COPY . .
# Provide dummy data to Rails so it can pre-compile assets.
RUN bundle exec rake RAILS_ENV=production DATABASE_URL=postgresql://user:pass#127.0.0.1/dbname SECRET_TOKEN=pickasecuretoken assets:precompile
# Expose a volume so that nginx will be able to read in assets in production.
VOLUME ["$INSTALL_PATH/public"]
# The default command that gets ran will be to start the Unicorn server.
CMD bundle exec unicorn -c config/unicorn.rb
I get the following error when trying to run docker-compose up:
You need to install git to be able to use gems from git repositories. For help
installing git, please refer to GitHub's tutorial at
https://help.github.com/articles/set-up-git
I'm assuming that this is because of lines in the Gemfile like:
gem 'logstasher', github: 'MarkMurphy/logstasher', ref: 'be3e871385bde7b1897ec2a1831f868a843d8000'
However, we also use some private Gems as well.
Is installing Git on the container the way to go? How will this authenticate with Github?
Is installing Git on the container the way to go?
In that case, yes: you can see an example at "Using Docker to maintain a Ruby gem". It Dockerfile does include a:
# ~~~~ OS Maintenance ~~~~
RUN apt-get update && apt-get install -y git
How will this authenticate with Github?
It does not have to authenticate to GitHub in order to read, ie clone.
It you needed to push back a gem (to publish it), then you would need for instance your ssh keys (mounted through a volume).
But that is not needed here.
I'm trying to get running my rails application with docker and fig, it counts with a redis server, mongodb, postgres, and nginx as well,
Here is how my fig.yml looks like:
pg:
image: docker-index.my.com/postgres
ports:
- 5432
redis:
image: docker-index.my.com/redis
ports:
- 6379
mongodb:
image: docker-index.my.com/mongodb
ports:
- 27017
app:
build: .
command: bundle exec rails s
volumes:
- .:/beesor
ports:
- 3000:3000
links:
- pg
- redis
- mongodb
environment:
RAILS_ENV: production
Everything works ok till the moment of starting app, as rails initializers hooks on server starts then I got errors regarding the database connection, the database does not exists! of course because it was not created on the Dockerfile (see below)
Dockerfile contents:
# DOCKER-VERSION 0.10.0
FROM docker-index.my.com/ruby:1.9.3
MAINTAINER my.com
RUN apt-get update -qq && apt-get install -y git-core xvfb curl nodejs libqt4-dev libgtk2.0-0 libgtkmm-3.0-1 libnotify4 sqlite3 libsqlite3-dev graphicsmagick imagemagick subversion libpq-dev libxml2-dev libxslt-dev git build-essential
RUN mkdir /my_app
WORKDIR /my_app
RUN gem install bundler
ADD Gemfile /my_app/Gemfile
ADD Gemfile.lock /my_app/Gemfile.lock
RUN bundle install
RUN bundle pack --all
ADD . /my_app
I don't see a place where I can put the rake db:create db:migrate db:seed commands!, if I put them at the end of the Dockerfile then when fig tries to build app it complains about the database server does not exits, (in the time that fig builds app container the other containers are not started), and I could not fix this changing the order on the fig.yml,
I'm facing egg-chicken problem here, who can I get this working?
I'm sure that all the links work perfectly so the problem is more about orchestration of scripts.
Found the solution!:
I created a rake task to wrap what I need, it runs migrations, seeds, and starts the rails server, so the fix is to change the command on fig by this one:
command: rake my_app:setup