Phonemos User Guide

Networking

Overview

Phonemos uses an Nginx reverse proxy as the single external entry point. Nginx terminates TLS on ports 80 (redirect) and 443 (HTTPS) and routes requests to internal services over Docker networks. All inter-service communication happens on private Docker networks that are not exposed to the host.

diagram

Docker Networks

Three Docker networks isolate traffic between service groups:

phonemosIngress

Services that need to be reachable from the Nginx reverse proxy:

Service

Role

ingress

Nginx reverse proxy

frontend

Web UI

hasura

GraphQL API

backend

Main backend

backend-pdf

PDF generation

keycloak

Authentication

minio-filestore

Object storage

phonemos

Internal application communication (not exposed through Nginx):

Service

Role

hasura, backend, backend-pdf

Application services (also on phonemosIngress)

postgres

PostgreSQL database

redis

Cache and job queue

pandoc, converter-*

Document converters (Pandoc, Draw.io, BPMN, LibreOffice, Linux tools)

confluence-converter

Confluence import converter

youtrack-connector, jira-dc-connector

External connectors (optional)

phonemosKeycloak

Isolated network for Keycloak and its dedicated database (keycloak and keycloak-postgres). Note that keycloak is on both phonemosKeycloak and phonemosIngress, bridging the two networks.

Traffic Flow

External traffic:

  1. A client sends a request to the server on port 443 (or 80, which redirects to 443).

  2. Nginx terminates TLS and inspects the URL path.

  3. Based on the path, Nginx proxies the request to the appropriate upstream service on the phonemosIngress network.

Internal traffic:

  • hasura and backend communicate with postgres and redis on the phonemos network.

  • backend dispatches conversion jobs to converter services via redis on the phonemos network.

  • keycloak communicates with keycloak-postgres on the isolated phonemosKeycloak network.

No internal ports are published to the host. Only ports 80 and 443 are exposed externally.

Routing Table

URL Path

Upstream

Port

Location File

/

frontend

8080

phonemos.loc

/v1/*, /v1alpha1/*, /v2/*, /healthz

hasura

8080

phonemos.loc

/console

hasura

8080

phonemos.loc

/api/pdf

backend-pdf

8080

phonemos.loc

/_files

backend

8081

phonemos.loc

/_api/scim

backend

8082

scim.loc

/auth

keycloak

8080

keycloak.loc

/phonemos-files*

minio-filestore

9000

minio.loc

Ingress / Nginx Configuration

Nginx configuration is split across several files:

File

Location in container

Purpose

nginx.conf

/etc/nginx/nginx.conf

Main config (worker settings, gzip, log format)

phonemos.conf

/etc/nginx/conf.d/phonemos.conf

Server blocks (HTTP redirect, HTTPS with TLS)

routes.conf

/etc/nginx/routes.loc

Location includes (which .loc files to load)

servers.conf

/etc/nginx/servers.loc

Additional server blocks

*.loc

/etc/nginx/conf.d/*.loc

Individual location routing rules

Key Settings

Setting

Value

HTTP/2

Enabled

Client max body size

50 MB

Proxy connect timeout

5 seconds

Proxy send/read timeout

60 seconds

Proxy buffering

Off

Gzip

On

TLS Certificates

The setup script supports three TLS modes, configured via TLS_TYPE in /etc/phonemos/setup.conf:

  • Public certificate — provide your .crt and .key files during setup. Recommended for production.

  • Self-signed — generated automatically using OpenSSL. Added to system CA store and a Java keystore is created. Suitable for testing.

  • Skip — no certificate configured. You must set up TLS manually.

Certificate files are located at /etc/phonemos/ingress/certs/cert.crt and /etc/phonemos/ingress/certs/cert.key.

DNS and Firewall

DNS: Create an A-record (or CNAME) pointing your hostname to the server's IP address. The hostname must be resolvable for Keycloak and the application to function correctly.

Firewall: Only two ports need to be accessible externally:

Port

Protocol

Purpose

80

TCP

HTTP (redirects to HTTPS)

443

TCP

HTTPS (all application traffic)

All other ports (8080, 8081, 8082, 9000, 5432, 6379) are internal to Docker networks and are not published to the host.

Service Discovery

Nginx uses Docker's built-in DNS resolver (127.0.0.11) to resolve container names to IP addresses at request time. Each location block uses a variable to hold the upstream name, forcing Nginx to resolve DNS on every request rather than caching it at startup:

1 2 3 4 5 location / { resolver 127.0.0.11 valid=30s ipv6=off; set $upstream_frontend frontend; proxy_pass http://$upstream_frontend:8080$request_uri; }

This ensures Nginx handles container restarts gracefully — if a container gets a new IP after a restart, Nginx resolves the updated address within 30 seconds.

Customization

Adding Routes

Edit /etc/phonemos/ingress/routes.conf to include or exclude location files. Comment out lines to disable routing to specific services (e.g. if you use an external Keycloak or MinIO).

Adding Server Blocks

Edit /etc/phonemos/ingress/servers.conf to add additional Nginx server blocks (e.g. for a separate subdomain or custom redirect rules).

Docker Compose Overlay

Edit /etc/phonemos/ingress/overlay.yaml to customize the ingress Docker Compose configuration. After making changes, restart the ingress service:

1 sudo systemctl restart phonemos-ingress