Rails run with puma in dockerfile and enable https - ruby-on-rails

This is an example of a Dockerfile for ruby on rails project.
I want to run it with ssl key and cert
RUN apt-get update -yqq && apt-get install -y npm && npm install -g yarn
RUN apt-get install -y ruby-full
RUN apt install libsqlite3-dev
RUN gem install rails --version=6.1
RUN mkdir /var/app
WORKDIR /var/app
COPY . .
RUN bundle install --without development test
RUN npm install --force
RUN export SECRET_KEY_BASE=...............................
EXPOSE 3000
EXPOSE 80
EXPOSE 443
EXPOSE 8443
RUN rails webpacker:install
#RUN rake assets:clean
RUN rake assets:precompile
CMD rails s -b 0.0.0.0 -e production

FROM ruby:3.0.2
RUN apt-get update -yqq && apt-get install -y npm && npm install -g yarn
RUN apt-get install -y ruby-full
RUN apt install libsqlite3-dev
RUN gem install rails --version=6.1
RUN mkdir /var/app
WORKDIR /var/app
COPY . .
RUN bundle install --without development test
RUN npm install --force
RUN export SECRET_KEY_BASE=...............................
EXPOSE 3000
EXPOSE 80
EXPOSE 443
EXPOSE 8443
RUN rails webpacker:install
#RUN rake assets:clean
RUN rake assets:precompile
CMD puma -b 'ssl://0.0.0.0:8443?key=yourkey.key&cert=yourcertificat.pem&verify_mode=none' -b 'tcp://0.0.0.0:80' -e production
In config/environment/production.rb add: config.force_ssl=true
You can you freessl to get ssl key and certificat for your domain;
https://freessl.org/
To run it on you virtual machine or instance: docker run -d -p 443:443 -p 80:80 yourimage:tag

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"]

Problem Loading Ruby Rails Unicorn in ECS Fargate When Building Image in CircleCI (Works Locally)

I am having issues deploying a Ruby on Rails App to ECS Fargate. When I build the image locally (the same way it is done in the pipeline). I can easily start the web service with this command ["bundle", "exec", "unicorn", "-c", "config/unicorn.rb"]. However, running this same image in Fargate returns this: 2022-07-27 15:46:33bundler: failed to load command: unicorn (/usr/local/bundle/bin/unicorn)
Here is my Docker file:
FROM ruby:2.6.7
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client sudo
WORKDIR /app
ENV RAILS_ENV="staging"
ENV NODE_ENV="staging"
ENV LANG="en_US.UTF-8"
ENV RACK_ENV ="staging"
ENV BUNDLE_WITHOUT='development:test'
ARG GITHUB_TOKEN
RUN gem install bundler -v '2.2.28'
RUN bundle config https://github.com/somename/somerepo someuser:"${GITHUB_TOKEN}"
COPY . /app
RUN rm -rf /app/tmp
RUN mkdir -p /app/tmp
RUN bundle install
RUN bundle exec rails assets:precompile
EXPOSE 3000
The CMD is missing from Docker because its'a added in the task definition. Has anyone run into this issue? I've tried a number of different approaches, but am unsure of what is being changed locally running and running in Fargate.
Update
Looking into this issue further and found some more information that will need to be updated here.
I am using CircleCI to build and push this image to ECR. The issue seems to be that when created in CircleCI, any artifacts created by the bundle install become unreachable on run time and Docker is unable to run any gems because the GEM path is not even accessible to the root user. I pulled the image created by CircleCI Docker, locally, and confirmed the same errors. EXECing into the container and running chmod 755 -R /usr/local/bundle/bin/ and then executing the bundle exec to start the service, properly starts unicorn.
Next Steps
As a result, I attempted to add those changes into the Dockerfile on build and the same behavior still persists.
RUN bundle install
RUN chmod 755 -R /usr/local/bundle/bin/
Then I tried changing permissions in an entrypoint script and the container won't start at all.
Finally figured this out a few days ago. The answer is to add VOLUME arguments at the end of your Dockerfile. This will maintain persistence with any changes you have made. My final Dockerfile:
FROM ruby:2.6.7
ARG NPM_TOKEN
RUN apt-get update -qq && apt-get install -y \
build-essential \
curl \
postgresql-client \
software-properties-common \
sudo
RUN curl -fsSL https://deb.nodesource.com/setup_9.x | sudo -E bash - && \
sudo apt-get install -y nodejs
RUN apt-get install -y \
npm \
yarn
ENV BUNDLE_WITHOUT='development:test'
ENV RAILS_ENV="staging"
ENV RACK_ENV="staging"
ENV NPM_TOKEN="${NPM_TOKEN}"
RUN mkdir -p /dashboard
WORKDIR /dashboard
RUN mkdir -p /dashboard/tmp/pids
COPY Gemfile* ./
COPY gems/rails_admin_history_rollback /dashboard/gems/rails_admin_history_rollback
ARG GITHUB_TOKEN
RUN sudo gem install bundler -v '2.2.28' && \
bundle config https://github.com/some-company/some-repo some-name:"${GITHUB_TOKEN}"
RUN bundle install
COPY . /dashboard
RUN bundle exec rails assets:precompile
RUN chmod +x bin/entrypoint.sh
VOLUME /dashboard/
VOLUME /usr/local/bundle
EXPOSE 3000

Yarn executable was not detected in the system

