-
-
Save ebababi/444363241eb934ea5fda64898190a205 to your computer and use it in GitHub Desktop.
# Ruby on Rails Deployment Image | |
# | |
# Builds a ready to be deployed image of a Ruby on Rails application. | |
# https://ebababi.net/dockerfile-for-ruby-on-rails-deployments.html | |
# Copyright (C) 2019 Nikolaos Anastopoulos, Inc. All rights reserved. | |
# | |
# Redistribution and use in source and binary forms, with or without | |
# modification, are permitted provided that the following conditions | |
# are met: | |
# 1. Redistributions of source code must retain the above copyright | |
# notice, this list of conditions and the following disclaimer. | |
# 2. Redistributions in binary form must reproduce the above copyright | |
# notice, this list of conditions and the following disclaimer in the | |
# documentation and/or other materials provided with the distribution. | |
# | |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
# SUCH DAMAGE. | |
FROM ruby:2.4.5 | |
# Install Ruby on Rails dependencies. | |
# https://guides.rubyonrails.org/development_dependencies_install.html#ubuntu | |
RUN apt-get update \ | |
&& apt-get install -y --no-install-recommends \ | |
apt-transport-https \ | |
software-properties-common \ | |
&& apt-key adv --keyserver "hkp://ipv4.pool.sks-keyservers.net" \ | |
--recv-key "9FD3B784BC1C6FC31A8A0A1C1655A0AB68576280" \ | |
&& add-apt-repository "deb https://deb.nodesource.com/node_10.x stretch main" \ | |
&& apt-key adv --keyserver "hkp://ipv4.pool.sks-keyservers.net" \ | |
--recv-key "72ECF46A56B4AD39C907BBB71646B01B86E50310" \ | |
&& add-apt-repository "deb https://dl.yarnpkg.com/debian/ stable main" \ | |
&& apt-get update \ | |
&& apt-get install -y --no-install-recommends \ | |
nodejs \ | |
yarn \ | |
sqlite3 \ | |
libsqlite3-dev \ | |
mysql-client \ | |
default-libmysqlclient-dev \ | |
postgresql-client \ | |
libpq-dev \ | |
imagemagick \ | |
ffmpeg \ | |
poppler-utils \ | |
&& rm -rf /var/lib/apt/lists/* | |
# Use the recommended working path. | |
WORKDIR /usr/src/app | |
# Set environment variables indicating a production build. | |
ENV RACK_ENV production | |
ENV RAILS_ENV production | |
ENV NODE_ENV production | |
# Install Ruby dependencies. | |
COPY Gemfile* ./ | |
RUN bundle install --without development:test --frozen --no-cache | |
# Install JavaScript dependencies. | |
COPY package.json yarn.lock ./ | |
RUN yarn install --frozen-lockfile --no-cache --production \ | |
&& yarn cache clean | |
# Copy application code to the working path. | |
COPY . ./ | |
# Set Rails environment variables appropriate to a Docker image. | |
ENV RAILS_LOG_TO_STDOUT enabled | |
ENV RAILS_SERVE_STATIC_FILES enabled | |
ENV REDIS_PROVIDER REDIS_URL | |
# Set default values to required Rails environment variables. | |
ARG SECRET_KEY_BASE=deca1fc2f5da822a699fffb01fffbf97bb736e9ec3720637 | |
ARG DATABASE_URL=sqlite3::memory: | |
# Prepare for Rails asset pipeline. | |
RUN bin/rake assets:precompile \ | |
&& bin/rake assets:clean | |
ENV PORT 3000 | |
EXPOSE $PORT | |
CMD ["bin/rails", "server", "--binding=0.0.0.0"] |
I usually keep the database as a separate docker, since we use Postgres and not SQLite.
You're right, @kp666, that's a good practice. The proposed Dockerfile does not imply a way to setup database connections. Either config/database.yml
, or DATABASE_URL
, or any other way can be used to do so. As a note though, someone might be confused with the DATABASE_URL
set to sqlite3::memory:
during build time. This is done because bin/rake assets:precompile
requires a database connection present, although it is not using it and that "hack" allows for the image to build on systems without access to the database.
Also, I mount the master.key from a volume.
Yeap, that's important. In addition, keys files must be included in .dockerignore
...
As a note though, someone might be confused with the
DATABASE_URL
set tosqlite3::memory:
during build time. This is done becausebin/rake assets:precompile
requires a database connection present, although it is not using it and that "hack" allows for the image to build on systems without access to the database.
This is something I didn't know, that's a neat hack :)
What I was mentioning about the database been in a separate docker is that then I wouldn't have to install any of the databases on this docker image. But then my deployment is also different from your's as assets are precompiled at the CI for me.
I usually keep the database as a separate docker, since we use Postgres and not SQLite.
Also, I mount the master.key from a volume.