How to install gems in vendor dir in Docker? - ruby-on-rails

Following is my dockerfile
FROM ruby:2.7.1-slim as Builder
ARG FOLDERS_TO_REMOVE
ARG BUNDLE_WITHOUT
ENV GEM_HOME="/vendor/bundle"
ENV PATH $GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH
RUN apt-get update && apt-get install -y gnupg2
ADD https://dl.yarnpkg.com/debian/pubkey.gpg /tmp/yarn-pubkey.gpg
RUN apt-key add /tmp/yarn-pubkey.gpg && rm /tmp/yarn-pubkey.gpg
RUN echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -qq -y --fix-missing --no-install-recommends \
build-essential \
libpq-dev \
git \
tzdata \
libgeos-dev \
nodejs \
yarn
WORKDIR /code
COPY Gemfile* package.json yarn.lock ./
RUN yarn install --check-files
RUN gem install bundler:2.1.4 -N && \
bundle config set without $BUNDLE_WITHOUT && \
bundle config set deployment 'true' && \
bundle config set no-cache 'true' && \
bundle install -j4 --retry 3
COPY . .
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server"]
When I build the image and run it I get
bundler: command not found: rails
When I remove the line bundle config set deployment 'true' it works perfectly fine.
What could be the problem?

Related

/bin/bash: 1: ./entrypoint.sh: not found

In Debian GNU/Linux 11 (bullseye) based Dockerfile, I tried to use CMD to run an entry point command:
#EDIT
WORKDIR "/tmp"
USER root
COPY ./entrypoint.sh /tmp/rails/entrypoint.sh
RUN chmod +x /tmp/rails/entrypoint.sh
EXPOSE 80
CMD ["/bin/bash","-c","/tmp/rails/entrypoint.sh"]
/tmp/rails/entrypoint.sh:
#!/bin/bash
nginx -g 'daemon off;'
cd /tmp
RAILS_ENV=proudction bundle exec rails server -p 3000
service nginx start
But I still getting error
/bin/bash: 1: ./entrypoint.sh: not found
I also tried
ENTRYPOINT /tmp/rails/entrypoint.sh
CMD ["/bin/bash","-c","/tmp/rails/entrypoint.sh"]
but it always show entrypoint.sh not found, Any idea?
EDIT
full docker file:
FROM ruby:3.0.5
RUN apt update -y
RUN apt install -y nginx
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.6.1 /lambda-adapter /opt/extensions/lambda-adapter
RUN apt-get update -y
RUN apt-get --assume-yes install autoconf bison patch build-essential rustc libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev
RUN apt-get install -y rubygems #ruby-dev
RUN gem install bundler -v '2.2.32'
RUN bundle config --local build.sassc --disable-march-tune-native
# UPDATE NODE:
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs
# YARN:
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 update && apt install yarn
# Fix issue with sassc gem
RUN bundle config --local build.sassc --disable-march-tune-native
RUN apt-get install -y awscli
#END OF ORIGINAL
#RUN bundle config set without 'development test'
#RUN rm -rf /home/app/webapp/app
RUN mkdir /tmp/rails
COPY . /tmp/rails
WORKDIR "/tmp/rails"
RUN bundle install # --path=vendor
ENV RAILS_SERVE_STATIC_FILES false
ENV EXECJS_RUNTIME=Disabled
ENV WEBPACKER_PRECOMPILE=false
ENV NODE_ENV=production
RUN yarn config set ignore-engines true
#RUN bundle exec rails webpacker:compile
RUN bundle exec rails assets:precompile
ARG GIT_REVISION_ARG
ENV GIT_REVISION=$GIT_REVISION_ARG
#Rails App
RUN rm -f /etc/service/nginx/down
RUN rm -f /etc/nginx/sites-enabled/default
ADD webapp.conf /etc/nginx/sites-enabled/webapp.conf
RUN chmod +x /tmp/rails/entrypoint.sh
WORKDIR "/tmp"
ADD nginx/app/config/ /etc/nginx/
ADD nginx/app/images/ /usr/share/nginx/html/images
USER root
COPY ./entrypoint.sh /tmp/rails/entrypoint.sh
RUN chmod +x /tmp/rails/entrypoint.sh
ENTRYPOINT /tmp/rails/entrypoint.sh
EXPOSE 80
CMD ["/bin/bash","-c","/tmp/rails/entrypoint.sh"]

Entrypoint not found when deployed to Fargate. Locally works

