Files
Gabriel Brown 913a57f8a6 Snapshot both servers: the VPS catalog moves to server/vps, the home server joins as server/home
The catalog in server/containers had drifted from the VPS. Eleven compose
files and twelve units no longer matched what runs, and two running
services, Gbrown_Agent and BillTracker, were missing. server/vps is now a
copy of the live files, and panama-server reads from it.

server/home holds the home server's services in the same shape. They still
run under Docker, so the podman units there are drafts for a later move, and
nothing installs from that tree. PostHog, Sentry and Plausible are checkouts
of upstream repositories. Only their local files are kept, next to an
UPSTREAM file naming the repository and the exact commit.

Every secret in both trees is a ${VAR} reference named in .env.example, or
CHANGE_ME in files that are not compose files. The live servers still hold
some of those values inline, so a live file can differ from its copy on
those lines alone. Existing .env.example files keep their comments, with new
keys appended at the end.

The ignore rules and the secrets contract now cover both trees, plus the
volume/ and volumes/ directories the home server uses.
2026-10-06 10:52:47 -04:00

73 lines
2.9 KiB
Python

"""Local source patches, applied to /code at container start.
Called from compose/start, compose/worker and compose/temporal-django-worker
before the app boots, so every recreated container comes back patched. (The old
approach patched running containers by hand and silently vanished on the next
`docker compose up`.)
Both patches exist because PostHog no longer sells self-hosted licenses, so the
license branches below are unreachable here. Both are gated on
MULTI_ORG_ENABLED (set in compose.override.yml), so unsetting it restores
upstream behaviour without un-patching. Only posthog/ files are touched, which
is MIT-licensed; ee/ is not involved.
Idempotent. If upstream changes shape, this warns loudly and lets the app start
unpatched rather than taking PostHog down. Check with:
docker compose logs web worker | grep LOCAL-PATCH
"""
import sys
PATCHES = [
(
# Shows the "New project" / "New organization" buttons. Upstream gates
# them on preflight's can_create_org, which demands a license.
"can_create_org",
"/code/posthog/utils.py",
""" if settings.MULTI_ORG_ENABLED:
license = get_cached_instance_license()
if license is not None and AvailableFeature.ZAPIER in license.available_features:
return True
else:
logger.warning("You have configured MULTI_ORG_ENABLED, but not the required premium PostHog plan!")
""",
""" if settings.MULTI_ORG_ENABLED:
# Local patch, see compose/local-patches.py
return True
""",
),
(
# Lifts the 1-project-per-org limit in the project API. Without a
# license, every org save and the periodic feature sync reset the org's
# features to [], and an org without `organizations_projects` may only
# have one project. With it and no `limit`, the cap is upstream's
# MAX_ALLOWED_PROJECTS_PER_ORG (2000).
"organizations_projects",
"/code/posthog/models/organization.py",
""" return self.available_product_features
def get_available_feature(""",
""" # Local patch, see compose/local-patches.py
if settings.MULTI_ORG_ENABLED and not self.get_available_feature("organizations_projects"):
self.available_product_features = [
*self.available_product_features,
{"key": "organizations_projects", "name": "Organizations projects"},
]
return self.available_product_features
def get_available_feature(""",
),
]
for name, path, old, new in PATCHES:
src = open(path).read()
if new in src:
status = "already applied"
elif src.count(old) == 1:
open(path, "w").write(src.replace(old, new))
status = "applied"
else:
status = "PATTERN NOT FOUND, upstream changed, running UNPATCHED"
print(f"LOCAL-PATCH {name}: {status}", file=sys.stderr, flush=True)