Dockerfile for Rails app - Permission Denied - ruby-on-rails

I am attempting to create a docker image of a rails app using rvm (as non-root) and am running into permission errors:
Dockerfile:
FROM ubuntu
RUN apt-get update -q
RUN apt-get install -qy curl
RUN apt-get install -y libpq-dev
RUN apt-get install -y imagemagick --fix-missing
RUN apt-get install -y curl patch gawk g++ gcc make libc6-dev patch libreadline6-dev zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 autoconf libgdbm-dev libncurses5-dev automake libtool bison pkg-config libffi-dev
RUN useradd -ms /bin/bash app
USER app
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
RUN curl -sSL https://get.rvm.io | bash -s stable
RUN /bin/bash -c -l 'rvm install 2.2.1'
RUN /bin/bash -c -l 'rvm use 2.2.1'
RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
RUN /bin/bash -c -l 'gem install bundler --no-ri --no-rdoc'
RUN /bin/bash -c -l 'mkdir /home/app/rails_app'
WORKDIR /home/app/rails_app
ADD Gemfile /home/app/rails_app/Gemfile
ADD Gemfile.lock /home/app/rails_app/Gemfile.lock
RUN /bin/bash -c -l 'bundle install'
ADD . /home/app/rails_app
EXPOSE 3000
CMD /bin/bash -c -l 'RAILS_ENV=production rails server -p 3000'
The image builds fine but when I run the container with docker run
I get the following error:
/home/app/.rvm/gems/ruby-2.2.1/gems/rack-1.6.4/lib/rack/server.rb:367:in `delete': Permission denied # unlink_internal - /home/app/rails_app/tmp/pids/server.pid (Errno::EACCES)
If I add:
USER root
RUN /bin/bash -c -l 'chmod -R 777 /home/app/rails_app/'
RUN /bin/bash -c -l 'chown -R app:app /home/app/rails_app/'
USER app
The container runs but the rails server did not start and there is nothing in the logs. Executing /bin/bash on the running container and trying to start the rails server ends in rails: command not found while logged in as app. Any Ideas?
Thanks

Related

How to install homebrew on Ubuntu inside Docker container

When I try to install homebrew on Ubuntu 18.04
# Dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install build-essential curl file git -y
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
getting errors:
==> Add Ruby to your PATH by running: PATH=/root/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/current/bin:$PATH
Don't run this as root!
Is there a reason you can't use the official image (docker pull linuxbrew/linuxbrew)? It is based on Ubuntu 16.04 / Xenial.
If you must use Bionic (18.04), the correct way to install homebrew will be to follow the steps in the official Dockerfile.
But to get your Dockerfile working, you need to install ruby, create a non-root user and execute the installation script as that user. Like so,
FROM ubuntu:18.04
RUN apt-get update && \
apt-get install build-essential curl file git ruby-full locales --no-install-recommends -y && \
rm -rf /var/lib/apt/lists/*
RUN localedef -i en_US -f UTF-8 en_US.UTF-8
RUN useradd -m -s /bin/bash linuxbrew && \
echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers
USER linuxbrew
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
USER root
ENV PATH="/home/linuxbrew/.linuxbrew/bin:${PATH}"
PS: I have added --no-install-recommends to ignore optional dependencies and rm -rf /var/lib/apt/lists/* to remove apt-get leftovers thus reducing the image size. Also, locales is added to install UTF-8 or brew will throw a warning when you run the command.
The new correct way is:
RUN apt-get update && \
apt-get install -y -q --allow-unauthenticated \
git \
sudo
RUN useradd -m -s /bin/zsh linuxbrew && \
usermod -aG sudo linuxbrew && \
mkdir -p /home/linuxbrew/.linuxbrew && \
chown -R linuxbrew: /home/linuxbrew/.linuxbrew
USER linuxbrew
RUN /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Gabriel's answer mostly worked for me, but was missing one step. I needed to chown the /home/linuxbrew/.linuxbrew folder to the user that would be running Homebrew:
RUN apt-get update && \
apt-get install -y -q --allow-unauthenticated \
git \
sudo
RUN useradd -m -s /bin/zsh linuxbrew && \
usermod -aG sudo linuxbrew && \
mkdir -p /home/linuxbrew/.linuxbrew && \
chown -R linuxbrew: /home/linuxbrew/.linuxbrew
USER linuxbrew
RUN /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
USER root
RUN chown -R $CONTAINER_USER: /home/linuxbrew/.linuxbrew

Yarn not in path on Laradock worskpace when using it in inline docker exec command

I have a problem using Laradock and yarn with an inline docker exec command from "outside" the workspace container.
When I use it from inside the workspace container, everything is working as expected :
docker exec -it --user=laradock laradock_workspace_1 bash
yarn -v
1.3.2
When I try to use it from an inline command, here is what happens :
docker exec -it --user=laradock laradock_workspace_1 yarn -v
OCI runtime exec failed: exec failed: container_linux.go:296: starting container process caused "exec: \"yarn\": executable file not found in $PATH": unknown
Am I doing anything wrong ?
I found the solution myself.
For those who encounter the same issue, just use docker exec following the example below, in order to get access to node or yarn :
docker exec -it --user=laradock laradock_workspace_1 bash --login -c "yarn -v"
I found the solution here : https://gitlab.com/gitlab-org/gitlab-runner/issues/82
try this
#apt-get install sudo -y
#sudo apt-get install apt-transport-https
#sudo apt-get install apt-transport-https
#apt-get remove node
#apt-get remove yarn
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
#sudo apt-get install -y nodejs
#curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
#echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
#sudo apt-get update && sudo apt-get install yarn
#apt-get remove node
#apt-get remove yarn
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
#sudo apt-get install -y nodejs
#curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
#echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
#sudo apt-get update && sudo apt-get install yarn
#yarn -v
1.13.0
#yarn install

Docker Sidekiq Starting - Rails App with Puma

The following Dockerfile it's supposed to start sidekiq when the container it's started:
FROM phusion/baseimage:0.9.18
ENV RUBY_MAJOR "2.0"
ENV RUBY_VERSION "2.0.0-p643"
ENV RUBYGEMS_VERSION "2.5.2"
ENV BUNDLER_VERSION "1.11.2"
ENV NODE_VERSION "5.5.0"
ENV BOWER_VERSION "1.7.6"
ENV APT_PACKAGES " \
git imagemagick \
gcc g++ make patch binutils libc6-dev \
libjemalloc-dev libffi-dev libssl-dev libyaml-dev zlib1g-dev libgmp-dev \
libxml2-dev libxslt1-dev libpq-dev libreadline-dev libsqlite3-dev htop \
"
ENV APT_REMOVE_PACKAGES "openssh-server"
RUN apt-get update && apt-get -y dist-upgrade
RUN apt-get install -y $APT_PACKAGES
RUN apt-get remove --purge -y $APT_REMOVE_PACKAGES
RUN apt-get autoremove --purge -y
WORKDIR /tmp
RUN curl -o ruby.tgz \
"https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR}/ruby-${RUBY_VERSION}.tar.gz" && \
tar -xzf ruby.tgz && \
cd ruby-${RUBY_VERSION} && \
./configure --enable-shared --with-jemalloc --disable-install-doc && \
make -j4 && \
make install && \
rm /usr/local/lib/libruby-static.a
ENV GEM_SPEC_CACHE "/tmp/gemspec"
RUN echo 'gem: --no-document' > $HOME/.gemrc
RUN gem update --system ${RUBYGEMS_VERSION}
RUN gem install -v ${BUNDLER_VERSION} bundler
RUN curl https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz \
|tar -xz -C /usr --strip-components=1
RUN npm install bower#${BOWER_VERSION} -g
RUN rm /etc/my_init.d/00_regen_ssh_host_keys.sh
RUN rm -r /etc/service/sshd
RUN useradd -m app
RUN mkdir /home/app/webapp && chown app:app -R /home/app
RUN rm -rf /tmp/* /var/tmp/* /var/lib/apt /var/lib/dpkg /usr/share/man /usr/share/doc
WORKDIR /home/app/webapp
# Copy the Gemfile as well as the Gemfile.lock and install
# the RubyGems. This is a separate step so the dependencies
# will be cached unless changes to one of those two files
# are made.
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && bundle install --jobs 20 --retry 5 --without development test
# Copy the main application.
COPY . ./
COPY .cron/daily_run_app /etc/cron.daily/
RUN chmod a+x /etc/cron.daily/daily_run_app
# Precompile Rails assets
RUN bundle exec rake assets:precompile
EXPOSE 3000
COPY .conf_files/sidekiq.sh /etc/service/sidekiq/run
COPY .conf_files/appserver.sh /etc/service/appserver/run
# Start puma
RUN chmod a+x /etc/service/appserver/run
ENTRYPOINT /etc/service/appserver/run
#ENTRYPOINT bundle exec puma -C config/puma.rb
# Start sidekiq
#ENTRYPOINT bundle exec sidekiq -L log/sidekiq.log
#RUN chmod a+x /etc/service/sidekiq/run
#ENTRYPOINT /etc/service/sidekiq/run
The script /etc/service/appserver/run:
#!/bin/bash
SIDEKIQ_THREADS=${SIDEKIQ_THREADS:-16}
cd /home/app/webapp
exec chpst -u app bundle exec puma -C config/puma.rb \
2>&1 |logger -t appserver
SIDEKIQ_CONFIG="/home/app/webapp/config/sidekiq.yml"
exec chpst -u root bundle exec sidekiq -t 5 -c $SIDEKIQ_THREADS -C $SIDEKIQ_CONFIG \
2>&1 |logger -t sidekiq
You can enquequed jobs because you can see that in the sidekiq dasboard, but they are not going to be processed because sidekiq it's not started, but it should be started with the Dockerfile and Script that are shown above. So when you type manually:
bundle exec sidekiq
Right here sidekiq it's started and the jobs now could be processed. what could be happening?

How to check ruby version inside docker container

I have build the docker container by creating below docker file
# Select ubuntu as the base image
FROM ubuntu
# Install nginx, nodejs and curl
RUN apt-get update -q
RUN apt-get install -qy nginx
RUN apt-get install -qy curl
RUN apt-get install -qy nodejs
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Install rvm, ruby, bundler
RUN curl -sSL https://get.rvm.io | bash -s stable
RUN /bin/bash -l -c "rvm requirements"
RUN /bin/bash -l -c "rvm install 2.1.0"
RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
# Add configuration files in repository to filesystem
ADD config/container/nginx-sites.conf /etc/nginx/sites-enabled/default
ADD config/container/start-server.sh /usr/bin/start-server
RUN chmod +x /usr/bin/start-server
# Add rails project to project directory
ADD ./ /rails
# set WORKDIR
WORKDIR /rails
# bundle install
RUN /bin/bash -l -c "bundle install"
# Publish port 80
EXPOSE 80
# Startup commands
ENTRYPOINT /usr/bin/start-server
When i go inside the container and give the command ruby -v it throws bash: ruby: command not found
Could any one help me in doing this
I've spent a bit of time messing with RVM, Ruby and Docker recently. This answer might not be what you're looking for, but it needs to be said anyway: if you don't absolutely need RVM, then don't use it in your docker file. You've already noticed one downside: having to pre-empt your commands with /bin/bash -lc. You'll run into another downside if you ever want to have a non-root user run a ruby program in your Docker container. Also, your problem is most likely related to Docker not loading .bashrc or .bash_profile (I forgot which one RVM modifies) when you run a bash shell.
Instead use this to compile Ruby from source:
RUN apt-get update
RUN apt-get install -yq build-essential openssl libreadline6 libreadline6-dev curl git-core \
zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev \
autoconf libc6-dev ncurses-dev automake libtool bison subversion libmysqlclient-dev
ADD http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz /tmp/
RUN cd /tmp && tar -xzf /tmp/ruby-2.1.2.tar.gz
RUN cd /tmp/ruby-2.1.2/ && ./configure --disable-install-doc && make && make install
RUN rm -rf /tmp/*
ADD http://production.cf.rubygems.org/rubygems/rubygems-2.4.1.tgz /tmp/
RUN cd /tmp && tar -xzf /tmp/rubygems-2.4.1.tgz
RUN cd /tmp/rubygems-2.4.1 && ruby setup.rb
RUN rm -rf /tmp/*
RUN echo "gem: --no-ri --no-rdoc" > ~/.gemrc
RUN gem install bundler --no-rdoc --no-ri
You are not setting the default ruby after installing RVM. Trying setting the default ruby after installing it.
RUN /bin/bash -l -c "rvm install 2.1.0"
RUN /bin/bash -l -c "rvm use 2.1.0 --default"

Error when creating a Docker image for Ruby On Rails environment (from a Dockerfile)

I guess it's a environment problem.
When I do it manually (without a Dockerfile) it works.
Here's my Dockerfile:
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get upgrade --assume-yes
RUN apt-get install wget vim git --assume-yes
# install RVM
RUN apt-get install build-essential curl --assume-yes
RUN curl -L https://get.rvm.io | bash -s stable
RUN echo 'source /etc/profile.d/rvm.sh' >> ~/.bashrc
RUN /usr/local/rvm/bin/rvm-shell -c "rvm requirements"
# install Ruby
RUN /usr/local/rvm/bin/rvm-shell -c "rvm autolibs enable"
RUN /usr/local/rvm/bin/rvm-shell -c "rvm install 2.1.2"
# install Rails
RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc
RUN gem install rails -v 4.1.5
# install nodeJS
RUN sudo apt-get install nodejs --assume-yes
EXPOSE 3000
Than I build with:
sudo docker build -t="james/rails" .
I get that error:
Step 11 : RUN gem install rails -v 4.1.5
---> Running in 44efc6b7c254
/bin/sh: 1: gem: not found
2014/09/04 18:33:52 The command [/bin/sh -c gem install rails -v 4.1.5] returned a non-zero code: 127
Try RUN /bin/bash -l -c "gem install rails -v 4.1.5" instead of the line you've got in there. Does that change anything?
With the help from Alex Lynham, here's a working Dockerfile:
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install wget vim git --assume-yes
# install RVM
RUN apt-get install build-essential curl --assume-yes
RUN curl -L https://get.rvm.io | bash -s stable
RUN echo 'source /etc/profile.d/rvm.sh' >> ~/.bashrc
RUN /usr/local/rvm/bin/rvm-shell -c "rvm requirements"
# install Ruby
RUN /bin/bash -l -c "rvm autolibs enable"
RUN /bin/bash -l -c "rvm install 2.1.2"
# install Rails
RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc
RUN /bin/bash -l -c "gem install rails -v 4.1.5"
# install nodeJS
RUN sudo apt-get install nodejs --assume-yes
EXPOSE 3000
You need to install rubygems before being able to use it.
RUN apt-get install rubygems
see also : Can I install gems with apt-get on Ubuntu?

Resources