GitHub

On this page

Changes Made

1. Docker Compose Port Binding Fixes

Every exposed Docker container was fixed by prepending 127.0.0.1: to the host port mapping in its compose file, then recreating the container.

/srv/apps/ORCTA-BACKEND-PSS/docker-compose.yml

  app:
    ports:
-     - "9999:9999"
+     - "127.0.0.1:9999:9999"

/srv/apps/OrctaDocsMCP/docker-compose.yml

  postgres:
    ports:
-     - 5433:5432
+     - 127.0.0.1:5433:5432

  valkey:
    ports:
-     - 6379:6379
+     - 127.0.0.1:6379:6379

/srv/apps/mentorship-app-backend/apps/apiServer/docker-compose.yml

  app:
    ports:
-     - "9393:9393"
+     - "127.0.0.1:9393:9393"

/srv/apps/mentorship-app-backend/apps/chartServer/docker-compose.yml

  chartserver:
    ports:
-     - "3001:3001"
+     - "127.0.0.1:3001:3001"

/srv/apps/orcta-stack/docker-compose.prod.yml

  backend:
    ports:
-     - "9292:9292"
+     - "127.0.0.1:9292:9292"

/srv/apps/email-ping/docker-compose.yml

  deno-app:
    ports:
-     - "9696:9696"
+     - "127.0.0.1:9696:9696"

/srv/orcta-postgres/docker-compose.yml

  pgbouncer:
    ports:
-     - "6432:6432"
+     - "127.0.0.1:6432:6432"

Drizzle-Gate (no compose — recreated with docker run)

docker stop drizzle-gate && docker rm drizzle-gate
docker run -d --name drizzle-gate \
  --restart always \
  -p 127.0.0.1:4983:4983 \
  -e PORT=4983 \
  -v drizzle-gateway:/app \
  --network orcta_net \
  ghcr.io/drizzle-team/gateway:latest

2. Ollama — Systemd Service

/etc/systemd/system/ollama.service

- Environment="OLLAMA_HOST=0.0.0.0"
+ Environment="OLLAMA_HOST=127.0.0.1"

Then systemctl daemon-reload && systemctl restart ollama.

3. Python MCP Server — Code Fix

/srv/apps/OrctaDocsMCP/mcpserver/server.py

- mcp.run(transport="streamable-http", host="0.0.0.0", port=8000, path="/mcp")
+ mcp.run(transport="streamable-http", host="127.0.0.1", port=8000, path="/mcp")

Container rebuilt with docker compose build mcp and recreated.

4. Caddyfile — Security Header Overhaul

Added (security) snippet

Refactored all sites to use a shared snippet, eliminating duplication and adding missing Permissions-Policy.

(security) {
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
        Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()"
    }
}

Then import security in every site block.

New site: gate.orctatech.com

gate.orctatech.com {
    reverse_proxy localhost:4983
    encode zstd gzip
    log { output file /var/log/caddy/gate.access.log format json }
    import security
}

Sites that received headers for the first time

  • waybills.orctatech.com
  • api.waybills.orctatech.com
  • ames.orctatech.com
  • api.ames.orctatech.com
  • pss.orctatech.com
  • gate.orctatech.com (new entry)

5. Tailscale — Migrated from Personal to Org

# Removed from personal tailnet (done by user in admin console)
# Reset state and re-authenticated to org
sudo systemctl stop tailscaled
sudo rm -f /var/lib/tailscale/tailscaled.state
sudo systemctl start tailscaled
sudo tailscale up --auth-key=<org-auth-key>
Before After
Personal: Adjanour@ Org: Orcta-tech@
IP: 100.120.2.25 IP: 100.125.3.44
Node: omarchy Node: vmi2813472

6. SSH — Locked Down to Tailscale

Systemd socket override

Created /etc/systemd/system/ssh.socket.d/override.conf:

[Socket]
ListenStream=
ListenStream=100.125.3.44:22
ListenStream=127.0.0.1:22
FreeBind=true

This replaced the default 0.0.0.0:22 and [::]:22 listeners.

iptables restriction

iptables -A INPUT -p tcp --dport 22 -s 100.109.232.127 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
iptables-save > /etc/iptables/rules.v4

Only 100.109.232.127 (laptop Tailscale IP) can connect to SSH.

Local SSH config

~/.ssh/config updated:

  Host orcta_vps
-   HostName 158.220.100.30
+   HostName 100.125.3.44

Additional: sshd_config safety net

/etc/ssh/sshd_config.d/10-tailscale-only.conf:

ListenAddress 100.125.3.44
ListenAddress 127.0.0.1

(Overridden by socket activation but kept as defense-in-depth.)

Edit this page
Last modified: 2026-08-03