ServBay + Docker Integration FAQ
When using ServBay for local web development, you might want to leverage Docker for a containerized environment. This FAQ addresses common questions about integrating ServBay with Docker, supporting both macOS and Windows scenarios—including accessing ServBay services from Docker and using ServBay as a reverse proxy for applications running inside containers.
Q1: Why does ServBay modify my system's hosts
file? Can I prevent this?
ServBay adds entries to your system's hosts
file (e.g., mysite.servbay.demo 127.0.0.1
) so you can access your local development sites using custom local domains like mysite.servbay.demo
. These sites actually run on your machine at the 127.0.0.1
address.
However, due to Docker’s mechanism of reading the hosts
file from the host system (macOS or Windows), the domain mysite.servbay.demo
will resolve to 127.0.0.1
inside Docker, causing containers to access the wrong service (their own internal service instead of the host).
Core mechanism:
- When you create a new site in ServBay and specify a domain name (e.g.,
example.servbay.demo
), ServBay automatically points that domain to127.0.0.1
. - This is a standard approach to provide friendly local domain access. Without modifying the
hosts
file, you would only be able to access your site viahttp://127.0.0.1:PORT
and not via your chosen custom domain.
Can you prevent this?
Technically, you can manually remove the entries that ServBay adds, but this will prevent you from accessing your local sites via the domains set up through ServBay, undermining ServBay’s convenience-focused design. One of ServBay’s core features is to simplify the creation and access of local sites. If you don’t want ServBay to manage certain domain entries in hosts
, it’s better not to create sites with those domains in ServBay.
For most local development cases, ServBay’s automatic management of the hosts
file is a desired feature that significantly streamlines the development workflow.
Q2: How can my Docker container correctly access a ServBay-managed website on the host via domain name (e.g., mysite.servbay.demo
)?
This is a common need but must be handled properly to avoid issues. When ServBay runs a site on your host system (macOS or Windows)—for example, mysite.servbay.demo
resolving to 127.0.0.1
on the host—inside the Docker container 127.0.0.1
refers to the container itself, not the host.
Incorrect method: Directly using host.docker.internal
as the hostname in your URL
Although Docker Desktop for Mac (and Windows) provides a special DNS name, host.docker.internal
, allowing containers to resolve the host’s IP address, it is strongly discouraged to use this directly in URLs to access ServBay-hosted websites (e.g., accessing http://host.docker.internal/
and expecting it to resolve as mysite.servbay.demo
).
This is because if you do this, the HTTP request sent to the ServBay web server (such as Caddy or Nginx) will use host.docker.internal
in the Host
header. ServBay’s web servers rely on this Host
header to determine which site is being requested. If the Host
header is host.docker.internal
instead of mysite.servbay.demo
, the web server cannot route your request correctly to the target site, and with HTTPS, you'll get SNI (Server Name Indication) errors because the SSL certificate is issued for mysite.servbay.demo
—not for host.docker.internal
.
Proper solution: Add extra_hosts
when starting the Docker container
To ensure apps inside Docker can use the original ServBay domain (like mysite.servbay.demo
) and send the correct Host
header, you should add this domain to the container’s /etc/hosts
file, pointing it to the host’s IP address. This is done with extra_hosts
in your docker-compose.yml
or --add-host
with docker run
, mapping 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 replaced by Docker with the internal IP of the host system. For Docker versions 20.10+, this acts as a lower-level alias forhost.docker.internal
.)Using
docker-compose.yml
:yamlversion: '3.8' services: myapp: image: your_image extra_hosts: - "mysite.servbay.demo:host-gateway" # ... other config
1
2
3
4
5
6
7
After configuring:
- When your app in the container tries to access
http://mysite.servbay.demo
orhttps://mysite.servbay.demo
, internally/etc/hosts
resolvesmysite.servbay.demo
to the IP of your macOS (or Windows) host. - Requests are sent to the ServBay web server running on the host.
- The HTTP
Host
header ismysite.servbay.demo
, so ServBay routes the request correctly and serves the matching SSL certificate (if using HTTPS).
Q3: How can my Docker container connect to a database (like MySQL, PostgreSQL) managed by ServBay, or other non-HTTP services?
Unlike web services that rely on domain names, for connecting to databases or other TCP services not dependent on SNI, using host.docker.internal
as the server hostname is both recommended and effective.
Steps:
Make sure ServBay’s database (or other services) are running and configured to allow connections from the host (default settings usually work for local development).
In your Docker container, when setting up the connection:
- Hostname/Server: Use
host.docker.internal
. - Port: Use the port configured in ServBay for the database (e.g., MySQL’s default
3306
, PostgreSQL’s default5432
). - Username/password: Use the credentials you set up in ServBay for the database or service.
Example (connecting to ServBay-managed MySQL): Suppose MySQL is running at port
3306
in ServBay. In your container app, set:- Host:
host.docker.internal
- Port:
3306
- User:
your_db_user
- Password:
your_db_password
- Hostname/Server: Use
Q4: When my Docker container accesses a ServBay HTTPS site (using extra_hosts
config) that uses a ServBay User CA certificate, how can I make the container trust that CA?
Assuming you’ve followed Q2, using extra_hosts
or --add-host
to map secure.servbay.demo
to host-gateway
, and secure.servbay.demo
uses an ServBay User CA issued SSL certificate, your Docker container by default does not trust this CA—this causes SSL handshake failures.
ServBay CA file paths:
- ServBay User CA root certificate:
- macOS:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Windows:
C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt
- macOS:
- PEM file including ServBay User CA, Public CA, and Mozilla root certificates:
- macOS (ARM):
/Applications/ServBay/package/common/openssl/3.2/cacert.pem
- macOS (Intel):
/Applications/ServBay/package/common/openssl/1.1.1u/cacert.pem
- Windows:
C:\ServBay\package\common\openssl\3.3\cacert.pem
- macOS (ARM):
Solutions Overview:
There are several ways to make the container trust ServBay User CA:
- Method 1: System-wide trust during image build (via Dockerfile) – best for custom images needing broad trust of the CA.
- Method 2: Application-level trust at runtime (via volume mount and environment variable) – for trusting the CA in just certain apps or if you don’t want to edit the image.
- Method 3: System-wide trust at runtime (via volume mount and custom startup command) – for granting system-wide trust at runtime without a custom build.
Method 1: System-wide trust during image build (Dockerfile)
Integrate the CA into your container’s trusted certificates during the build:
- Prepare the CA file: Copy ServBay User CA root certificate into your Docker build context (e.g., next to your Dockerfile):
- macOS:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Windows:
C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt
- macOS:
- Example 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 - Example 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 - Docker Compose build:yaml
version: '3.8' services: myapp: build: context: ./app_service dockerfile: Dockerfile extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
Method 2: Application-level trust at runtime (volume mount & environment variable)
Mount the CA file into the container and configure your app to use it via environment variable.
- Sample
docker-compose.yml
:yamlCheck your application’s documentation for the correct environment variable to use.version: '3.8' services: myapp: image: some-base-image volumes: # macOS path example - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/etc/ssl/certs/MyCustomCA.crt:ro # Windows example (update for your OS) # - C:\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
15
16
17
Method 3: System-wide trust at runtime (volume mount & custom startup command)
Mount the CA file and run commands to update system trust at container start. This avoids a custom image build but can complicate the startup sequence.
- Sample
docker-compose.yml
(Debian/Ubuntu-based image):yamlNotes:version: '3.8' services: myapp: image: ubuntu:latest volumes: # Mount CA directly to expected location # macOS path example - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro # Windows example (update for your OS) # - C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro # Override command to update certs and run original app 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 " extra_hosts: ["secure.servbay.demo:host-gateway"] # If you need root permissions for update-ca-certificates but your app runs as non-root, further entrypoint adjustments may be needed # user: root
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
26
27- Complexity: Modifying
command
orentrypoint
can be challenging for official images with intricate startup logic. You must ensure your actual application launch command is executed. - Permissions:
update-ca-certificates
typically requires root. If your container runs as non-root by default, this method may fail without privilege escalation. - Package requirements: The container must include the
ca-certificates
package and theupdate-ca-certificates
command. The sample script will attempt installation via apt if missing. - Startup time: Running these checks and commands at every start introduces a startup delay.
- Alpine Linux: For Alpine, use
apk add --no-cache ca-certificates && update-ca-certificates
.
- Complexity: Modifying
Which method should you use?
- If you can build custom images and want broad system-level CA trust, Method 1 is usually best.
- If you don’t want to modify the image and only need specific apps to trust the CA, Method 2 is convenient.
- If you want no image build and want to minimize system changes while requiring system-wide trust, Method 3 is appropriate.
For certificates from public CAs (e.g., Let’s Encrypt): If your ServBay site uses a certificate from a public CA such as Let’s Encrypt, most base Docker images will already trust these CAs out of the box. No extra steps are typically needed.
Q5: How do I configure a domain name and reverse proxy in ServBay for an application running inside a Docker container?
Suppose you’re running an app (e.g., Node.js listening on port 3000 inside the container) and want to expose it on your host via a friendly domain name (e.g., myapp.servbay.demo
) using ServBay, and take advantage of ServBay’s SSL certificate management.
Steps:
Run your Docker container and map the port to host’s
127.0.0.1
: Ensure your container maps its app port to a port on the host system (macOS or Windows) and binds to127.0.0.1
for local-only access, avoiding exposure to external networks.bash# Example: App inside container listens on port 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
2In this example, your application in the container listening on
3000
is now available viahttp://127.0.0.1:3001
on the host.Add a new site and configure reverse proxy in ServBay:
- Open the ServBay management interface.
- Click “Add Site.”
- Domain Name: Enter your desired domain, e.g.,
myapp.servbay.demo
. - Site Type: Select “Reverse Proxy” from the dropdown.
- IP Address: Type
127.0.0.1
. - Port: Enter the port mapped from Docker to the host in step 1, e.g.,
3001
. - Save your configurations.
(Optional) Configure SSL: Once the site’s added, go to its settings to enable SSL. ServBay supports automatic certificate issuance from public CAs like Let’s Encrypt via ACME, or you can use ServBay’s User CA or Public CA. ServBay will handle SSL termination; traffic between ServBay and the Docker container can use plain HTTP (e.g.,
http://127.0.0.1:3001
).Test access: After saving your configuration in ServBay, you should be able to visit
http://myapp.servbay.demo
orhttps://myapp.servbay.demo
(if SSL is set up) in your browser. ServBay will proxy the request to the application running inside the Docker container.
Workflow: Browser ->
https://myapp.servbay.demo
->
ServBay (SSL termination, proxy lookup) ->
http://127.0.0.1:3001
(host-mapped port) ->
App inside Docker container.
Summary
ServBay greatly simplifies local web development on macOS and Windows. When used with Docker:
- To access ServBay-hosted websites from Docker containers, use
extra_hosts
or--add-host
to map the site’s domain tohost-gateway
, making sure theHost
header is correct and avoiding SNI errors. - To connect to ServBay-managed databases or other non-HTTP services from Docker, use
host.docker.internal
as the server hostname—this is straightforward and reliable. - To make Docker containers trust ServBay User CA-issued SSL certificates, copy the CA certificate into your Docker image and update the trust store as appropriate.
- To use ServBay as a reverse proxy for apps inside Docker containers, set up a “Reverse Proxy” site type in ServBay and point it to the host’s
127.0.0.1
port that maps to your container.
Always make sure the required ServBay packages (web server, database, etc.) and your Docker containers are properly configured and running.