I’m trying fly.io capabilities for the first time using a small, placeholder Rails 7 app. Deployment is working fine, but I noted that the Dockerfile created by fly.io that replaced my old one is making docker-compose to mount the server in production mode (even if supplied with an environment flag -e development).
Here’s my Dockerfile (exactly the same as the generated by fly launch)
# syntax = docker/dockerfile:experimental
# Dockerfile used to build a deployable image for a Rails application.
# Adjust as required.
#
# Common adjustments you may need to make over time:
# * Modify version numbers for Ruby, Bundler, and other products.
# * Add library packages needed at build time for your gems, node modules.
# * Add deployment packages needed by your application
# * Add (often fake) secrets needed to compile your assets
#######################################################################
# Learn more about the chosen Ruby stack, Fullstaq Ruby, here:
# https://github.com/evilmartians/fullstaq-ruby-docker.
#
# We recommend using the highest patch level for better security and
# performance.
ARG RUBY_VERSION=3.2.0
ARG VARIANT=jemalloc-slim
FROM quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-${VARIANT} as base
LABEL fly_launch_runtime="rails"
ARG BUNDLER_VERSION=2.4.1
ARG RAILS_ENV=production
ENV RAILS_ENV=${RAILS_ENV}
ENV RAILS_SERVE_STATIC_FILES true
ENV RAILS_LOG_TO_STDOUT true
ARG BUNDLE_WITHOUT=development:test
ARG BUNDLE_PATH=vendor/bundle
ENV BUNDLE_PATH ${BUNDLE_PATH}
ENV BUNDLE_WITHOUT ${BUNDLE_WITHOUT}
RUN mkdir /app
WORKDIR /app
RUN mkdir -p tmp/pids
RUN gem update --system --no-document && \
gem install -N bundler -v ${BUNDLER_VERSION}
#######################################################################
# install packages only needed at build time
FROM base as build_deps
ARG BUILD_PACKAGES="git build-essential libpq-dev wget vim curl gzip xz-utils libsqlite3-dev"
ENV BUILD_PACKAGES ${BUILD_PACKAGES}
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y ${BUILD_PACKAGES} \
&& rm -rf /var/lib/apt/lists /var/cache/apt/archives
#######################################################################
# install gems
FROM build_deps as gems
COPY Gemfile* ./
RUN bundle install && rm -rf vendor/bundle/ruby/*/cache
#######################################################################
# install deployment packages
FROM base
ARG DEPLOY_PACKAGES="postgresql-client file vim curl gzip libsqlite3-0"
ENV DEPLOY_PACKAGES=${DEPLOY_PACKAGES}
RUN --mount=type=cache,id=prod-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=prod-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y \
${DEPLOY_PACKAGES} \
&& rm -rf /var/lib/apt/lists /var/cache/apt/archives
# copy installed gems
COPY --from=gems /app /app
COPY --from=gems /usr/lib/fullstaq-ruby/versions /usr/lib/fullstaq-ruby/versions
COPY --from=gems /usr/local/bundle /usr/local/bundle
#######################################################################
# Deploy your application
COPY . .
# Adjust binstubs to run on Linux and set current working directory
RUN chmod +x /app/bin/* && \
sed -i 's/ruby.exe\r*/ruby/' /app/bin/* && \
sed -i 's/ruby\r*/ruby/' /app/bin/* && \
sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)' /app/bin/*
# The following enable assets to precompile on the build server. Adjust
# as necessary. If no combination works for you, see:
# https://fly.io/docs/rails/getting-started/existing/#access-to-environment-variables-at-build-time
ENV SECRET_KEY_BASE 1
# ENV AWS_ACCESS_KEY_ID=1
# ENV AWS_SECRET_ACCESS_KEY=1
# Run build task defined in lib/tasks/fly.rake
ARG BUILD_COMMAND="bin/rails fly:build"
RUN ${BUILD_COMMAND}
# Default server start instructions. Generally Overridden by fly.toml.
ENV PORT 8080
ARG SERVER_COMMAND="bin/rails fly:server"
ENV SERVER_COMMAND ${SERVER_COMMAND}
CMD ${SERVER_COMMAND}
The docker-compose.yml:
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0' -e development"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
and the output:
c9-03-web-1 | => Booting Puma
c9-03-web-1 | => Rails 7.0.4.2 application starting in production
c9-03-web-1 | => Run `bin/rails server --help` for more startup options
c9-03-web-1 | [1] Puma starting in cluster mode...
c9-03-web-1 | [1] * Puma version: 5.6.5 (ruby 3.2.0-p0) ("Birdie's Version")
c9-03-web-1 | [1] * Min threads: 5
c9-03-web-1 | [1] * Max threads: 5
c9-03-web-1 | [1] * Environment: development
c9-03-web-1 | [1] * Master PID: 1
c9-03-web-1 | [1] * Workers: 2
c9-03-web-1 | [1] * Restarts: (✔) hot (✖) phased
c9-03-web-1 | [1] * Preloading application
c9-03-web-1 | [1] * Listening on http://0.0.0.0:3000
c9-03-web-1 | [1] Use Ctrl-C to stop
c9-03-web-1 | [1] - Worker 0 (PID: 10) booted in 0.0s, phase: 0
c9-03-web-1 | [1] - Worker 1 (PID: 12) booted in 0.0s, phase: 0
I don’t have any significant experience with Docker tbh, so even if this problem is not that confusing, I figured that asking people wouldn’t hurt. Basically, I want that when I run docker compose up
I get as output => Rails 7.0.4.2 application starting in development
instead of => Rails 7.0.4.2 application starting in production
, but that it will still use production mode when deployed to fly
Thanks!