I have the following Dockerfile, currently working locally in my device:
FROM python:3.7-slim-buster
WORKDIR /app
COPY . /app
VOLUME /app
RUN chmod +x /app/cat/sitemap_download.py
COPY entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
ARG VERSION=3.7.4
RUN apt update && \
apt install -y bash wget && \
wget -O /tmp/nordrepo.deb https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn-release_1.0.0_all.deb && \
apt install -y /tmp/nordrepo.deb && \
apt update && \
apt install -y nordvpn=$VERSION && \
apt remove -y wget nordvpn-release
RUN apt-get clean \
&& apt-get -y update
RUN apt-get -y install python3-dev \
python3-psycopg2 \
&& apt-get -y install build-essential
RUN pip install --upgrade pip
RUN pip install -r cat/requirements.txt
RUN pip install awscli
ENTRYPOINT ["sh", "-c", "./entrypoint.sh"]
But when I deploy it to Fargate, the container stops before reaching the steady state with:
sh: 1: ./entrypoint.sh: not found
Edit: Adding entrypoint.sh file for clarification:
#!/bin/env sh
# start process, but it should exit once the file is in S3
/app/cat/sitemap_download.py
# Once the process is done, we are good to scale down the service
aws ecs update-service --cluster cluster_name --region eu-west-1 --service service-name --desired-count 0
I have tried modifying ENTRYPOINT to use it as exec form, or with full path but always get the same issue. Any ideas on what am I doing wrong?
I've managed to fix it now.
Changing the Dockerfile to look as follows solves the issue:
COPY . /app
VOLUME /app
RUN chmod +x /app/cat/sitemap_download.py
COPY entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
ARG VERSION=3.7.4
RUN apt update && \
apt install -y bash wget && \
wget -O /tmp/nordrepo.deb https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn-release_1.0.0_all.deb && \
apt install -y /tmp/nordrepo.deb && \
apt update && \
apt install -y nordvpn=$VERSION && \
apt remove -y wget nordvpn-release
RUN apt-get clean \
&& apt-get -y update
RUN apt-get -y install python3-dev \
python3-psycopg2 \
&& apt-get -y install build-essential
RUN pip install --upgrade pip
RUN pip install -r cat/requirements.txt
RUN pip install awscli
ENTRYPOINT ["/bin/bash"]
CMD ["./entrypoint.sh"]
I tried this after reading: What is the difference between CMD and ENTRYPOINT in a Dockerfile?
I believe this syntax fixes it because with entrypoint I'm indicating bash to be run at start, and then passing the script as parameter.

Deploy Rails app into Heroku with Docker using heroku.yml

