Rbenv → specifies a Ruby version
Ruby → loads some gems that are part of the base Ruby distribution (bundler, rubygems, irb, etc)
Rubygems →loads other gems (for the system or user) → GEM_HOME
and GEM_PATH
Bundler → loads other gems (for the current project) → BUNDLE_PATH
So basically Ruby ships with a bunch of gems, rubygems manages most of the gems you install, and bundler manages all of the gems for a specific project, and both rubygems and bundler ship with Ruby.
The initial release of Docker was done at PyCon in 2013, but I wonder how much Ruby and the various shades of gem catostrophe helped inspire Docker adoption?
If you're using Docker and thus only running a single set of gems
at a time, I think you should simplify the models as much as possible. For a ruby focused docker container, just skip rbenv
and similar tools, try to bypass the system gems as much as possible, and try to get bundler / rubygems to force everything into /gems.
You'll want to check what bundler and rubygems detect as the environment via:
bundler env
gems env
Basically, inside of your docker-compose.yml
and Dockerfile
and perhaps even your dip.yml
you want to set
HOME: /app
BUNDLE_PATH: /gems
GEM_HOME: /gems
GEM_PATH: /gems
PATH: /gems/ruby/<ruby-version>/bin:/gems/bin:/app/bin:$PATH
Also, I found my local docker
build environment to be far less annoying when I figured out how to run everything as my local user... Ultimately I need to move to actually using a text template system to process all of the required variables (it's pretty lame that the Docker people make permissions that match the developer impossible without your own wrappers) but if it bothers you enough you could always fork docker.
ARG UID=<your id -u>
ARG GID=<your id -g>
ARG APPUSER=appuser
RUN set -x \
&& addgroup --system --gid $GID $APPUSER || true \
&& adduser --system --disabled-login --ingroup $APPUSER --no-create-home --home /app --gecos "$APPUSER" --shell /bin/false --uid $UID $APPUSER || true
USER $APPUSER
# Why on earth does Docker's COPY always copy as root instead of the USER: you set? Only the Docker people know...
COPY --chown=$APPUSER: Gemfile* /app/
Then in your dip.yml
makle sure to add run_option
s for your user...
interaction:
shell:
description: Open the Bash Shell in Container
service: web
command: bash
compose:
run_options: ["no-deps", "user=<your id -u>"]