Port offset

SPLENT automatically adjusts feature port numbers per product so you can run multiple products on the same host without collisions.

Table of contents

Why it exists

Every infrastructure feature declares host ports in its .env.example (e.g. REDIS_HOST_PORT=6380, PMA_HOST_PORT=8081). If two products use the same features, their ports would collide. The port offset solves this by shifting every feature port by a deterministic, product-specific amount.


How it works

When product:env --merge runs, it:

  1. Scans the merged environment for variables that look like port declarations (ending in _HOST_PORT, _PORT_ONE, _PORT_TWO).
  2. Computes a deterministic offset from the product name:

    offset = crc32(product_name.encode("utf-8")) % 1000
    
  3. Adds the offset to each detected port value.
  4. Writes the adjusted values to the product’s merged .env.

The offset is stable — the same product name always produces the same offset, so ports don’t change between runs.


Example

For a product named my_first_app (offset 591):

Feature Variable Base port Adjusted port
Redis REDIS_HOST_PORT 6380 6971
phpMyAdmin PMA_HOST_PORT 8081 8672
Mailhog SMTP MAILHOG_SMTP_HOST_PORT 1025 1616
Mailhog UI MAILHOG_UI_HOST_PORT 8025 8616

The merge output confirms adjustments:

  ports    adjusted 4 feature port(s) (+591)
  merged   4 feature .env file(s) into product .env

What is and isn’t adjusted

Only feature port variables are adjusted. Product-level ports (like the web server port in docker-compose.dev.yml) are never touched.

Rules:

  • Variables ending in _HOST_PORT, _PORT_ONE, or _PORT_TWO are adjusted.
  • Feature ports that already exist in the product’s .env are left unchanged (product values take precedence).
  • The offset only applies during product:env --merge — base values in each feature’s .env.example are never modified.

Implications for feature authors

When creating a new infrastructure feature with Docker services:

  1. Use an _HOST_PORT suffix for your port variable (e.g. NGINX_HTTP_HOST_PORT=80).
  2. Pick a sensible base value that doesn’t overlap with common system ports.
  3. Reference the variable in your docker-compose.yml:

    ports:
      - "${NGINX_HTTP_HOST_PORT}:80"
    
  4. The offset mechanism handles the rest — no extra code needed.


Back to top

splent. Distributed by an LGPL license v3. Contact us: drorganvidez@us.es