After following the tutorial at: https://devcenter.heroku.com/articles/build-docker-images-heroku-yml it was not clear which contents we should put in the Dockerfile.
For a Rails app what do we need in our Dockerfile?
There is a Rails 5 example that you can base your solution: https://github.com/jahangiranwari/rails5-docker-heroku/
For a Rails 6 project I've used the following Dockerfile:
FROM ruby:2.6.6
# Install node & yarn
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs
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 && apt-get install -y yarn
# Install base deps or additional (e.g. tesseract)
ARG INSTALL_DEPENDENCIES
RUN apt-get update -qq \
&& apt-get install -y --no-install-recommends ${INSTALL_DEPENDENCIES} \
build-essential libpq-dev git \
&& apt-get clean autoclean \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt \
/var/lib/dpkg \
/var/lib/cache \
/var/lib/log
# Install deps with bundler
RUN mkdir /app
WORKDIR /app
COPY Gemfile* /app/
ARG BUNDLE_INSTALL_ARGS
RUN gem install bundler:2.1.4
RUN bundle config set without 'development test'
RUN bundle install ${BUNDLE_INSTALL_ARGS} \
&& rm -rf /usr/local/bundle/cache/* \
&& find /usr/local/bundle/gems/ -name "*.c" -delete \
&& find /usr/local/bundle/gems/ -name "*.o" -delete
COPY . /app/
# Compile assets
ARG RAILS_ENV=development
RUN if [ "$RAILS_ENV" = "production" ]; then SECRET_KEY_BASE=$(rake secret) bundle exec rake assets:precompile; fi
And this heroku.yml file:
build:
docker:
web: Dockerfile
config:
BUNDLE_INSTALL_ARGS: --jobs 10 --retry=3
RAILS_ENV: production
# Put extra deps here
INSTALL_DEPENDENCIES: curl openssh-server python
run:
web: bundle exec puma -C config/puma.rb
Update 20-1-22:
It works for Rails 7

How to activate GRPC PHP extension via Dockerfile?

I have this Dockerfile. When I try to run it, in the Composer Update line it returns an error, that extensions are not installed.
That is because of GRPC not being activated on the php.ini
My question is, how can I activated it via terminal?
FROM php:7.2-apache
WORKDIR /var/www/html
COPY . ./
RUN apt-get update && apt-get install -y -q nodejs npm curl unzip git rake ruby-ronn zlib1g-dev libpng-dev && apt-get clean
RUN apt-get install php7.2=dev php-pear phpunit
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
RUN pecl install grpc
RUN docker-php-ext-install mbstring
RUN docker-php-ext-install zip
RUN docker-php-ext-install gd
RUN npm install
RUN npm install -g gulp-cli
RUN composer update
RUN gulp --env=production
EXPOSE 80 443
you forgot to activate the grcp extension ,you can use the code under the comment #install protoc to activated,and you will get message if it has activated or not by RUN php -r "echo extension_loaded('grpc') ? 'yes' : 'no';"
I think this way is better and more concise:
FROM php:7-apache
RUN apt-get update && apt-get install -y -q git rake ruby-ronn zlib1g-dev && apt-get clean
# install composer
RUN cd /usr/local/bin && curl -sS https://getcomposer.org/installer | php
RUN cd /usr/local/bin && mv composer.phar composer
RUN pecl install grpc
#install protoc
RUN mkdir -p /tmp/protoc && \
curl -L https://github.com/google/protobuf/releases/download/v3.2.0/protoc-3.2.0-linux-x86_64.zip > /tmp/protoc/protoc.zip && \
cd /tmp/protoc && \
unzip protoc.zip && \
cp /tmp/protoc/bin/protoc /usr/local/bin && \
cd /tmp && \
rm -r /tmp/protoc && \
docker-php-ext-enable grpc
RUN php -r "echo extension_loaded('grpc') ? 'yes' : 'no';"
WORKDIR /app
COPY . /app
RUN composer install
RUN npm install
RUN npm install -g gulp-cli
RUN gulp --env=production
EXPOSE 8181

Why docker-compose build start from begining

For example.
Every time I build.
Copy package.json
Install package.json
Add current directory.
My question is:
Why it does not use from the cache. For example, It should not install the package.json from the start if the package.json does not change.
It should use the cache and update only the changes code.
Update:
Dockerfile
FROM ubuntu:18.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
gcc \
git \
libpq-dev \
make \
python-pip \
python2.7 \
python2.7-dev \
apt-transport-https \
curl \
g++ \
sudo \
wget \
bzip2 \
chrpath \
libssl-dev \
libxft-dev \
libfreetype6 \
libfreetype6-dev \
libfontconfig1 \
libfontconfig1-dev \
libfontconfig \
poppler-utils \
imagemagick \
&& apt-get clean \
&& rm -rf /tmp/* /var/lib/apt/lists/* \
&& apt-get -y autoclean
RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common && add-apt-repository ppa:malteworld/ppa && apt update && apt install -y --no-install-recommends pdftk \
&& apt-get clean \
&& rm -rf /tmp/* /var/lib/apt/lists/* \
&& apt-get -y autoclean
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 10.6.0
# Install nvm with node and npm
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh | bash \
&& source $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default
# Set up our PATH correctly so we don't have to long-reference npm, node, &c.
ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
# Set the work directory
RUN mkdir -p /var/www/app/jobsaf-website
RUN mkdir /data
RUN mkdir /data/db
WORKDIR /var/www/app/jobsaf-website
RUN npm install -g node-gyp #angular/cli#6.2.3 nodemon request
# Add our package.json and install *before* adding our application files
COPY package.json ./
# RUN npm install --force
RUN npm install --force
RUN npm rebuild node-sass
# Add application files
ADD . .
EXPOSE 3000 5858 4200 35729 27017 6379 49153
.dockerignore
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/tmp
/public/__build__/
/src/*/__build__/
/__build__/**
/public/dist/
/src/*/dist/
/dist/**
/.awcache
.webpack.json
/compiled/
dll/
package-lock.json
# dependencies
/node_modules
*/node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
**.js.map
.settings/
# IDE - VSCode
.vscode/
# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log
testem.log
/typings
# e2e
/e2e/*.js
/e2e/*.map
#System Files
.DS_Store
Thumbs.db
*.csv
*.dat
*.iml
*.log
*.out
*.pid
*.seed
*.sublime-*
*.swo
*.swp
*.tgz
*.xml
.strong-pm
coverage
npm-debug*
/admin/dist
npm
/.cache-loader/*
stats.json
!/src/assets/js/admin-header.js
!/src/assets/js/website-custom.js
webpack-cache/
web/
/src/app/**/*.map
/src/app/**/*.js
--force should be removed from the following line as it will ignore any cache and do a fresh installation for your packages which leads to a new docker build layer starting from the installation step.
RUN npm install --force
The -f or --force argument will force npm to fetch remote resources even if a local copy exists on disk.

Resources