Dockerfile-hanami?

My name is Sam Ruby. I work for fly.io and maintain a gem named dockerfile-rails.

I’d like to explore if there would be any interest in a dockerfile-hanami gem built on the same codebase. The basic idea would be to have a single command that can be run to build a Dockerfile and optionally a docker-compose.yml file. This gem would have no dependencies on Rails, but likely on things like Thor to parse command line arguments and to process templates. My current codebase may have incidental dependencies on active_support, and when we get there we can jointly decide if that’s OK or if that should be worked around.

The Dockerfiles produced would enable the application to be deployed pretty much anywhere, or even run on your own machine.

From a purely packaging point of view, all Rack/Postgres/Redis applications are essentially the same, the key difference being in the spelling of the command to launch the server, and how things like migrations are handled.

What I’m looking for is people with experience in the Hanami ecosystem to know what gems are common and what special configurations are worth looking for.

I’m open to whatever mode of cooperation works best - gathering requirements here, merging in pull requests, or even adding collaborators who are interested in helping maintaining this.

1 Like

Hey Sam, this sounds great! I’m happy to help you with this :slightly_smiling_face:

2 Likes

Sweet!

The thing that I would find most helpful is if somebody familiar with the hanami ecosystem could define a few concrete scenarios. If you look at dockerfile-rails/DEMO.md at main · rubys/dockerfile-rails · GitHub you will find a number of scripts that you can copy/paste to your OSX/Linux/WSL2 terminal to launch a demo. The equivalent to the first demo is fairly obvious. Perhaps the next one to focus on would be the third. Feel free to replace ActionCable with AnyCable. ActiveRecord with rom-rb. It looks like a SVG can be found here: Hanami Vector SVG Icon - SVG Repo. Writing down an equivalent scenario that I can run on my machine (ignoring the last few lines that set up and run the Dockerfile) would give me something to go on.

Then go from there to define other scenarios that are representative of hanami usage. Don’t worry about matching other scenarios on that page unless there is some significant difference as you will get the remaining scenarios for free (and conversely, Rails will get AnyCable and rom-rb for free - isn’t synergy wonderful?)

Once such scenario(s) is/are ready, the rest should fall in place quickly.

@rubys Thanks for getting in touch. We want this to happen!

@solnic Here are some inputs for you:


Folks, please let me know if you’ll need my input. Cheers!

I’m going to start in parallel on a minimal hanami application. My first question: with Rails it is possible to add a generator simply by subclassing:

class DockerfileGenerator < Rails::Generators::Base

Is something like this possible with Hanami?

Edit: unless I hear otherwise, I’m going to see if I can use this as an example: GitHub - davydovanton/hanami-operation-generator: Simple library for generating operations for hanami-dry-system project

Yeah, the equivalent in Hanami is to subclass App::Command. Example:

module Docker
  class Demo < App::Command
    desc "A demonstration command"

    def call(**)
      # Implementation details go here.
    end
  end
end

Here are a few additional references to get you bootstrapped:

  • Dry CLI: This is where you can read up on how all of this works.
  • Hanami CLI: Sits atop Dry CLI. Within this repository, you might want to check out the commands and generators for further examples.
  • Hemo: This is my Hanami demonstration project built with HTMX so you can use this as a source as well. This extension of the Hanami CLI might be of interest as well.
1 Like

Possibly dumb question, does hanami load plugins anymore?

I found this code commit 625a709746122b5549255abd2cd3aef14133608d but that executable has moved to cli and no longer appears to load plugins.

In any case, I have the following in my Gemfile and my plugin is not being loaded when I run 'bundle exec hanami generate`:

group :plugins do
  gem 'dockerfile-hanami', path: '/Users/rubys/git/dockerfile-hanami'
end

No question is ever a dumb question. :wink:

I don’t know the direct answer to this but, in searching through both the CLI and Hanami core projects, I couldn’t find any reference to bundler_groups which is the method that defines [:plugins]. Someone in the community with more knowledge might need to chime in.

This may or may not help, but here’s how I use a special tools group through my Hemo application:

Anyway, may or may not help you until someone else can chime in.

Things noticed along the way: Avoiding links as they seem to trigger spam filters.

  • If you go to github hanami/hanami and click on the API docs, you get “The page isn’t redirecting properly”
  • If you go to hanamirb.org and click on docs, you get 1.3.3
  • If you search for “register” in the 1.3.3 docs, you find an example that does not work:
    • you need to require “hanami/cli/command” (no trailing s)
    • you need to also require “hanami/cli”

I still haven’t tested the final line in that example as I have yet to get plugins to work.

Is there an example docker file? We’re thinking of deploying our app to fly.

Hi,

I hope it’s fine to reply here and it’s not too off the main topic.

FWIW here is the link to my unrelated SO question, but you’ll see how I’ve setup two compose files for production and staging: How to run two or more Docker environments with nginx and ssl enabled - Stack Overflow. Variables come from different .env files.

Every environment (production, staging and so on) boots 3 containers: DB, nginx and web app.

I have most of the stuff in compose files, so the Docker file is short:

    FROM ruby:2.7.5-bullseye
    RUN apt-get update && apt-get install vim -y
    RUN bundle config --global frozen 1
    RUN adduser --disabled-login app_owner
    USER app_user
    WORKDIR /usr/src/app
    COPY --chown=app_user Gemfile Gemfile.lock ./
    COPY --chown=app_user . ./
    RUN gem install bundler:1.17.3
    RUN bundle install
    ENV HANAMI_HOST=0.0.0.0
    ENV HANAMI_ENV=production
    EXPOSE 2300

I also have a Makefile to streamline deployment for all environments and clients. Here is a sample of the Makefile for the staging:

# Staging for deploy environment
stage-f:
	docker-compose -f docker-compose-staging.yml --env-file .env.staging up
stage:
	docker-compose -f docker-compose-staging.yml --env-file .env.staging up -d
stage-b:
	docker-compose -f docker-compose-staging.yml --env-file .env.staging up --build -d
stage-bf:
	docker-compose -f docker-compose-staging.yml --env-file .env.staging up --build
stage-down:
	docker-compose -f docker-compose-staging.yml --env-file .env.staging down
stage-down-v:
	docker-compose -f docker-compose-staging.yml --env-file .env.staging down --volumes
stage-stop:
	docker-compose -f docker-compose-staging.yml --env-file .env.staging stop

See also here: https://codereviewvideos.com/course/docker-tutorial-for-beginners/video/docker-compose-multiple-environments

I control now everything with a Makefile and it really pays off. The problem in the question above is most likely linked to my poor knowledge of port mapping. Hopefully, I’ll resolve it soon.

I hope this helps.

Best, Seba

Hi, @rubys

I have a similar gem GitHub - elct9620/boxing: The zero-configuration Dockerfile generator for Ruby. that can generate Dockerfile, too.

According to the discussion, I think we both depend on Thor’s template feature to generate it.

I have an idea is use Rake to replace Thor and use ERB directly to generate the Dockerfile. The Rails and Hanami both support the rake and we can easily extend them to have the same command.

1 Like