Andrés
•
2 January 2026
•
4 mins
¡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.
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.
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.
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!
¿Te gustó? ¡Compártelo!