Report this

What is the reason for this report?

How do I get Ruby with Hanami to serve dynamic files via Falcon?

Posted on January 25, 2026

I have been trying to get Ruby 4.0.1 to run with Hanami 2.3, but I am running into issues. I am using a Ubuntu 24.04 server. It is working with Nginx and Hanami static pages, but when it comes to running dynamic hanami via routes and index.html.erb files it fails to function. The guides on hanami with falcon are kind of out of date. I am looking for a way to get ruby and hanami to read falcon correctly but I keep getting Gateway 502 errors.

I commented out the problematic @proxy settings as these were resulting in 502 error messages when viewed at https://dev.duelingpets.net. For some reason it doesn’t recognize the 3000 or 9292 ports when they are configured in the falcon.rb file. I am using ssl certificates on my web server. When I run falcon I get a message about boot not showing up.

I don’t know why it is not working as I do have a generated index file that should work, but it does not. I have added the route table and the homepage view page. Maybe you will see something that I am missing. I am quite new to this language as I have not used hanami before. I am using hanami as it is better on performance and the same goes with falcon. I am also using postgres sql for my database server. The information is below.

Here is the nginx sites-available configuration file setting which works with the static public folder index page but not the dynamic falcon index.html.erb file put in routes. upstream hanami_app { server 127.0.0.1:3000; }

#Main Duelingpets folder server { root /var/www/duelingpets/public;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;
server_name duelingpets.net www.duelingpets.net dev.duelingpets.net; # managed by Certbot


    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            #try_files $uri $uri/ =404;
            #try_files $uri @proxy;
    }

    location @proxy {
        #include proxy_params;
        #proxy_pass https://localhost:9292;
        #proxy_pass http://hanami_app;
        #proxy_set_header Host $host;
        #proxy_set_header X-Real-IP $remote_addr;
        #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #proxy_set_header X-Forwarded-Proto $scheme;

        # Required for Falcon/Puma HTTP handling
        #proxy_http_version 1.1;
        #proxy_set_header Connection "";
    }

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/duelingpets.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/duelingpets.net/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

} server { if ($host = dev.duelingpets.net) { return 301 https://$host$request_uri; } # managed by Certbot

if ($host = www.duelingpets.net) {
    return 301 https://$host$request_uri;
} # managed by Certbot

if ($host = duelingpets.net) {
    return 301 https://$host$request_uri;
} # managed by Certbot

    listen 80 ;
    listen [::]:80 ;
server_name duelingpets.net www.duelingpets.net dev.duelingpets.net;
return 404; # managed by Certbot

}

This is the falcon.rb file #!/usr/bin/env -S falcon-host

frozen_string_literal: true

require “falcon/environment/rack”

hostname = File.basename(dir)

service hostname do include Falcon::Environment::Rack

Default to port 3000 unless otherwise specified.

port {ENV.fetch(“PORT”, 3000).to_i}

Default to HTTP/1.1

endpoint do Async::HTTP::Endpoint.parse( “http://127.0.0.1:#{port}” ) end end

Root set up for generated route duelingpets@DuelingpetsWS1b:/var/www/duelingpets/config$ cat routes.rb

frozen_string_literal: true

module Duelingpets class Routes < Hanami::Routes # Add your routes here. See https://guides.hanamirb.org/routing/overview/ for details. root to: “home.index” end end

duelingpets@DuelingpetsWS1b:/var/www/duelingpets/app/views/home$ cat index.rb

frozen_string_literal: true

App views file module Duelingpets module Views module Home class Index < Duelingpets::View end end end end

Not sure what these errors mean. duelingpets@DuelingpetsWS1b:/var/www/duelingpets/config$ falcon serve 0.0s info: Falcon::Command::Serve [oid=0x3e0] [ec=0x3e8] [pid=4087] [2026-01-24 23:13:04 +0000] | Falcon v0.53.1 taking flight! Using Async::Container::Forked {count: 1, restart: true, health_check_timeout: 30.0}. | - Running on ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux] | - Binding to: #<Falcon::Endpoint https://localhost:9292/ {}> | - To terminate: Ctrl-C or kill 4087 | - To reload configuration: kill -HUP 4087 0.21s info: Async::Container::Notify::Console [oid=0x548] [ec=0x3e8] [pid=4087] [2026-01-24 23:13:04 +0000] | {status: “Initializing controller…”} /home/duelingpets/.rbenv/versions/4.0.1/lib/ruby/gems/4.0.0/gems/localhost-1.7.0/lib/localhost/issuer.rb:138: warning: IO::Buffer is experimental and both the Ruby and C interface may change in the future! 1.18s info: Falcon::Service::Server [oid=0x558] [ec=0x3e8] [pid=4087] [2026-01-24 23:13:05 +0000] | Starting https://localhost:9292 on #<Falcon::Endpoint https://localhost:9292/ {}> 1.18s info: Async::Service::Controller [oid=0x560] [ec=0x3e8] [pid=4087] [2026-01-24 23:13:05 +0000] | Controller starting… 1.18s info: Async::Service::Controller [oid=0x560] [ec=0x3e8] [pid=4087] [2026-01-24 23:13:05 +0000] | Starting container… 1.19s info: Async::Service::Controller [oid=0x560] [ec=0x3e8] [pid=4087] [2026-01-24 23:13:05 +0000] | Waiting for startup… 1.19s warn: Async::Task [oid=0x568] [ec=0x570] [pid=4103] [2026-01-24 23:13:05 +0000] | Task may have ended with unhandled exception. | Errno::ENOENT: No such file or directory @ rb_sysopen - config.ru | → /home/duelingpets/.rbenv/versions/4.0.1/lib/ruby/gems/4.0.0/gems/rack-3.2.4/lib/rack/builder.rb:88 in ‘IO.read’



This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.