The Dockerfile and Procfile: Defining the Image and Behavior of your Application

Overview

The Dockerfile and Procfile are the primary configuration elements used to tell EYK how to run your application. This article provides an overview of each file and the role it plays in defining your containers and your overall application. A full treatment of Dockerfiles is outside the scope of this article, however additional information can be found in the Docker documentation.


Solution

Let's look at the EYK Ruby Quiz sample application to see these files in action. Keep in mind the image defined by the Dockerfile in your project is used by all of the process types (defined in the Procfile) for your application. Thus, all the resources you need for all components and processes should be included here.

The Dockerfile

Each application differs in its requirements and thus will have different entries in its Dockerfile. The Dockerfile is Infrastructure-as-Code in that it enumerates commands that are executed to build your container image. The Ruby Quiz sample application is a basic Rails application but serves as a good example for the basic concepts. Its Dockerfile has the following basic requirements:

  • Install a specific version of Ruby: The FROM statement (line 1) uses a ruby:2.6.6 base image that already has this version installed. 
  • Install NodeJS: The RUN statement (line 2) uses the apt-get package manager to install NodeJS.

    InformationThe Ruby images and package manager for EYK are based on Debian GNU/Linux 10 (Buster). Consult the list of available software packages as needed. Note that some packages may be named differently than you are used to. For example, mysql-client is named default-mysql-client.

  • Install Ruby gems: The five executable lines are used to create an /app directory and install the Ruby application there. First, the Gemfile and corresponding lock file are copied to the /app directory so that the bundle install can be run. Following this, the rest of the Rails application files are copied to this directory using the COPY . /app statement.
  • Initialize the database: The two RUN bundle exec lines near the bottom are used to Rails database migration and load seed date.
  • Expose the web application through a named port. As long as routing is enabled for your application, EYK will automatically route traffic from your domain name to the exposed port in your Dockerfile.
  • The final command (CMD) here is not used for any practical purpose but it is needed as the last statement. Remember that the application processes, in this case, the actual Rails server, is started via an entry in the Procfile (discussed in the next section).

    InformationAn important distinction between basic Docker containers and EYK is that the executable command (process) to run is defined in the Procfile as opposed to the last line of the Dockerfile.

FROM ruby:2.6.6
RUN apt-get update -qq && apt-get install -y nodejs
RUN mkdir -p /app
WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN gem install bundler && bundle install --jobs 20 --retry 5

COPY . /app

RUN bundle exec rake db:migrate RAILS_ENV=development
RUN bundle exec rake db:seed

EXPOSE 3000

CMD ls

The Procfile

The sample Ruby Quiz application's Procfile has only a single entry that runs the Puma web server that hosts the Rails application.

web: bundle exec puma -C config/puma.rb

Each line in the Procfile represents a process type. Each process type will scale independently based on demand. Entries have the format

<process-type-name>: <executable-command>

Example Scenario with Multiple Process Types

Consider a scenario where you have your Rails web server and an asynchronous process that runs in the background. Your web application is an eCommerce app that accepts purchase orders and your background job implements the fulfillment of those orders. Your Procfile might look something like this:

web: bundle exec puma -C config/puma.rb
fulfillment: bundle exec rake background_fulfillment_task:execute

Both of these process types will use the same image created by the Dockerfile, however the number of container instances for each type will scale independently. For example, if the webserver handles more requests, it can scale up to 5 instances whereas the fulfillment job may only require 2 instances to meet its demand. You can configure the behavior of this in the scaling tab of your application in the EYK web console.


Related Articles

 

Comments

Article is closed for comments.