Preguntas Frecuentes sobre la Integración de ServBay y Docker (FAQ)
Cuando utilizas ServBay para el desarrollo web local, puedes querer combinarlo con Docker para trabajar en entornos contenerizados. Este FAQ está diseñado para responder algunas de las dudas más habituales al utilizar ServBay junto con Docker, especialmente en macOS: desde cómo acceder a servicios de ServBay desde Docker, hasta cómo hacer proxy inverso a aplicaciones dentro de contenedores Docker usando ServBay.
P1: ¿Por qué ServBay modifica el archivo hosts
de mi sistema? ¿Puedo evitarlo?
ServBay agrega entradas en el archivo hosts
de tu sistema (por ejemplo, mysite.servbay.demo 127.0.0.1
) para que puedas usar dominios personalizados (como mysite.servbay.demo
) al acceder a tus sitios de desarrollo local. Estos sitios realmente se ejecutan en la dirección 127.0.0.1
de tu máquina.
Sin embargo, debido al funcionamiento de Docker, este también lee el archivo hosts del host macOS, lo que provoca que mysite.servbay.demo
apunte a 127.0.0.1
dentro del contenedor, derivando en que Docker acceda a su propio servicio interno, y no al deseado.
Mecanismo principal:
- Cuando creas un nuevo sitio en ServBay y le das un nombre de dominio (como
example.servbay.demo
), ServBay lo asigna automáticamente a127.0.0.1
. - Esta es la forma estándar para habilitar dominios locales amigables. Si no se modifica el archivo
hosts
, solo podrías acceder víahttp://127.0.0.1:PUERTO
y no mediante un dominio personalizado.
¿Se puede evitar esto?
En teoría, puedes quitar manualmente las entradas que ServBay añade, pero dejarías de poder acceder al sitio usando el dominio personalizado, perdiendo una de las principales ventajas de ServBay: la facilidad de crear y acceder a sitios locales. Si prefieres que ServBay no gestione el dominio específico, lo mejor es no crear el sitio con ese dominio en ServBay.
Para la mayoría de escenarios de desarrollo local, ServBay gestionando automáticamente tu archivo hosts
es lo habitual y te ahorrará muchos problemas y tiempo.
P2: ¿Cómo puede un contenedor Docker acceder correctamente, por dominio, a un sitio gestionado por ServBay en macOS (por ejemplo mysite.servbay.demo
)?
Esto es una necesidad común, pero hay que gestionarlo correctamente para evitar inconvenientes. Cuando ServBay ejecuta un sitio en tu macOS (por ejemplo, mysite.servbay.demo
, que resuelve a 127.0.0.1
en el host), el 127.0.0.1
dentro del contenedor Docker apunta al propio contenedor, no al host macOS.
Solución incorrecta: Usar host.docker.internal
directamente como el hostname de la URL
Aunque Docker Desktop para Mac (y Windows) provee el nombre DNS especial host.docker.internal
para referirse al host desde el contenedor, no se recomienda usarlo directamente como el hostname en la URL para acceder a sitios gestionados por ServBay (por ejemplo, para intentar acceder a http://host.docker.internal/
esperando llegar a mysite.servbay.demo
).
La razón es que al hacerlo, el contenedor envía al servidor web de ServBay (como Caddy o Nginx) una cabecera HTTP Host
con el valor host.docker.internal
. Los servidores web de ServBay dependen de esa cabecera para determinar qué sitio debe responder. Si la cabecera Host
no coincide con mysite.servbay.demo
, el servidor web no enruta el tráfico correctamente y, además, en HTTPS, puedes obtener un error SNI (Server Name Indication) porque el certificado SSL es para mysite.servbay.demo
y no para host.docker.internal
.
Solución correcta: Añadir extra_hosts
al iniciar el contenedor Docker
Para que una aplicación dentro del contenedor pueda usar el dominio original de ServBay (como mysite.servbay.demo
) y enviar correctamente la cabecera Host
, debes añadir una entrada en el /etc/hosts
del contenedor, apuntando ese dominio a la IP del host. Esto se logra usando extra_hosts
(en docker-compose.yml
) o --add-host
(con docker run
), apuntando el dominio a host.docker.internal
o al preferido host-gateway
.
Usando
docker run
:bashdocker run --add-host=mysite.servbay.demo:host-gateway ... your_image
1(
host-gateway
es un valor especial; Docker lo sustituye por la IP interna del host. En Docker 20.10+ suele ser un alias más bajo de nivel dehost.docker.internal
.)Usando
docker-compose.yml
:yamlversion: '3.8' services: myapp: image: your_image extra_hosts: - "mysite.servbay.demo:host-gateway" # o "mysite.servbay.demo:host.docker.internal" # ... otras configuraciones
1
2
3
4
5
6
7
Una vez configurado, dentro del contenedor Docker:
- Cuando la app intente acceder a
http://mysite.servbay.demo
ohttps://mysite.servbay.demo
, el/etc/hosts
del contenedor resolverá ese dominio a la IP del host macOS. - La petición será enviada al servidor web de ServBay en el host.
- La cabecera HTTP
Host
se conserva comomysite.servbay.demo
, permitiendo que ServBay enrute la solicitud correctamente y entregue el certificado SSL correcto (si se usa HTTPS).
P3: ¿Cómo puede un contenedor Docker conectar a las bases de datos gestionadas por ServBay (como MySQL, PostgreSQL) u otros servicios no HTTP?
A diferencia del acceso web basado en dominio, al conectar a bases de datos u otros servicios TCP que no dependen de SNI, es recomendado y efectivo usar host.docker.internal
como hostname del servidor.
Pasos:
- Asegúrate de que el servicio de base de datos (u otro) esté iniciado en ServBay y que permite conexiones desde el host (casi siempre la configuración predeterminada es suficiente para desarrollo local).
- Dentro del contenedor Docker, al definir la conexión a la base de datos (o al servicio):
- Host/Servidor: utiliza
host.docker.internal
- Puerto: el puerto configurado para ese servicio en ServBay (por ejemplo, MySQL por defecto es
3306
, PostgreSQL es5432
). - Usuario/Contraseña: tus credenciales configuradas en ServBay.
- Host/Servidor: utiliza
Ejemplo (conexión MySQL ServBay): Supón que MySQL en ServBay corre en el puerto 3306
. En la app del contenedor Docker, la configuración sería:
- Host:
host.docker.internal
- Puerto:
3306
- Usuario:
tu_usuario_db
- Contraseña:
tu_contraseña_db
P4: Cuando el contenedor Docker accede vía dominio (con extra_hosts
) a un sitio HTTPS de ServBay (usando ServBay User CA), ¿cómo hago para que confíe en ese CA?
Supongamos que seguiste la sugerencia de la P2 y asignaste secure.servbay.demo
al host-gateway
usando extra_hosts
o --add-host
. Si en ServBay el dominio utiliza un certificado SSL expedido por ServBay User CA, el contenedor Docker, por defecto, no confiará en esa CA y puede fallar el handshake SSL.
Rutas de los archivos CA de ServBay (en el host macOS):
- Certificado raíz ServBay User CA:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Archivo PEM con ServBay User CA, Public CA y raíces Mozilla:
- Mac ARM:
/Applications/ServBay/package/common/openssl/3.2/cacert.pem
- Mac Intel:
/Applications/ServBay/package/common/openssl/1.1.1u/cacert.pem
- Mac ARM:
Opciones de solución:
Puedes elegir entre varias formas de hacer que Docker confíe en ServBay User CA:
- Opción 1: Confianza a nivel sistema en build (mediante Dockerfile) – Recomendada si puedes crear tu propia imagen Docker personalizada.
- Opción 2: Confianza a nivel de aplicación en runtime (mediante volumen y variables de entorno) – Útil si solo una app concreta debe confiar en el CA o no quieres modificar la imagen.
- Opción 3: Confianza a nivel sistema en runtime (montando volumen y comando custom) – Para confiar en el CA a nivel sistema al iniciar, sin rebuild de imagen.
Opción 1: Confianza a nivel sistema en build (mediante Dockerfile)
Aquí, al construir la imagen Docker, integras el certificado CA en el almacén de confianza del sistema.
- Prepara el archivo CA: Copia
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
a tu contexto de build Docker (junto al Dockerfile). - Ejemplo Dockerfile (Debian/Ubuntu):dockerfile
# Dockerfile FROM ubuntu:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && \ update-ca-certificates && \ rm -rf /var/lib/apt/lists/*
1
2
3
4
5
6 - Ejemplo Dockerfile (Alpine):dockerfile
# Dockerfile FROM alpine:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apk add --no-cache ca-certificates && update-ca-certificates
1
2
3
4 - Construcción con Docker Compose:yaml
# docker-compose.yml version: '3.8' services: myapp: build: context: ./app_service # Carpeta con Dockerfile y ServBay-Private-CA-ECC-Root.crt dockerfile: Dockerfile extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
8
Opción 2: Confianza a nivel de aplicación en runtime (con volumen y variable de entorno)
Aquí montas el archivo del certificado CA dentro del contenedor y configuras la app para que lo use vía variable de entorno.
- Ejemplo
docker-compose.yml
:yamlConsulta la documentación de tu aplicación para saber la variable exacta.version: '3.8' services: myapp: image: some-base-image volumes: - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/etc/ssl/certs/MyCustomCA.crt:ro environment: # Ejemplo para Node.js: - NODE_EXTRA_CA_CERTS=/etc/ssl/certs/MyCustomCA.crt # Ejemplo para Python (requests): # - REQUESTS_CA_BUNDLE=/etc/ssl/certs/MyCustomCA.crt # Ejemplo genérico SSL_CERT_FILE: # - SSL_CERT_FILE=/etc/ssl/certs/MyCustomCA.crt extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Opción 3: Confianza a nivel sistema en runtime (montando volumen y comando personalizado)
En este caso, combinas un volumen con el certificado y actualizas el almacén CA cuando el contenedor arranca, evitando crear una imagen especial.
- Ejemplo
docker-compose.yml
(imagen Debian/Ubuntu):yamlNotas importantes:version: '3.8' services: myapp: image: ubuntu:latest # O cualquier imagen compatible con update-ca-certificates volumes: # Montar el certificado directamente en el directorio esperado - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro # Sobrescribir command para actualizar certificados y ejecutar el comando original # El contenedor debe correr como root o tener permiso para update-ca-certificates command: > sh -c " echo 'Intentando actualizar los certificados CA...' && if command -v update-ca-certificates > /dev/null; then if [ ! -f /usr/bin/update-ca-certificates ]; then apt-get update && apt-get install -y --no-install-recommends ca-certificates; fi && update-ca-certificates && echo 'Certificados CA actualizados.' else echo 'Comando update-ca-certificates no encontrado. Saltando actualización de CA.' fi && echo 'Iniciando la aplicación...' && exec your_original_application_command_here # Sustituye por tu comando de inicio real " extra_hosts: ["secure.servbay.demo:host-gateway"] # Para correr el update como root si tu app se ejecuta con otro usuario # user: root # O usar un entrypoint adecuado para gestión de permisos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25- Complejidad: Modificar
command
oentrypoint
puede complicarse, sobre todo con imágenes oficiales complejas. Asegúrate de que tu app arranca como corresponde. - Permisos:
update-ca-certificates
requiere root normalmente. Si tu contenedor no corre con root, puede fallar. - Dependencias: Debes tener
ca-certificates
yupdate-ca-certificates
en la imagen. El ejemplo trata de instalarlo vía apt si falta. - Alpine Linux: Para Alpine, el comando sería
apk add --no-cache ca-certificates && update-ca-certificates
.
- Complejidad: Modificar
¿Qué método elegir?
- Si puedes construir tu propia imagen personalizada y buscas confianza a nivel general, la Opción 1 es ideal.
- Si no quieres modificar imágenes y solo precisa una app confiar en el CA, la Opción 2 es cómoda y directa.
- Si buscas la mínima modificación y confianza a nivel sistema sin crear imágenes, la Opción 3 es la indicada.
¿Y para certificados de CA públicos como Let's Encrypt? Si tu sitio en ServBay usa un certificado público adquirido vía ACME (por ejemplo, Let's Encrypt), casi todas las imágenes base de Docker ya confían en ese tipo de CA por defecto, ¡no necesitas nada extra!
P5: ¿Cómo asigno dominio y habilito proxy inverso desde ServBay a una app corriendo dentro de Docker?
Quizás tengas, por ejemplo, una app Node.js en un contenedor Docker escuchando en el puerto 3000
, y quieres acceder a ella usando un dominio amigable (como myapp.servbay.demo
) desde el navegador, gestionando el SSL desde ServBay.
Pasos:
Ejecuta el contenedor Docker mapeando el puerto a
127.0.0.1
en el host: Asegúrate de mapear el puerto interno del contenedor a un puerto en tu macOS, enlazado solo a127.0.0.1
. Eso hace que solo el host pueda acceder, no redes externas.bash# Ejemplo: App en el contenedor escucha en 3000, mapea en el host a 127.0.0.1:3001 docker run -d -p 127.0.0.1:3001:3000 your-docker-app-image
1
2Así, la aplicación interna ahora es accesible por
http://127.0.0.1:3001
en el host.Agrega el nuevo sitio en ServBay y configura el proxy inverso:
- Abre la interfaz de ServBay.
- Haz clic en "Agregar sitio".
- Dominio: Pon el dominio deseado, por ejemplo,
myapp.servbay.demo
. - Tipo de sitio: Elige "Proxy inverso" en el desplegable.
- Dirección IP: Introduce
127.0.0.1
. - Puerto: Escribe el puerto del host donde mapeaste el contenedor (ej.
3001
). - Haz clic en "Guardar" o "Agregar".
(Opcional) Configura SSL: Tras el alta del sitio, podrás editar su configuración para activar SSL. ServBay puede gestionar certificados automáticamente (Let's Encrypt u otras CA públicas), o puedes usar ServBay User CA o ServBay Public CA. ServBay terminará la conexión SSL; la comunicación de ServBay al contenedor normalmente es en HTTP (
http://127.0.0.1:3001
).Prueba el acceso: Después de los pasos anteriores, deberías poder entrar desde el navegador a
http://myapp.servbay.demo
ohttps://myapp.servbay.demo
(si configuraste SSL). ServBay se encargará de hacer de proxy inverso a la app en el contenedor.
Flujo de trabajo: Navegador del usuario ->
https://myapp.servbay.demo
->
ServBay (gestiona SSL y búsqueda de la regla de proxy) ->
http://127.0.0.1:3001
(puerto del host) ->
Aplicación dentro de Docker.
Resumen
ServBay simplifica enormemente el desarrollo web local en macOS. Si lo usas junto con Docker:
- Para que contenedores Docker accedan a sitios ServBay, usa
extra_hosts
o--add-host
para apuntar el dominio alhost-gateway
, garantizando que la cabeceraHost
sea correcta y evitando problemas SNI. - Para que contenedores Docker accedan a bases de datos u otros servicios no HTTP gestionados por ServBay,
host.docker.internal
suele ser suficiente y fácil. - Para que contenedores Docker confíen en el certificado SSL generado por ServBay User CA, copia el CA dentro de la imagen y actualiza los certificados de confianza.
- Para usar ServBay como proxy inverso a apps dentro de Docker, crea un sitio tipo "Proxy inverso" y apunta al puerto de
127.0.0.1
del host mapeado por Docker.
Asegúrate siempre de que los paquetes relevantes en ServBay (servidor web, base de datos, etc.) y tus contenedores Docker estén correctamente configurados y ejecutándose.