Fediverse Logo FediMap - Join The Fediverse

Cómo usar kamal‑proxy para exponer tus contenedores de Docker.

Cómo usar kamal‑proxy para exponer tus contenedores de Docker.

¡Hola! Llevaba un tiempo sin escribir un post para mi blog, y este año quiero volver a documentar mis hallazgos técnicos. Así que aquí estamos.

Una de las últimas tareas que he tenido en mi trabajo fue levantar una instancia propia de SonarQube Community. Nos decidimos por levantar nuestra propia instancia porque el plan nos iba a salir 96 dólares mensuales, mientras que un servidor nos costaría no más de 25 dólares.

Con ese desafío, entonces, estuve buscando la forma más fácil, mantenible y rápida de hacerlo y me pregunté: ¿por qué no hacer un deploy con Kamal pero usando una imagen ya construida y pública, como la de SonarQube? La respuesta es que no se puede; Kamal espera construir y etiquetar la imagen con el hash del commit y luego hacer el deploy y configurar el proxy.

De todo eso, lo que yo simplemente quería era obtener las ventajas del proxy, la configuración de TLS y la renovación automática de los certificados. Fue entonces cuando me puse a investigar kamal‑proxy. Ahora te mostraré cómo levantar rápidamente un contenedor de Sonar (puede ser cualquier servicio/aplicación que tú quieras) y exponerlo utilizando kamal‑proxy.

El servidor

Primero que todo tienes que tener un servidor, configurar tu acceso mediante SSH e instalar Docker. Cuando tengas Docker instalado y funcionando, lo primero que vas a tener que crear es una network que sea común para tu servicio/aplicación y para el proxy de Kamal. Eso lo haces con el siguiente comando:

docker network create kamal-proxy-network

Dependiendo de tus configuraciones deberás usar sudo o no para ejecutar los comandos de Docker.

La aplicación

Ahora, como te comenté, yo necesitaba levantar SonarQube, pero tú puede que estés queriendo levantar cualquier otro servicio. Lo importante de este paso es que levantes tu aplicación ya sea con Docker Compose o simplemente con Docker y que el contenedor utilice la network que ya creamos.

En mi caso utilicé este docker-compose.yml:

services:
  sonarqube:
    image: sonarqube:community
    hostname: sonarqube
    container_name: sonarqube
    read_only: true
    depends_on:
      db:
        condition: service_healthy
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
      - sonarqube_temp:/opt/sonarqube/temp
    ports:
      - "9000:9000"
    networks:
      - kamal-proxy-network
  db:
    image: postgres:17
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
      interval: 10s
      timeout: 5s
      retries: 5
    hostname: postgresql
    container_name: postgresql
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar
      POSTGRES_DB: sonar
    volumes:
      - postgresql:/var/lib/postgresql
    networks:
      - kamal-proxy-network

volumes:
  sonarqube_data:
  sonarqube_temp:
  sonarqube_extensions:
  sonarqube_logs:
  postgresql:

networks:
  kamal-proxy-network:
    external: true

Fíjate en la configuración de network, donde uso la misma red creada anteriormente.

El proxy

Ahora es cuando utilizamos kamal‑proxy. No encontré ninguna referencia a cómo “instalar” kamal‑proxy, pero sí a cómo usarlo. Esa información está aquí en su GitHub. Este fue el punto en el que me perdí y por el cual quise dejarlo escrito en este post.

Me di cuenta, en un deploy que tengo con Kamal, de que kamal‑proxy simplemente es otro contenedor, así que fui a Docker Hub a buscar alguna imagen y la encontré aquí. Entonces, para levantar un contenedor con el proxy, lo hice con el siguiente comando, siempre utilizando la network que ya creamos:

docker run -d --network kamal-proxy-network -p 80:80 -p 443:443 basecamp/kamal-proxy:latest

La salida te entregará el hash ID del contenedor. Cópialo para poder entrar al contenedor:

docker exec -it 18cc77126e10b71b1ab1e0b88565868500f68af961a419c835b82e65a50cc4f7 bash

Ahora tendrás disponible el comando kamal-proxy y podrás configurar los deploys. En mi caso, para enlazar el contenedor de Sonar y exponerlo a través de kamal‑proxy:

kamal-proxy deploy SonarQube --target sonarqube:9000
kamal-proxy@b6d74e5f5551:/$ kamal-proxy list
Service   Host  Path  Target          State    TLS  
service1  *     /     sonarqube:9000  running  no

Para utilizar tls:

kamal-proxy deploy SonarQube --target sonarqube:9000 --host sonar.example.com --tls

Y con eso ya tendrías tu aplicación corriendo detrás de kamal‑proxy. Mis razones principales para hacer esto fueron que kamal‑proxy simplifica toda la configuración; como pudiste ver, basta con levantar el contenedor y ejecutar un par de comandos para tener el proxy funcionando. Además, lo mejor es la renovación automática de los certificados.

¡Espero haberte ayudado! Si estabas buscando cómo exponer y configurar de forma fácil un proxy para tus contenedores, cualquier duda o comentario puedes escribirme. ¡Saludos!