Closed ignisf closed 7 years ago
Ideally someone would provide either an official Vagrant box (like the ones we use for Linux and FreeBSD) or a script for creating a box from an iso so we can create one ourselves.
What about Docker? The Alpine distribution is quite popular these days: https://hub.docker.com/_/alpine/
I will look into it, thanks for the idea!
For reference https://www.vagrantup.com/docs/docker/basics.html
OK, a Vagrantfile
such as the one below seems to start up, however I'm not sure how to install the needed packages, start an SSH server and keep the image running so I can use it for testing like a normal Vagrant VM.
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.image = "library/alpine"
d.cmd = ['uname']
end
end
Why not just start with Docker for Mac or Docker for Windows? You can be up & running with an Alpine container in about 2 minutes.
I got here because I'm trying to put together a base-rails Alpine based container for our app. The ExecJS is giving me fits trying to run libv8. I was hoping to use V8 with mini-racer on Alpine 3.4...
The answer is no. Since you're building with glibc, it lacks some GNU internals when used with musl.
One choice is static linking, and another is provide separate binary for musl.
Another note for you: the v8 build system downloads their custom binutils, which also use glibc. What the hell.
Best part is that I had to start using these binutils because of https://github.com/cowboyd/libv8/issues/227
Linking libc statically should solve this perfectly. Some size growth though.
I'm happy compiling it within a Docker container with basic ruby things + alpine-sdk
+ findutils
, python2
, bash
, linux-headers
, binutils-gold
installed. Adding the glibc package makes the custom binutils usable.
This sounds great, could you possibly collect your changes in a PR and add an alpine how-to to the readme? Maybe start with the docs so I could help you out along the way.
It would be good if you added this as a type of binary release. I currently compile the extension locally and overwrites the one on my server to achieve the same thing.
There's no stable vagrant image for Alpine, so Docker is preferred. The dependencies I mentioned above is enough to compile it.
This is the way I currently produce Linux binary releases https://github.com/cowboyd/libv8/blob/master/Rakefile#L53-L70. I would appreciate it if you showed me how to extend this process for Docker. I've never used it.
Here's the command:
# replace localgit with the git directory, outdir with the release output
docker run -it --rm -v localgit:/libv8 -v outdir:/out alpine:edge /bin/sh -c 'apk add --update \
ruby ruby-bigdecimal ruby-bundler ruby-rdoc ruby-io-console ruby-irb ruby-dev \
alpine-sdk bash ca-certificates libressl libressl-dev findutils python2 linux-headers binutils-gold \
&& wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub \
&& wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-2.23-r3.apk \
&& apk add glibc-2.23-r3.apk \
&& git clone /libv8/.git ~/libv8 --recursive \
&& cd ~/libv8 && bundle install --path vendor/bundle \
&& cd ~/libv8 && env MAKEFLAGS+=-j4 bundle exec rake binary \
&& cp ~/libv8/pkg/*.gem /out'
Of course root is needed. By the way, 32bit isn't officially available for Docker, so we can ignore it. (Only a few people runs Alpine on their bare metal, much less 32bit, and they can follow the script to build from source anyway.)
UPDATE: added ruby-dev
I came across this "fix" for alpine here:
I've tested and confirmed that v8 / therubyracer work correctly with the following addition to my Dockerfile:
ENV LIBV8_MAJOR 3.16
ENV LIBV8_VERSION 3.16.14.17-x86_64-linux
RUN set -ex \
\
&& apk add --update --no-cache --virtual .libv8-builddeps \
make \
python \
git \
bash \
curl \
findutils \
binutils-gold \
tar \
linux-headers \
build-base \
\
&& git clone -b $LIBV8_MAJOR --recursive git://github.com/cowboyd/libv8.git \
&& cd ./libv8 \
&& sed -i -e 's/Gem::Platform::RUBY/Gem::Platform.local/' libv8.gemspec \
&& gem build --verbose libv8.gemspec \
&& export GYP_DEFINES="$GYP_DEFINES linux_use_bundled_binutils=0 linux_use_bundled_gold=0" \
&& gem install --verbose libv8-$LIBV8_VERSION.gem \
\
&& apk del --purge .libv8-builddeps \
\
&& cd ../ \
&& rm -rf ./libv8 \
&& cd /usr/local/bundle/gems/libv8-$LIBV8_VERSION/vendor/ \
&& mkdir -p /tmp/v8 \
&& mv ./v8/out /tmp/v8/. \
&& mv ./v8/include /tmp/v8/. \
&& rm -rf ./v8 ./depot_tools \
&& mv /tmp/v8 . \
\
&& apk add --update --no-cache libstdc++ \
&& apk add --update --no-cache --virtual=build-dependencies \
build-base \
&& gem install therubyracer \
&& rm -fr /usr/local/bundle/gems/libv8-$LIBV8_VERSION/vendor \
&& apk del --purge build-dependencies \
&& rm -rf /tmp/* /var/tmp/* /var/cache/apk/*
@ignisf Is this helpful? I'd be happy to open a PR with a Dockerfile of the above.
Hello, @mwarkentin, thank you for the tip! I still haven't found the time to go through the suggestions here but they do look promising. I'll get back to you.
@mwarkentin I've only done a very basic test of the above mentioned 'ruby-with-therubyracer', but it looks like it will work for my alpine/therubyracer needs. Thanks for the pointer!
hey all, I just hit this issue and it resolved easily in alpine with followings:
RUN set -ex \
&& apk add --no-cache --virtual .ruby-builddeps \
autoconf \
bison \
bzip2 \
bzip2-dev \
ca-certificates \
coreutils \
dpkg-dev dpkg \
gcc \
gdbm-dev \
glib-dev \
libc-dev \
libffi-dev \
libressl \
libressl-dev \
libxml2-dev \
libxslt-dev \
linux-headers \
make \
ncurses-dev \
procps \
readline-dev \
ruby \
tar \
xz \
yaml-dev \
zlib-dev \
libffi-dev \
libstdc++ \
g++ \
musl-dev \
libstdc++ \
autoconf \
bison \
bzip2 \
bzip2-dev \
ca-certificates \
coreutils \
dpkg-dev dpkg \
gcc \
gdbm-dev \
glib-dev \
libc-dev \
libffi-dev \
libressl \
libressl-dev \
libxml2-dev \
libxslt-dev \
linux-headers \
make \
ncurses-dev \
procps \
readline-dev \
ruby \
tar \
xz \
yaml-dev \
zlib-dev \
libffi-dev \
&& wget -O ruby.tar.xz "https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR%-rc}/ruby-$RUBY_VERSION.tar.xz" \
&& echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum -c - \
&& mkdir -p /usr/src/ruby \
&& tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1 \
&& rm ruby.tar.xz \
&& cd /usr/src/ruby \
&& { \
echo '#define ENABLE_PATH_CHECK 0'; \
echo; \
cat file.c; \
} > file.c.new \
&& mv file.c.new file.c \
&& autoconf \
&& gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \
&& export ac_cv_func_isnan=yes ac_cv_func_isinf=yes \
&& ./configure \
--build="$gnuArch" \
--disable-install-doc \
--enable-shared \
&& make -j "$(nproc)" \
&& make install \
&& runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)" \
&& apk add --no-network --virtual .ruby-rundeps $runDeps \
bzip2 \
ca-certificates \
libffi-dev \
procps \
yaml-dev \
zlib-dev \
&& gem update --system "$RUBYGEMS_VERSION" \
&& gem install bundler --version "$BUNDLER_VERSION" --force
RUN apk add nodejs && gem install libv8 -v '3.16.14.19' -- --with-system-v8 && gem install compass-rails therubyracer
Hope it helps some :)
@Adel-Magebinary what version of Alpine are you using for your Dockerfile? Would you mind posting the whole file (if possible)?
@rafaelmagu im running alpine 3.7
Below is the latest code that I can successfully build ruby & libv8. Just copy paste below to your Dockerfile.
RUN set -ex \
\
&& apk add --no-cache --virtual .ruby-builddeps \
autoconf \
bison \
bzip2 \
bzip2-dev \
ca-certificates \
coreutils \
dpkg-dev dpkg \
gcc \
gdbm-dev \
glib-dev \
libc-dev \
libffi-dev \
libressl \
libressl-dev \
libxml2-dev \
libxslt-dev \
linux-headers \
make \
ncurses-dev \
procps \
readline-dev \
ruby \
tar \
xz \
yaml-dev \
zlib-dev \
libffi-dev \
libstdc++ \
g++ \
musl-dev \
libstdc++ \
autoconf \
bison \
bzip2 \
bzip2-dev \
ca-certificates \
coreutils \
dpkg-dev dpkg \
gcc \
gdbm-dev \
glib-dev \
libc-dev \
libffi-dev \
libressl \
libressl-dev \
libxml2-dev \
libxslt-dev \
linux-headers \
make \
ncurses-dev \
procps \
readline-dev \
ruby \
tar \
xz \
yaml-dev \
zlib-dev \
libffi-dev \
\
&& wget -O ruby.tar.xz "https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR%-rc}/ruby-$RUBY_VERSION.tar.xz" \
&& echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum -c - \
\
&& mkdir -p /usr/src/ruby \
&& tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1 \
&& rm ruby.tar.xz \
\
&& cd /usr/src/ruby \
\
# hack in "ENABLE_PATH_CHECK" disabling to suppress:
# warning: Insecure world writable dir
&& { \
echo '#define ENABLE_PATH_CHECK 0'; \
echo; \
cat file.c; \
} > file.c.new \
&& mv file.c.new file.c \
\
&& autoconf \
&& gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \
# the configure script does not detect isnan/isinf as macros
&& export ac_cv_func_isnan=yes ac_cv_func_isinf=yes \
&& ./configure \
--build="$gnuArch" \
--disable-install-doc \
--enable-shared \
&& make -j "$(nproc)" \
&& make install \
\
&& runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)" \
&& apk add --no-network --virtual .ruby-rundeps $runDeps \
bzip2 \
ca-certificates \
libffi-dev \
procps \
yaml-dev \
zlib-dev \
&& gem update --system "$RUBYGEMS_VERSION" \
&& gem install bundler --version "$BUNDLER_VERSION" --force
# install gems & other sass / js compiling stuff.
ADD Gemfile /var/www/html/
RUN apk add nodejs && gem install libv8 -v '3.16.14.19' -- --with-system-v8 && gem install compass-rails therubyracer && bundle install
#clean ups
RUN apk del --no-network .ruby-builddeps \
&& cd / \
&& rm -r /usr/src/ruby \
\
&& rm -r /root/.gem/
@Adel-Magebinary do you also use therubyracer
gem by any chance? The above does indeed get me a working Ruby + libv8 image, but therubyracer install fails. :/
@rafaelmagu can you please paste the error here?
Seems the error has already been reported here, though the "solution" (switching to a different non-Alpine base image) isn't really a solution: https://github.com/docker-library/ruby/issues/113
I am experimenting with a few different settings to try and at least get the assets to compile now.
@rafaelmagu Can you please exec to /bin/bash in your docker and try to install it manually with gem. If it throws error and post it here?
@Adel-Magebinary the gem installation doesn't fail anymore. I have decided to dump therubyracer
altogether in favour of mini_racer
.
@rafaelmagu Interesting thing is you are from NZ too lol
libv8 is currently not tested on Alpine. A Vagrant box would help the libv8 maintainers in making sure it builds successfully.