ServBay & Docker Integration FAQ
When developing locally with ServBay, you may want to leverage Docker for containerized environments. This FAQ aims to address some of the most common issues encountered when using ServBay alongside Docker on macOS, specifically how to access ServBay services from Docker containers and how to configure ServBay as a reverse proxy for apps running inside Docker containers.
Q1: Why does ServBay modify my system hosts
file? Can I prevent that?
ServBay adds entries to your system's hosts
file (e.g. mysite.servbay.demo 127.0.0.1
) so you can use custom local domain names (like mysite.servbay.demo
) when accessing your development sites. These sites are actually running at the local 127.0.0.1
address.
However, because of how Docker works, it reads the hosts file from the macOS host. This means mysite.servbay.demo
resolves to 127.0.0.1
, causing Docker to access a service inside the container itself instead of your Mac host.
Key mechanism:
- When you create a new site in ServBay and assign a domain (such as
example.servbay.demo
), ServBay automatically points that domain to127.0.0.1
. - This is a standard practice for local-friendly development domains. Without hosts file changes, you'd only be able to access via
http://127.0.0.1:PORT
, not with a custom domain.
Can I block this behavior?
In theory, you can manually remove entries added by ServBay, but doing so means you can't access your local sites with the friendly domains set up by ServBay. This defeats the purpose of ServBay, whose core functionality is to simplify local website creation and access. If you don’t want ServBay to manage the hosts file for certain domains, simply don’t create sites for those domains within ServBay.
For most local development scenarios, having ServBay manage your hosts
file is the expected and most efficient behavior.
Q2: How can my Docker container properly access ServBay-managed websites on the macOS host (e.g., mysite.servbay.demo
) via domain name?
This is a common requirement, but it needs to be handled correctly. When ServBay runs a site on your macOS host (e.g. mysite.servbay.demo
, which resolves to 127.0.0.1
on your host), the 127.0.0.1
inside your Docker container refers to the container itself, not your Mac host.
Incorrect method: Trying to access ServBay sites with host.docker.internal
as the URL hostname
Although Docker Desktop for Mac (and Windows) provides the special DNS name host.docker.internal
so containers can reach the host IP, you should NOT use it directly in your URL when trying to access a ServBay-managed site (e.g. accessing http://host.docker.internal/
and expecting it to reach mysite.servbay.demo
).
This is because the HTTP request sent to ServBay’s web server (such as Caddy or Nginx) will have a Host
header set to host.docker.internal
, not mysite.servbay.demo
. ServBay’s web servers rely on this Host header to route the request to the correct site. If the Host header is incorrect, ServBay won’t be able to properly route the request, and with HTTPS you’ll also get SNI (Server Name Indication) errors because the SSL certificate is for mysite.servbay.demo
—not host.docker.internal
.
Correct solution: Add extra_hosts
when starting your Docker container
To allow your app inside the Docker container to use the original ServBay site domain (mysite.servbay.demo
) and ensure the correct Host header is sent, you should add an entry in the container's /etc/hosts
file, mapping the domain to your host’s IP. This is achieved using extra_hosts
(in docker-compose.yml
) or --add-host
(with docker run
), pointing the domain to host.docker.internal
or (preferably) host-gateway
.
Using
docker run
:bashdocker run --add-host=mysite.servbay.demo:host-gateway ... your_image
1(
host-gateway
is a special value substituted by Docker with the host’s internal IP; for Docker 20.10+ it’s a low-level alias forhost.docker.internal
.)Using
docker-compose.yml
:yamlversion: '3.8' # or higher services: myapp: image: your_image extra_hosts: - "mysite.servbay.demo:host-gateway" # or "mysite.servbay.demo:host.docker.internal" # ...other config
1
2
3
4
5
6
7
With this configuration, inside your Docker container:
- When your app tries to access
http://mysite.servbay.demo
orhttps://mysite.servbay.demo
, the container’s/etc/hosts
will resolvemysite.servbay.demo
to your macOS host’s IP. - The request is sent to the ServBay web server running on your host.
- The HTTP
Host
header remains correct, allowing ServBay to route the request accurately and provide the proper SSL certificate (if using HTTPS).
Q3: How can my Docker container connect to a database (such as MySQL, PostgreSQL) or other non-HTTP service managed by ServBay?
Unlike web access via domains, when connecting to databases or other non-SNI TCP services, using host.docker.internal
as the hostname is recommended and works well.
Steps:
- Ensure your ServBay database service (or other service) is running and set up to accept connections from your host (for local dev, the default config typically works).
- In your Docker container, when configuring the database/service connection:
- Hostname/Server: use
host.docker.internal
- Port: use the port ServBay configures for that database/service (e.g., MySQL defaults to
3306
, PostgreSQL to5432
) - Username/Password: use the credentials you set in ServBay
- Hostname/Server: use
Example (connecting to ServBay-managed MySQL): If MySQL is running in ServBay on port 3306
, your app's connection config should look like:
- Host:
host.docker.internal
- Port:
3306
- User:
your_db_user
- Password:
your_db_password
Q4: How do I make Docker containers trust ServBay User CA when accessing ServBay HTTPS sites (with domain via extra_hosts
)?
Assuming you followed the guidance in Q2 and mapped secure.servbay.demo
to host-gateway
via extra_hosts
or --add-host
, and your ServBay HTTPS site uses a certificate issued by the ServBay User CA, the container by default will not trust this CA. This leads to SSL handshake failures.
ServBay CA certificate file locations (on macOS host):
- ServBay User CA root certificate:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Combined PEM file with User CA, Public CA, and Mozilla roots:
- ARM Macs:
/Applications/ServBay/package/common/openssl/3.2/cacert.pem
- Intel Macs:
/Applications/ServBay/package/common/openssl/1.1.1u/cacert.pem
- ARM Macs:
Solution overview:
There are several ways to make Docker containers trust ServBay User CA:
- Method 1: System-wide trust at build time (via Dockerfile) — Best when you control the Docker image and need the CA trusted globally.
- Method 2: App-level trust at runtime (via volume mount + env var) — Good when you just want a specific app to trust the CA, or don't want to build a new image.
- Method 3: System-wide trust at runtime (via volume mount + custom entrypoint) — Useful when you want system-wide trust without building a new image, but willing to tweak the startup command.
Method 1: System-wide trust at build time (Dockerfile)
Copy the CA certificate into the Docker build context (e.g., alongside your Dockerfile), and add the CA to the container’s trust store.
- Prepare the CA file: Copy
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
to your Docker build context. - For Debian/Ubuntu: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 - For Alpine: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 - Docker Compose example:yaml
version: '3.8' services: myapp: build: context: ./app_service # Dir containing Dockerfile & the CA file dockerfile: Dockerfile extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
Method 2: App-level trust at runtime (volume mount + env var)
Mount the CA cert into your running container and configure relevant ENV variables for your app.
- docker-compose.yml example:yamlCheck your app’s documentation for the correct environment variable.
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: # Example for Node.js: - NODE_EXTRA_CA_CERTS=/etc/ssl/certs/MyCustomCA.crt # Example for Python (requests): # - REQUESTS_CA_BUNDLE=/etc/ssl/certs/MyCustomCA.crt # Example for generic 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
Method 3: System-wide trust at runtime (volume mount + custom entrypoint)
Mount the CA file directly and execute commands to update CA trust at container startup. This avoids building a custom image but makes the container’s command more complex.
- docker-compose.yml example (for Debian/Ubuntu base images):yamlNotes:
version: '3.8' services: myapp: image: ubuntu:latest # Or any base supporting update-ca-certificates volumes: - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro command: > sh -c " echo 'Attempting to update CA certificates...' && 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 'CA certificates updated.' else echo 'update-ca-certificates command not found, skipping CA update.' fi && echo 'Starting application...' && exec your_original_application_command_here # Replace with the default CMD or your app launch command " extra_hosts: ["secure.servbay.demo:host-gateway"] # If needed, run as root for CA updates, or handle permissions via entrypoint script # user: root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22- Complexity: Overriding
command
orentrypoint
can be tricky, especially with complex original startup logic. Make sure you still start your app after updating CA certs. - Permissions:
update-ca-certificates
usually requires root. - Package availability: Container must have
ca-certificates
and theupdate-ca-certificates
command. The sample script installs them if missing and running apt. - Alpine Linux: For Alpine, use
apk add --no-cache ca-certificates && update-ca-certificates
.
- Complexity: Overriding
Which method to choose?
- If you can build a custom image and want widespread CA trust, Method 1 is ideal.
- If you prefer not to build or just need a specific app to trust the CA, Method 2 is convenient.
- If you don't want to rebuild and want system-wide trust with minimal changes, Method 3 is for you.
For certificates issued by public CAs (e.g. Let’s Encrypt): If your ServBay site uses a cert from a public CA like Let’s Encrypt (via ACME), most base Docker images already trust these CAs by default—no extra steps needed.
Q5: How do I set up a domain and reverse proxy through ServBay for an app running inside a Docker container?
Suppose you have an app in your Docker container (e.g. a Node.js service listening on port 3000 inside the container), and you wish to assign it a friendly domain (such as myapp.servbay.demo
) accessible from your host browser, leveraging ServBay’s SSL management.
Steps:
Run your Docker container and map its port to host
127.0.0.1
: Be sure to bind the port to127.0.0.1
on the Mac host, so the port is only accessible locally and not exposed to your network.bash# Example: App in container listens on 3000, mapped to host’s 127.0.0.1:3001 docker run -d -p 127.0.0.1:3001:3000 your-docker-app-image
1
2Now the app is accessible at
http://127.0.0.1:3001
from your Mac host.Add a new site to ServBay and configure reverse proxy:
- Open the ServBay management UI.
- Click “Add Site.”
- Domain: Enter the domain you want, e.g.
myapp.servbay.demo
. - Site Type: Select “Reverse Proxy” from the dropdown.
- IP Address: Input
127.0.0.1
. - Port: Enter the host port you mapped above, e.g.
3001
. - Click "Save" or “Add.”
(Optional) Configure SSL: After adding the site, in ServBay's settings you can enable SSL. ServBay will manage SSL certificates (via ACME with Let’s Encrypt or using ServBay User/Public CA). ServBay handles SSL termination—the connection from ServBay to the Docker container can remain plain HTTP (
http://127.0.0.1:3001
).Test access: Once configuration is saved, visit
http://myapp.servbay.demo
orhttps://myapp.servbay.demo
(if SSL is enabled) in your browser. ServBay proxies the request to the application inside the Docker container.
Workflow: Browser ->
https://myapp.servbay.demo
->
ServBay (SSL, reverse proxy) ->
http://127.0.0.1:3001
(on host) ->
Docker container app.
Summary
ServBay greatly simplifies local web development on macOS. When combined with Docker:
- To access ServBay-managed websites from Docker containers, use
extra_hosts
or--add-host
to map the site’s domain tohost-gateway
—ensuring the Host header is preserved and SNI issues are avoided. - To access ServBay-managed databases or other non-HTTP services from Docker, use
host.docker.internal
as the server hostname for straightforward, effective connectivity. - To make Docker containers trust SSL certificates issued by ServBay User CA, copy the CA cert into the image and update its trust store.
- To reverse proxy Docker container apps via ServBay with custom domain and SSL, create a “Reverse Proxy” site type in ServBay, pointing to the port mapped to host
127.0.0.1
.
Always make sure the necessary ServBay packages (web server, databases, etc.) as well as your Docker containers are properly configured and running.