Ceryx logo
Menu
View as Markdown

Internal network gateway

Expose services on a private network through one entry point, with public or self-managed certificates.

Put Ceryx in front of the services on a private network, such as an office, a homelab or a cloud VPC, so each one gets a hostname like fakos.internal.withlogic.work instead of an IP address and a port.

Route to services outside Docker

Targets don't have to be containers. Any HTTP address Ceryx can reach works:

docker compose -p ceryx exec ceryx curl -X POST localhost:8080/api/routes \
  -H 'Content-Type: application/json' \
  -d '{"source": "fakos.internal.withlogic.work", "target": "http://10.0.0.12:3000"}'

Ceryx resolves hostnames in targets with Docker's DNS, which also answers for names the server itself can resolve. If your internal names only resolve on another DNS server, set CERYX_DNS_RESOLVER to its IP address. Container names stop resolving when you do, so use IP addresses or internal hostnames for every target.

Choose your certificates

Public domains, reachable from the internet

If the hostnames are public and port 80 is reachable from the internet, Let's Encrypt works as usual. Nothing to set up.

Internal-only hostnames

Let's Encrypt can't check hostnames it can't reach. Turn it off by setting this environment variable when running docker compose up -d:

CERYX_DISABLE_LETS_ENCRYPT=true

Then bring your own certificates, from your internal certificate authority, or a public wildcard certificate obtained with a DNS challenge. Either store them with the API:

jq -n \
  --rawfile certificate internal.pem \
  --rawfile private_key internal-key.pem \
  '{domain: "*.internal.withlogic.work", certificate: $certificate, private_key: $private_key}' |
docker compose -p ceryx exec -T ceryx curl -X POST localhost:8080/api/certificates \
  -H 'Content-Type: application/json' \
  -d @-

Or keep them as files. Mount them into the container with a compose.override.yml next to compose.yml:

services:
  ceryx:
    volumes:
      - ./certs:/etc/ceryx/certs:ro

Then point the route at them:

docker compose -p ceryx exec ceryx curl -X PUT localhost:8080/api/routes/fakos.internal.withlogic.work \
  -H 'Content-Type: application/json' \
  -d '{"settings": {"certificate_path": "/etc/ceryx/certs/fakos.pem", "key_path": "/etc/ceryx/certs/fakos-key.pem"}}'

Ceryx reads certificate files when clients connect, so replacing the files takes effect without a restart. See How certificates work for which certificate wins when there are several.

Listen on the internal network only

To keep Ceryx off other networks the server is on, bind its ports to the internal address by setting these environment variables when running docker compose up -d:

CERYX_EXTERNAL_HTTP_PORT=10.0.0.5:80
CERYX_EXTERNAL_HTTPS_PORT=10.0.0.5:443
Esc

Type to search the docs.