I’m deploying a Rails API server on Fly.io with a database hosted on PlanetScale. After running “fly deploy,” the deployment succeeds, but the server enters a suspended state. The logs indicate a potential issue related to ActiveRecord and SSL:
nrt [info] ActiveRecord::ConnectionNotEstablished (TLS/SSL error: No such file or directory (2)):
Accessing the application yields this error:
To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:
config.hosts << "<app-name>.fly.dev"
I’ve configured SSL for PlanetScale and set the allowed hosts in production.rb. I’m seeking insights on resolving the ActiveRecord SSL connection issue.
Relevant configurations:
production.rb: includes config.hosts << "<app-name>.fly.dev"
Dockerfile: includes installation of openssl and ca-certificates
database.yml: configures ssl_mode and sslca for production
Any advice on troubleshooting this would be greatly appreciated.
config/environments/production.rb
Rails.application.configure do
config.hosts << "<app-name>.fly.dev"
end
Dockerfile
FROM ruby:3.2.2
ENV APP_ROOT /app
RUN apt-get update -qq && apt-get install -y build-essential default-mysql-client vim openssl ca-certificates
WORKDIR ${APP_ROOT}
COPY Gemfile Gemfile.lock ${APP_ROOT}
RUN bundle install
COPY . ${APP_ROOT}
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Rails defaults to development mode unless RAILS_ENV=production is set. Installing ca-certificates creates /etc/ssl/certs/ca-certificates.crt not /etc/ssl/cert.pem.
If you want to switch to production mode (highly recommended), you are going to need quite a few changes to your Dockerfile. Running bin/rails generate dockerfile will produce a much better starting point, and one that will produce a significantly smaller image size. I suspect that you will also need to update your database.yml to extract credentials.
If you wisth to remain in development mode you need to adjust the sslca line in the development section, but after doing so you may not be able to run the result on your development machine.
I have merged a Dockerfile generated by running bin/rails generate dockerfile with my existing one. Here’s the integrated Dockerfile:
Dockerfile
# syntax = docker/dockerfile:1
ARG RUBY_VERSION=3.2.2
FROM ruby:$RUBY_VERSION-slim as base
LABEL fly_launch_runtime="rails"
WORKDIR /app
ENV BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development:test" \
RAILS_ENV="production" \
TZ=Asia/Tokyo
RUN gem update --system --no-document && \
gem install -N bundler
FROM base as build
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential default-libmysqlclient-dev nodejs npm vim openssl ca-certificates
COPY --link Gemfile Gemfile.lock ./
RUN bundle install && \
bundle exec bootsnap precompile --gemfile && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git
COPY --link . .
RUN bundle exec bootsnap precompile app/ lib/
FROM base
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl default-mysql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /app /app
RUN groupadd --system --gid 1000 rails && \
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
chown -R 1000:1000 db log storage tmp
USER 1000:1000
ENTRYPOINT ["/app/bin/docker-entrypoint"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
The deployment succeeded, but the server keeps going into a suspended state. Here are the error logs I received:
nrt [error] instance refused connection. is your app listening on 0.0.0.0:3000? make sure it is not only listening on 127.0.0.1 (hint: look at your startup logs, servers often print the address they are listening on)
nrt [error] failed to change machine state: machine still active, refusing to start
When I start the Docker container in my local environment, I get the following log, which suggests that the port configuration is correct:
* Listening on http://0.0.0.0:3000
Could you please advise on what might be causing this issue?
Without seeing your logs, I would only be guessing. But knowing that the Dockerfile works locally, most common problems would be: not enough memory or database setup problems. Two links: