Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ruby:slim! #30

Closed
tianon opened this issue Jan 15, 2015 · 21 comments · Fixed by #33
Closed

ruby:slim! #30

tianon opened this issue Jan 15, 2015 · 21 comments · Fixed by #33

Comments

@tianon
Copy link
Member

tianon commented Jan 15, 2015

No description provided.

@yosifkit
Copy link
Member

I have had it ready for months but nobody ever said it was good or bad, but I guess it was only linked in irc.
https://gist.github.com/yosifkit/a0b5ef92327acea743c5

FROM debian:jessie

RUN apt-get update \
    && apt-get install -y bzip2 curl libffi-dev libssl-dev procps zlib1g-dev \
    && rm -rf /var/lib/apt/lists/*

ENV RUBY_MAJOR 2.1
ENV RUBY_VERSION 2.1.2

# some of ruby's build scripts are written in ruby
# we purge this later to make sure our final image uses what we just built
RUN set -x; \
    apt-get update \
    && apt-get install -y autoconf bison gcc make ruby \
    && rm -rf /var/lib/apt/lists/* \
    && mkdir -p /usr/src/ruby \
    && curl -SL "http://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.bz2" \
        | tar -xjC /usr/src/ruby --strip-components=1 \
    && cd /usr/src/ruby \
    && autoconf \
    && ./configure --disable-install-doc \
    && make -j"$(nproc)" \
    && make install \
    && rm -r /usr/src/ruby \
    && apt-get purge -y --auto-remove autoconf bison gcc make ruby

# skip installing gem documentation
RUN echo 'gem: --no-rdoc --no-ri' >> /.gemrc

RUN gem install bundler

CMD [ "irb" ]

@tianon
Copy link
Member Author

tianon commented Jan 15, 2015

Ahhhh I knew we'd discussed it and thought it was created so I was going
crazy looking for it!

@tianon
Copy link
Member Author

tianon commented Jan 15, 2015

We should write a test first to make sure we at least have some basic
functionality that we don't regress on. :)

@yosifkit
Copy link
Member

I approve. 😄

@nickjj
Copy link

nickjj commented Jan 16, 2015

I looked at other tools that compile ruby and setup a list of what's in the current buildpack-deps vs what's needed to compile ruby vs what's needed to compile ruby + highly useful optional deps

Source:
https://github.com/sstephenson/ruby-build/wiki

Not needed to compile ruby
libbz2-dev
libcurl4-openssl-dev
libevent-dev
libmysqlclient-dev
libpq-dev
libsqlite3-dev
libssl-dev
libxml2-dev
libxslt-dev
Needed to compile ruby
autoconf
libffi-dev
libglib2.0-dev
libgdbm3
libgdbm-dev
libncurses-dev
libreadline-dev
libyaml-dev
zlib1g-dev 
Optional but very useful
libjpeg-dev
imagemagick
libmagickcore-dev
libmagickwand-dev

libbz2-dev # how often does this get used?
Database specific but you tend to only need 1

Not sure how to work this in a way that's reasonable?

libpq-dev
libmysqlclient-dev
libsqlite3-dev

@yosifkit, do you have a before/after image size with your Dockerfile vs the official buildpacks-deps version?

@tianon
Copy link
Member Author

tianon commented Jan 16, 2015

The whole point of the slim image would be that it's just ruby --
everything else is strictly BYO.

@nickjj
Copy link

nickjj commented Jan 16, 2015

Ok, I wasn't sure on the slim protocol. I'll test his snippet today with minor modifications and let you know how it goes.

I'm curious though, for things like bz2 wouldn't we need that in at compile time? It's not strictly needed but anyone who wants to create compressed files with ruby would need it in? Is this in BYO territory?

@yosifkit
Copy link
Member

I think we might be able to squeeze a bit more out using your list rather than mine, but I am not sure which could be removed and which are required at runtime.

ruby                2.2.0                1c5f62436eb8        2 weeks ago         829.7 MB
ruby                2.1.5                ec43d7fe280d        2 weeks ago         831.8 MB
ruby                2.1.4                766162a99b23        9 weeks ago         797.9 MB
ruby                2.1.2                227510c3fed6        4 months ago        890.4 MB

ruby                2.1-slim             e0b364f431a3        4 months ago        302.5 MB

@tianon
Copy link
Member Author

tianon commented Jan 16, 2015

This is good -- this is a perfect example of why we need to look at that
list of packages and come up with some short simple test scripts that use
those core modules to make sure they work properly.

(ala
https://github.com/infosiftr/stackbrew/tree/e08f902b1eafd30ed83d9b061f4aae704bb37607/test/tests/python-artifacts
)

@yosifkit
Copy link
Member

If I remember correctly the ones that I have that I don't remove were items that prevented me from even starting irb or possibly a bundle install. Which again is the case for tests to make sure the image just "works".

@nickjj
Copy link

nickjj commented Jan 16, 2015

That's a huge difference in size.

I'm not an expert but I think these might need to be in at compile time if you want to use them.

libbz2-dev
libssl-dev
libxml2-dev
libxslt-dev

@yosifkit would you be willing to do 1 more file size test that adds in these 4 libs (3 since you already use ssl). If it's very small it might be worth just adding them in to cover more users.

@yosifkit
Copy link
Member

No problem. I did two tests, one as you suggested with adding those in for the build and then a second build with those additions and a --no-install-recommends on both of the apt-get install lines. I still don't have any tests in place to tell you what works, but they build.

I used 2.1.2 since that is the version on the slim from the size before for a more accurate comparison.

ruby                2.1.2-slim           f0a837ca368f        5 seconds ago       305.2 MB

# no-install-recommends (adding in ca-certificates explicitly)
ruby                2.1.2-slim           18d405f9a425        32 seconds ago      294.3 MB

We may want to throw in some others like readline since it has to be added at compile time.

@nickjj
Copy link

nickjj commented Jan 16, 2015

Yes, if I remember correctly readline needs to be in there or you can't open a rails console. Size is looking very nice.

Do you think it's reasonable then to offload things such as imagemagik and database deps to the user's app Dockerfile? So they could for example pull in rails which would use this new slim ruby setup and then add in their app-specific deps?

I wonder if Ruby 2.2 will change anything. I also wonder which libs are causing it to spike from 300mb to 800mb+.

@yosifkit
Copy link
Member

You can still use the irb console, but you cannot use the arrow keys to move around in the line and other readline features.

It is appropriate to expect users to bring their own external deps like imagemagick and databases, since the point is to be as slim as possible while still making sure all of ruby core is there. If ruby needs to be recompiled to add it, then we should make sure it is there. If it just an external library that is invoked when needed, then I think we can leave it out (open to reasons for keeping specific external deps). We want slim versions to be for users that know what their doing.

@nickjj
Copy link

nickjj commented Jan 16, 2015

Should we try one more size test?

autoconf
libbz2-dev
libffi-dev
libglib2.0-dev
libgdbm3
libgdbm-dev
libncurses-dev
libreadline-dev
libssl-dev
libyaml-dev
libxml2-dev
libxslt-dev
zlib1g-dev

This is a bare bones list to compile ruby + the 4 "might need to be compiled" libs from before + yaml. This would seem like a decent base IMO if it all works.

@yosifkit
Copy link
Member

I assume we should keep libgdbm3 after compiling, but I am not sure which are just needed for build and which will be needed when running that module.

@nickjj
Copy link

nickjj commented Jan 16, 2015

Here's a small test that goes through ruby's stdlib and tries to require libraries. It might be ok to use for our test. Is it safe to assume if you can require a lib, it works?

stdlib = [
  'abbrev',
  'base64',
  'benchmark',
  'bigdecimal',
  'cgi',
  'cmath',
  'coverage',
  'csv',
  'date',
  'dbm',
  'delegate',
  'digest',
  'drb',
  'e2mmap',
  'erb',
  'etc',
  'expect',
  'fcntl',
  'fiddle',
  'fileutils',
  'find',
  'forwardable',
  'gdbm',
  'getoptlong',
  'io/console',
  'io/nonblock',
  'io/wait',
  'ipaddr',
  'irb',
  'json',
  'logger',
  'mathn',
  'matrix',
  'mkmf',
  'monitor',
  'mutex_m',
  'net/ftp',
  'net/http',
  'net/imap',
  'net/pop',
  'net/smtp',
  'net/telnet',
  'nkf',
  'objspace',
  'observer',
  'open-uri',
  'open3',
  'openssl',
  'optparse',
  'ostruct',
  'pathname',
  'pp',
  'prettyprint',
  'prime',
  'profile',
  'profiler',
  'pstore',
  'psych',
  'pty',
  'rake',
  'rdoc',
  'readline',
  'resolv',
  'resolv-replace',
  'ripper',
  'rss',
  'rubygems',
  'scanf',
  'sdbm',
  'securerandom',
  'set',
  'shell',
  'shellwords',
  'singleton',
  'socket',
  'stringio',
  'strscan',
  'sync',
  'syslog',
  'tempfile',
  'thread',
  'thwait',
  'time',
  'timeout',
  'tmpdir',
  'tracer',
  'tsort',
  'un',
  'uri',
  'weakref',
  'webrick',
  'xmlrpc',
  'yaml',
  'zlib'
]

stdlib.each do |lib|
  puts "Testing #{lib}"
  require lib
end

@mpapis
Copy link

mpapis commented Jan 16, 2015

@nickjj reject those that are ruby only

@yosifkit
Copy link
Member

I have a slim branch up that passes all of those stdlibs (the current "fat" ruby doesn't even do that yet).

https://github.com/infosiftr/ruby/blob/slim/2.1/slim/Dockerfile

@nickjj
Copy link

nickjj commented Jan 17, 2015

Awesome, you're removing a lot too after you build it. What's the size on it in the end?

@yosifkit
Copy link
Member

I'll go ahead and get slims for the other versions of ruby onto that branch and hopefully make a PR today.

ruby                2.1.5-slim           3e42c3a744b9        2 days ago          296.8 MB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants