Sass is not found for gulp-ruby-sass within Docker container - docker

I have a web application that uses the gulp-ruby-sass plugin and it runs within a container that installs the sass gem.
This is the Dockerfile:
FROM phusion/passenger-customizable:0.9.19
# Set correct environment variables.
ENV HOME /root
# Use baseimage-docker's init process.
CMD ["/sbin/my_init"]
# Build system and git.
RUN /pd_build/utilities.sh && \
# Ruby support.
/pd_build/ruby-2.3.*.sh && \
# Node.js and Meteor support.
/pd_build/nodejs.sh && \
npm install -g gulp jspm yarn && \
npm install phantomjs-prebuilt#2.1.9 && \
mv node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs /usr/bin && \
rm -r node_modules && \
# Clean up APT when done.
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
EXPOSE 9000
WORKDIR /var/www/
CMD /bin/bash
This is the bootstrap script file (to bootstrap the application):
#! /bin/bash
bundle install
npm install
jspm install
npm config set bin-links false
npm rebuild node-sass
gulp watch
This is the Gemfile:
source "https://rubygems.org"
gem "sass"
And I launch the container this way:
docker run -it --name web -p 9000:9000 --volume $(pwd):/var/www brainy_web sh bootstrap.sh
The problem is that when the gulp task gulp build-css is executed using docker-compose, it doesn't find the sass gem as it is shown in the log: Gem sass is not installed (complete log here), but when I run the container with bash and execute the bootstrap.sh file everything runs smoothly.
Any thoughts on how to use sass with docker and gulp-ruby-sass?
UPDATE
I found that executing from the outside the gulp task, it doesn't find either:
docker exec web gulp build-css

I found the solution! I followed the advice from #webert-s-lima and in here: https://stackoverflow.com/a/29999734/532912
I just added the -l argument when launching the container. The statement would be like this:
docker run -it --name web -p 9000:9000 --volume $(pwd):/var/www brainy_web /bin/bash -l bootstrap.sh

Related

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

Change node version using nvm and docker-compose

I have a Dockerfile running centos/systemd that also installs nvm and have an entrypoint.sh that runs /usr/sbin/init (as required by docs) it also accept an argument from docker-compose command to control the node version being used - BUT it seems the node version is not persistent/kept for some reason.
How can I control node version from docker-compose file?
Dockerfile:
FROM centos/systemd
# Install & enable httpd
RUN yum -y update
RUN yum -y install \
httpd \
autofs \
gcc-c++ \
make \
git \
fontconfig \
bzip2 \
libpng-devel \
ruby \
ruby-devel \
zip \
unzip
RUN yum clean all
RUN systemctl enable httpd.service
# Setting up virtual hosts
RUN echo "IncludeOptional apps/*.conf" >> /etc/httpd/conf/httpd.conf
# Install nvm to later use in compose
ENV NVM_DIR /root/.nvm
ENV NODE_VERSION 13.10.0
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
# install node and npm
RUN source $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm install 12.16.1 \
&& nvm install 11.9.0 \
&& nvm install 10.9.0 \
&& nvm alias default $NODE_VERSION \
&& nvm use default
# add node and npm to path so the commands are available
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
# Expose ports
EXPOSE 80
EXPOSE 443
COPY entrypoint.sh ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
entrypoint.sh:
#!/bin/bash
source root/.nvm/nvm.sh && nvm use "$#"
node --version
exec /usr/sbin/init
docker-compose:
version: '3'
services:
httpd:
build: '..\Web-Server\Apache'
privileged: true
ports:
- 80:80
- 443:443
command: 11.9.0
docker-compose up (output):
httpd_1 | Now using node v11.9.0 (npm v6.5.0)
httpd_1 | v11.9.0
docker exec -it /bin/sh -lc "node --version":
v13.10.0
Thanks!
If you create a dockerfile for each project then, combine them with docker-compose files, for each deployment, that is your best option. If you want to facilitate for code reuse you can look at creating a generic base image to which all your dockerfiles use.
Answering my own question after endless searches across the web.
2 things to note/change:
We need to set the default node version as well (inside the shell script). Unfortunately, I don't no why it's necessary to set it as default to keep it persistent but it just works (if anyone can explain that, please do). So entrypoint.sh looks like this:
#!/bin/bash
source root/.nvm/nvm.sh && nvm use "$#" && nvm alias default "$#"
node --version
exec /usr/sbin/init
when running bash with docker exec -it <container_id> /bin/sh -c "node --version" and not in interactive mode or login to shell it will not read startup scripts so node version set by using source /root/.nvm/nvm.sh and nvm use XXX is not red and thats why it's not "changed" for this specific bash session. Solution is to login to container and run node --version from within OR source nvm.sh as well before running node --version e.g. docker exec -it <container_id> sh -c "source /root/.nvm/nvm.sh && node --version"
Hope that helps to anyone that came across the same issue.

