kamal icon indicating copy to clipboard operation
kamal copied to clipboard

Using kamal-proxy for accessories

Open tommica opened this issue 1 year ago • 1 comments

Is it possible to do some kind of a reverse proxy configuration to accessories? I'd like to have multiple applications on one server, and for each of them to have their own mailpit instance, accessed by it's own sub-domain - so something like this:

APP1: foo.bar.baz.test MAIL: mail.foo.bar.baz.test (80 -> 8025)

APP2: john.bar.baz.test MAIL: mail.john.bar.baz.test (80 -> 8025)

tommica avatar Oct 16 '24 11:10 tommica

https://github.com/basecamp/kamal/pull/981

luizkowalski avatar Oct 22 '24 11:10 luizkowalski

@djmb this issue can be closed, since #981 has been merged.

igor-alexandrov avatar Nov 26 '24 09:11 igor-alexandrov

@djmb this issue can be closed, since #981 has been merged.

Some services require authentication or may return non-200 HTTP status codes. The proxy health check setting should accept a non-200 status codes, or offer more authentication settings.

shiny avatar Dec 07 '24 05:12 shiny

@shiny can you provide an example of such containers? My implementation of proxy for accessories has been based on PgHero service, which exposes a health check route without an authentication.

igor-alexandrov avatar Dec 07 '24 06:12 igor-alexandrov

@shiny can you provide an example of such containers? My implementation of proxy for accessories has been based on PgHero service, which exposes a health check route without an authentication.

I am using the Docker image appwrite/resque-web, here is my deploy file

  resque-web:
    image: appwrite/resque-web:1.1.0
    proxy:
      ssl: true
      host: <host>
      app_port: 5678
      healthcheck:
        path: /
    env:
      clear:
        RESQUE_WEB_HOST: <redis-host>
        RESQUE_WEB_PORT: 6379
        RESQUE_WEB_HTTP_BASIC_AUTH_USER: admin
        RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD: <password>

Related Repo

  • https://github.com/resque/resque-web
  • https://github.com/appwrite/docker-resque-ui

PS This feature has been a great help to me, thank you so much!

shiny avatar Dec 07 '24 06:12 shiny

This makes sense... As a workaround you can fork appwrite/resque-web and create a small Rack app in config.ru that won't be password protected to serve a health check route.

@djmb what do you think about the ability of adding --health-check-username and --health-check-password flags to the kamal-proxy deploy command?

igor-alexandrov avatar Dec 07 '24 07:12 igor-alexandrov

Another situation, I'm struggling with containers that have two ports, as they are difficult to proxy. My case is minio/minio

This is because it uses both port 9000 and 9001 — 9000 for the API and 9001 for the console. I'm aimming to bind s3.example.com to port 9000 and console.s3.example.com to 9001. However, it seems that is not possible.

I have to directly publish the HTTP ports instead. Another approach is separate the minio server and it's console, but this is a little bit tricky. MinIO has even removed the minio/console image.

shiny avatar Dec 08 '24 09:12 shiny

@shiny I'm facing the exact same issue. What did you end up with? Any recommendations?

aesmail avatar Jan 28 '25 19:01 aesmail

@shiny I'm facing the exact same issue. What did you end up with? Any recommendations?

I chose to directly expose the management UI port, while binding the S3 API to a domain using HTTPS. However, during testing, I found that HTTPS access still had issues, whereas directly using port 9000 worked well.

for now my configuration file looks like below

accessories:
  minio:
    host: example.com
    image: quay.io/minio/minio
    options:
      publish:
        - 9001:9001
        - 9000:9000
    proxy:
      ssl: true
      host: s3.example.com
      app_port: 9000
      healthcheck:
        path: /minio/health/live
    env:
      clear:
        MINIO_ROOT_USER
        MINIO_ROOT_PASSWORD
    cmd: minio server /data --console-address ":9001"
    directories:
      - /data/minio-data:/data

shiny avatar Feb 05 '25 07:02 shiny

@shiny interesting! I couldn't get kamal to deploy minio to a new host with the proxy option (other than the primary web host). It kept complaining that kamal-proxy was not installed. I ended up installing minio on the same web host and using nginx as an accessory to direct traffic to both minio api (9000) and minio console (9001) using storage.example.com and console.example.com respectively. Since nginx is listening to port 80, I also used it to direct traffic to the main app example.com which means extra steps and layers to connect everything, but it works. Because of this, I put all my (sub)domains on Cloudflare which has its benefits.

This is my config file:

accessories:
  loadbalancer:
    image: nginx:latest
    port: "80:80"
    roles:
      - web
    files:
      - config/storage.nginx.conf:/etc/nginx/conf.d/default.conf
  minio:
    image: minio/minio
    roles:
      - web
    options:
      publish:
        - "9000:9000"
        - "9001:9001"
    env:
      secret:
        - MINIO_ROOT_USER
        - MINIO_ROOT_PASSWORD
    directories:
      - data:/data
    cmd: server /data --console-address ":9001"

I wonder if your configs makes kamal deal with ssl for your s3.example.com domain automatically? I would much rather get rid of nginx (for this case at least) and Cloudflare domain hosting if it's possible to do everything through the deploy.yml file.

aesmail avatar Feb 05 '25 07:02 aesmail

@aesmail Yes, Kamal automatically handles SSL for s3.example.com, since v2.4.0. I love Kamal's approach, but for the current situation, I'm still looking forward to new features in the future.

shiny avatar Feb 05 '25 09:02 shiny