I am trying to deploy a Hanami app (a ruby framework–process should be similar to Sinatra), but I’m having trouble executing db setup tasks to create and migrate the database.
DATABASE_URL
was setup with fly launch
. I have not changed it, but I notice that the URL does not include a database name, just user, password, and host connection.
My dockerfile, below, was created by fly launch
and I added some items. fly.toml
is untouched.
ARG RUBY_VERSION=3.2.2
FROM ruby:$RUBY_VERSION-slim as base
# Rack app lives here
WORKDIR /app
# Set production environment
ENV HANAMI_ENV="production" \
HANAMI_PORT=8080 \
BUNDLE_WITHOUT="development:test" \
BUNDLE_DEPLOYMENT="1"
# Update gems and bundler
RUN gem update --system --no-document && \
gem install -N bundler
# Throw-away build stage to reduce size of final image
FROM base as build
# Install packages needed to build gems
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential libpq-dev
# Install application gems
COPY Gemfile* .
RUN bundle install
# Final stage for app image
FROM base
# Run and own the application files as a non-root user for security
RUN useradd ruby --home /app --shell /bin/bash
USER ruby:ruby
# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=ruby:ruby /app /app
# Copy application code
COPY --chown=ruby:ruby . .
# Entrypoint prepares the database
ENTRYPOINT ["./bin/fly-entrypoint"]
# Start the server
EXPOSE 8080
CMD ["bundle", "exec", "rackup", "--host", "0.0.0.0", "--port", "8080"]
I added libpq-dev
to the apt-get install
command on line 22. I also added the ENV block and the Entrypoint block to run my script. If all goes well, the script should execute db commands and then execute the CMD from the dockerfile.
My entrypoint script looks like this:
#!/usr/bin/env bash
# exit on error
set -o errexit
# Uncomment for first deploy
bundle exec bin/hanami db create
# Uncomment after first deploy
# bundle exec bin/hanami db migrate
# Execute the container's main process (CMD in the dockerfile)
exec "$@"
I have been trying to execute the create
command to get the database set up. Once setup, I would like to always run the migrate
command on each deploy.
These are the relevant log entries. All seems well until this point.:
[info] INFO Preparing to run: `./bin/entrypoint bundle exec rackup --host 0.0.0.0 --port 8080` as ruby
[info] 2023/10/03 19:39:03 listening on [fdaa:2:96dd:a7b:d828:3375:22ab:2]:22 (DNS: [fdaa::3]:53)
[info] sh: 1: psql: not found
[info] => failed to create database <app-name>_app
[info] INFO Main child exited normally with code: 127
[info] INFO Starting clean up.
[info] WARN hallpass exited, pid: 304, status: signal: 15 (SIGTERM)
[info] 2023/10/03 19:39:05 listening on [fdaa:2:96dd:a7b:d828:3375:22ab:2]:22 (DNS: [fdaa::3]:53)
[info] [ 3.287869] reboot: Restarting system
It seems to call the entrypoint script correctly, and then fails on the third line, sh: 1: psql: not found
.
The database cluster exists and I can connect to it with fly postgres connect
. Fly created a default <app-name>_app
database, but Hanami expects to create a database named <app-name>_production
. Therefore, line four confuses me: => failed to create database <app-name>_app
. The create
command should not use this database name (as far as I know).
Just for completeness, if I try to use migrate
, the Hanami app itself crashes (presumably due to the missing database).
How should I proceed? I don’t know how to troubleshoot this further. Is it possible that psql
(which must be used by the bin/hanami
commands) is no longer available in this stage of the dockerfile build? If so, how do I fix that?
Any help is appreciated!