Rails with docker gives me error when asset precompiled.
i am trying to setup rails application with docker. everything is fine but asset precompiled issue raise during build image.
Yarn executable was not detected in the system.
Dcoker file
`FROM ruby:2.7.2
ENV RAILS_ROOT /var/www/quickcard
ENV BUNDLE_VERSION 2.1.4
ENV BUNDLE_PATH usr/local/bundle/gems
ENV RAILS_LOG_TO_STDOUT true
ENV RAILS_PORT 5000
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
RUN apt-get update -qq && apt-get install -y build-essential \
git \
libxml2-dev \
libpq-dev \
libxslt-dev \
nodejs \
yarn \
imagemagick \
tzdata \
less \
&& rm -rf /var/cache/apk/*
RUN gem install bundler --version "$BUNDLE_VERSION"
RUN bundle config set path $BUNDLE_PATH
RUN mkdir -p $RAILS_ROOT
WORKDIR $RAILS_ROOT
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
COPY yarn.lock yarn.lock
RUN bundle install
EXPOSE $RAILS_PORT
RUN ln -s $RAILS_ROOT/config/systemd/puma.service /etc/systemd/system/quickcard
COPY . .
ENTRYPOINT ["entrypoint.sh"]
RUN bundle exec rake assets:precompile
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
`
How to resolve this error?

Docker web image does now work with rspec gem

I'll jump straight into the problem.
I have installed a rspec gem for testing(add rspec gem, then bundle install and rails g rspec:install). However when I run docker-compose up to run my app with docker a web image does not work. Here is a log message returned from that image:
web_1 | Could not find diff-lcs-1.4.4 in any of the sources
web_1 | Run `bundle install` to install missing gems.
My Dockerfile.web is defined bellow:
FROM ruby:2.6.5
ENV BUNDLER_VERSION=2.1.4
# Set Rails to run in production
ENV RAILS_ENV production
ENV RACK_ENV production
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client libpq-dev yarn
RUN gem install bundler -v 2.1.4
RUN mkdir /my_app
WORKDIR /my_app
COPY Gemfile /my_app/Gemfile
COPY Gemfile.lock /my_app/Gemfile.lock
RUN bundle install --without development test
COPY . /my_app
# 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
# Start the main process.
RUN bundle exec rake SECRET_KEY_BASE=<token> assets:precompile
CMD bundle exec puma -C config/puma.rb
Dockerfile:
FROM ruby:2.6.5
ENV BUNDLER_VERSION=2.1.4
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client libpq-dev
RUN gem install bundler -v 2.1.4
RUN mkdir /my_app
WORKDIR /my_app
COPY Gemfile /my_app/Gemfile
COPY Gemfile.lock /my_app/Gemfile.lock
RUN bundle install
COPY . /my_app
# 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
RUN bundle exec rake assets:precompile
CMD ["rails", "server", "-b", "0.0.0.0"]
I have diff-lcs gem installed so I don't know why I get this error.If I remove rspec gem then all docker images work fine.
I would appreciate any help.
Thanks in advance.
Rebuild that image, It will run bundle install and all will work fine.

rails, whenever and docker - cron tasks doesn't run

My crontasks from schedule.rb doesn't work on docker container, but crontab -l result already contains this lines:
# Begin Whenever generated tasks for: /app/config/schedule.rb
45 19 * * * /bin/bash -l -c 'bundle exec rake stats:cleanup'
45 19 * * * /bin/bash -l -c 'bundle exec rake stats:count'
0 5 * * * /bin/bash -l -c 'bundle exec rake stats:history'
# End Whenever generated tasks for: /app/config/schedule.rb
I can run this commands manually in container and it works. It seems like cron doesn't start.
Dockerfile:
FROM ruby:2.4.0-slim
RUN apt-get update
RUN apt-get install -qq -y --no-install-recommends build-essential libpq-dev cron postgresql-client
RUN cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
ENV LANG C.UTF-8
ENV RAILS_ENV production
ENV INSTALL_PATH /app
RUN mkdir $INSTALL_PATH
RUN touch /log/cron.log
ADD Gemfile Gemfile.lock ./
WORKDIR $INSTALL_PATH
RUN bundle install --binstubs --without development test
COPY . .
RUN bundle exec whenever --update-crontab
RUN service cron start
ENTRYPOINT ["bundle", "exec", "puma"]
In a Dockerfile, the RUN command is only execute when building the image.
If you want to start cron when you start your container, you should run cron in CMD. I modified your Dockerfile by removing RUN service cron start and changing your ENTRYPOINT.
FROM ruby:2.4.0-slim
RUN apt-get update
RUN apt-get install -qq -y --no-install-recommends build-essential libpq-dev cron postgresql-client
RUN cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
ENV LANG C.UTF-8
ENV RAILS_ENV production
ENV INSTALL_PATH /app
RUN mkdir $INSTALL_PATH
RUN touch /log/cron.log
ADD Gemfile Gemfile.lock ./
WORKDIR $INSTALL_PATH
RUN bundle install --binstubs --without development test
COPY . .
RUN bundle exec whenever --update-crontab
CMD cron && bundle exec puma
It's a best practice to reduce the number of layer an image have, for example, you should always combine RUN apt-get update with apt-get install in the same RUN statement, and clean apt files after: rm -rf /var/lib/apt/lists/*
FROM ruby:2.4.0-slim
RUN apt-get update && \
apt-get install -qq -y --no-install-recommends build-essential libpq-dev cron postgresql-client \
rm -rf /var/lib/apt/lists/* && \
cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
ENV LANG C.UTF-8
ENV RAILS_ENV production
ENV INSTALL_PATH /app
RUN mkdir $INSTALL_PATH && \
touch /log/cron.log
ADD Gemfile Gemfile.lock ./
WORKDIR $INSTALL_PATH
RUN bundle install --binstubs --without development test
COPY . .
RUN bundle exec whenever --update-crontab
CMD cron && bundle exec puma

Resources