<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Slava Pocheptsov</title>
    <description>The latest articles on DEV Community by Slava Pocheptsov (@pocheptsov).</description>
    <link>https://dev.to/pocheptsov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F215649%2F8223bed0-0c8a-426f-958c-20c2bea4d594.png</url>
      <title>DEV Community: Slava Pocheptsov</title>
      <link>https://dev.to/pocheptsov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pocheptsov"/>
    <language>en</language>
    <item>
      <title>Bootstrap Ruby project in Docker</title>
      <dc:creator>Slava Pocheptsov</dc:creator>
      <pubDate>Tue, 25 Oct 2022 13:00:00 +0000</pubDate>
      <link>https://dev.to/pocheptsov/bootstrap-ruby-project-in-docker-c9f</link>
      <guid>https://dev.to/pocheptsov/bootstrap-ruby-project-in-docker-c9f</guid>
      <description>&lt;p&gt;In the Ruby community, we have a lot of tools to help us to create a new project. But, if you are a beginner, you can be lost in the middle of all these tools. This code is a simple way to start a new project in Ruby using &lt;code&gt;Docker&lt;/code&gt; without &lt;code&gt;Rails&lt;/code&gt;, &lt;code&gt;dip&lt;/code&gt; or any other framework dependencies.&lt;br&gt;
Great examples to start a new project in Ruby:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://evilmartians.com/chronicles/ruby-on-whales-docker-for-ruby-rails-development"&gt;Ruby on Whales&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://semaphoreci.com/community/tutorials/dockerizing-a-ruby-on-rails-application"&gt;Dockerizing a Ruby on Rails Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.akshaykhot.com/setting-up-development-environment-for-rails/"&gt;Setting Up Development Environment for Rails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Development environment
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;p&gt;Installed Docker with BuildKit support and docker-compose are required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/install/"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/compose/install/"&gt;Docker Compose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Docker setup
&lt;/h3&gt;

&lt;p&gt;This article will use Docker Compose to run the Ruby code. Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application's services. Then, you create and start all the services from the configuration with a single command.&lt;/p&gt;

&lt;p&gt;Let's build the image with the following &lt;code&gt;docker/Dockerfile&lt;/code&gt; where we can pass the &lt;code&gt;RUBY_VERSION&lt;/code&gt;, &lt;code&gt;DEBIAN_CODENAME&lt;/code&gt; as build arguments. The &lt;code&gt;UID&lt;/code&gt; and &lt;code&gt;GID&lt;/code&gt; are the neat parameters to configure file permissions for container volume that will be set in &lt;code&gt;docker/docker-compose&lt;/code&gt;. Another important thing is that we are using a non-root user (&lt;code&gt;UID:GID -&amp;gt; app_user:app_group&lt;/code&gt;) to run the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ARG RUBY_VERSION=3.1.2
ARG DEBIAN_CODENAME=bullseye
FROM ruby:$RUBY_VERSION-$DEBIAN_CODENAME

ENV APP_DIR=/app
ARG UID=1000
ARG GID=1000

RUN groupadd --gid $GID app_group \
  &amp;amp;&amp;amp; useradd --no-log-init --uid $UID --gid $GID app_user --create-home \
  \
  &amp;amp;&amp;amp; mkdir -p $APP_DIR \
  &amp;amp;&amp;amp; chown -R $UID:$GID $APP_DIR \
  \
  &amp;amp;&amp;amp; gem update bundler \
  &amp;amp;&amp;amp; chown -R $UID:$GID /usr/local/bundle \
  &amp;amp;&amp;amp; bundler --version

# copy files required for `bundle install` step
COPY --chown=$UID:$GID Gemfile* $APP_DIR/

# entry point setup
COPY --chmod=755 docker/entrypoint.sh /usr/bin/

# switching to app user
USER $UID:$GID
WORKDIR $APP_DIR

RUN echo "!!!!! Install gems !!!!!" \
  &amp;amp;&amp;amp; bundle install -j "$(($(nproc)+1))"

ENTRYPOINT ["entrypoint.sh"]

CMD /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker entrypoint script &lt;code&gt;docker/entrypoint.sh&lt;/code&gt; can be used to run commands as a non-root user on container start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash -e

export PATH="$PATH:/app"

bundle check || bundle install -j "$(($(nproc) + 1))"

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this article, we have a simple Docker environment with Ruby-only &lt;code&gt;app&lt;/code&gt; service. The &lt;code&gt;docker-compose.yml&lt;/code&gt; file is responsible for creating the containers and the &lt;code&gt;docker/Dockerfile&lt;/code&gt; is accountable for creating the image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3'
services:
  app:
    build:
      context: .
      dockerfile: docker/Dockerfile
      args:
        RUBY_VERSION: 3.1.2
        DEBIAN_CODENAME: bullseye
        UID: 1000
        GID: 1000
    environment:
      RAILS_ENV: development
    volumes:
      - .:/app:delegated
      - bundle:/usr/local/bundle
    stdin_open: true
    tty: true
volumes:
  bundle:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Gemfile&lt;/code&gt; is copied to the container and installed gems. The &lt;code&gt;bundle&lt;/code&gt; volume is used to cache the gems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# frozen_string_literal: true

source "https://rubygems.org"

gem "byebug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a final file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree .
.
├── Gemfile
├── docker
│   ├── Dockerfile
│   └── entrypoint.sh
└── docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run app container in other OS versions, different user/group ids, build composed containers with &lt;code&gt;docker-compose build --build-arg RUBY_VERSION="3.0.4" --build-arg DEBIAN_CODENAME="buster" --build-arg UID="1001" --build-arg GID="1001"&lt;/code&gt;, re-build it &lt;code&gt;docker-compose build --no-cache&lt;/code&gt;. All the build arguments are optional.&lt;/p&gt;

&lt;p&gt;The development environment can be started with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose run app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then run any ruby commands.&lt;/p&gt;

&lt;p&gt;The complete repository source code is available on &lt;a href="https://github.com/pocheptsov/pocheptsov.github.io/tree/master/source/2022/docker-rails-bootstrap"&gt;docker-rails-bootstrap&lt;/a&gt;. Feel free to use it as a template for your projects. If you have any questions, feel free to ask them in the comments or reach out to me at &lt;a href="https://twitter.com/pocheptsov"&gt;@pocheptsov&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;In the following article, we will add &lt;code&gt;Rails&lt;/code&gt; app to the project and compare &lt;a href="https://railsbytes.com/public/templates/z5OsoB"&gt;full-size solution&lt;/a&gt; with our skeleton bootstrap.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>docker</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
