Launch docker compose in development mode?

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!

1 Like

Perhaps you want to change these lines?

If you like to deploy in production mode and run an application using docker compose up locally in development mode you can change docker-compose.yml

...
web:
  build:
    context: .
    args:
      RAILS_ENV: development
    ...