Gcloud meanjs build failing via docker install

I'm trying to deploy the following container on google cloud app engine using gcloud app deploy, it's the meanjs.org vanilla image. It uses a dockerfile, I'm new to docker and I'm trying to learn it on the fly, so if anyone can help that'd be great, thanks.
It looks as if the install of node via the dockerfile fails, I've checked node's documentation on github, and nothing has changed syntactically to what is in the existing dockerfile. I will attempt to recreate on my local workstation this morning, and will update this query shortly.
the errors are as follows..first docker error second errorbuild fail error
The docker file..
# Build:
# docker build -t meanjs/mean .
#
# Run:
# docker run -it meanjs/mean
#
# Compose:
# docker-compose up -d
FROM ubuntu:latest
MAINTAINER MEAN.JS
# 80 = HTTP, 443 = HTTPS, 3000 = MEAN.JS server, 35729 = livereload, 8080 = node-inspector
EXPOSE 80 443 3000 35729 8080
# Set development environment as default
ENV NODE_ENV development
# Install Utilities
RUN apt-get update -q \
&& apt-get install -yqq \
curl \
git \
ssh \
gcc \
make \
build-essential \
libkrb5-dev \
sudo \
apt-utils \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install nodejs
RUN curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
RUN sudo apt-get install -yq nodejs \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install MEAN.JS Prerequisites
RUN npm install --quiet -g gulp bower yo mocha karma-cli pm2 && npm cache clean
RUN mkdir -p /opt/mean.js/public/lib
WORKDIR /opt/mean.js
# Copies the local package.json file to the container
# and utilities docker container cache to not needing to rebuild
# and install node_modules/ everytime we build the docker, but only
# when the local package.json file changes.
# Install npm packages
COPY package.json /opt/mean.js/package.json
RUN npm install --quiet && npm cache clean
# Install bower packages
COPY bower.json /opt/mean.js/bower.json
COPY .bowerrc /opt/mean.js/.bowerrc
RUN bower install --quiet --allow-root --config.interactive=false
COPY . /opt/mean.js
# Run MEAN.JS server
CMD npm install && npm start
Okay, so after much wrestling unsuccessfully trying to install docker on windows, I went back to the dockerfile to try and identify the core issue here. Fortunately I find a solution as follows..
NodeJS is attempting to install on Ubuntu.
In the dockerfile at the root of the app
Ubuntu version is configured as:
FROM ubuntu:latest
simply change it to:
FROM ubuntu:14.04
I'm not sure if this is the best version to use for the build but it seems to be running successfully. Please feel free to amend/recommend an alternative solution. I'm new to Docker so pls be kind.

Docker CMD doesn't see installed components

I am trying to build a docker image using the following docker file.
FROM ubuntu:latest
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Update packages
RUN apt-get -y update && apt-get install -y \
curl \
build-essential \
libssl-dev \
git \
&& rm -rf /var/lib/apt/lists/*
ENV APP_NAME testapp
ENV NODE_VERSION 5.10
ENV SERVE_PORT 8080
ENV LIVE_RELOAD_PORT 8888
# Install nvm, node, and angular
RUN (curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash -) \
&& source /root/.nvm/nvm.sh \
&& nvm install $NODE_VERSION \
&& npm install -g angular-cli \
&& ng new $APP_NAME \
&& cd $APP_NAME \
&& npm run postinstall
EXPOSE $SERVE_PORT $LIVE_RELOAD_PORT
WORKDIR $APP_NAME
EXPOSE 8080
CMD ["node", "-v"]
But I keep getting an error when trying to run it:
docker: Error response from daemon: Container command 'node' not found or does not exist..
I know node is being properly installed because if I rebuild the image by commenting out the CMD line from the docker file
#CMD ["node", "-v"]
And then start a shell session
docker run -it testimage
I can see that all my dependencies are there and return proper results
node -v
v5.10.1
.....
ng -v
angular-cli: 1.0.0-beta.5
node: 5.10.1
os: linux x64
So my question is. Why is the CMD in Dockerfile not able to run these and how can I fix it?
When using the shell to RUN node via nvm, you have sourced the nvm.sh file and it will have a $PATH variable set in it's environment to search for executable files via nvm.
When you run commands via docker run it will only inject a default PATH
docker run <your-ubuntu-image> echo $PATH
docker run <your-ubuntu-image> which node
docker run <your-ubuntu-image> nvm which node
Specifying a CMD with an array execs a binary directly without a shell or a $PATH to lookup.
Provide the full path to your node binary.
CMD ["/bin/node","-v"]
It's better to use the node binary rather than the nvm helper scripts due to the way dockers signal processing works. It might be easier to use the node apt packages in docker rather than nvm.

Why does docker overwrite everything I've installed?

I've got a rails proxy app that runs with jupyter notebooks, and I'm trying to get a docker image up and running with supervisor as the entry point.
However, after including a FROM jupyter/notebook, everything I did to set up the rails is gone!
My dockerfile
#Installs Jupyter Notebook and IPython kernel from the current branch
# Another Docker container should inherit with `FROM jupyter/notebook`
# to run actual services.
# For RVM support - ultimately do out own solution here.
FROM tzenderman/docker-rvm:latest
# Update aptitude
RUN apt-get update
# Install software
RUN apt-get install -y git supervisor libgmp3-dev
# Set up loggin for now
RUN mkdir -p /var/log/supervisor
# USING TOKENS ###################################################
ARG DEPLOYMENT_TOKEN
RUN git clone https://$DEPLOYMENT_TOKEN:x-oauth-basic#github.com/proversity-org/edx-api-jupyter.git /tmpapp/
RUN mkdir /home/sifu/
RUN cp -R /tmpapp/* /home/sifu/
RUN cp -R -r /tmpapp/. /home/sifu/
RUN chown root:root -R /home/sifu/
#################################################################
WORKDIR /home/sifu
# Install ruby using RVM
RUN /bin/bash -l -c "rvm install $(cat .ruby-version) --verify-downloads"
RUN /bin/bash -l -c "rvm use $(cat .ruby-version) --default"
RUN /bin/bash -l -c "rvm list"
RUN rvm requirements
# run docker env for ruby apps
RUN /bin/bash -l -c "source .docker-ruby-version"
RUN echo $RUBY-VERSION
ENV GEM_HOME /usr/local
ENV PATH /usr/local/rvm/gems/ruby-2.2.3/bin:$PATH
ENV PATH /usr/local/rvm/rubies/ruby-2.2.3/bin:$PATH
# Install Bundler
RUN ruby --version
RUN gem install bundler
RUN bundle config --global silence_root_warning 1
# Install Sifu gems
RUN bundle install --gemfile=/home/sifu/Gemfile
# Alow for arugments to sifu & notebook (server ip & port etc)
#RUN /bin/bash -l -c "which bundle"
#RUN /bin/bash -l -c "cp $(which ruby) /usr/bin/"
# Set up supervisor config -- move this up later
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Set as environment variables
FROM jupyter/notebook
CMD ["/usr/bin/supervisord"]
ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/myapp/supervisord.conf"]
All the software I installed is gone, when I use a FROM jupyter/notebook to include the notebooks in the image.
Is there something crucial I am missing?

Resources