@geekmidas/cli 10.0.0-alpha.97 → 10.0.0-alpha.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{GoDaddyProvider-AqNu60WQ.mjs → GoDaddyProvider-C2fK-zeQ.mjs} +2 -2
- package/dist/{GoDaddyProvider-AqNu60WQ.mjs.map → GoDaddyProvider-C2fK-zeQ.mjs.map} +1 -1
- package/dist/{GoDaddyProvider-B4R_QFl8.cjs → GoDaddyProvider-SLlyDwD1.cjs} +2 -2
- package/dist/{GoDaddyProvider-B4R_QFl8.cjs.map → GoDaddyProvider-SLlyDwD1.cjs.map} +1 -1
- package/dist/{LegacyStateStore-B-aRqRdD.cjs → LegacyStateStore-CAvxM8U5.cjs} +3 -3
- package/dist/{LegacyStateStore-B-aRqRdD.cjs.map → LegacyStateStore-CAvxM8U5.cjs.map} +1 -1
- package/dist/{LegacyStateStore-8F05-BOo.mjs → LegacyStateStore-D9QDWCst.mjs} +3 -3
- package/dist/{LegacyStateStore-8F05-BOo.mjs.map → LegacyStateStore-D9QDWCst.mjs.map} +1 -1
- package/dist/{LocalStateStore-B_mfgcO8.mjs → LocalStateStore-DPQSqkSb.mjs} +2 -2
- package/dist/{LocalStateStore-B_mfgcO8.mjs.map → LocalStateStore-DPQSqkSb.mjs.map} +1 -1
- package/dist/{LocalStateStore-B_bRI8M7.cjs → LocalStateStore-QcrdjCl6.cjs} +2 -2
- package/dist/{LocalStateStore-B_bRI8M7.cjs.map → LocalStateStore-QcrdjCl6.cjs.map} +1 -1
- package/dist/{S3StateStore-zK9zcd9f.cjs → S3StateStore-C16tVikU.cjs} +10 -9
- package/dist/S3StateStore-C16tVikU.cjs.map +1 -0
- package/dist/{S3StateStore-CMN0Uzdp.mjs → S3StateStore-jorgKaee.mjs} +10 -9
- package/dist/S3StateStore-jorgKaee.mjs.map +1 -0
- package/dist/{SSMStateStore-Cv7VcMak.mjs → SSMStateStore-Dvjt_INw.mjs} +2 -2
- package/dist/{SSMStateStore-Cv7VcMak.mjs.map → SSMStateStore-Dvjt_INw.mjs.map} +1 -1
- package/dist/{SSMStateStore-C489DnR6.cjs → SSMStateStore-mPAEr2P2.cjs} +2 -2
- package/dist/{SSMStateStore-C489DnR6.cjs.map → SSMStateStore-mPAEr2P2.cjs.map} +1 -1
- package/dist/{add-BA5d4pA0.mjs → add-CZIIsTcv.mjs} +4 -4
- package/dist/{add-BA5d4pA0.mjs.map → add-CZIIsTcv.mjs.map} +1 -1
- package/dist/{add-HXzTCy_I.cjs → add-SRk65Udu.cjs} +4 -4
- package/dist/{add-HXzTCy_I.cjs.map → add-SRk65Udu.cjs.map} +1 -1
- package/dist/{aws-Dz2bYxK1.mjs → aws-8QQ8n-t6.mjs} +2 -2
- package/dist/{aws-Dz2bYxK1.mjs.map → aws-8QQ8n-t6.mjs.map} +1 -1
- package/dist/{aws-BTReGjpY.cjs → aws-DY9NqQIT.cjs} +2 -2
- package/dist/{aws-BTReGjpY.cjs.map → aws-DY9NqQIT.cjs.map} +1 -1
- package/dist/{awsStore-BWa1KNY-.mjs → awsStore-Bx5nCFnS.mjs} +8 -6
- package/dist/awsStore-Bx5nCFnS.mjs.map +1 -0
- package/dist/{awsStore-B5We7bMg.cjs → awsStore-u3ehhMoY.cjs} +8 -6
- package/dist/awsStore-u3ehhMoY.cjs.map +1 -0
- package/dist/{bundler-SX3Uy8qT.cjs → bundler-B0Pj5FXT.cjs} +5 -5
- package/dist/{bundler-SX3Uy8qT.cjs.map → bundler-B0Pj5FXT.cjs.map} +1 -1
- package/dist/{bundler-CBomFsnd.mjs → bundler-DxJ-cIEt.mjs} +5 -5
- package/dist/{bundler-CBomFsnd.mjs.map → bundler-DxJ-cIEt.mjs.map} +1 -1
- package/dist/{cli-1l0L9LCA.cjs → cli-CRDJWWmZ.cjs} +2 -2
- package/dist/{cli-1l0L9LCA.cjs.map → cli-CRDJWWmZ.cjs.map} +1 -1
- package/dist/{cli-D7z1lQtO.mjs → cli-CV85bY3-.mjs} +2 -2
- package/dist/{cli-D7z1lQtO.mjs.map → cli-CV85bY3-.mjs.map} +1 -1
- package/dist/{compose-DgWrNd2k.mjs → compose-CQQRRJC3.mjs} +7 -7
- package/dist/{compose-DgWrNd2k.mjs.map → compose-CQQRRJC3.mjs.map} +1 -1
- package/dist/{compose-C39XupJu.cjs → compose-DMY4ouEk.cjs} +7 -7
- package/dist/{compose-C39XupJu.cjs.map → compose-DMY4ouEk.cjs.map} +1 -1
- package/dist/{config-xIWIaDhW.d.cts → config-CS76CzXM.d.cts} +4 -4
- package/dist/{config-D-k0gaAr.d.mts.map → config-CS76CzXM.d.cts.map} +1 -1
- package/dist/{config-D-k0gaAr.d.mts → config-pBzLfNef.d.mts} +4 -4
- package/dist/{config-xIWIaDhW.d.cts.map → config-pBzLfNef.d.mts.map} +1 -1
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -1
- package/dist/deploy/public.cjs +7 -7
- package/dist/deploy/public.d.cts +5 -5
- package/dist/deploy/public.d.mts +5 -5
- package/dist/deploy/public.mjs +7 -7
- package/dist/{deploy-Cu_HyWoJ.cjs → deploy-277jek46.cjs} +7 -7
- package/dist/{deploy-Cu_HyWoJ.cjs.map → deploy-277jek46.cjs.map} +1 -1
- package/dist/{deploy-LY-20Yeb.mjs → deploy-Dw8g3sLY.mjs} +7 -7
- package/dist/{deploy-LY-20Yeb.mjs.map → deploy-Dw8g3sLY.mjs.map} +1 -1
- package/dist/{discover-CbJCQq4J.d.mts → discover-CU1LjCOf.d.cts} +2 -2
- package/dist/{discover-CbJCQq4J.d.mts.map → discover-CU1LjCOf.d.cts.map} +1 -1
- package/dist/{discover-RCW5mBXb.d.cts → discover-DJCCgimv.d.mts} +2 -2
- package/dist/{discover-RCW5mBXb.d.cts.map → discover-DJCCgimv.d.mts.map} +1 -1
- package/dist/{dns-Dro_vbk9.cjs → dns-4RAiVFa7.cjs} +5 -5
- package/dist/{dns-Dro_vbk9.cjs.map → dns-4RAiVFa7.cjs.map} +1 -1
- package/dist/{dns-Bmbhmz41.mjs → dns-CU22K_i0.mjs} +5 -5
- package/dist/{dns-Bmbhmz41.mjs.map → dns-CU22K_i0.mjs.map} +1 -1
- package/dist/{dns-BFnoawgh.cjs → dns-Dhjbnjgl.cjs} +3 -3
- package/dist/{dns-BFnoawgh.cjs.map → dns-Dhjbnjgl.cjs.map} +1 -1
- package/dist/{dns-BbTOzmVp.mjs → dns-LqWzPb8l.mjs} +3 -3
- package/dist/{dns-BbTOzmVp.mjs.map → dns-LqWzPb8l.mjs.map} +1 -1
- package/dist/{dokploy-LR94sBVI.mjs → dokploy-D_uCbZQ7.mjs} +2 -2
- package/dist/{dokploy-LR94sBVI.mjs.map → dokploy-D_uCbZQ7.mjs.map} +1 -1
- package/dist/{dokploy-CKgSww82.cjs → dokploy-Dw4oCXqR.cjs} +2 -2
- package/dist/{dokploy-CKgSww82.cjs.map → dokploy-Dw4oCXqR.cjs.map} +1 -1
- package/dist/{encryption-C0plOf4a.mjs → encryption-C0uKYE9v.mjs} +3 -3
- package/dist/{encryption-C0plOf4a.mjs.map → encryption-C0uKYE9v.mjs.map} +1 -1
- package/dist/{encryption-CUyw-8sc.cjs → encryption-CtVPHWWq.cjs} +3 -3
- package/dist/{encryption-CUyw-8sc.cjs.map → encryption-CtVPHWWq.cjs.map} +1 -1
- package/dist/{engine-DqbqQhck.mjs → engine-BE5PdE8S.mjs} +4 -4
- package/dist/{engine-DqbqQhck.mjs.map → engine-BE5PdE8S.mjs.map} +1 -1
- package/dist/{engine-D8TeraDK.cjs → engine-HI8aLw1M.cjs} +4 -4
- package/dist/{engine-D8TeraDK.cjs.map → engine-HI8aLw1M.cjs.map} +1 -1
- package/dist/{github-DC4SIqV1.cjs → github-BCdfZ9zO.cjs} +41 -19
- package/dist/github-BCdfZ9zO.cjs.map +1 -0
- package/dist/{github-zgaBOQvh.mjs → github-CT3X720_.mjs} +41 -19
- package/dist/github-CT3X720_.mjs.map +1 -0
- package/dist/{index-ClqOsbBl.d.mts → index-DKtB01YC.d.cts} +2 -2
- package/dist/{index-ClqOsbBl.d.mts.map → index-DKtB01YC.d.cts.map} +1 -1
- package/dist/{index-DgOBAEl5.d.cts → index-ZAUrXH6Q.d.mts} +2 -2
- package/dist/{index-DgOBAEl5.d.cts.map → index-ZAUrXH6Q.d.mts.map} +1 -1
- package/dist/index.cjs +73 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +73 -58
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-BJ8aLOWk.mjs → migrate-CCZUgxMK.mjs} +3 -3
- package/dist/{migrate-BJ8aLOWk.mjs.map → migrate-CCZUgxMK.mjs.map} +1 -1
- package/dist/{migrate-CWq8-s21.cjs → migrate-Cs7kQxD5.cjs} +3 -3
- package/dist/{migrate-CWq8-s21.cjs.map → migrate-Cs7kQxD5.cjs.map} +1 -1
- package/dist/migrate-DBGyoBvZ.cjs +181 -0
- package/dist/migrate-DBGyoBvZ.cjs.map +1 -0
- package/dist/migrate-DH-lOK3j.mjs +181 -0
- package/dist/migrate-DH-lOK3j.mjs.map +1 -0
- package/dist/openapi.cjs +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +1 -1
- package/dist/{projectBucket-Cho9DpSh.cjs → projectBucket-BjeDcAYy.cjs} +2 -2
- package/dist/{projectBucket-Cho9DpSh.cjs.map → projectBucket-BjeDcAYy.cjs.map} +1 -1
- package/dist/{projectBucket-BFp-SFee.mjs → projectBucket-DrkEht-j.mjs} +2 -2
- package/dist/{projectBucket-BFp-SFee.mjs.map → projectBucket-DrkEht-j.mjs.map} +1 -1
- package/dist/reconcile/public.d.cts +2 -2
- package/dist/reconcile/public.d.mts +2 -2
- package/dist/{resolve-C8VkR4oW.cjs → resolve-CScrqgdC.cjs} +3 -3
- package/dist/{resolve-C8VkR4oW.cjs.map → resolve-CScrqgdC.cjs.map} +1 -1
- package/dist/{resolve-6EYNqYdr.mjs → resolve-OfLaxaxY.mjs} +3 -3
- package/dist/{resolve-6EYNqYdr.mjs.map → resolve-OfLaxaxY.mjs.map} +1 -1
- package/dist/{rollback-CvGfm4DX.cjs → rollback-D7p4wJNO.cjs} +5 -5
- package/dist/{rollback-CvGfm4DX.cjs.map → rollback-D7p4wJNO.cjs.map} +1 -1
- package/dist/{rollback-BsThTeSN.mjs → rollback-DQBSN-i7.mjs} +5 -5
- package/dist/{rollback-BsThTeSN.mjs.map → rollback-DQBSN-i7.mjs.map} +1 -1
- package/dist/{runtime-CaW4QqF2.d.cts → runtime-BlHOVx8L.d.cts} +2 -2
- package/dist/{runtime-CaW4QqF2.d.cts.map → runtime-BlHOVx8L.d.cts.map} +1 -1
- package/dist/{runtime-K5uxp6HE.d.mts → runtime-DMq9C3KB.d.mts} +2 -2
- package/dist/{runtime-K5uxp6HE.d.mts.map → runtime-DMq9C3KB.d.mts.map} +1 -1
- package/dist/s3-CUKzBBae.mjs +215 -0
- package/dist/s3-CUKzBBae.mjs.map +1 -0
- package/dist/s3-QQi4sNOQ.cjs +215 -0
- package/dist/s3-QQi4sNOQ.cjs.map +1 -0
- package/dist/{sandbox-D8cfZUAA.d.cts → sandbox-ArJ_hEKk.d.cts} +2 -2
- package/dist/{sandbox-B_BkfmTP.d.mts.map → sandbox-ArJ_hEKk.d.cts.map} +1 -1
- package/dist/{sandbox-B_BkfmTP.d.mts → sandbox-Cm4X6HRh.d.mts} +2 -2
- package/dist/{sandbox-D8cfZUAA.d.cts.map → sandbox-Cm4X6HRh.d.mts.map} +1 -1
- package/dist/{secrets-HzKNTWg9.mjs → secrets-AA_tQUl-.mjs} +3 -3
- package/dist/{secrets-HzKNTWg9.mjs.map → secrets-AA_tQUl-.mjs.map} +1 -1
- package/dist/{secrets-BTY6JhTp.cjs → secrets-B_biKsKx.cjs} +3 -3
- package/dist/{secrets-BTY6JhTp.cjs.map → secrets-B_biKsKx.cjs.map} +1 -1
- package/dist/{secretsManager-C6wm-9uZ.mjs → secretsManager-CQORubp9.mjs} +2 -2
- package/dist/{secretsManager-C6wm-9uZ.mjs.map → secretsManager-CQORubp9.mjs.map} +1 -1
- package/dist/{secretsManager-Cwwgs81g.cjs → secretsManager-RAGcEDX1.cjs} +2 -2
- package/dist/{secretsManager-Cwwgs81g.cjs.map → secretsManager-RAGcEDX1.cjs.map} +1 -1
- package/dist/{seeds-BsJRUL1K.mjs → seeds-BvxWUGKJ.mjs} +32 -6
- package/dist/seeds-BvxWUGKJ.mjs.map +1 -0
- package/dist/{seeds-BQlj9Fsg.cjs → seeds-Df4BI-T3.cjs} +32 -6
- package/dist/seeds-Df4BI-T3.cjs.map +1 -0
- package/dist/{sniffer-DVsvP8s-.mjs → sniffer-BqjXvcaK.mjs} +7 -7
- package/dist/{sniffer-DVsvP8s-.mjs.map → sniffer-BqjXvcaK.mjs.map} +1 -1
- package/dist/{sniffer-CeUKUoHn.cjs → sniffer-DZeQJKty.cjs} +7 -7
- package/dist/{sniffer-CeUKUoHn.cjs.map → sniffer-DZeQJKty.cjs.map} +1 -1
- package/dist/{stack-BQOyqaVG.mjs → stack-A6MAFZ6u.mjs} +3 -3
- package/dist/{stack-BQOyqaVG.mjs.map → stack-A6MAFZ6u.mjs.map} +1 -1
- package/dist/{stack-Clzi40EE.cjs → stack-BpkZEEfB.cjs} +3 -3
- package/dist/{stack-Clzi40EE.cjs.map → stack-BpkZEEfB.cjs.map} +1 -1
- package/dist/{stages-DEmn7qI8.mjs → stages-6SEoRA4x.mjs} +6 -5
- package/dist/stages-6SEoRA4x.mjs.map +1 -0
- package/dist/{stages-BpDXFPGg.cjs → stages-DH5z89eT.cjs} +6 -5
- package/dist/stages-DH5z89eT.cjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{types-4vPS_YFX.d.cts → types-DipUP9zp.d.cts} +62 -8
- package/dist/types-DipUP9zp.d.cts.map +1 -0
- package/dist/{types-CFsEyFb1.d.mts → types-Drpl9HX9.d.mts} +62 -8
- package/dist/types-Drpl9HX9.d.mts.map +1 -0
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-Bv4xROeu.mjs → workspace-BBeT6Pil.mjs} +56 -4
- package/dist/workspace-BBeT6Pil.mjs.map +1 -0
- package/dist/{workspace-C1M-S4al.cjs → workspace-BJ78Bgvm.cjs} +67 -3
- package/dist/workspace-BJ78Bgvm.cjs.map +1 -0
- package/package.json +15 -15
- package/dist/S3StateStore-CMN0Uzdp.mjs.map +0 -1
- package/dist/S3StateStore-zK9zcd9f.cjs.map +0 -1
- package/dist/awsStore-B5We7bMg.cjs.map +0 -1
- package/dist/awsStore-BWa1KNY-.mjs.map +0 -1
- package/dist/github-DC4SIqV1.cjs.map +0 -1
- package/dist/github-zgaBOQvh.mjs.map +0 -1
- package/dist/migrate-C230QeXU.mjs +0 -94
- package/dist/migrate-C230QeXU.mjs.map +0 -1
- package/dist/migrate-CsMrI7Dk.cjs +0 -94
- package/dist/migrate-CsMrI7Dk.cjs.map +0 -1
- package/dist/seeds-BQlj9Fsg.cjs.map +0 -1
- package/dist/seeds-BsJRUL1K.mjs.map +0 -1
- package/dist/stages-BpDXFPGg.cjs.map +0 -1
- package/dist/stages-DEmn7qI8.mjs.map +0 -1
- package/dist/types-4vPS_YFX.d.cts.map +0 -1
- package/dist/types-CFsEyFb1.d.mts.map +0 -1
- package/dist/workspace-Bv4xROeu.mjs.map +0 -1
- package/dist/workspace-C1M-S4al.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose-C39XupJu.cjs","names":["GkmError","spawn","run","runOutput","mkdir","dirname","join","gkmHome","EDGE_PROJECT","GkmError","writeFile","chmod","rename","readFile","mkdir","traefikStaticFile","edgeComposeFile","EDGE_NETWORK","EDGE_SERVICE","copyFile","rm","existsSync","GkmError","request","GkmError","join","runOutput","LOGS_PORT_ENV","EDGE_PORT_ENV","pgClient","bucketClient","ensurePostgresLogin","migrateDatabases","seedDatabases","systemLookup","RegistryRequired","imageRef","discover","constructGlobs","imageLayout","composeStack","loadLocalCredentials","assertImagesExist","stackDir","existsSync","composeProject","ComposeTlsFileMissing","stackHosts","isLocalHost","installedFrom","requiredServerAddress","SERVER_IPV4_KEY","serverAddressHint","stageDns","DeployJournal","createComposeState","recordDnsChanges","HostNotPointingAtServer","deployedStackSecrets","pinImages","plannedSeeds","EDGE_PROJECT","EDGE_SERVICE","LOG_ROTATION","applyBuckets","applyPolicies","LEGACY_LOCAL_LOGIN","postgresStatements","applyPostgres","envFor","primaryPortKey","SeedFailed","DeploySeedsFailed","currentActor","readFile","LOGS_SERVICE","logsAccess","hostname","userInfo","mkdir","chmod","dirname","writeFile","rm","envFile","REDIS_SERVICE","readdir","ensureDockerignore","findBuildRoot","stringify","defineTarget"],"sources":["../src/compose/docker.ts","../src/compose/edge.ts","../src/target/compose/health.ts","../src/target/compose/phases.ts","../src/target/compose/index.ts"],"sourcesContent":["/**\n * The Docker operations `gkm compose` needs, behind an interface.\n *\n * Small on purpose, like reconcile's: the rules about *when* each runs — the\n * registry is asked before anything is pulled, nothing is started for a tag\n * that is missing — are asserted against a fake, and this file is only the\n * wiring to the real CLI.\n *\n * Every call is an argument array. Image refs, tags and paths come from the\n * workspace, and none of them reaches a shell.\n */\n\nimport { spawn } from 'node:child_process';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { GkmError } from '../errors';\nimport { type RunOptions, run, runOutput } from '../run';\n\n/** Where one stack lives: its compose project and the file that defines it. */\nexport interface StackRef {\n\tproject: string;\n\tfile: string;\n\t/**\n\t * The project's own files merged over `file`, in order — its\n\t * `docker-compose.<stage>.yml`, where it has one.\n\t */\n\toverrides?: readonly string[];\n\t/** Where relative paths in the file resolve — the workspace root. */\n\tcwd: string;\n\t/**\n\t * Where docker's own output goes: the terminal (the default), stderr — so\n\t * a `--json` run's stdout carries only events — or nowhere.\n\t */\n\toutput?: 'inherit' | 'stderr' | 'ignore';\n\t/** Stops whatever docker is doing for the stack. */\n\tsignal?: AbortSignal;\n}\n\n/** `output` as `spawn` reads it. */\nconst STDIO: Record<NonNullable<StackRef['output']>, RunOptions['stdio']> = {\n\tinherit: 'inherit',\n\tstderr: ['ignore', 2, 2],\n\tignore: 'ignore',\n};\n\n/** How a stack's docker commands run: where it is, where output goes. */\nfunction runOptions(stack: StackRef, env?: NodeJS.ProcessEnv): RunOptions {\n\treturn {\n\t\tcwd: stack.cwd,\n\t\tstdio: STDIO[stack.output ?? 'inherit'],\n\t\t...(env ? { env } : {}),\n\t\t...(stack.signal ? { signal: stack.signal } : {}),\n\t};\n}\n\n/** What the registry said about one image ref. */\nexport type ImageLookup =\n\t| { ref: string; status: 'found' }\n\t| { ref: string; status: 'missing' }\n\t| { ref: string; status: 'unreachable'; detail: string };\n\n/** A running container that publishes a host port. */\nexport interface PortHolder {\n\t/** The container's name. */\n\tcontainer: string;\n\t/** Its compose project and service, when compose started it. */\n\tproject?: string;\n\tservice?: string;\n}\n\nexport interface ComposeDocker {\n\t/** Ask the registry whether `ref` exists, without pulling it. */\n\tlookup(ref: string): Promise<ImageLookup>;\n\t/** Build every service with a `build:` entry. */\n\tbuild(stack: StackRef, services: readonly string[]): Promise<void>;\n\t/** Pull the named services' images. */\n\tpull(stack: StackRef, services: readonly string[]): Promise<void>;\n\t/**\n\t * Start services, detached, and wait for their health checks. With no\n\t * services named, the whole stack — and anything it no longer defines is\n\t * removed.\n\t */\n\tup(stack: StackRef, services?: readonly string[]): Promise<void>;\n\t/** Stop the stack. Its volumes are kept. */\n\tdown(stack: StackRef): Promise<void>;\n\t/** The host port a running service publishes for `inside`. */\n\tport(stack: StackRef, service: string, inside: number): Promise<number>;\n\t/**\n\t * A running service's health, as its own check reports it — `healthy`,\n\t * `starting`, `unhealthy` — or undefined when it is not running.\n\t */\n\thealth(stack: StackRef, service: string): Promise<string | undefined>;\n\t/** Copy a file out of a running service. */\n\tcopyOut(\n\t\tstack: StackRef,\n\t\tservice: string,\n\t\tfrom: string,\n\t\tto: string,\n\t): Promise<void>;\n\t/**\n\t * Push an image built here to its registry, and return the digest the\n\t * registry stored it under (`sha256:…`).\n\t */\n\tpush(stack: StackRef, ref: string): Promise<string>;\n\t/**\n\t * What an image resolved to: the registry digest a pulled image has, or\n\t * the content id of one built here and never pushed.\n\t */\n\tdigest(ref: string): Promise<string | undefined>;\n\t/** Create a network, unless one by that name is there. */\n\tensureNetwork(name: string): Promise<void>;\n\t/** Every running container publishing `port` on the host. */\n\tpublishers(port: number): Promise<PortHolder[]>;\n}\n\n/**\n * The host ports a `docker ps` Ports column publishes: `0.0.0.0:443->443/tcp,\n * [::]:443->443/tcp, 0.0.0.0:9000-9001->9000-9001/tcp`.\n */\nexport function publishedPorts(column: string): number[] {\n\tconst ports = new Set<number>();\n\tfor (const match of column.matchAll(\n\t\t/(?:[\\d.]+|\\[[^\\]]*\\]):(\\d+)(?:-(\\d+))?->/g,\n\t)) {\n\t\tconst first = Number(match[1]);\n\t\tconst last = match[2] ? Number(match[2]) : first;\n\t\tfor (let port = first; port <= last; port++) ports.add(port);\n\t}\n\treturn [...ports];\n}\n\n/** Each line `docker ps` printed, as the containers holding `port`. */\nexport function portHolders(output: string, port: number): PortHolder[] {\n\treturn output\n\t\t.split('\\n')\n\t\t.filter(Boolean)\n\t\t.map((line) => line.split('\\t'))\n\t\t.filter(([, , , column = '']) => publishedPorts(column).includes(port))\n\t\t.map(([container = '', project, service]) => ({\n\t\t\tcontainer,\n\t\t\t...(project ? { project } : {}),\n\t\t\t...(service ? { service } : {}),\n\t\t}));\n}\n\n/** How long a stack has to pass its health checks. */\nconst WAIT_TIMEOUT_S = 180;\n\n/** `docker compose port` printed nothing a port can be read from. */\nexport class ServicePortUnknown extends GkmError {\n\tconstructor(\n\t\treadonly service: string,\n\t\treadonly inside: number,\n\t\treadonly output: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${service}' publishes no host port for ${inside} (docker said: ${output.trim() || 'nothing'}). Is it running? \\`docker compose ps\\` shows the stack.`,\n\t\t);\n\t\tthis.name = 'ServicePortUnknown';\n\t}\n}\n\n/**\n * Whether `ref` names a registry on this machine's loopback — which the\n * daemon pulls from and pushes to over plain HTTP by default, and `docker\n * manifest inspect` reaches only when told `--insecure` (without it, a local\n * registry's image is reported as no such manifest).\n */\nexport function isLoopbackRegistry(ref: string): boolean {\n\tconst first = ref.split('/')[0]!;\n\tif (!ref.includes('/') || !/[.:]|^localhost$/.test(first)) return false;\n\tconst host = first.replace(/:\\d+$/, '');\n\treturn host === 'localhost' || /^127(?:\\.\\d{1,3}){3}$/.test(host);\n}\n\n/** `docker push` finished without saying what digest the registry stored. */\nexport class PushDigestUnknown extends GkmError {\n\tconstructor(\n\t\treadonly ref: string,\n\t\treadonly output: string,\n\t) {\n\t\tsuper(\n\t\t\t`Pushed ${ref}, but docker did not say which digest the registry stored ` +\n\t\t\t\t`(it said: ${output.trim().split('\\n').slice(-3).join(' / ') || 'nothing'}). ` +\n\t\t\t\t`Check the push with \\`docker buildx imagetools inspect ${ref}\\`.`,\n\t\t);\n\t\tthis.name = 'PushDigestUnknown';\n\t}\n}\n\n/** The digest `docker push` reports last: `<tag>: digest: sha256:… size: …`. */\nexport function pushedDigest(output: string): string | undefined {\n\tconst matches = [...output.matchAll(/digest: (sha256:[0-9a-f]{64})/g)];\n\treturn matches.at(-1)?.[1];\n}\n\nfunction compose(stack: StackRef, args: readonly string[]): string[] {\n\treturn [\n\t\t'compose',\n\t\t'-p',\n\t\tstack.project,\n\t\t'-f',\n\t\tstack.file,\n\t\t...(stack.overrides ?? []).flatMap((file) => ['-f', file]),\n\t\t...args,\n\t];\n}\n\n/** Run a program and keep everything it said, whatever it exits with. */\nfunction capture(\n\tcommand: string,\n\targs: readonly string[],\n\ttimeoutMs = 60_000,\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(command, [...args], {\n\t\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\t\tshell: false,\n\t\t});\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\t\tchild.stdout.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString();\n\t\t});\n\t\tchild.stderr.on('data', (chunk: Buffer) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\t\tconst timer = setTimeout(() => child.kill('SIGKILL'), timeoutMs);\n\t\ttimer.unref?.();\n\t\tchild.on('error', (error) => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(error);\n\t\t});\n\t\tchild.on('close', (code) => {\n\t\t\tclearTimeout(timer);\n\t\t\tresolve({ code, stdout, stderr });\n\t\t});\n\t});\n}\n\n/**\n * Whether a failed `docker manifest inspect` means the tag is not there, as\n * opposed to the registry not answering.\n *\n * Read off the message because that is all the CLI gives. Anything not\n * recognisably \"no such tag\" is treated as the registry being unreachable:\n * a registry that refused credentials must not be reported as a tag that was\n * never pushed, or the fix offered would be the wrong one.\n */\nexport function isMissingManifest(output: string): boolean {\n\treturn /no such manifest|manifest unknown|manifest for .* not found|not found: manifest/i.test(\n\t\toutput,\n\t);\n}\n\nexport const dockerCompose: ComposeDocker = {\n\tasync lookup(ref) {\n\t\tconst { code, stdout, stderr } = await capture('docker', [\n\t\t\t'manifest',\n\t\t\t'inspect',\n\t\t\t...(isLoopbackRegistry(ref) ? ['--insecure'] : []),\n\t\t\tref,\n\t\t]);\n\t\tif (code === 0) return { ref, status: 'found' };\n\n\t\tconst output = `${stderr}\\n${stdout}`.trim();\n\t\treturn isMissingManifest(output)\n\t\t\t? { ref, status: 'missing' }\n\t\t\t: { ref, status: 'unreachable', detail: output };\n\t},\n\n\tasync build(stack, services) {\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['build', ...services]),\n\t\t\trunOptions(stack, { ...process.env, DOCKER_BUILDKIT: '1' }),\n\t\t);\n\t},\n\n\tasync pull(stack, services) {\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['pull', ...services]),\n\t\t\trunOptions(stack),\n\t\t);\n\t},\n\n\tasync up(stack, services) {\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, [\n\t\t\t\t'up',\n\t\t\t\t'-d',\n\t\t\t\t'--wait',\n\t\t\t\t`--wait-timeout=${WAIT_TIMEOUT_S}`,\n\t\t\t\t// Only when the whole stack is asked for: starting the databases\n\t\t\t\t// first must not remove the apps an earlier run left running.\n\t\t\t\t...(services ? [] : ['--remove-orphans']),\n\t\t\t\t...(services ?? []),\n\t\t\t]),\n\t\t\trunOptions(stack),\n\t\t);\n\t},\n\n\tasync down(stack) {\n\t\tawait run('docker', compose(stack, ['down']), runOptions(stack));\n\t},\n\n\tasync port(stack, service, inside) {\n\t\tconst output = await runOutput(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['port', service, String(inside)]),\n\t\t\t{ cwd: stack.cwd, ...(stack.signal ? { signal: stack.signal } : {}) },\n\t\t);\n\t\t// `127.0.0.1:54321` — the part after the last colon is the host port.\n\t\tconst port = Number(output.trim().split(':').pop());\n\t\tif (!Number.isInteger(port) || port <= 0) {\n\t\t\tthrow new ServicePortUnknown(service, inside, output);\n\t\t}\n\t\treturn port;\n\t},\n\n\tasync health(stack, service) {\n\t\tconst { code, stdout } = await capture('docker', [\n\t\t\t...compose(stack, ['ps', '--format', '{{.Health}}', service]),\n\t\t]);\n\t\tif (code !== 0) return undefined;\n\t\treturn stdout.trim().split('\\n')[0] || undefined;\n\t},\n\n\tasync copyOut(stack, service, from, to) {\n\t\tawait mkdir(dirname(to), { recursive: true });\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['cp', `${service}:${from}`, to]),\n\t\t\trunOptions(stack),\n\t\t);\n\t},\n\n\tasync push(stack, ref) {\n\t\t// What it printed is read back for the digest; its errors still reach\n\t\t// the terminal.\n\t\tconst output = await runOutput('docker', ['push', ref], {\n\t\t\tcwd: stack.cwd,\n\t\t\t...(stack.signal ? { signal: stack.signal } : {}),\n\t\t});\n\t\tconst digest = pushedDigest(output);\n\t\tif (!digest) throw new PushDigestUnknown(ref, output);\n\t\treturn digest;\n\t},\n\n\tasync digest(ref) {\n\t\tconst { code, stdout } = await capture('docker', [\n\t\t\t'image',\n\t\t\t'inspect',\n\t\t\t'--format={{json .RepoDigests}} {{.Id}}',\n\t\t\tref,\n\t\t]);\n\t\tif (code !== 0) return undefined;\n\n\t\tconst [json = '[]', id] = stdout.trim().split(' ');\n\t\tconst repository = ref.split('@')[0]!.replace(/:[\\w][\\w.-]*$/, '');\n\t\ttry {\n\t\t\tconst digests = JSON.parse(json) as unknown;\n\t\t\tconst match = Array.isArray(digests)\n\t\t\t\t? digests.find(\n\t\t\t\t\t\t(entry): entry is string =>\n\t\t\t\t\t\t\ttypeof entry === 'string' && entry.startsWith(`${repository}@`),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t\tif (match) return match.slice(repository.length + 1);\n\t\t} catch {\n\t\t\t// Fall through to the content id.\n\t\t}\n\t\treturn id || undefined;\n\t},\n\n\tasync ensureNetwork(name) {\n\t\tconst { code } = await capture('docker', ['network', 'inspect', name]);\n\t\tif (code === 0) return;\n\t\tconst created = await capture('docker', ['network', 'create', name]);\n\t\t// Another run may have created it between the two calls.\n\t\tif (created.code !== 0 && !/already exists/.test(created.stderr)) {\n\t\t\tthrow new NetworkCreateFailed(name, created.stderr);\n\t\t}\n\t},\n\n\tasync publishers(port) {\n\t\tconst { stdout } = await capture('docker', [\n\t\t\t'ps',\n\t\t\t'--format',\n\t\t\t'{{.Names}}\\t{{.Label \"com.docker.compose.project\"}}\\t{{.Label \"com.docker.compose.service\"}}\\t{{.Ports}}',\n\t\t]);\n\t\treturn portHolders(stdout, port);\n\t},\n};\n\n/** `docker network create` failed. */\nexport class NetworkCreateFailed extends Error {\n\tconstructor(\n\t\treadonly network: string,\n\t\treadonly output: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not create the Docker network '${network}' (docker said: ${output.trim() || 'nothing'}). Create it by hand with \\`docker network create ${network}\\` and run again.`,\n\t\t);\n\t\tthis.name = 'NetworkCreateFailed';\n\t}\n}\n","/**\n * The server's shared Traefik edge, on disk and in Docker: started when a\n * stack needs it, and each stack's routes written to — and removed from —\n * the directory it watches.\n *\n * The edge lives in the deploy user's gkm home (`$GKM_HOME/edge`, else\n * `~/.gkm/edge`): the user who runs `gkm compose` owns it, so nothing needs\n * root, and it sits beside the stage keys that same user already keeps.\n *\n * ~/.gkm/edge/\n * docker-compose.yml the edge's compose project (gkm-edge)\n * traefik.yml its static configuration\n * dynamic/<project>.yml one per stack: its routers, services, middlewares\n * certs/<project>.crt|.key a stack's own certificate, where it has one\n */\n\nimport { existsSync } from 'node:fs';\nimport {\n\tchmod,\n\tcopyFile,\n\tmkdir,\n\treadFile,\n\trename,\n\trm,\n\twriteFile,\n} from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { GkmError } from '../errors';\nimport { gkmHome } from '../home.js';\nimport type { ComposeDocker, PortHolder, StackRef } from './docker.js';\nimport type { ComposeProxy } from './routes.js';\nimport {\n\tEDGE_NETWORK,\n\tEDGE_PROJECT,\n\tEDGE_SERVICE,\n\ttype EdgePorts,\n\tedgeComposeFile,\n\ttraefikStaticFile,\n} from './traefik.js';\n\n/** The edge's directory on this machine. */\nexport function edgeDir(env: NodeJS.ProcessEnv = process.env): string {\n\treturn join(gkmHome(env), 'edge');\n}\n\n/** The edge's compose project, as docker is asked about it. */\nexport function edgeRef(\n\tdir: string,\n\toptions: Pick<StackRef, 'output' | 'signal'> = {},\n): StackRef {\n\treturn {\n\t\tproject: EDGE_PROJECT,\n\t\tfile: join(dir, 'docker-compose.yml'),\n\t\tcwd: dir,\n\t\t...options,\n\t};\n}\n\n/**\n * Something other than the proxy a stack is set to holds the edge's ports.\n *\n * With `proxy: 'traefik'`, the stack's own Caddy — still running from before\n * the switch — or any other container; with `proxy: 'caddy'`, the shared\n * edge, or another stack's Caddy. Refused before anything is started, so the\n * stack is never left half on one proxy and half on the other.\n */\nexport class ComposeProxyClash extends GkmError {\n\tconstructor(\n\t\treadonly project: string,\n\t\treadonly proxy: ComposeProxy,\n\t\treadonly port: number,\n\t\treadonly holder: PortHolder,\n\t) {\n\t\tconst by = holder.project\n\t\t\t? `${holder.container} (compose project ${holder.project})`\n\t\t\t: holder.container;\n\t\tconst fix =\n\t\t\tproxy === 'traefik'\n\t\t\t\t? holder.project === project && holder.service === 'caddy'\n\t\t\t\t\t? `That is this stack's own Caddy, from before it was switched to proxy: 'traefik'. Move it once: stop it (docker compose -p ${project} stop caddy), then run gkm compose again — the shared edge takes 80/443 and the stack registers with it.`\n\t\t\t\t\t: `The shared edge needs ports 80 and 443. Stop ${holder.container}${holder.project ? ` (docker compose -p ${holder.project} down, or its own gkm compose --down)` : ''}, or move the edge with GKM_COMPOSE_HTTPS_PORT/GKM_COMPOSE_HTTP_PORT.`\n\t\t\t\t: holder.project === EDGE_PROJECT\n\t\t\t\t\t? `That is the server's shared Traefik edge, which other stacks register with. Set deploy.compose.proxy to 'traefik' for this stage so the stack registers with it too, or stop the edge once nothing uses it (docker compose -p ${EDGE_PROJECT} down).`\n\t\t\t\t\t: `Stop ${holder.container}, or publish this stack's Caddy elsewhere with GKM_COMPOSE_HTTPS_PORT/GKM_COMPOSE_HTTP_PORT.`;\n\t\tsuper(\n\t\t\t`${project} is set to proxy: '${proxy}', and port ${port} is held by ${by}. ${fix}`,\n\t\t);\n\t\tthis.name = 'ComposeProxyClash';\n\t}\n}\n\n/**\n * Refuse a stack whose edge ports are held by anything but its own proxy:\n * the shared edge for `'traefik'`, the stack's own Caddy for `'caddy'`.\n */\nexport async function assertEdgePorts(\n\tdocker: ComposeDocker,\n\toptions: { project: string; proxy: ComposeProxy; ports: EdgePorts },\n): Promise<void> {\n\tconst { project, proxy, ports } = options;\n\tfor (const port of [ports.https, ports.http]) {\n\t\tfor (const holder of await docker.publishers(port)) {\n\t\t\tconst own =\n\t\t\t\tproxy === 'traefik'\n\t\t\t\t\t? holder.project === EDGE_PROJECT\n\t\t\t\t\t: holder.project === project && holder.service === 'caddy';\n\t\t\tif (!own) throw new ComposeProxyClash(project, proxy, port, holder);\n\t\t}\n\t}\n}\n\n/** Write a file whole or not at all: a temporary file, then a rename. */\nasync function writeAtomic(\n\tpath: string,\n\tcontent: string,\n\tmode = 0o644,\n): Promise<void> {\n\t// Not `.yml`: the edge reads only `.yml`, `.yaml` and `.toml` files, so it\n\t// never sees one half written.\n\tconst temporary = `${path}.${process.pid}.tmp`;\n\tawait writeFile(temporary, content, { mode });\n\tawait chmod(temporary, mode);\n\tawait rename(temporary, path);\n}\n\n/** Write a file only when its content changed; whether it did. */\nasync function writeIfChanged(path: string, content: string): Promise<boolean> {\n\tconst current = await readFile(path, 'utf-8').catch(() => undefined);\n\tif (current === content) return false;\n\tawait writeAtomic(path, content);\n\treturn true;\n}\n\n/**\n * The edge, up: its network, its files, and its container — started when it\n * is not running, and recreated when its configuration changed. Idempotent:\n * on a server where it already runs as configured, `up` changes nothing.\n */\nexport async function ensureEdge(\n\tdocker: ComposeDocker,\n\toptions: {\n\t\tdir: string;\n\t\tports: EdgePorts;\n\t\tlogging: { driver: string; options: Record<string, string> };\n\t\toutput?: StackRef['output'];\n\t\tsignal?: AbortSignal;\n\t},\n): Promise<string[]> {\n\tconst { dir, ports } = options;\n\tawait mkdir(join(dir, 'dynamic'), { recursive: true });\n\tawait mkdir(join(dir, 'certs'), { recursive: true, mode: 0o700 });\n\n\tconst staticConfig = traefikStaticFile(ports);\n\tawait writeIfChanged(join(dir, 'traefik.yml'), staticConfig);\n\tawait writeIfChanged(\n\t\tjoin(dir, 'docker-compose.yml'),\n\t\tedgeComposeFile({ dir, ports, staticConfig, logging: options.logging }),\n\t);\n\n\tawait docker.ensureNetwork(EDGE_NETWORK);\n\tawait docker.up(\n\t\tedgeRef(dir, {\n\t\t\t...(options.output ? { output: options.output } : {}),\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t}),\n\t\t[EDGE_SERVICE],\n\t);\n\treturn [join(dir, 'traefik.yml'), join(dir, 'docker-compose.yml')];\n}\n\n/** A stack's file in the edge's directory. */\nexport function routesFile(dir: string, project: string): string {\n\treturn join(dir, 'dynamic', `${project}.yml`);\n}\n\n/**\n * Register a stack with the edge: its certificate first, where it has one,\n * so the routes that need it never load without it — then its routes, in one\n * rename the edge picks up whole.\n */\nexport async function writeEdgeRoutes(\n\tdir: string,\n\tproject: string,\n\troutes: string,\n\tcertificate?: { certFile: string; keyFile: string },\n): Promise<string[]> {\n\tconst files: string[] = [];\n\tif (certificate) {\n\t\tconst certs = join(dir, 'certs');\n\t\tawait mkdir(certs, { recursive: true, mode: 0o700 });\n\t\tconst crt = join(certs, `${project}.crt`);\n\t\tconst key = join(certs, `${project}.key`);\n\t\tawait copyFile(certificate.certFile, `${crt}.tmp`);\n\t\tawait rename(`${crt}.tmp`, crt);\n\t\tawait copyFile(certificate.keyFile, `${key}.tmp`);\n\t\tawait chmod(`${key}.tmp`, 0o600);\n\t\tawait rename(`${key}.tmp`, key);\n\t\tfiles.push(crt, key);\n\t} else {\n\t\tawait removeCertificate(dir, project);\n\t}\n\tawait mkdir(join(dir, 'dynamic'), { recursive: true });\n\tconst file = routesFile(dir, project);\n\tawait writeAtomic(file, routes);\n\tfiles.push(file);\n\treturn files;\n}\n\n/** What a stack's file holds for the moment between emptying and removal. */\nconst UNREGISTERED = '# Unregistered by gkm compose --down.\\n';\n\nasync function removeCertificate(dir: string, project: string): Promise<void> {\n\tfor (const ext of ['crt', 'key']) {\n\t\tawait rm(join(dir, 'certs', `${project}.${ext}`), { force: true });\n\t}\n}\n\n/**\n * Unregister a stack: its routes, then its certificate. Whether there was\n * anything to remove.\n */\nexport async function removeEdgeRoutes(\n\tdir: string,\n\tproject: string,\n): Promise<boolean> {\n\tconst file = routesFile(dir, project);\n\tconst existed = existsSync(file);\n\tif (existed) {\n\t\t// Emptied by a rename before it is removed. A watcher that misses the\n\t\t// removal — Docker Desktop's file sharing can drop a delete event —\n\t\t// has still seen the stack's routes go.\n\t\tawait writeAtomic(file, UNREGISTERED);\n\t}\n\tawait rm(file, { force: true });\n\tawait removeCertificate(dir, project);\n\treturn existed;\n}\n","/**\n * Asking each app of a stack whether it answers — through Caddy, over HTTPS,\n * the way a browser reaches it.\n *\n * `docker compose up --wait` already knows each container passed its own\n * health check, asked on 127.0.0.1 inside it. What that cannot say is whether\n * the stack is reachable: whether the edge routes the host to the app, and\n * whether the certificate it presents is one a client accepts. So the check\n * goes through the edge, by hostname, and verifies the certificate.\n */\n\nimport { request } from 'node:https';\nimport { GkmError } from '../../errors';\n\n/** One request to the edge. */\nexport interface HealthRequest {\n\t/** The app's public URL plus its health path. */\n\turl: string;\n\t/**\n\t * The certificate authority to verify against, PEM — Caddy's internal CA\n\t * on the local stage. The system's when absent.\n\t */\n\tca?: string;\n\t/**\n\t * Connect here instead of resolving the URL's host — the local edge, at\n\t * 127.0.0.1. The host is still sent as SNI and `Host`, so nothing depends\n\t * on how this machine resolves `*.localhost`.\n\t */\n\tconnectTo?: string;\n\t/**\n\t * With `connectTo`, the port to connect to, where it is not the URL's —\n\t * the shared edge's published port, asked for a deployed host.\n\t */\n\tconnectPort?: number;\n\ttimeoutMs: number;\n\tsignal?: AbortSignal;\n}\n\n/** Asks once, resolving with the HTTP status. Rejects when nothing answers. */\nexport type HealthProbe = (request: HealthRequest) => Promise<number>;\n\n/** A request that got no answer in time. */\nexport class HealthRequestTimedOut extends GkmError {\n\tconstructor(\n\t\treadonly url: string,\n\t\treadonly timeoutMs: number,\n\t) {\n\t\tsuper(\n\t\t\t`${url} did not answer within ${timeoutMs}ms. Check the stack is up with \\`docker compose ps\\`.`,\n\t\t);\n\t\tthis.name = 'HealthRequestTimedOut';\n\t}\n}\n\n/** The real probe: one HTTPS GET, the certificate verified. */\nexport const httpsProbe: HealthProbe = ({\n\turl,\n\tca,\n\tconnectTo,\n\tconnectPort,\n\ttimeoutMs,\n\tsignal,\n}) => {\n\tconst target = new URL(url);\n\treturn new Promise((resolve, reject) => {\n\t\tconst req = request(\n\t\t\t{\n\t\t\t\thost: connectTo ?? target.hostname,\n\t\t\t\tport: connectPort ?? (target.port || 443),\n\t\t\t\tservername: target.hostname,\n\t\t\t\tpath: `${target.pathname}${target.search}`,\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { host: target.host },\n\t\t\t\t...(ca ? { ca } : {}),\n\t\t\t\t...(signal ? { signal } : {}),\n\t\t\t\ttimeout: timeoutMs,\n\t\t\t},\n\t\t\t(res) => {\n\t\t\t\t// The status is the answer; the body is drained so the socket closes.\n\t\t\t\tres.resume();\n\t\t\t\tres.on('end', () => resolve(res.statusCode ?? 0));\n\t\t\t\tres.on('error', reject);\n\t\t\t},\n\t\t);\n\t\treq.on('timeout', () =>\n\t\t\treq.destroy(new HealthRequestTimedOut(url, timeoutMs)),\n\t\t);\n\t\treq.on('error', reject);\n\t\treq.end();\n\t});\n};\n\n/** Whether a status means the app answered as it should. */\nexport function isHealthy(status: number): boolean {\n\treturn status >= 200 && status < 400;\n}\n\n/** Apps that did not answer through the edge. */\nexport class ComposeAppsUnhealthy extends GkmError {\n\tconstructor(\n\t\treadonly project: string,\n\t\t/** Each app, and the last thing its check got: a status or an error. */\n\t\treadonly apps: readonly { app: string; url: string; last: string }[],\n\t\t/** The proxy they were asked through. */\n\t\treadonly proxy: 'caddy' | 'traefik' = 'caddy',\n\t) {\n\t\tconst names = apps.map((a) => a.app).join(' ');\n\t\tsuper(\n\t\t\t`${project} started, but ${apps.length === 1 ? 'this app does' : 'these apps do'} not answer through ${proxy === 'caddy' ? 'Caddy' : 'the shared Traefik edge'}:\\n` +\n\t\t\t\tapps.map(({ url, last }) => ` - ${url}: ${last}`).join('\\n') +\n\t\t\t\t(proxy === 'caddy'\n\t\t\t\t\t? `\\nSee why with \\`docker compose -p ${project} logs caddy ${names}\\`.`\n\t\t\t\t\t: `\\nSee why with \\`docker compose -p gkm-edge logs traefik\\` and \\`docker compose -p ${project} logs ${names}\\`.`),\n\t\t);\n\t\tthis.name = 'ComposeAppsUnhealthy';\n\t}\n}\n","/**\n * The compose target's phases: a stage as one Docker Compose stack behind\n * Caddy, on the machine the deploy runs on.\n *\n * The order is the point of this file, and the rules it keeps are these:\n *\n * - A tag is checked before anything happens (`validate`). Every app's image\n * is asked of the registry first; one missing image stops the run naming\n * them all, and nothing is written, pulled or started.\n * - The databases exist before the apps do (`provision`). Postgres comes up\n * alone, its databases, roles and grants are created, its migrations\n * applied and its seeds run from this machine, and only then do the apps\n * start — so an app\n * never boots against a schema that is not there yet.\n * - What a stage runs is recorded (`release`). Each app's image, the tag it\n * was released under and the digest it resolved to are written to the\n * stage's state, so \"what is this stage running\" has an exact answer.\n * - What was started answers (`verify`): each app is asked through Caddy,\n * over HTTPS, with the certificate verified.\n *\n * Every image is built inside Docker from a pruned slice of the build root —\n * the same Dockerfiles `gkm docker` writes — so nothing is built on this\n * machine before `docker compose build`.\n *\n * Docker, the registry, Postgres and the health probe are\n * injected, so the rules are asserted without a daemon; the defaults are the\n * real ones.\n */\n\nimport { existsSync } from 'node:fs';\nimport {\n\tchmod,\n\tmkdir,\n\treaddir,\n\treadFile,\n\trm,\n\twriteFile,\n} from 'node:fs/promises';\nimport { hostname, userInfo } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport { stringify } from 'yaml';\nimport {\n\ttype HostLookup,\n\tHostNotPointingAtServer,\n\tisLocalHost,\n\trequiredServerAddress,\n\tSERVER_IPV4_KEY,\n\tserverAddressHint,\n\tstackHosts,\n\tstageDns,\n\tsystemLookup,\n} from '../../compose/dns';\nimport {\n\ttype ComposeDocker,\n\tdockerCompose,\n\ttype StackRef,\n} from '../../compose/docker';\nimport {\n\tassertEdgePorts,\n\tedgeDir,\n\tensureEdge,\n\tremoveEdgeRoutes,\n\twriteEdgeRoutes,\n} from '../../compose/edge';\nimport {\n\tassertImagesExist,\n\ttype ImageDigests,\n\tpinImages,\n\tRegistryRequired,\n} from '../../compose/images';\nimport { LOGS_SERVICE, logsAccess, type StackLogs } from '../../compose/logs';\nimport { ComposeTlsFileMissing } from '../../compose/proxy';\nimport { REDIS_SERVICE } from '../../compose/redis';\nimport { deployedStackSecrets } from '../../compose/secrets';\nimport {\n\ttype ComposeStack,\n\tcomposeProject,\n\tcomposeStack,\n\tEDGE_PORT_ENV,\n\tenvFile,\n\tLOG_ROTATION,\n\tLOGS_PORT_ENV,\n\ttype StackApp,\n\tstackDir,\n} from '../../compose/stack';\nimport { EDGE_PROJECT, EDGE_SERVICE } from '../../compose/traefik';\nimport { currentActor } from '../../deploy/actor.js';\nimport { recordDnsChanges } from '../../deploy/dnsResources.js';\nimport type { ResourceChange } from '../../deploy/events';\nimport { imageRef } from '../../deploy/identity.js';\nimport { DeployJournal } from '../../deploy/journal';\nimport {\n\tcreateComposeState,\n\ttype DeployedImage,\n\trecordRelease,\n} from '../../deploy/state.js';\nimport type { DeployResult } from '../../deploy/types';\nimport { ensureDockerignore } from '../../docker/index.js';\nimport { imageLayout } from '../../docker/layout.js';\nimport { findBuildRoot } from '../../docker/templates.js';\nimport { GkmError } from '../../errors';\nimport { installedFrom } from '../../generators/drivers.js';\nimport {\n\tmigrateDatabases,\n\tplannedSeeds,\n\tSeedFailed,\n\tseedDatabases,\n} from '../../migrate/databases.js';\nimport { bucketClient, pgClient } from '../../reconcile/clients.js';\nimport { primaryPortKey } from '../../reconcile/containers.js';\nimport { type ConstructSource, discover } from '../../reconcile/discover.js';\nimport { envFor } from '../../reconcile/env.js';\nimport { loadLocalCredentials } from '../../reconcile/localCredentials.js';\nimport {\n\tensurePostgresLogin,\n\tLEGACY_LOCAL_LOGIN,\n} from '../../reconcile/logins.js';\nimport {\n\tapplyBuckets,\n\tapplyPolicies,\n\tapplyPostgres,\n\tpostgresStatements,\n} from '../../reconcile/provision.js';\nimport { constructGlobs } from '../../reconcile/workspace.js';\nimport { runOutput } from '../../run';\nimport type { StageSecrets } from '../../secrets/types.js';\nimport type {\n\tDnsProvider as DnsProviderConfig,\n\tNormalizedWorkspace,\n} from '../../workspace/types.js';\nimport type { DnsProvider } from '../dokploy/dns/DnsProvider';\nimport {\n\tDeploySeedsFailed,\n\treportDatabaseRuns,\n\treportPlannedSeeds,\n} from '../seeds';\nimport type { DeployPhaseContext } from '../types';\nimport {\n\tComposeAppsUnhealthy,\n\ttype HealthProbe,\n\thttpsProbe,\n\tisHealthy,\n} from './health';\n\n/** Every phase's context: the compose target takes no options. */\nexport type ComposeContext = DeployPhaseContext<undefined>;\n\n/** What the target needs from outside the process, so tests can stand in. */\nexport interface ComposeDeps {\n\tdocker: ComposeDocker;\n\t/** The commit a build is tagged with. */\n\trevision: (root: string) => Promise<string>;\n\t/** The Postgres client provisioning and migrations connect through. */\n\tsql: typeof pgClient;\n\t/** The S3 client the stack's buckets are created through. */\n\tbuckets: typeof bucketClient;\n\t/** Bring the stack's Postgres onto its superuser — see `logins.ts`. */\n\tlogins: typeof ensurePostgresLogin;\n\t/** Apply the stage's migrations — `migrateDatabases` by default. */\n\tmigrate: typeof migrateDatabases;\n\t/** Run the stage's seeds, after its migrations — `seedDatabases` by default. */\n\tseed: typeof seedDatabases;\n\t/** Ask one app, through the edge, whether it answers. */\n\tprobe: HealthProbe;\n\t/** How many times each app is asked before it counts as down. */\n\thealthAttempts: number;\n\t/** How long to wait between two asks of one app. */\n\thealthIntervalMs: number;\n\t/** Where the edge's ports are read from (`GKM_COMPOSE_HTTPS_PORT`, …). */\n\tenv: NodeJS.ProcessEnv;\n\t/**\n\t * Resolves a public host to every address it has, for the DNS check —\n\t * the system resolver by default.\n\t */\n\tlookup?: HostLookup;\n\t/** The DNS provider for a `dns` domain — `createDnsProvider` by default. */\n\tdnsProviderFor?: (config: DnsProviderConfig) => Promise<DnsProvider | null>;\n}\n\n/** One app's image, as the stage runs it. */\nexport interface ComposeImage {\n\tref: string;\n\ttag: string;\n\tdigest?: string;\n}\n\n/** A compose deploy in progress: what `validate` found, and what follows. */\nexport interface ComposeRun {\n\t/** Build the images from this checkout, or pull the ones a tag names. */\n\tmode: 'build' | 'pull';\n\t/**\n\t * Build and push the images, and nothing else (`--build --push`): no\n\t * provisioning, no container started, nothing recorded.\n\t */\n\tpush: boolean;\n\tstack: ComposeStack;\n\t/** The stack's directory, absolute: `.gkm/compose/<stage>`. */\n\tdir: string;\n\tref: StackRef;\n\t/** The stage's secrets, with whatever a deployed stage generates once. */\n\tsecrets: StageSecrets | null;\n\t/** The names of what was generated, written back in `provision`. */\n\tgenerated: string[];\n\t/** Each app's image as the stage's state last recorded it. */\n\tprevious: Record<string, DeployedImage>;\n\t/** Every file written, absolute. */\n\tfiles: string[];\n\t/** Each app's image, once built or pulled. */\n\timages: Record<string, ComposeImage>;\n\t/** Every resource the run touched, or for a dry run would. */\n\tchanges: ResourceChange[];\n}\n\n/** How a run gets its images, beyond what the tag implies. */\nexport interface ComposeRunOptions {\n\t/**\n\t * Build or pull whatever the tag says. By default a given tag is pulled\n\t * and no tag builds from the checkout.\n\t */\n\tmode?: 'build' | 'pull';\n\t/** Push what was built, and start nothing (`--build --push`). */\n\tpush?: boolean;\n\t/** Run each pulled image at the digest a push reported for it. */\n\tpin?: { file: string; digests: ImageDigests };\n}\n\n/** `--push` without `--build`: there is nothing built here to push. */\nexport class ComposePushNeedsBuild extends GkmError {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'--push pushes the images this checkout builds, so it needs --build ' +\n\t\t\t\t'(and never --pull): gkm compose --stage <stage> --build --push --tag <tag>.',\n\t\t);\n\t\tthis.name = 'ComposePushNeedsBuild';\n\t}\n}\n\n/** Digests to run by, on a run that pulls nothing. */\nexport class ComposePinNeedsPull extends GkmError {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'--digests-file pins the images a release pulls, so it needs --tag ' +\n\t\t\t\t'(or --pull) — or, with --build --push, it is where the pushed digests ' +\n\t\t\t\t'are written.',\n\t\t);\n\t\tthis.name = 'ComposePinNeedsPull';\n\t}\n}\n\n/** A port variable that does not hold a port. */\nexport class EdgePortInvalid extends GkmError {\n\tconstructor(\n\t\treadonly variable: string,\n\t\treadonly value: string,\n\t) {\n\t\tsuper(\n\t\t\t`${variable}=${value} is not a port. Set it to a number between 1 and 65535, or unset it for the default.`,\n\t\t);\n\t\tthis.name = 'EdgePortInvalid';\n\t}\n}\n\n/** A build with no commit to tag its images with. */\nexport class NoGitRevision extends GkmError {\n\tconstructor(readonly root: string) {\n\t\tsuper(\n\t\t\t`Images built here are tagged with the commit they were built from, ` +\n\t\t\t\t`and ${root} is not in a git repository with a commit. Commit, or ` +\n\t\t\t\t`pass --tag to name the images yourself.`,\n\t\t);\n\t\tthis.name = 'NoGitRevision';\n\t}\n}\n\n/**\n * The project's own file merged over a stage's stack: `docker-compose.<stage>.yml`\n * at the workspace root. What the generated file cannot know — a port bound\n * to a tailnet address, another log driver — goes there, and is never\n * overwritten.\n */\nexport function stackOverrideFile(root: string, stage: string): string {\n\treturn join(root, `docker-compose.${stage}.yml`);\n}\n\n/** The commit HEAD is at, short — and `-dirty` when the tree has changes. */\nexport async function gitRevision(root: string): Promise<string> {\n\tlet sha: string;\n\ttry {\n\t\tsha = (\n\t\t\tawait runOutput('git', ['rev-parse', '--short', 'HEAD'], { cwd: root })\n\t\t).trim();\n\t} catch {\n\t\tthrow new NoGitRevision(root);\n\t}\n\tif (!sha) throw new NoGitRevision(root);\n\n\t// An image built from uncommitted changes is not the commit's image, and a\n\t// tag that said it was would be the one thing worse than no tag.\n\tconst status = await runOutput('git', ['status', '--porcelain'], {\n\t\tcwd: root,\n\t}).catch(() => '');\n\treturn status.trim() ? `${sha}-dirty` : sha;\n}\n\n/** The edge's ports, from the environment — 443 and 80 when unset. */\nexport function edgePorts(env: NodeJS.ProcessEnv = process.env): {\n\thttps: number;\n\thttp: number;\n\tlogs?: number;\n} {\n\tconst read = (variable: string, fallback: number) => {\n\t\tconst value = env[variable];\n\t\tif (value === undefined || value === '') return fallback;\n\t\tconst port = Number(value);\n\t\tif (!Number.isInteger(port) || port < 1 || port > 65_535) {\n\t\t\tthrow new EdgePortInvalid(variable, value);\n\t\t}\n\t\treturn port;\n\t};\n\tconst logs = env[LOGS_PORT_ENV] ? read(LOGS_PORT_ENV, 0) : undefined;\n\treturn {\n\t\thttps: read(EDGE_PORT_ENV.https, 443),\n\t\thttp: read(EDGE_PORT_ENV.http, 80),\n\t\t...(logs ? { logs } : {}),\n\t};\n}\n\n/**\n * The real ones. Each app is asked for three minutes before it counts as\n * down: a deployed stage's first ACME certificate can take that long.\n */\nexport const defaultDeps: ComposeDeps = {\n\tdocker: dockerCompose,\n\trevision: gitRevision,\n\tsql: pgClient,\n\tbuckets: bucketClient,\n\tlogins: ensurePostgresLogin,\n\tmigrate: migrateDatabases,\n\tseed: seedDatabases,\n\tprobe: httpsProbe,\n\thealthAttempts: 90,\n\thealthIntervalMs: 2_000,\n\tenv: process.env,\n\tlookup: systemLookup,\n};\n\n// ============================================================================\n// validate\n// ============================================================================\n\n/**\n * The stack the stage would run, and — for a tag — the registry's word that\n * every image it names exists. Nothing is written: a missing image stops the\n * run here, before a file, a secret or a container is touched.\n */\nexport async function validateCompose(\n\tctx: ComposeContext,\n\tdeps: ComposeDeps,\n\toptions: ComposeRunOptions = {},\n): Promise<ComposeRun> {\n\tconst { workspace, stage, identity, tag } = ctx;\n\tconst root = workspace.root;\n\tconst mode = options.mode ?? (ctx.tagGiven ? 'pull' : 'build');\n\tconst push = options.push === true;\n\tif (push && mode !== 'build') throw new ComposePushNeedsBuild();\n\tif (options.pin && mode !== 'pull') throw new ComposePinNeedsPull();\n\n\t// An image pushed or pulled with no registry is a Docker Hub name, which\n\t// is somebody else's. Refused before anything is discovered, built or\n\t// asked of a registry.\n\tconst registry = workspace.deploy?.registry;\n\tif (!registry && (push || mode === 'pull')) {\n\t\tthrow new RegistryRequired(\n\t\t\tpush ? 'push' : 'pull',\n\t\t\timageRef(identity, ctx.apps[0] ?? workspace.name, undefined, tag),\n\t\t);\n\t}\n\n\t// The runnables' edges say which surface reaches which; the manifest the\n\t// run discovered has the declarations but not them.\n\tconst runnables: Record<string, string[]> = {};\n\tconst background: Record<string, string[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns: constructGlobs(workspace),\n\t\tcwd: root,\n\t\trunnables,\n\t\tbackground,\n\t});\n\n\tconst { secrets, generated } = await stageSecrets(ctx, manifest);\n\n\t// Where and with what the images are built — only asked when they are.\n\tconst layout = mode === 'build' ? imageLayout(workspace) : undefined;\n\n\tconst composed = composeStack({\n\t\tworkspace,\n\t\tmanifest,\n\t\trunnables,\n\t\tbackground,\n\t\tstage,\n\t\tidentity,\n\t\timages: {\n\t\t\tmode,\n\t\t\ttag,\n\t\t\t...(registry ? { registry } : {}),\n\t\t},\n\t\tsecrets,\n\t\t...(stage === workspace.stages.local\n\t\t\t? {\n\t\t\t\t\tlocalCredentials: (await loadLocalCredentials(workspace)).credentials,\n\t\t\t\t}\n\t\t\t: {}),\n\t\tallowDevServices: ctx.allowDevServices,\n\t\tports: edgePorts(deps.env),\n\t\t...(layout ? { layout } : {}),\n\t\t...(push ? { buildOnly: true } : {}),\n\t});\n\n\t// A cache is reached over the Redis wire protocol, and the client is the\n\t// project's own dependency: a build without it fails deep inside Docker.\n\tif (mode === 'build') assertRedisClient(workspace, composed);\n\n\t// No image embeds the stage's secrets: a backend reads them at runtime\n\t// from its env file, so one image built at a commit runs on every stage.\n\t// A pinned release runs each image at the digest its push reported.\n\tconst stack = options.pin\n\t\t? withPinnedImages(composed, options.pin.file, options.pin.digests)\n\t\t: composed;\n\n\t// A release is all of its images or none of them. A dry run asks nothing,\n\t// so it can be run without a registry login.\n\tif (mode === 'pull' && !ctx.dryRun) {\n\t\tawait assertImagesExist(deps.docker, tag, [\n\t\t\t...stack.apps,\n\t\t\t...stack.workers,\n\t\t]);\n\t}\n\n\tif (stack.redis && !stack.local) ctx.secrets.mask(stack.redis.password);\n\n\t// The log UI's root login and the header every backend signs in with:\n\t// secrets, unless they are the local stage's fixed ones.\n\tif (stack.logs && (!stack.local || stack.logs.passwordFromSecrets)) {\n\t\tctx.secrets.mask(stack.logs.password);\n\t\tctx.secrets.mask(stack.logs.appEnv.OTEL_EXPORTER_OTLP_HEADERS);\n\t}\n\n\tconst dir = join(root, stackDir(stage));\n\tconst override = stackOverrideFile(root, stage);\n\tconst overrides = existsSync(override) ? [override] : [];\n\tif (overrides.length > 0) {\n\t\tctx.logger.info(\n\t\t\t`🧩 Merging docker-compose.${stage}.yml over the generated stack`,\n\t\t);\n\t}\n\t// What each app ran before this release: its current release, by the same\n\t// record the Dokploy target keeps, so a rollback reads one shape for both.\n\t// A push changes no stage, so it reads none of its state either.\n\tconst recorded = push ? undefined : await ctx.state.read(stage);\n\tconst previous = Object.fromEntries(\n\t\tObject.entries(recorded?.state.releases ?? {}).map(\n\t\t\t([name, releases]): [string, DeployedImage] => {\n\t\t\t\tconst { ref, tag, digest } = releases.current;\n\t\t\t\treturn [\n\t\t\t\t\tname,\n\t\t\t\t\t{ ref, ...(tag ? { tag } : {}), ...(digest ? { digest } : {}) },\n\t\t\t\t];\n\t\t\t},\n\t\t),\n\t);\n\n\treturn {\n\t\tmode,\n\t\tpush,\n\t\tstack,\n\t\tdir,\n\t\tref: {\n\t\t\tproject: composeProject(identity),\n\t\t\tfile: join(dir, 'docker-compose.yml'),\n\t\t\t...(overrides.length > 0 ? { overrides } : {}),\n\t\t\tcwd: root,\n\t\t\toutput: ctx.childOutput,\n\t\t\tsignal: ctx.signal,\n\t\t},\n\t\tsecrets,\n\t\tgenerated,\n\t\tprevious,\n\t\tfiles: [],\n\t\timages: {},\n\t\tchanges: [],\n\t};\n}\n\n// ============================================================================\n// ready\n// ============================================================================\n\n/**\n * What only a compose deploy checks before it changes anything, once the\n * stage's own keys are: the stage's own certificate is there, and every\n * public host points at the stage's server — its records written where a\n * provider holds them, then confirmed — before Caddy or Traefik ask Let's\n * Encrypt for a certificate it could not issue. A build-only run never asks.\n */\nexport async function readyCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack } = run;\n\n\t// Read when the stack starts; one that is not there stops the run here,\n\t// before anything is written or started.\n\tif (stack.tls) {\n\t\tfor (const file of [stack.tls.certFile, stack.tls.keyFile]) {\n\t\t\tif (!existsSync(file)) throw new ComposeTlsFileMissing(ctx.stage, file);\n\t\t}\n\t}\n\n\tif (stack.local) return;\n\tawait stageHostsDns(\n\t\tctx,\n\t\tdeps,\n\t\tstackHosts(stack).filter((host) => !isLocalHost(host)),\n\t\trun.secrets?.custom,\n\t);\n}\n\n/** A stack whose caches are in Redis, built for an app that has no client. */\nexport class RedisClientMissing extends GkmError {\n\tconstructor(readonly apps: readonly string[]) {\n\t\tsuper(\n\t\t\t`The stack keeps every cache in Redis, and ${apps.join(', ')} ` +\n\t\t\t\t`${apps.length === 1 ? 'does' : 'do'} not depend on ioredis, the client ` +\n\t\t\t\t'the generated server reaches it with. Add it to the workspace: ' +\n\t\t\t\t'pnpm add ioredis',\n\t\t);\n\t\tthis.name = 'RedisClientMissing';\n\t}\n}\n\n/**\n * Every backend and worker image built for a stack with a cache can resolve\n * `ioredis` — listed by its app or a directory above it, the way Node and\n * the image's install find it.\n */\nfunction assertRedisClient(\n\tworkspace: NormalizedWorkspace,\n\tstack: ComposeStack,\n): void {\n\tif (!stack.plan.resources.some((r) => r.kind === 'cache')) return;\n\n\tconst hosts = new Set([\n\t\t...stack.apps.filter((app) => app.kind === 'rest-api').map((a) => a.name),\n\t\t...stack.workers.map((worker) => worker.host),\n\t]);\n\tconst missing = [...hosts]\n\t\t.filter((name) => {\n\t\t\tconst app = workspace.apps[name];\n\t\t\treturn app && !installedFrom(join(workspace.root, app.path), 'ioredis');\n\t\t})\n\t\t.sort();\n\tif (missing.length > 0) throw new RedisClientMissing(missing);\n}\n\n/**\n * The stage's secrets — and, for a deployed stage, everything it generates\n * once: its seed, and each declared secret and keyring. Kept only once the\n * run goes ahead (`provision`), so a dry run, or a tag that is not there,\n * leaves the stage's secrets as it found them.\n */\n/**\n * The deploy's DNS step, for a deployed stage: its server's address — required\n * where it serves a real domain — then its own hosts written through each\n * domain's provider in `dns` where they differ, read back from it, and\n * recorded in the stage's state; hosts no provider writes resolved with the\n * system resolver. A dry run prints the plan and writes nothing, and warns\n * rather than stops. What a deploy (`ready`) and `--resources-only` both run.\n *\n * @throws {ServerAddressMissing} when the stage has a domain and no address\n * @throws {ServerAddressInvalid} for a value that is not an address\n * @throws {HostNotPointingAtServer} when a host is not the server\n */\nasync function stageHostsDns(\n\tctx: ComposeContext,\n\tdeps: ComposeDeps,\n\thosts: readonly string[],\n\tcustom: Readonly<Record<string, string>> | undefined,\n): Promise<void> {\n\tconst { workspace, stage } = ctx;\n\tconst server = requiredServerAddress(\n\t\tstage,\n\t\tworkspace.domains?.[stage],\n\t\tcustom,\n\t);\n\tif (hosts.length === 0) return;\n\tif (ctx.skipDns) {\n\t\tctx.logger.info(\n\t\t\t'🌐 DNS skipped (--skip-dns): no record is written or checked',\n\t\t);\n\t\treturn;\n\t}\n\tif (ctx.skipResources) {\n\t\tctx.logger.info(\n\t\t\t'🌐 DNS skipped (--skip-resources): the --resources-only run wrote and confirmed the records',\n\t\t);\n\t\treturn;\n\t}\n\tif (!server) {\n\t\tctx.logger.info(\n\t\t\t`🌐 DNS skipped: no ${SERVER_IPV4_KEY} in '${stage}''s secrets — ${serverAddressHint(stage)}`,\n\t\t);\n\t\treturn;\n\t}\n\tconst log = (line: string) => ctx.logger.info(line);\n\tif (workspace.dns) {\n\t\tlog(\n\t\t\t`🌐 DNS for '${stage}' → ${server.ipv4}${server.ipv6 ? ` / ${server.ipv6}` : ''}${ctx.dryRun ? ' (dry run — nothing is written)' : ''}`,\n\t\t);\n\t}\n\ttry {\n\t\tconst result = await stageDns({\n\t\t\tstage,\n\t\t\thosts,\n\t\t\tserver,\n\t\t\tdns: workspace.dns,\n\t\t\tcredentials: ctx.credentials,\n\t\t\tlog,\n\t\t\tlookup: deps.lookup ?? systemLookup,\n\t\t\t...(ctx.dryRun ? { dryRun: true } : {}),\n\t\t\t...(deps.dnsProviderFor ? { providerFor: deps.dnsProviderFor } : {}),\n\t\t});\n\t\t// What it wrote, kept in the stage's state; what it deleted, forgotten.\n\t\tif (!ctx.dryRun) {\n\t\t\tconst journal = await DeployJournal.open(ctx.state, stage, () =>\n\t\t\t\tcreateComposeState(stage),\n\t\t\t);\n\t\t\tconst providers = new Map(\n\t\t\t\tresult.plan.domains.map((d) => [d.domain, d.provider]),\n\t\t\t);\n\t\t\tawait recordDnsChanges(journal, result.changes, (domain) =>\n\t\t\t\tproviders.get(domain),\n\t\t\t);\n\t\t}\n\t\tconst parts = [\n\t\t\tresult.confirmed.length > 0\n\t\t\t\t? `${result.confirmed.length} host${result.confirmed.length === 1 ? '' : 's'} confirmed by the DNS provider`\n\t\t\t\t: '',\n\t\t\tresult.resolved.length > 0\n\t\t\t\t? `${result.resolved.length} host${result.resolved.length === 1 ? '' : 's'} resolve${result.resolved.length === 1 ? 's' : ''} to ${server.ipv4}`\n\t\t\t\t: '',\n\t\t].filter(Boolean);\n\t\tif (parts.length > 0) log(`🌐 ${parts.join(', ')}`);\n\t} catch (error) {\n\t\tif (ctx.dryRun && error instanceof HostNotPointingAtServer) {\n\t\t\tctx.logger.warn(`⚠ ${error.message}`);\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * `--resources-only`: the stage's DNS records, from the hosts its stack would\n * serve — composed in memory, nothing written, no image asked for. What a CI\n * runner runs with the DNS provider's token, so the server never holds it.\n */\nexport async function resourcesCompose(\n\tctx: ComposeContext,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { workspace, stage } = ctx;\n\tif (stage === workspace.stages.local) return;\n\t// The DNS token was asked for before the providers ran.\n\tconst stored = await ctx.secrets.read();\n\tconst { composeStageHosts } = await import('../../providers/dns.js');\n\tconst hosts = await composeStageHosts({\n\t\tworkspace,\n\t\tstage,\n\t\tstored,\n\t\tmanifest: ctx.manifest,\n\t\trunnables: (ctx.runnables ?? {}) as Record<string, string[]>,\n\t\tbackground: (ctx.background ?? {}) as Record<string, string[]>,\n\t});\n\tawait stageHostsDns(\n\t\tctx,\n\t\tdeps,\n\t\thosts.filter((host) => !isLocalHost(host)),\n\t\tstored?.custom,\n\t);\n}\n\nasync function stageSecrets(\n\tctx: ComposeContext,\n\tmanifest: ConstructManifest,\n): Promise<{ secrets: StageSecrets | null; generated: string[] }> {\n\tconst stored = await ctx.secrets.read();\n\tif (ctx.stage === ctx.workspace.stages.local) {\n\t\t// The local stage's logins are this machine's, generated once with\n\t\t// `gkm dev`'s — not the stage's secrets.\n\t\treturn { secrets: stored, generated: [] };\n\t}\n\n\tconst { secrets, generated } = deployedStackSecrets(\n\t\tctx.workspace,\n\t\tctx.stage,\n\t\tstored,\n\t\tmanifest,\n\t);\n\t// Read through the store they are masked; made up here, they are not yet.\n\tif (secrets.seed) ctx.secrets.mask(secrets.seed);\n\tfor (const value of Object.values(secrets.custom ?? {})) {\n\t\tctx.secrets.mask(value);\n\t}\n\treturn { secrets, generated };\n}\n\n/**\n * The stack with each app's and worker's image pinned to the digest the file\n * names: the refs it is checked, pulled and recorded by, and the image each\n * compose service runs.\n */\nfunction withPinnedImages(\n\tstack: ComposeStack,\n\tfile: string,\n\tdigests: ImageDigests,\n): ComposeStack {\n\tconst apps = pinImages(file, digests, stack.apps);\n\tconst workers = pinImages(file, digests, stack.workers);\n\tconst services = { ...stack.compose.services };\n\tfor (const image of [...apps, ...workers]) {\n\t\tservices[image.name] = { ...services[image.name]!, image: image.ref };\n\t}\n\treturn {\n\t\t...stack,\n\t\tapps,\n\t\tworkers,\n\t\tcompose: { ...stack.compose, services },\n\t};\n}\n\n// ============================================================================\n// plan (dry run)\n// ============================================================================\n\n/**\n * A dry run: the stack's files, written so they can be read, and what a real\n * run would do — no image is built or pulled, no container touched, nothing\n * recorded and no secret kept.\n */\nexport async function planCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n): Promise<void> {\n\tif (run.generated.length > 0) {\n\t\tctx.logger.info(\n\t\t\t`🔑 \"${ctx.stage}\" has no ${run.generated.join(', ')} yet; this dry run used values it did not keep.`,\n\t\t);\n\t}\n\trun.files = await writeStack(ctx.cwd, run.dir, run.stack);\n\tprintPlan(ctx, run);\n\n\t// A push migrates and seeds nothing; a release runs every seed, every\n\t// time, so the list is the same whatever the database holds.\n\tif (!run.push && run.stack.infra.includes('postgres')) {\n\t\treportPlannedSeeds(\n\t\t\t(\n\t\t\t\tawait plannedSeeds({ root: ctx.workspace.root, manifest: ctx.manifest })\n\t\t\t).map(({ target, seeds }) => ({ folder: target.seeds, seeds })),\n\t\t\t(line) => ctx.logger.info(line),\n\t\t);\n\t}\n\n\tconst planned = (change: ResourceChange) => {\n\t\trun.changes.push(change);\n\t\tctx.emit({ type: 'resource.planned', ...change });\n\t};\n\tfor (const service of run.push ? [] : run.stack.infra) {\n\t\tplanned({\n\t\t\tkey: `service:${service}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t});\n\t}\n\tfor (const app of run.stack.apps) {\n\t\tplanned({\n\t\t\tkey: `image:${app.name}`,\n\t\t\tresourceType: 'image',\n\t\t\taction: run.mode === 'build' ? 'build' : 'reuse',\n\t\t\tid: app.ref,\n\t\t});\n\t\tif (run.push) continue;\n\t\tplanned({\n\t\t\tkey: `service:${app.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: run.previous[app.name] ? 'reuse' : 'create',\n\t\t});\n\t}\n\tfor (const worker of run.stack.workers) {\n\t\tplanned({\n\t\t\tkey: `image:${worker.name}`,\n\t\t\tresourceType: 'image',\n\t\t\taction: run.mode === 'build' ? 'build' : 'reuse',\n\t\t\tid: worker.ref,\n\t\t});\n\t\tif (run.push) continue;\n\t\tplanned({\n\t\t\tkey: `service:${worker.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: run.previous[worker.name] ? 'reuse' : 'create',\n\t\t});\n\t}\n\tif (!run.push) {\n\t\tplanned({\n\t\t\tkey:\n\t\t\t\trun.stack.proxy === 'caddy'\n\t\t\t\t\t? 'service:caddy'\n\t\t\t\t\t: `service:${EDGE_PROJECT}/${EDGE_SERVICE}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t});\n\t}\n}\n\n// ============================================================================\n// provision\n// ============================================================================\n\n/**\n * What the apps run on: the stage's generated secrets kept, the stack's files\n * written, its infrastructure started, and its databases, roles, grants and\n * migrations applied.\n */\nexport async function provisionCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack, ref } = run;\n\t// A push provisions nothing; its files are written where it builds.\n\tif (run.push) return;\n\n\tif (run.generated.length > 0 && run.secrets) {\n\t\tawait ctx.secrets.write(run.secrets);\n\t\tctx.logger.info(\n\t\t\t`🔑 Generated for \"${ctx.stage}\" (${ctx.secrets.store}): ${run.generated.join(', ')}`,\n\t\t);\n\t}\n\n\t// Nothing but the stack's own proxy may hold the edge's ports — checked\n\t// before a file is written or a container started.\n\tconst ports = edgePorts(deps.env);\n\tawait assertEdgePorts(deps.docker, {\n\t\tproject: stack.project,\n\t\tproxy: stack.proxy,\n\t\tports,\n\t});\n\n\trun.files = await writeStack(ctx.cwd, run.dir, stack);\n\tprintPlan(ctx, run);\n\n\t// The shared edge, and the network the stack's public services join —\n\t// before any of them, MinIO among them, is started.\n\tif (stack.proxy === 'traefik') {\n\t\tconst dir = edgeDir(deps.env);\n\t\tctx.logger.info(\n\t\t\t`\\n🌐 Starting the shared edge (${EDGE_PROJECT}) from ${dir}…`,\n\t\t);\n\t\trun.files.push(\n\t\t\t...(await ensureEdge(deps.docker, {\n\t\t\t\tdir,\n\t\t\t\tports,\n\t\t\t\tlogging: {\n\t\t\t\t\tdriver: LOG_ROTATION.driver,\n\t\t\t\t\toptions: { ...LOG_ROTATION.options },\n\t\t\t\t},\n\t\t\t\t...(ref.output ? { output: ref.output } : {}),\n\t\t\t\t...(ref.signal ? { signal: ref.signal } : {}),\n\t\t\t})),\n\t\t);\n\t\tapplied(ctx, run, {\n\t\t\tkey: `service:${EDGE_PROJECT}/${EDGE_SERVICE}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t\tid: `${EDGE_PROJECT}/${EDGE_SERVICE}`,\n\t\t\tvia: 'found',\n\t\t});\n\t}\n\n\tif (stack.infra.length > 0) {\n\t\tctx.logger.info(`\\n🗄️ Starting ${stack.infra.join(', ')}…`);\n\t\tawait deps.docker.up(ref, stack.infra);\n\t\tfor (const service of stack.infra) {\n\t\t\tapplied(ctx, run, {\n\t\t\t\tkey: `service:${service}`,\n\t\t\t\tresourceType: 'service',\n\t\t\t\taction: 'ensure',\n\t\t\t\tid: `${stack.project}/${service}`,\n\t\t\t\tvia: Object.keys(run.previous).length > 0 ? 'recorded' : 'created',\n\t\t\t});\n\t\t}\n\t}\n\n\tif (stack.infra.includes('postgres')) {\n\t\tawait prepareDatabases(ctx, run, deps);\n\t}\n\tif (stack.storage && stack.infra.includes('minio')) {\n\t\tawait prepareBuckets(ctx, run, deps);\n\t}\n}\n\n/**\n * Create each bucket the stack's MinIO serves, and the open paths of each\n * one a file server fronts — from this machine, on MinIO's loopback port,\n * the way `gkm dev` creates them.\n */\nasync function prepareBuckets(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst storage = run.stack.storage!;\n\tif (storage.buckets.length === 0) return;\n\n\tconst port = await deps.docker.port(run.ref, 'minio', 9000);\n\tconst client = deps.buckets(port, storage);\n\tconst done = [\n\t\t...(await applyBuckets(client, storage.buckets)),\n\t\t...(await applyPolicies(client, storage.policies)),\n\t];\n\tconst created = done.filter((entry) => entry.created).length;\n\tctx.logger.info(\n\t\t`🪣 Buckets: ${storage.buckets.join(', ')}${created ? ` (${created} change(s))` : ''}`,\n\t);\n}\n\n/**\n * Create what the plan names in the stack's Postgres, migrate it, then run\n * its seeds — every one, every time, as each construct's owner.\n */\nasync function prepareDatabases(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack } = run;\n\tconst workspace: NormalizedWorkspace = ctx.workspace;\n\tconst port = await deps.docker.port(run.ref, 'postgres', 5432);\n\n\t// A stack an older gkm started made its superuser under the old fixed\n\t// name, with the password this stage derives; it is moved to the\n\t// superuser named now — the local stage's from the old fixed login too.\n\tconst superuser = stack.credential.containers.postgres;\n\tconst login = await deps.logins({\n\t\tport,\n\t\tlogin: superuser,\n\t\tlegacy: [\n\t\t\t{ user: LEGACY_LOCAL_LOGIN.user, password: superuser.password },\n\t\t\t...(stack.local ? [LEGACY_LOCAL_LOGIN] : []),\n\t\t],\n\t});\n\tif (login.notice) ctx.logger.info(login.notice);\n\n\tconst statements = postgresStatements(\n\t\tstack.plan,\n\t\tworkspace.name,\n\t\tstack.credential.seed,\n\t);\n\tif (statements.length > 0) {\n\t\tctx.logger.info('🗄️ Creating databases, roles and grants…');\n\t\tawait applyPostgres(deps.sql(port, login.login), statements);\n\t}\n\n\t// Migrations run here, with the project's own Kysely, the way `gkm\n\t// migrate` runs them — so the constructs themselves are needed, which\n\t// only an in-process discovery hands back.\n\tconst sources: Record<string, ConstructSource> = {};\n\tconst manifest = await discover({\n\t\tpatterns: constructGlobs(workspace),\n\t\tcwd: workspace.root,\n\t\tsources,\n\t});\n\n\t// The owner URLs, on the port published to this machine.\n\tconst env = envFor(stack.plan, {\n\t\tports: { [primaryPortKey('postgres')]: port },\n\t\tproject: workspace.name,\n\t\tcredentials: {\n\t\t\t...stack.credential.containers,\n\t\t\tpostgres: login.login,\n\t\t},\n\t\tseed: stack.credential.seed,\n\t});\n\tconst options = { root: workspace.root, manifest, sources, env };\n\tconst runs = await deps.migrate(options);\n\n\t// Seeds after migrations, before any app starts: an app that boots with\n\t// its reference data missing fails on the first request that needs it.\n\tconst seeds = await deps\n\t\t.seed({ ...options, stage: ctx.stage })\n\t\t.catch((error: unknown) => {\n\t\t\tif (error instanceof SeedFailed) {\n\t\t\t\tthrow new DeploySeedsFailed(\n\t\t\t\t\tctx.stage,\n\t\t\t\t\terror.construct,\n\t\t\t\t\terror.seed,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\n\treportDatabaseRuns(\n\t\truns.map(({ target, applied }) => ({\n\t\t\tconstruct: target.id,\n\t\t\tfolder: target.migrations,\n\t\t\tapplied,\n\t\t})),\n\t\tseeds.map(({ target, seeded }) => ({\n\t\t\tconstruct: target.id,\n\t\t\tfolder: target.seeds,\n\t\t\tseeded,\n\t\t})),\n\t\t(line) => ctx.logger.info(line),\n\t\t(event) => ctx.emit(event),\n\t);\n}\n\n// ============================================================================\n// build\n// ============================================================================\n\n/**\n * Each app's image: built from this checkout — inside Docker, every one of\n * them, from a pruned slice of the build root — or pulled at the tag. Nothing\n * live changes.\n */\nexport async function buildCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack, ref } = run;\n\tconst images = [...stack.apps, ...stack.workers];\n\tconst apps = images.map((image) => image.app);\n\n\t// Nothing was provisioned, so nothing has written the files it builds from.\n\tif (run.push) {\n\t\trun.files = await writeStack(ctx.cwd, run.dir, stack);\n\t\tprintPlan(ctx, run);\n\t}\n\n\tif (run.mode === 'build') {\n\t\tctx.logger.info('\\n🐳 Building images…');\n\t\tawait deps.docker.build(ref, apps);\n\t} else {\n\t\tctx.logger.info(`\\n🐳 Pulling ${ctx.tag}…`);\n\t\tawait deps.docker.pull(ref, apps);\n\t}\n\n\tif (run.push) ctx.logger.info('\\n📤 Pushing images…');\n\n\t// What each tag resolved to: the registry's digest for a pushed or pulled\n\t// image, or — for one built here and never pushed — its content id.\n\tfor (const image of images) {\n\t\tconst digest = run.push\n\t\t\t? await deps.docker.push(ref, image.ref)\n\t\t\t: await deps.docker.digest(image.ref);\n\t\tif (run.push) {\n\t\t\tctx.logger.info(` ${image.app.padEnd(12)} ${image.ref}@${digest}`);\n\t\t}\n\t\trun.images[image.app] = {\n\t\t\tref: image.ref,\n\t\t\ttag: image.tag,\n\t\t\t...(digest ? { digest } : {}),\n\t\t};\n\t\tctx.emit({\n\t\t\ttype: 'artifact.built',\n\t\t\tapp: image.app,\n\t\t\timageRef: image.ref,\n\t\t\t...(digest ? { digest } : {}),\n\t\t});\n\t\trun.changes.push({\n\t\t\tkey: `image:${image.app}`,\n\t\t\tresourceType: 'image',\n\t\t\taction: run.mode === 'build' ? 'build' : 'reuse',\n\t\t\tid: digest ?? image.ref,\n\t\t});\n\t}\n}\n\n// ============================================================================\n// release\n// ============================================================================\n\n/**\n * The whole stack up — anything it no longer defines removed — and each\n * app's image recorded in the stage's state.\n */\nexport async function releaseCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack, ref } = run;\n\t// A push starts nothing and records nothing: a stage runs what it pulls.\n\tif (run.push) return;\n\n\tctx.logger.info('\\n🚀 Starting the stack…');\n\tawait deps.docker.up(ref);\n\n\t// Registered with the shared edge once its services are up, so the edge\n\t// never routes to a container that is not there yet. A stack on its own\n\t// Caddy leaves nothing behind there from a run on the edge.\n\tconst edge = edgeDir(deps.env);\n\tif (stack.proxy === 'traefik' && stack.traefik) {\n\t\tconst written = await writeEdgeRoutes(\n\t\t\tedge,\n\t\t\tstack.project,\n\t\t\tstack.traefik,\n\t\t\tstack.tls,\n\t\t);\n\t\trun.files.push(...written);\n\t\tctx.logger.info(\n\t\t\t`🌐 Registered ${stack.routes.length} route(s) with ${EDGE_PROJECT}: ${written.at(-1)}`,\n\t\t);\n\t} else {\n\t\tawait removeEdgeRoutes(edge, stack.project);\n\t}\n\n\tif (stack.local) {\n\t\t// Caddy's CA is generated on its first start. Copied out so a process —\n\t\t// `verify` among them — can trust it without installing anything.\n\t\tawait deps.docker\n\t\t\t.copyOut(\n\t\t\t\tref,\n\t\t\t\t'caddy',\n\t\t\t\t'/data/caddy/pki/authorities/local/root.crt',\n\t\t\t\tcaFile(run),\n\t\t\t)\n\t\t\t.catch(() => {});\n\t}\n\n\tawait recordImages(ctx, run);\n\n\tfor (const app of stack.apps) {\n\t\tconst image = run.images[app.name];\n\t\tapplied(ctx, run, {\n\t\t\tkey: `service:${app.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t\tid: `${stack.project}/${app.name}`,\n\t\t\tvia: run.previous[app.name] ? 'recorded' : 'created',\n\t\t});\n\t\tctx.emit({\n\t\t\ttype: 'app.deployed',\n\t\t\tapp: app.name,\n\t\t\tapplicationId: `${stack.project}/${app.name}`,\n\t\t\timageRef: image?.ref ?? app.ref,\n\t\t\turl: app.url,\n\t\t});\n\t}\n\n\t// A worker has no URL, so no `app.deployed`: its service, applied, is it.\n\tfor (const worker of stack.workers) {\n\t\tapplied(ctx, run, {\n\t\t\tkey: `service:${worker.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t\tid: `${stack.project}/${worker.name}`,\n\t\t\tvia: run.previous[worker.name] ? 'recorded' : 'created',\n\t\t});\n\t}\n\n\tctx.logger.info(`\\n✅ ${stack.project} is running:`);\n\tfor (const app of stack.apps) {\n\t\tctx.logger.info(` ${app.name.padEnd(12)} ${app.url}`);\n\t}\n\tfor (const worker of stack.workers) {\n\t\tctx.logger.info(` ${worker.name.padEnd(12)} worker ${worker.id}`);\n\t}\n\tif (stack.local) {\n\t\tctx.logger.info(\n\t\t\t`\\n🔐 Certificates are from Caddy's local CA: NODE_EXTRA_CA_CERTS=${join(stackDir(ctx.stage), 'caddy-root.crt')}`,\n\t\t);\n\t}\n}\n\n/**\n * Each app's image in the stage's state — the same `images` a Dokploy deploy\n * records: the ref it runs, the tag it was released under, and the digest\n * the tag resolved to.\n */\nasync function recordImages(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n): Promise<void> {\n\tconst journal = await DeployJournal.open(ctx.state, ctx.stage, () =>\n\t\tcreateComposeState(ctx.stage),\n\t);\n\tconst by = currentActor();\n\tfor (const app of [...run.stack.apps, ...run.stack.workers]) {\n\t\tconst image = run.images[app.app] ?? { ref: app.ref, tag: app.tag };\n\t\trecordRelease(journal.state, app.app, image, by);\n\t}\n\tjournal.state.identity = ctx.identity.key;\n\tawait journal.save();\n}\n\n// ============================================================================\n// verify\n// ============================================================================\n\n/**\n * Each app asked through Caddy, over HTTPS, the certificate verified: an API\n * at `/health`, a site at `/`. On the local stage the edge is this machine and\n * its certificates are Caddy's internal CA's, so the CA `release` copied out\n * is the one trusted and the request goes to 127.0.0.1.\n */\nexport async function verifyCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack } = run;\n\tif (run.push) return;\n\tconst ca = stack.local\n\t\t? await readFile(caFile(run), 'utf-8').catch(() => undefined)\n\t\t: undefined;\n\n\tctx.logger.info(\n\t\t`\\n🩺 Checking each app through ${stack.proxy === 'caddy' ? 'Caddy' : 'the shared edge'}…`,\n\t);\n\t// The local stage's edge is this machine. So is the shared edge, by\n\t// construction — compose starts it here — so it is asked directly, on\n\t// its published port, with each host as SNI and Host: what is checked is\n\t// its routing and its certificate, whatever DNS or a NAT in front of\n\t// the server does with a request from the server to itself.\n\tconst edge =\n\t\tstack.local || stack.proxy === 'traefik'\n\t\t\t? {\n\t\t\t\t\tconnectTo: '127.0.0.1',\n\t\t\t\t\t...(stack.local ? {} : { connectPort: edgePorts(deps.env).https }),\n\t\t\t\t}\n\t\t\t: undefined;\n\tconst results = await Promise.all(\n\t\tstack.apps.map((app) => checkApp(ctx, app, deps, { ca, edge })),\n\t);\n\n\t// A worker has no route through the edge: its own health check, as Docker\n\t// reports it, is the answer.\n\tresults.push(\n\t\t...(await Promise.all(\n\t\t\tstack.workers.map((worker) =>\n\t\t\t\tcheckContainer(ctx, run, deps, worker.name),\n\t\t\t),\n\t\t)),\n\t);\n\tif (stack.logs) {\n\t\tresults.push(await checkContainer(ctx, run, deps, LOGS_SERVICE));\n\t}\n\n\tconst down = results\n\t\t.filter((result) => !result.healthy)\n\t\t.map(({ app, url, last }) => ({ app, url, last }));\n\tif (down.length > 0) {\n\t\tthrow new ComposeAppsUnhealthy(stack.project, down, stack.proxy);\n\t}\n\n\tif (stack.logs) reportLogs(ctx, stack.logs, stack.local);\n}\n\n/**\n * A container's own health check, as Docker reports it: a worker's, which\n * has no route through the edge, and OpenObserve's — by default it has no\n * host there, and served publicly it answers only the addresses it allows,\n * which need not include this one.\n */\nasync function checkContainer(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n\tservice: string,\n): Promise<{ app: string; url: string; last: string; healthy: boolean }> {\n\tconst url = `docker:${service}`;\n\tlet last = 'not asked';\n\n\tfor (let attempt = 1; attempt <= deps.healthAttempts; attempt++) {\n\t\tctx.signal.throwIfAborted();\n\t\tconst health = await deps.docker\n\t\t\t.health(run.ref, service)\n\t\t\t.catch((error: unknown) =>\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\n\t\tlast = health ?? 'not running';\n\t\tconst healthy = health === 'healthy';\n\t\tctx.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp: service,\n\t\t\turl,\n\t\t\thealthy,\n\t\t\tattempt,\n\t\t});\n\t\tif (healthy) {\n\t\t\tctx.logger.info(` ✓ ${service.padEnd(12)} ${url} (${last})`);\n\t\t\treturn { app: service, url, last, healthy };\n\t\t}\n\t\tif (attempt < deps.healthAttempts) {\n\t\t\tawait new Promise((resolve) =>\n\t\t\t\tsetTimeout(resolve, deps.healthIntervalMs),\n\t\t\t);\n\t\t}\n\t}\n\n\tctx.logger.warn(` ✗ ${service.padEnd(12)} ${url} (${last})`);\n\treturn { app: service, url, last, healthy: false };\n}\n\n/** How to open the logs, printed — and as an event, for a headless caller. */\nfunction reportLogs(\n\tctx: ComposeContext,\n\tlogs: StackLogs,\n\tlocal: boolean,\n): void {\n\tconst lines = logsAccess(logs, {\n\t\tstage: ctx.stage,\n\t\tlocal,\n\t\tuser: currentUser(),\n\t\thostname: hostname(),\n\t});\n\tctx.logger.info(`\\n${lines.join('\\n')}`);\n\tctx.emit({\n\t\ttype: 'logs.ready',\n\t\tservice: LOGS_SERVICE,\n\t\taccess: logs.public ? 'public' : 'tunnel',\n\t\turl: logs.url,\n\t\t...(logs.public ? { allow: [...logs.public.allow] } : { port: logs.port }),\n\t\temail: logs.email,\n\t});\n}\n\n/** This machine's user — a guess at who would SSH in. */\nfunction currentUser(): string {\n\ttry {\n\t\treturn userInfo().username;\n\t} catch {\n\t\treturn process.env.USER ?? 'user';\n\t}\n}\n\nasync function checkApp(\n\tctx: ComposeContext,\n\tapp: StackApp,\n\tdeps: ComposeDeps,\n\toptions: {\n\t\tca: string | undefined;\n\t\tedge?: { connectTo: string; connectPort?: number };\n\t},\n): Promise<{ app: string; url: string; last: string; healthy: boolean }> {\n\tconst url = `${app.url}${app.kind === 'site' ? '/' : '/health'}`;\n\tlet last = 'not asked';\n\n\tfor (let attempt = 1; attempt <= deps.healthAttempts; attempt++) {\n\t\tctx.signal.throwIfAborted();\n\t\tlet status: number | undefined;\n\t\ttry {\n\t\t\tstatus = await deps.probe({\n\t\t\t\turl,\n\t\t\t\t...(options.ca ? { ca: options.ca } : {}),\n\t\t\t\t...options.edge,\n\t\t\t\ttimeoutMs: 10_000,\n\t\t\t\tsignal: ctx.signal,\n\t\t\t});\n\t\t\tlast = `HTTP ${status}`;\n\t\t} catch (error) {\n\t\t\tlast = error instanceof Error ? error.message : String(error);\n\t\t}\n\n\t\tconst healthy = status !== undefined && isHealthy(status);\n\t\tctx.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp: app.name,\n\t\t\turl,\n\t\t\thealthy,\n\t\t\t...(status !== undefined ? { status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (healthy) {\n\t\t\tctx.logger.info(` ✓ ${app.name.padEnd(12)} ${url} (${last})`);\n\t\t\treturn { app: app.name, url, last, healthy };\n\t\t}\n\t\tif (attempt < deps.healthAttempts) {\n\t\t\tawait new Promise((resolve) =>\n\t\t\t\tsetTimeout(resolve, deps.healthIntervalMs),\n\t\t\t);\n\t\t}\n\t}\n\n\tctx.logger.warn(` ✗ ${app.name.padEnd(12)} ${url} (${last})`);\n\treturn { app: app.name, url, last, healthy: false };\n}\n\n// ============================================================================\n// result\n// ============================================================================\n\nexport function composeResult(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n): DeployResult {\n\tconst apps = [\n\t\t...run.stack.apps.map((app) => {\n\t\t\tconst image = run.images[app.name];\n\t\t\treturn {\n\t\t\t\tappName: app.name,\n\t\t\t\ttype: app.kind === 'site' ? ('web' as const) : ('backend' as const),\n\t\t\t\tsuccess: !ctx.dryRun,\n\t\t\t\tapplicationId: `${run.stack.project}/${app.name}`,\n\t\t\t\timageRef: image?.ref ?? app.ref,\n\t\t\t\t...(image?.digest ? { digest: image.digest } : {}),\n\t\t\t\turl: app.url,\n\t\t\t};\n\t\t}),\n\t\t...run.stack.workers.map((worker) => {\n\t\t\tconst image = run.images[worker.name];\n\t\t\treturn {\n\t\t\t\tappName: worker.name,\n\t\t\t\ttype: 'backend' as const,\n\t\t\t\tsuccess: !ctx.dryRun,\n\t\t\t\tapplicationId: `${run.stack.project}/${worker.name}`,\n\t\t\t\timageRef: image?.ref ?? worker.ref,\n\t\t\t\t...(image?.digest ? { digest: image.digest } : {}),\n\t\t\t};\n\t\t}),\n\t];\n\treturn {\n\t\tapps,\n\t\tprojectId: run.stack.project,\n\t\tsuccessCount: ctx.dryRun ? 0 : apps.length,\n\t\tfailedCount: 0,\n\t\tstage: ctx.stage,\n\t\tidentity: ctx.identity.key,\n\t\ttag: ctx.tag,\n\t\tdryRun: ctx.dryRun,\n\t\tenvironmentId: '',\n\t\tskipped: [...ctx.skipped],\n\t\turls: Object.fromEntries(run.stack.apps.map((app) => [app.name, app.url])),\n\t\tchanges: run.changes,\n\t};\n}\n\n// ============================================================================\n// Files\n// ============================================================================\n\nfunction caFile(run: ComposeRun): string {\n\treturn join(run.dir, 'caddy-root.crt');\n}\n\nfunction applied(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tchange: ResourceChange & {\n\t\tid: string;\n\t\tvia: 'recorded' | 'resumed' | 'found' | 'created';\n\t},\n): void {\n\tconst { via, ...rest } = change;\n\trun.changes.push(rest);\n\tctx.emit({ type: 'resource.applied', ...rest, via });\n}\n\n/** Write the stack's files: owner-only, since the env files hold secrets. */\nasync function writeStack(\n\troot: string,\n\tdir: string,\n\tstack: ComposeStack,\n): Promise<string[]> {\n\tawait mkdir(dir, { recursive: true, mode: 0o700 });\n\tawait chmod(dir, 0o700);\n\n\tconst files: string[] = [];\n\tconst write = async (path: string, content: string, mode = 0o644) => {\n\t\tawait mkdir(dirname(path), { recursive: true });\n\t\tawait writeFile(path, content, { mode });\n\t\tawait chmod(path, mode);\n\t\tfiles.push(path);\n\t};\n\n\tawait write(join(dir, 'docker-compose.yml'), composeYaml(stack));\n\t// The proxy's configuration: the stack's own Caddy's, or — for reading —\n\t// a copy of what the stack registers with the shared edge. The other is\n\t// removed, so the directory never shows a proxy the stack does not use.\n\tif (stack.caddyfile !== undefined) {\n\t\tawait write(join(dir, 'Caddyfile'), stack.caddyfile);\n\t\tawait rm(join(dir, 'traefik.yml'), { force: true });\n\t} else {\n\t\tawait rm(join(dir, 'Caddyfile'), { force: true });\n\t}\n\tif (stack.traefik !== undefined) {\n\t\tawait write(join(dir, 'traefik.yml'), stack.traefik);\n\t}\n\t// The stage's own certificate, where Caddy mounts it.\n\tif (stack.proxy === 'caddy' && stack.tls) {\n\t\tawait mkdir(join(dir, 'tls'), { recursive: true, mode: 0o700 });\n\t\tawait write(\n\t\t\tjoin(dir, 'tls', 'cert.pem'),\n\t\t\tawait readFile(stack.tls.certFile, 'utf-8'),\n\t\t);\n\t\tawait write(\n\t\t\tjoin(dir, 'tls', 'key.pem'),\n\t\t\tawait readFile(stack.tls.keyFile, 'utf-8'),\n\t\t\t0o600,\n\t\t);\n\t} else {\n\t\tawait rm(join(dir, 'tls'), { recursive: true, force: true });\n\t}\n\tfor (const app of [...stack.apps, ...stack.workers]) {\n\t\tif (app.env)\n\t\t\tawait write(join(dir, `${app.name}.env`), envFile(app.env), 0o600);\n\t}\n\t// A stack that only builds reads no env file, so none is written.\n\tif (stack.logs && stack.compose.services[LOGS_SERVICE]?.env_file) {\n\t\tawait write(\n\t\t\tjoin(dir, `${LOGS_SERVICE}.env`),\n\t\t\tenvFile(stack.logs.env),\n\t\t\t0o600,\n\t\t);\n\t}\n\tif (stack.redis && stack.compose.services[REDIS_SERVICE]?.env_file) {\n\t\tawait write(\n\t\t\tjoin(dir, `${REDIS_SERVICE}.env`),\n\t\t\tenvFile(stack.redis.env),\n\t\t\t0o600,\n\t\t);\n\t}\n\t// Images no longer embed a stage's credentials. The ciphertexts an older\n\t// gkm left beside the compose file for them to embed are removed.\n\tfor (const entry of await readdir(dir)) {\n\t\tif (entry.endsWith('.credentials')) await rm(join(dir, entry));\n\t}\n\tfor (const [path, content] of Object.entries(stack.dockerfiles)) {\n\t\tawait write(join(root, path), content);\n\t}\n\n\t// The build context is the build root, and the env files are under it:\n\t// its ignore file is what keeps a stage's secrets out of every image's\n\t// context.\n\tawait ensureDockerignore(findBuildRoot(root));\n\n\treturn files;\n}\n\nfunction composeYaml(stack: ComposeStack): string {\n\tconst stage = ` --stage ${stack.stage}`;\n\treturn `# Generated by gkm compose from the construct manifest — do not edit.\n# The ${stack.stage} stage's APIs and sites behind ${stack.proxy === 'caddy' ? 'one Caddy' : `the shared Traefik edge (${EDGE_PROJECT})`}, and its workers.\n# Each backend and worker reads exactly the keys in its own env file beside\n# this one.\n#\n# gkm compose${stage} start or update it\n# gkm compose${stage} --down stop it\n${stringify(stack.compose, { lineWidth: 0, aliasDuplicateObjects: false })}`;\n}\n\nfunction printPlan(ctx: ComposeContext, run: ComposeRun): void {\n\tconst { stack, mode, files } = run;\n\tctx.logger.info(`\\n🧱 ${stack.project} — stage ${stack.stage}`);\n\tfor (const app of stack.apps) {\n\t\tctx.logger.info(\n\t\t\t` ${app.name.padEnd(12)} ${app.url.padEnd(40)} ${mode} ${app.ref}`,\n\t\t);\n\t}\n\tfor (const worker of stack.workers) {\n\t\tctx.logger.info(\n\t\t\t` ${worker.name.padEnd(12)} ${`worker ${worker.id} (no route)`.padEnd(40)} ${mode} ${worker.ref}`,\n\t\t);\n\t}\n\tif (stack.infra.length > 0) {\n\t\tctx.logger.info(` infrastructure: ${stack.infra.join(', ')}`);\n\t}\n\tctx.logger.info(\n\t\t`\\n📝 Wrote ${files.length} file(s) under ${stackDir(stack.stage)}/`,\n\t);\n}\n","/**\n * The built-in `compose` target: a stage as one Docker Compose stack behind\n * Caddy, on the machine that runs the deploy.\n *\n * ```bash\n * gkm deploy --target compose --stage production --tag v1.4.0 # what CI pushed\n * gkm deploy --target compose --stage production # built from here\n * gkm deploy --target compose --stage development # the local stage\n * ```\n *\n * - `validate`: the stack (`composeStack`, pure) and, for a tag, every image\n * looked up in the registry — `ImageTagNotFound` before anything changes\n * - `ready`: a deploy's own checks, after the stage's keys are — the stage's\n * certificate, its server's address, and every public host's DNS\n * - `plan`: the stack's files and what a run would create or reuse\n * - `provision`: generated secrets kept, files written, infrastructure up,\n * databases, roles, grants and migrations\n * - `build`: each backend bundled on the host and every image built — or, for\n * a tag, pulled\n * - `release`: `up --wait --remove-orphans`, and each app's image, tag and\n * digest in the stage's state\n * - `verify`: each app asked through Caddy over HTTPS\n *\n * With `push` (`gkm compose --build --push`), run with `buildOnly`, it builds\n * every image and pushes it to `deploy.registry`, and does nothing else: no\n * readiness check runs, so a stage whose keys the deploy has yet to write\n * still builds.\n *\n * `gkm compose` is this target with a few more switches (`--build`, `--pull`,\n * `--down`), run through the same `deploy()`.\n */\n\nimport { defineTarget } from '../define';\nimport type { DeployTarget } from '../types';\nimport {\n\tbuildCompose,\n\ttype ComposeDeps,\n\ttype ComposeRun,\n\ttype ComposeRunOptions,\n\tcomposeResult,\n\tdefaultDeps,\n\tplanCompose,\n\tprovisionCompose,\n\treadyCompose,\n\treleaseCompose,\n\tresourcesCompose,\n\tvalidateCompose,\n\tverifyCompose,\n} from './phases';\n\nexport {\n\tComposeAppsUnhealthy,\n\ttype HealthProbe,\n\ttype HealthRequest,\n\tHealthRequestTimedOut,\n} from './health';\nexport {\n\ttype ComposeDeps,\n\ttype ComposeImage,\n\tComposePinNeedsPull,\n\tComposePushNeedsBuild,\n\ttype ComposeRun,\n\ttype ComposeRunOptions,\n\tEdgePortInvalid,\n\tedgePorts,\n\tgitRevision,\n\tNoGitRevision,\n\tRedisClientMissing,\n\tstackOverrideFile,\n} from './phases';\n\nexport interface ComposeTargetOptions\n\textends Partial<ComposeDeps>,\n\t\tComposeRunOptions {\n\t/** Handed the finished run — `gkm compose` prints and returns from it. */\n\treport?: (run: ComposeRun) => void;\n}\n\n/** The compose target, with its Docker, bundler and probe as given. */\nexport function composeTarget(\n\toptions: ComposeTargetOptions = {},\n): DeployTarget<undefined, ComposeRun> {\n\tconst { mode, push, pin, report, ...given } = options;\n\tconst deps: ComposeDeps = { ...defaultDeps, ...given };\n\n\treturn defineTarget<undefined, ComposeRun>({\n\t\tname: 'compose',\n\t\truntime: 'server',\n\t\tcapabilities: {\n\t\t\trollback: false,\n\t\t\tmigrations: 'target',\n\t\t\timages: true,\n\t\t\t// The stack runs where the deploy does, so the local stage is one\n\t\t\t// it can run — the `gkm dev` hostnames, behind Caddy's own CA.\n\t\t\tlocalStage: true,\n\t\t\t// OpenObserve, in the stack, on loopback.\n\t\t\tselfHostedTelemetry: true,\n\t\t},\n\t\t// Images are pulled with this machine's own `docker login`.\n\t\tcredentials: [],\n\t\t// Built from the checkout, an image is named after its commit.\n\t\ttag: ({ cwd }) => deps.revision(cwd),\n\t\tvalidate: (ctx) =>\n\t\t\tvalidateCompose(ctx, deps, {\n\t\t\t\t...(mode ? { mode } : {}),\n\t\t\t\t...(push ? { push } : {}),\n\t\t\t\t...(pin ? { pin } : {}),\n\t\t\t}),\n\t\tready: (ctx, run) => readyCompose(ctx, run, deps),\n\t\tplan: (ctx, run) => planCompose(ctx, run),\n\t\tresources: (ctx) => resourcesCompose(ctx, deps),\n\t\tprovision: (ctx, run) => provisionCompose(ctx, run, deps),\n\t\tbuild: (ctx, run) => buildCompose(ctx, run, deps),\n\t\trelease: (ctx, run) => releaseCompose(ctx, run, deps),\n\t\tverify: (ctx, run) => verifyCompose(ctx, run, deps),\n\t\tresult: (ctx, run) => {\n\t\t\treport?.(run);\n\t\t\treturn composeResult(ctx, run);\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compose-DMY4ouEk.cjs","names":["GkmError","spawn","run","runOutput","mkdir","dirname","join","gkmHome","EDGE_PROJECT","GkmError","writeFile","chmod","rename","readFile","mkdir","traefikStaticFile","edgeComposeFile","EDGE_NETWORK","EDGE_SERVICE","copyFile","rm","existsSync","GkmError","request","GkmError","join","runOutput","LOGS_PORT_ENV","EDGE_PORT_ENV","pgClient","bucketClient","ensurePostgresLogin","migrateDatabases","seedDatabases","systemLookup","RegistryRequired","imageRef","discover","constructGlobs","imageLayout","composeStack","loadLocalCredentials","assertImagesExist","stackDir","existsSync","composeProject","ComposeTlsFileMissing","stackHosts","isLocalHost","installedFrom","requiredServerAddress","SERVER_IPV4_KEY","serverAddressHint","stageDns","DeployJournal","createComposeState","recordDnsChanges","HostNotPointingAtServer","deployedStackSecrets","pinImages","plannedSeeds","EDGE_PROJECT","EDGE_SERVICE","LOG_ROTATION","applyBuckets","applyPolicies","LEGACY_LOCAL_LOGIN","postgresStatements","applyPostgres","envFor","primaryPortKey","SeedFailed","DeploySeedsFailed","currentActor","readFile","LOGS_SERVICE","logsAccess","hostname","userInfo","mkdir","chmod","dirname","writeFile","rm","envFile","REDIS_SERVICE","readdir","ensureDockerignore","findBuildRoot","stringify","defineTarget"],"sources":["../src/compose/docker.ts","../src/compose/edge.ts","../src/target/compose/health.ts","../src/target/compose/phases.ts","../src/target/compose/index.ts"],"sourcesContent":["/**\n * The Docker operations `gkm compose` needs, behind an interface.\n *\n * Small on purpose, like reconcile's: the rules about *when* each runs — the\n * registry is asked before anything is pulled, nothing is started for a tag\n * that is missing — are asserted against a fake, and this file is only the\n * wiring to the real CLI.\n *\n * Every call is an argument array. Image refs, tags and paths come from the\n * workspace, and none of them reaches a shell.\n */\n\nimport { spawn } from 'node:child_process';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { GkmError } from '../errors';\nimport { type RunOptions, run, runOutput } from '../run';\n\n/** Where one stack lives: its compose project and the file that defines it. */\nexport interface StackRef {\n\tproject: string;\n\tfile: string;\n\t/**\n\t * The project's own files merged over `file`, in order — its\n\t * `docker-compose.<stage>.yml`, where it has one.\n\t */\n\toverrides?: readonly string[];\n\t/** Where relative paths in the file resolve — the workspace root. */\n\tcwd: string;\n\t/**\n\t * Where docker's own output goes: the terminal (the default), stderr — so\n\t * a `--json` run's stdout carries only events — or nowhere.\n\t */\n\toutput?: 'inherit' | 'stderr' | 'ignore';\n\t/** Stops whatever docker is doing for the stack. */\n\tsignal?: AbortSignal;\n}\n\n/** `output` as `spawn` reads it. */\nconst STDIO: Record<NonNullable<StackRef['output']>, RunOptions['stdio']> = {\n\tinherit: 'inherit',\n\tstderr: ['ignore', 2, 2],\n\tignore: 'ignore',\n};\n\n/** How a stack's docker commands run: where it is, where output goes. */\nfunction runOptions(stack: StackRef, env?: NodeJS.ProcessEnv): RunOptions {\n\treturn {\n\t\tcwd: stack.cwd,\n\t\tstdio: STDIO[stack.output ?? 'inherit'],\n\t\t...(env ? { env } : {}),\n\t\t...(stack.signal ? { signal: stack.signal } : {}),\n\t};\n}\n\n/** What the registry said about one image ref. */\nexport type ImageLookup =\n\t| { ref: string; status: 'found' }\n\t| { ref: string; status: 'missing' }\n\t| { ref: string; status: 'unreachable'; detail: string };\n\n/** A running container that publishes a host port. */\nexport interface PortHolder {\n\t/** The container's name. */\n\tcontainer: string;\n\t/** Its compose project and service, when compose started it. */\n\tproject?: string;\n\tservice?: string;\n}\n\nexport interface ComposeDocker {\n\t/** Ask the registry whether `ref` exists, without pulling it. */\n\tlookup(ref: string): Promise<ImageLookup>;\n\t/** Build every service with a `build:` entry. */\n\tbuild(stack: StackRef, services: readonly string[]): Promise<void>;\n\t/** Pull the named services' images. */\n\tpull(stack: StackRef, services: readonly string[]): Promise<void>;\n\t/**\n\t * Start services, detached, and wait for their health checks. With no\n\t * services named, the whole stack — and anything it no longer defines is\n\t * removed.\n\t */\n\tup(stack: StackRef, services?: readonly string[]): Promise<void>;\n\t/** Stop the stack. Its volumes are kept. */\n\tdown(stack: StackRef): Promise<void>;\n\t/** The host port a running service publishes for `inside`. */\n\tport(stack: StackRef, service: string, inside: number): Promise<number>;\n\t/**\n\t * A running service's health, as its own check reports it — `healthy`,\n\t * `starting`, `unhealthy` — or undefined when it is not running.\n\t */\n\thealth(stack: StackRef, service: string): Promise<string | undefined>;\n\t/** Copy a file out of a running service. */\n\tcopyOut(\n\t\tstack: StackRef,\n\t\tservice: string,\n\t\tfrom: string,\n\t\tto: string,\n\t): Promise<void>;\n\t/**\n\t * Push an image built here to its registry, and return the digest the\n\t * registry stored it under (`sha256:…`).\n\t */\n\tpush(stack: StackRef, ref: string): Promise<string>;\n\t/**\n\t * What an image resolved to: the registry digest a pulled image has, or\n\t * the content id of one built here and never pushed.\n\t */\n\tdigest(ref: string): Promise<string | undefined>;\n\t/** Create a network, unless one by that name is there. */\n\tensureNetwork(name: string): Promise<void>;\n\t/** Every running container publishing `port` on the host. */\n\tpublishers(port: number): Promise<PortHolder[]>;\n}\n\n/**\n * The host ports a `docker ps` Ports column publishes: `0.0.0.0:443->443/tcp,\n * [::]:443->443/tcp, 0.0.0.0:9000-9001->9000-9001/tcp`.\n */\nexport function publishedPorts(column: string): number[] {\n\tconst ports = new Set<number>();\n\tfor (const match of column.matchAll(\n\t\t/(?:[\\d.]+|\\[[^\\]]*\\]):(\\d+)(?:-(\\d+))?->/g,\n\t)) {\n\t\tconst first = Number(match[1]);\n\t\tconst last = match[2] ? Number(match[2]) : first;\n\t\tfor (let port = first; port <= last; port++) ports.add(port);\n\t}\n\treturn [...ports];\n}\n\n/** Each line `docker ps` printed, as the containers holding `port`. */\nexport function portHolders(output: string, port: number): PortHolder[] {\n\treturn output\n\t\t.split('\\n')\n\t\t.filter(Boolean)\n\t\t.map((line) => line.split('\\t'))\n\t\t.filter(([, , , column = '']) => publishedPorts(column).includes(port))\n\t\t.map(([container = '', project, service]) => ({\n\t\t\tcontainer,\n\t\t\t...(project ? { project } : {}),\n\t\t\t...(service ? { service } : {}),\n\t\t}));\n}\n\n/** How long a stack has to pass its health checks. */\nconst WAIT_TIMEOUT_S = 180;\n\n/** `docker compose port` printed nothing a port can be read from. */\nexport class ServicePortUnknown extends GkmError {\n\tconstructor(\n\t\treadonly service: string,\n\t\treadonly inside: number,\n\t\treadonly output: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${service}' publishes no host port for ${inside} (docker said: ${output.trim() || 'nothing'}). Is it running? \\`docker compose ps\\` shows the stack.`,\n\t\t);\n\t\tthis.name = 'ServicePortUnknown';\n\t}\n}\n\n/**\n * Whether `ref` names a registry on this machine's loopback — which the\n * daemon pulls from and pushes to over plain HTTP by default, and `docker\n * manifest inspect` reaches only when told `--insecure` (without it, a local\n * registry's image is reported as no such manifest).\n */\nexport function isLoopbackRegistry(ref: string): boolean {\n\tconst first = ref.split('/')[0]!;\n\tif (!ref.includes('/') || !/[.:]|^localhost$/.test(first)) return false;\n\tconst host = first.replace(/:\\d+$/, '');\n\treturn host === 'localhost' || /^127(?:\\.\\d{1,3}){3}$/.test(host);\n}\n\n/** `docker push` finished without saying what digest the registry stored. */\nexport class PushDigestUnknown extends GkmError {\n\tconstructor(\n\t\treadonly ref: string,\n\t\treadonly output: string,\n\t) {\n\t\tsuper(\n\t\t\t`Pushed ${ref}, but docker did not say which digest the registry stored ` +\n\t\t\t\t`(it said: ${output.trim().split('\\n').slice(-3).join(' / ') || 'nothing'}). ` +\n\t\t\t\t`Check the push with \\`docker buildx imagetools inspect ${ref}\\`.`,\n\t\t);\n\t\tthis.name = 'PushDigestUnknown';\n\t}\n}\n\n/** The digest `docker push` reports last: `<tag>: digest: sha256:… size: …`. */\nexport function pushedDigest(output: string): string | undefined {\n\tconst matches = [...output.matchAll(/digest: (sha256:[0-9a-f]{64})/g)];\n\treturn matches.at(-1)?.[1];\n}\n\nfunction compose(stack: StackRef, args: readonly string[]): string[] {\n\treturn [\n\t\t'compose',\n\t\t'-p',\n\t\tstack.project,\n\t\t'-f',\n\t\tstack.file,\n\t\t...(stack.overrides ?? []).flatMap((file) => ['-f', file]),\n\t\t...args,\n\t];\n}\n\n/** Run a program and keep everything it said, whatever it exits with. */\nfunction capture(\n\tcommand: string,\n\targs: readonly string[],\n\ttimeoutMs = 60_000,\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(command, [...args], {\n\t\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\t\tshell: false,\n\t\t});\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\t\tchild.stdout.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString();\n\t\t});\n\t\tchild.stderr.on('data', (chunk: Buffer) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\t\tconst timer = setTimeout(() => child.kill('SIGKILL'), timeoutMs);\n\t\ttimer.unref?.();\n\t\tchild.on('error', (error) => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(error);\n\t\t});\n\t\tchild.on('close', (code) => {\n\t\t\tclearTimeout(timer);\n\t\t\tresolve({ code, stdout, stderr });\n\t\t});\n\t});\n}\n\n/**\n * Whether a failed `docker manifest inspect` means the tag is not there, as\n * opposed to the registry not answering.\n *\n * Read off the message because that is all the CLI gives. Anything not\n * recognisably \"no such tag\" is treated as the registry being unreachable:\n * a registry that refused credentials must not be reported as a tag that was\n * never pushed, or the fix offered would be the wrong one.\n */\nexport function isMissingManifest(output: string): boolean {\n\treturn /no such manifest|manifest unknown|manifest for .* not found|not found: manifest/i.test(\n\t\toutput,\n\t);\n}\n\nexport const dockerCompose: ComposeDocker = {\n\tasync lookup(ref) {\n\t\tconst { code, stdout, stderr } = await capture('docker', [\n\t\t\t'manifest',\n\t\t\t'inspect',\n\t\t\t...(isLoopbackRegistry(ref) ? ['--insecure'] : []),\n\t\t\tref,\n\t\t]);\n\t\tif (code === 0) return { ref, status: 'found' };\n\n\t\tconst output = `${stderr}\\n${stdout}`.trim();\n\t\treturn isMissingManifest(output)\n\t\t\t? { ref, status: 'missing' }\n\t\t\t: { ref, status: 'unreachable', detail: output };\n\t},\n\n\tasync build(stack, services) {\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['build', ...services]),\n\t\t\trunOptions(stack, { ...process.env, DOCKER_BUILDKIT: '1' }),\n\t\t);\n\t},\n\n\tasync pull(stack, services) {\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['pull', ...services]),\n\t\t\trunOptions(stack),\n\t\t);\n\t},\n\n\tasync up(stack, services) {\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, [\n\t\t\t\t'up',\n\t\t\t\t'-d',\n\t\t\t\t'--wait',\n\t\t\t\t`--wait-timeout=${WAIT_TIMEOUT_S}`,\n\t\t\t\t// Only when the whole stack is asked for: starting the databases\n\t\t\t\t// first must not remove the apps an earlier run left running.\n\t\t\t\t...(services ? [] : ['--remove-orphans']),\n\t\t\t\t...(services ?? []),\n\t\t\t]),\n\t\t\trunOptions(stack),\n\t\t);\n\t},\n\n\tasync down(stack) {\n\t\tawait run('docker', compose(stack, ['down']), runOptions(stack));\n\t},\n\n\tasync port(stack, service, inside) {\n\t\tconst output = await runOutput(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['port', service, String(inside)]),\n\t\t\t{ cwd: stack.cwd, ...(stack.signal ? { signal: stack.signal } : {}) },\n\t\t);\n\t\t// `127.0.0.1:54321` — the part after the last colon is the host port.\n\t\tconst port = Number(output.trim().split(':').pop());\n\t\tif (!Number.isInteger(port) || port <= 0) {\n\t\t\tthrow new ServicePortUnknown(service, inside, output);\n\t\t}\n\t\treturn port;\n\t},\n\n\tasync health(stack, service) {\n\t\tconst { code, stdout } = await capture('docker', [\n\t\t\t...compose(stack, ['ps', '--format', '{{.Health}}', service]),\n\t\t]);\n\t\tif (code !== 0) return undefined;\n\t\treturn stdout.trim().split('\\n')[0] || undefined;\n\t},\n\n\tasync copyOut(stack, service, from, to) {\n\t\tawait mkdir(dirname(to), { recursive: true });\n\t\tawait run(\n\t\t\t'docker',\n\t\t\tcompose(stack, ['cp', `${service}:${from}`, to]),\n\t\t\trunOptions(stack),\n\t\t);\n\t},\n\n\tasync push(stack, ref) {\n\t\t// What it printed is read back for the digest; its errors still reach\n\t\t// the terminal.\n\t\tconst output = await runOutput('docker', ['push', ref], {\n\t\t\tcwd: stack.cwd,\n\t\t\t...(stack.signal ? { signal: stack.signal } : {}),\n\t\t});\n\t\tconst digest = pushedDigest(output);\n\t\tif (!digest) throw new PushDigestUnknown(ref, output);\n\t\treturn digest;\n\t},\n\n\tasync digest(ref) {\n\t\tconst { code, stdout } = await capture('docker', [\n\t\t\t'image',\n\t\t\t'inspect',\n\t\t\t'--format={{json .RepoDigests}} {{.Id}}',\n\t\t\tref,\n\t\t]);\n\t\tif (code !== 0) return undefined;\n\n\t\tconst [json = '[]', id] = stdout.trim().split(' ');\n\t\tconst repository = ref.split('@')[0]!.replace(/:[\\w][\\w.-]*$/, '');\n\t\ttry {\n\t\t\tconst digests = JSON.parse(json) as unknown;\n\t\t\tconst match = Array.isArray(digests)\n\t\t\t\t? digests.find(\n\t\t\t\t\t\t(entry): entry is string =>\n\t\t\t\t\t\t\ttypeof entry === 'string' && entry.startsWith(`${repository}@`),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t\tif (match) return match.slice(repository.length + 1);\n\t\t} catch {\n\t\t\t// Fall through to the content id.\n\t\t}\n\t\treturn id || undefined;\n\t},\n\n\tasync ensureNetwork(name) {\n\t\tconst { code } = await capture('docker', ['network', 'inspect', name]);\n\t\tif (code === 0) return;\n\t\tconst created = await capture('docker', ['network', 'create', name]);\n\t\t// Another run may have created it between the two calls.\n\t\tif (created.code !== 0 && !/already exists/.test(created.stderr)) {\n\t\t\tthrow new NetworkCreateFailed(name, created.stderr);\n\t\t}\n\t},\n\n\tasync publishers(port) {\n\t\tconst { stdout } = await capture('docker', [\n\t\t\t'ps',\n\t\t\t'--format',\n\t\t\t'{{.Names}}\\t{{.Label \"com.docker.compose.project\"}}\\t{{.Label \"com.docker.compose.service\"}}\\t{{.Ports}}',\n\t\t]);\n\t\treturn portHolders(stdout, port);\n\t},\n};\n\n/** `docker network create` failed. */\nexport class NetworkCreateFailed extends Error {\n\tconstructor(\n\t\treadonly network: string,\n\t\treadonly output: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not create the Docker network '${network}' (docker said: ${output.trim() || 'nothing'}). Create it by hand with \\`docker network create ${network}\\` and run again.`,\n\t\t);\n\t\tthis.name = 'NetworkCreateFailed';\n\t}\n}\n","/**\n * The server's shared Traefik edge, on disk and in Docker: started when a\n * stack needs it, and each stack's routes written to — and removed from —\n * the directory it watches.\n *\n * The edge lives in the deploy user's gkm home (`$GKM_HOME/edge`, else\n * `~/.gkm/edge`): the user who runs `gkm compose` owns it, so nothing needs\n * root, and it sits beside the stage keys that same user already keeps.\n *\n * ~/.gkm/edge/\n * docker-compose.yml the edge's compose project (gkm-edge)\n * traefik.yml its static configuration\n * dynamic/<project>.yml one per stack: its routers, services, middlewares\n * certs/<project>.crt|.key a stack's own certificate, where it has one\n */\n\nimport { existsSync } from 'node:fs';\nimport {\n\tchmod,\n\tcopyFile,\n\tmkdir,\n\treadFile,\n\trename,\n\trm,\n\twriteFile,\n} from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { GkmError } from '../errors';\nimport { gkmHome } from '../home.js';\nimport type { ComposeDocker, PortHolder, StackRef } from './docker.js';\nimport type { ComposeProxy } from './routes.js';\nimport {\n\tEDGE_NETWORK,\n\tEDGE_PROJECT,\n\tEDGE_SERVICE,\n\ttype EdgePorts,\n\tedgeComposeFile,\n\ttraefikStaticFile,\n} from './traefik.js';\n\n/** The edge's directory on this machine. */\nexport function edgeDir(env: NodeJS.ProcessEnv = process.env): string {\n\treturn join(gkmHome(env), 'edge');\n}\n\n/** The edge's compose project, as docker is asked about it. */\nexport function edgeRef(\n\tdir: string,\n\toptions: Pick<StackRef, 'output' | 'signal'> = {},\n): StackRef {\n\treturn {\n\t\tproject: EDGE_PROJECT,\n\t\tfile: join(dir, 'docker-compose.yml'),\n\t\tcwd: dir,\n\t\t...options,\n\t};\n}\n\n/**\n * Something other than the proxy a stack is set to holds the edge's ports.\n *\n * With `proxy: 'traefik'`, the stack's own Caddy — still running from before\n * the switch — or any other container; with `proxy: 'caddy'`, the shared\n * edge, or another stack's Caddy. Refused before anything is started, so the\n * stack is never left half on one proxy and half on the other.\n */\nexport class ComposeProxyClash extends GkmError {\n\tconstructor(\n\t\treadonly project: string,\n\t\treadonly proxy: ComposeProxy,\n\t\treadonly port: number,\n\t\treadonly holder: PortHolder,\n\t) {\n\t\tconst by = holder.project\n\t\t\t? `${holder.container} (compose project ${holder.project})`\n\t\t\t: holder.container;\n\t\tconst fix =\n\t\t\tproxy === 'traefik'\n\t\t\t\t? holder.project === project && holder.service === 'caddy'\n\t\t\t\t\t? `That is this stack's own Caddy, from before it was switched to proxy: 'traefik'. Move it once: stop it (docker compose -p ${project} stop caddy), then run gkm compose again — the shared edge takes 80/443 and the stack registers with it.`\n\t\t\t\t\t: `The shared edge needs ports 80 and 443. Stop ${holder.container}${holder.project ? ` (docker compose -p ${holder.project} down, or its own gkm compose --down)` : ''}, or move the edge with GKM_COMPOSE_HTTPS_PORT/GKM_COMPOSE_HTTP_PORT.`\n\t\t\t\t: holder.project === EDGE_PROJECT\n\t\t\t\t\t? `That is the server's shared Traefik edge, which other stacks register with. Set deploy.compose.proxy to 'traefik' for this stage so the stack registers with it too, or stop the edge once nothing uses it (docker compose -p ${EDGE_PROJECT} down).`\n\t\t\t\t\t: `Stop ${holder.container}, or publish this stack's Caddy elsewhere with GKM_COMPOSE_HTTPS_PORT/GKM_COMPOSE_HTTP_PORT.`;\n\t\tsuper(\n\t\t\t`${project} is set to proxy: '${proxy}', and port ${port} is held by ${by}. ${fix}`,\n\t\t);\n\t\tthis.name = 'ComposeProxyClash';\n\t}\n}\n\n/**\n * Refuse a stack whose edge ports are held by anything but its own proxy:\n * the shared edge for `'traefik'`, the stack's own Caddy for `'caddy'`.\n */\nexport async function assertEdgePorts(\n\tdocker: ComposeDocker,\n\toptions: { project: string; proxy: ComposeProxy; ports: EdgePorts },\n): Promise<void> {\n\tconst { project, proxy, ports } = options;\n\tfor (const port of [ports.https, ports.http]) {\n\t\tfor (const holder of await docker.publishers(port)) {\n\t\t\tconst own =\n\t\t\t\tproxy === 'traefik'\n\t\t\t\t\t? holder.project === EDGE_PROJECT\n\t\t\t\t\t: holder.project === project && holder.service === 'caddy';\n\t\t\tif (!own) throw new ComposeProxyClash(project, proxy, port, holder);\n\t\t}\n\t}\n}\n\n/** Write a file whole or not at all: a temporary file, then a rename. */\nasync function writeAtomic(\n\tpath: string,\n\tcontent: string,\n\tmode = 0o644,\n): Promise<void> {\n\t// Not `.yml`: the edge reads only `.yml`, `.yaml` and `.toml` files, so it\n\t// never sees one half written.\n\tconst temporary = `${path}.${process.pid}.tmp`;\n\tawait writeFile(temporary, content, { mode });\n\tawait chmod(temporary, mode);\n\tawait rename(temporary, path);\n}\n\n/** Write a file only when its content changed; whether it did. */\nasync function writeIfChanged(path: string, content: string): Promise<boolean> {\n\tconst current = await readFile(path, 'utf-8').catch(() => undefined);\n\tif (current === content) return false;\n\tawait writeAtomic(path, content);\n\treturn true;\n}\n\n/**\n * The edge, up: its network, its files, and its container — started when it\n * is not running, and recreated when its configuration changed. Idempotent:\n * on a server where it already runs as configured, `up` changes nothing.\n */\nexport async function ensureEdge(\n\tdocker: ComposeDocker,\n\toptions: {\n\t\tdir: string;\n\t\tports: EdgePorts;\n\t\tlogging: { driver: string; options: Record<string, string> };\n\t\toutput?: StackRef['output'];\n\t\tsignal?: AbortSignal;\n\t},\n): Promise<string[]> {\n\tconst { dir, ports } = options;\n\tawait mkdir(join(dir, 'dynamic'), { recursive: true });\n\tawait mkdir(join(dir, 'certs'), { recursive: true, mode: 0o700 });\n\n\tconst staticConfig = traefikStaticFile(ports);\n\tawait writeIfChanged(join(dir, 'traefik.yml'), staticConfig);\n\tawait writeIfChanged(\n\t\tjoin(dir, 'docker-compose.yml'),\n\t\tedgeComposeFile({ dir, ports, staticConfig, logging: options.logging }),\n\t);\n\n\tawait docker.ensureNetwork(EDGE_NETWORK);\n\tawait docker.up(\n\t\tedgeRef(dir, {\n\t\t\t...(options.output ? { output: options.output } : {}),\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t}),\n\t\t[EDGE_SERVICE],\n\t);\n\treturn [join(dir, 'traefik.yml'), join(dir, 'docker-compose.yml')];\n}\n\n/** A stack's file in the edge's directory. */\nexport function routesFile(dir: string, project: string): string {\n\treturn join(dir, 'dynamic', `${project}.yml`);\n}\n\n/**\n * Register a stack with the edge: its certificate first, where it has one,\n * so the routes that need it never load without it — then its routes, in one\n * rename the edge picks up whole.\n */\nexport async function writeEdgeRoutes(\n\tdir: string,\n\tproject: string,\n\troutes: string,\n\tcertificate?: { certFile: string; keyFile: string },\n): Promise<string[]> {\n\tconst files: string[] = [];\n\tif (certificate) {\n\t\tconst certs = join(dir, 'certs');\n\t\tawait mkdir(certs, { recursive: true, mode: 0o700 });\n\t\tconst crt = join(certs, `${project}.crt`);\n\t\tconst key = join(certs, `${project}.key`);\n\t\tawait copyFile(certificate.certFile, `${crt}.tmp`);\n\t\tawait rename(`${crt}.tmp`, crt);\n\t\tawait copyFile(certificate.keyFile, `${key}.tmp`);\n\t\tawait chmod(`${key}.tmp`, 0o600);\n\t\tawait rename(`${key}.tmp`, key);\n\t\tfiles.push(crt, key);\n\t} else {\n\t\tawait removeCertificate(dir, project);\n\t}\n\tawait mkdir(join(dir, 'dynamic'), { recursive: true });\n\tconst file = routesFile(dir, project);\n\tawait writeAtomic(file, routes);\n\tfiles.push(file);\n\treturn files;\n}\n\n/** What a stack's file holds for the moment between emptying and removal. */\nconst UNREGISTERED = '# Unregistered by gkm compose --down.\\n';\n\nasync function removeCertificate(dir: string, project: string): Promise<void> {\n\tfor (const ext of ['crt', 'key']) {\n\t\tawait rm(join(dir, 'certs', `${project}.${ext}`), { force: true });\n\t}\n}\n\n/**\n * Unregister a stack: its routes, then its certificate. Whether there was\n * anything to remove.\n */\nexport async function removeEdgeRoutes(\n\tdir: string,\n\tproject: string,\n): Promise<boolean> {\n\tconst file = routesFile(dir, project);\n\tconst existed = existsSync(file);\n\tif (existed) {\n\t\t// Emptied by a rename before it is removed. A watcher that misses the\n\t\t// removal — Docker Desktop's file sharing can drop a delete event —\n\t\t// has still seen the stack's routes go.\n\t\tawait writeAtomic(file, UNREGISTERED);\n\t}\n\tawait rm(file, { force: true });\n\tawait removeCertificate(dir, project);\n\treturn existed;\n}\n","/**\n * Asking each app of a stack whether it answers — through Caddy, over HTTPS,\n * the way a browser reaches it.\n *\n * `docker compose up --wait` already knows each container passed its own\n * health check, asked on 127.0.0.1 inside it. What that cannot say is whether\n * the stack is reachable: whether the edge routes the host to the app, and\n * whether the certificate it presents is one a client accepts. So the check\n * goes through the edge, by hostname, and verifies the certificate.\n */\n\nimport { request } from 'node:https';\nimport { GkmError } from '../../errors';\n\n/** One request to the edge. */\nexport interface HealthRequest {\n\t/** The app's public URL plus its health path. */\n\turl: string;\n\t/**\n\t * The certificate authority to verify against, PEM — Caddy's internal CA\n\t * on the local stage. The system's when absent.\n\t */\n\tca?: string;\n\t/**\n\t * Connect here instead of resolving the URL's host — the local edge, at\n\t * 127.0.0.1. The host is still sent as SNI and `Host`, so nothing depends\n\t * on how this machine resolves `*.localhost`.\n\t */\n\tconnectTo?: string;\n\t/**\n\t * With `connectTo`, the port to connect to, where it is not the URL's —\n\t * the shared edge's published port, asked for a deployed host.\n\t */\n\tconnectPort?: number;\n\ttimeoutMs: number;\n\tsignal?: AbortSignal;\n}\n\n/** Asks once, resolving with the HTTP status. Rejects when nothing answers. */\nexport type HealthProbe = (request: HealthRequest) => Promise<number>;\n\n/** A request that got no answer in time. */\nexport class HealthRequestTimedOut extends GkmError {\n\tconstructor(\n\t\treadonly url: string,\n\t\treadonly timeoutMs: number,\n\t) {\n\t\tsuper(\n\t\t\t`${url} did not answer within ${timeoutMs}ms. Check the stack is up with \\`docker compose ps\\`.`,\n\t\t);\n\t\tthis.name = 'HealthRequestTimedOut';\n\t}\n}\n\n/** The real probe: one HTTPS GET, the certificate verified. */\nexport const httpsProbe: HealthProbe = ({\n\turl,\n\tca,\n\tconnectTo,\n\tconnectPort,\n\ttimeoutMs,\n\tsignal,\n}) => {\n\tconst target = new URL(url);\n\treturn new Promise((resolve, reject) => {\n\t\tconst req = request(\n\t\t\t{\n\t\t\t\thost: connectTo ?? target.hostname,\n\t\t\t\tport: connectPort ?? (target.port || 443),\n\t\t\t\tservername: target.hostname,\n\t\t\t\tpath: `${target.pathname}${target.search}`,\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { host: target.host },\n\t\t\t\t...(ca ? { ca } : {}),\n\t\t\t\t...(signal ? { signal } : {}),\n\t\t\t\ttimeout: timeoutMs,\n\t\t\t},\n\t\t\t(res) => {\n\t\t\t\t// The status is the answer; the body is drained so the socket closes.\n\t\t\t\tres.resume();\n\t\t\t\tres.on('end', () => resolve(res.statusCode ?? 0));\n\t\t\t\tres.on('error', reject);\n\t\t\t},\n\t\t);\n\t\treq.on('timeout', () =>\n\t\t\treq.destroy(new HealthRequestTimedOut(url, timeoutMs)),\n\t\t);\n\t\treq.on('error', reject);\n\t\treq.end();\n\t});\n};\n\n/** Whether a status means the app answered as it should. */\nexport function isHealthy(status: number): boolean {\n\treturn status >= 200 && status < 400;\n}\n\n/** Apps that did not answer through the edge. */\nexport class ComposeAppsUnhealthy extends GkmError {\n\tconstructor(\n\t\treadonly project: string,\n\t\t/** Each app, and the last thing its check got: a status or an error. */\n\t\treadonly apps: readonly { app: string; url: string; last: string }[],\n\t\t/** The proxy they were asked through. */\n\t\treadonly proxy: 'caddy' | 'traefik' = 'caddy',\n\t) {\n\t\tconst names = apps.map((a) => a.app).join(' ');\n\t\tsuper(\n\t\t\t`${project} started, but ${apps.length === 1 ? 'this app does' : 'these apps do'} not answer through ${proxy === 'caddy' ? 'Caddy' : 'the shared Traefik edge'}:\\n` +\n\t\t\t\tapps.map(({ url, last }) => ` - ${url}: ${last}`).join('\\n') +\n\t\t\t\t(proxy === 'caddy'\n\t\t\t\t\t? `\\nSee why with \\`docker compose -p ${project} logs caddy ${names}\\`.`\n\t\t\t\t\t: `\\nSee why with \\`docker compose -p gkm-edge logs traefik\\` and \\`docker compose -p ${project} logs ${names}\\`.`),\n\t\t);\n\t\tthis.name = 'ComposeAppsUnhealthy';\n\t}\n}\n","/**\n * The compose target's phases: a stage as one Docker Compose stack behind\n * Caddy, on the machine the deploy runs on.\n *\n * The order is the point of this file, and the rules it keeps are these:\n *\n * - A tag is checked before anything happens (`validate`). Every app's image\n * is asked of the registry first; one missing image stops the run naming\n * them all, and nothing is written, pulled or started.\n * - The databases exist before the apps do (`provision`). Postgres comes up\n * alone, its databases, roles and grants are created, its migrations\n * applied and its seeds run from this machine, and only then do the apps\n * start — so an app\n * never boots against a schema that is not there yet.\n * - What a stage runs is recorded (`release`). Each app's image, the tag it\n * was released under and the digest it resolved to are written to the\n * stage's state, so \"what is this stage running\" has an exact answer.\n * - What was started answers (`verify`): each app is asked through Caddy,\n * over HTTPS, with the certificate verified.\n *\n * Every image is built inside Docker from a pruned slice of the build root —\n * the same Dockerfiles `gkm docker` writes — so nothing is built on this\n * machine before `docker compose build`.\n *\n * Docker, the registry, Postgres and the health probe are\n * injected, so the rules are asserted without a daemon; the defaults are the\n * real ones.\n */\n\nimport { existsSync } from 'node:fs';\nimport {\n\tchmod,\n\tmkdir,\n\treaddir,\n\treadFile,\n\trm,\n\twriteFile,\n} from 'node:fs/promises';\nimport { hostname, userInfo } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport { stringify } from 'yaml';\nimport {\n\ttype HostLookup,\n\tHostNotPointingAtServer,\n\tisLocalHost,\n\trequiredServerAddress,\n\tSERVER_IPV4_KEY,\n\tserverAddressHint,\n\tstackHosts,\n\tstageDns,\n\tsystemLookup,\n} from '../../compose/dns';\nimport {\n\ttype ComposeDocker,\n\tdockerCompose,\n\ttype StackRef,\n} from '../../compose/docker';\nimport {\n\tassertEdgePorts,\n\tedgeDir,\n\tensureEdge,\n\tremoveEdgeRoutes,\n\twriteEdgeRoutes,\n} from '../../compose/edge';\nimport {\n\tassertImagesExist,\n\ttype ImageDigests,\n\tpinImages,\n\tRegistryRequired,\n} from '../../compose/images';\nimport { LOGS_SERVICE, logsAccess, type StackLogs } from '../../compose/logs';\nimport { ComposeTlsFileMissing } from '../../compose/proxy';\nimport { REDIS_SERVICE } from '../../compose/redis';\nimport { deployedStackSecrets } from '../../compose/secrets';\nimport {\n\ttype ComposeStack,\n\tcomposeProject,\n\tcomposeStack,\n\tEDGE_PORT_ENV,\n\tenvFile,\n\tLOG_ROTATION,\n\tLOGS_PORT_ENV,\n\ttype StackApp,\n\tstackDir,\n} from '../../compose/stack';\nimport { EDGE_PROJECT, EDGE_SERVICE } from '../../compose/traefik';\nimport { currentActor } from '../../deploy/actor.js';\nimport { recordDnsChanges } from '../../deploy/dnsResources.js';\nimport type { ResourceChange } from '../../deploy/events';\nimport { imageRef } from '../../deploy/identity.js';\nimport { DeployJournal } from '../../deploy/journal';\nimport {\n\tcreateComposeState,\n\ttype DeployedImage,\n\trecordRelease,\n} from '../../deploy/state.js';\nimport type { DeployResult } from '../../deploy/types';\nimport { ensureDockerignore } from '../../docker/index.js';\nimport { imageLayout } from '../../docker/layout.js';\nimport { findBuildRoot } from '../../docker/templates.js';\nimport { GkmError } from '../../errors';\nimport { installedFrom } from '../../generators/drivers.js';\nimport {\n\tmigrateDatabases,\n\tplannedSeeds,\n\tSeedFailed,\n\tseedDatabases,\n} from '../../migrate/databases.js';\nimport { bucketClient, pgClient } from '../../reconcile/clients.js';\nimport { primaryPortKey } from '../../reconcile/containers.js';\nimport { type ConstructSource, discover } from '../../reconcile/discover.js';\nimport { envFor } from '../../reconcile/env.js';\nimport { loadLocalCredentials } from '../../reconcile/localCredentials.js';\nimport {\n\tensurePostgresLogin,\n\tLEGACY_LOCAL_LOGIN,\n} from '../../reconcile/logins.js';\nimport {\n\tapplyBuckets,\n\tapplyPolicies,\n\tapplyPostgres,\n\tpostgresStatements,\n} from '../../reconcile/provision.js';\nimport { constructGlobs } from '../../reconcile/workspace.js';\nimport { runOutput } from '../../run';\nimport type { StageSecrets } from '../../secrets/types.js';\nimport type {\n\tDnsProvider as DnsProviderConfig,\n\tNormalizedWorkspace,\n} from '../../workspace/types.js';\nimport type { DnsProvider } from '../dokploy/dns/DnsProvider';\nimport {\n\tDeploySeedsFailed,\n\treportDatabaseRuns,\n\treportPlannedSeeds,\n} from '../seeds';\nimport type { DeployPhaseContext } from '../types';\nimport {\n\tComposeAppsUnhealthy,\n\ttype HealthProbe,\n\thttpsProbe,\n\tisHealthy,\n} from './health';\n\n/** Every phase's context: the compose target takes no options. */\nexport type ComposeContext = DeployPhaseContext<undefined>;\n\n/** What the target needs from outside the process, so tests can stand in. */\nexport interface ComposeDeps {\n\tdocker: ComposeDocker;\n\t/** The commit a build is tagged with. */\n\trevision: (root: string) => Promise<string>;\n\t/** The Postgres client provisioning and migrations connect through. */\n\tsql: typeof pgClient;\n\t/** The S3 client the stack's buckets are created through. */\n\tbuckets: typeof bucketClient;\n\t/** Bring the stack's Postgres onto its superuser — see `logins.ts`. */\n\tlogins: typeof ensurePostgresLogin;\n\t/** Apply the stage's migrations — `migrateDatabases` by default. */\n\tmigrate: typeof migrateDatabases;\n\t/** Run the stage's seeds, after its migrations — `seedDatabases` by default. */\n\tseed: typeof seedDatabases;\n\t/** Ask one app, through the edge, whether it answers. */\n\tprobe: HealthProbe;\n\t/** How many times each app is asked before it counts as down. */\n\thealthAttempts: number;\n\t/** How long to wait between two asks of one app. */\n\thealthIntervalMs: number;\n\t/** Where the edge's ports are read from (`GKM_COMPOSE_HTTPS_PORT`, …). */\n\tenv: NodeJS.ProcessEnv;\n\t/**\n\t * Resolves a public host to every address it has, for the DNS check —\n\t * the system resolver by default.\n\t */\n\tlookup?: HostLookup;\n\t/** The DNS provider for a `dns` domain — `createDnsProvider` by default. */\n\tdnsProviderFor?: (config: DnsProviderConfig) => Promise<DnsProvider | null>;\n}\n\n/** One app's image, as the stage runs it. */\nexport interface ComposeImage {\n\tref: string;\n\ttag: string;\n\tdigest?: string;\n}\n\n/** A compose deploy in progress: what `validate` found, and what follows. */\nexport interface ComposeRun {\n\t/** Build the images from this checkout, or pull the ones a tag names. */\n\tmode: 'build' | 'pull';\n\t/**\n\t * Build and push the images, and nothing else (`--build --push`): no\n\t * provisioning, no container started, nothing recorded.\n\t */\n\tpush: boolean;\n\tstack: ComposeStack;\n\t/** The stack's directory, absolute: `.gkm/compose/<stage>`. */\n\tdir: string;\n\tref: StackRef;\n\t/** The stage's secrets, with whatever a deployed stage generates once. */\n\tsecrets: StageSecrets | null;\n\t/** The names of what was generated, written back in `provision`. */\n\tgenerated: string[];\n\t/** Each app's image as the stage's state last recorded it. */\n\tprevious: Record<string, DeployedImage>;\n\t/** Every file written, absolute. */\n\tfiles: string[];\n\t/** Each app's image, once built or pulled. */\n\timages: Record<string, ComposeImage>;\n\t/** Every resource the run touched, or for a dry run would. */\n\tchanges: ResourceChange[];\n}\n\n/** How a run gets its images, beyond what the tag implies. */\nexport interface ComposeRunOptions {\n\t/**\n\t * Build or pull whatever the tag says. By default a given tag is pulled\n\t * and no tag builds from the checkout.\n\t */\n\tmode?: 'build' | 'pull';\n\t/** Push what was built, and start nothing (`--build --push`). */\n\tpush?: boolean;\n\t/** Run each pulled image at the digest a push reported for it. */\n\tpin?: { file: string; digests: ImageDigests };\n}\n\n/** `--push` without `--build`: there is nothing built here to push. */\nexport class ComposePushNeedsBuild extends GkmError {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'--push pushes the images this checkout builds, so it needs --build ' +\n\t\t\t\t'(and never --pull): gkm compose --stage <stage> --build --push --tag <tag>.',\n\t\t);\n\t\tthis.name = 'ComposePushNeedsBuild';\n\t}\n}\n\n/** Digests to run by, on a run that pulls nothing. */\nexport class ComposePinNeedsPull extends GkmError {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'--digests-file pins the images a release pulls, so it needs --tag ' +\n\t\t\t\t'(or --pull) — or, with --build --push, it is where the pushed digests ' +\n\t\t\t\t'are written.',\n\t\t);\n\t\tthis.name = 'ComposePinNeedsPull';\n\t}\n}\n\n/** A port variable that does not hold a port. */\nexport class EdgePortInvalid extends GkmError {\n\tconstructor(\n\t\treadonly variable: string,\n\t\treadonly value: string,\n\t) {\n\t\tsuper(\n\t\t\t`${variable}=${value} is not a port. Set it to a number between 1 and 65535, or unset it for the default.`,\n\t\t);\n\t\tthis.name = 'EdgePortInvalid';\n\t}\n}\n\n/** A build with no commit to tag its images with. */\nexport class NoGitRevision extends GkmError {\n\tconstructor(readonly root: string) {\n\t\tsuper(\n\t\t\t`Images built here are tagged with the commit they were built from, ` +\n\t\t\t\t`and ${root} is not in a git repository with a commit. Commit, or ` +\n\t\t\t\t`pass --tag to name the images yourself.`,\n\t\t);\n\t\tthis.name = 'NoGitRevision';\n\t}\n}\n\n/**\n * The project's own file merged over a stage's stack: `docker-compose.<stage>.yml`\n * at the workspace root. What the generated file cannot know — a port bound\n * to a tailnet address, another log driver — goes there, and is never\n * overwritten.\n */\nexport function stackOverrideFile(root: string, stage: string): string {\n\treturn join(root, `docker-compose.${stage}.yml`);\n}\n\n/** The commit HEAD is at, short — and `-dirty` when the tree has changes. */\nexport async function gitRevision(root: string): Promise<string> {\n\tlet sha: string;\n\ttry {\n\t\tsha = (\n\t\t\tawait runOutput('git', ['rev-parse', '--short', 'HEAD'], { cwd: root })\n\t\t).trim();\n\t} catch {\n\t\tthrow new NoGitRevision(root);\n\t}\n\tif (!sha) throw new NoGitRevision(root);\n\n\t// An image built from uncommitted changes is not the commit's image, and a\n\t// tag that said it was would be the one thing worse than no tag.\n\tconst status = await runOutput('git', ['status', '--porcelain'], {\n\t\tcwd: root,\n\t}).catch(() => '');\n\treturn status.trim() ? `${sha}-dirty` : sha;\n}\n\n/** The edge's ports, from the environment — 443 and 80 when unset. */\nexport function edgePorts(env: NodeJS.ProcessEnv = process.env): {\n\thttps: number;\n\thttp: number;\n\tlogs?: number;\n} {\n\tconst read = (variable: string, fallback: number) => {\n\t\tconst value = env[variable];\n\t\tif (value === undefined || value === '') return fallback;\n\t\tconst port = Number(value);\n\t\tif (!Number.isInteger(port) || port < 1 || port > 65_535) {\n\t\t\tthrow new EdgePortInvalid(variable, value);\n\t\t}\n\t\treturn port;\n\t};\n\tconst logs = env[LOGS_PORT_ENV] ? read(LOGS_PORT_ENV, 0) : undefined;\n\treturn {\n\t\thttps: read(EDGE_PORT_ENV.https, 443),\n\t\thttp: read(EDGE_PORT_ENV.http, 80),\n\t\t...(logs ? { logs } : {}),\n\t};\n}\n\n/**\n * The real ones. Each app is asked for three minutes before it counts as\n * down: a deployed stage's first ACME certificate can take that long.\n */\nexport const defaultDeps: ComposeDeps = {\n\tdocker: dockerCompose,\n\trevision: gitRevision,\n\tsql: pgClient,\n\tbuckets: bucketClient,\n\tlogins: ensurePostgresLogin,\n\tmigrate: migrateDatabases,\n\tseed: seedDatabases,\n\tprobe: httpsProbe,\n\thealthAttempts: 90,\n\thealthIntervalMs: 2_000,\n\tenv: process.env,\n\tlookup: systemLookup,\n};\n\n// ============================================================================\n// validate\n// ============================================================================\n\n/**\n * The stack the stage would run, and — for a tag — the registry's word that\n * every image it names exists. Nothing is written: a missing image stops the\n * run here, before a file, a secret or a container is touched.\n */\nexport async function validateCompose(\n\tctx: ComposeContext,\n\tdeps: ComposeDeps,\n\toptions: ComposeRunOptions = {},\n): Promise<ComposeRun> {\n\tconst { workspace, stage, identity, tag } = ctx;\n\tconst root = workspace.root;\n\tconst mode = options.mode ?? (ctx.tagGiven ? 'pull' : 'build');\n\tconst push = options.push === true;\n\tif (push && mode !== 'build') throw new ComposePushNeedsBuild();\n\tif (options.pin && mode !== 'pull') throw new ComposePinNeedsPull();\n\n\t// An image pushed or pulled with no registry is a Docker Hub name, which\n\t// is somebody else's. Refused before anything is discovered, built or\n\t// asked of a registry.\n\tconst registry = workspace.deploy?.registry;\n\tif (!registry && (push || mode === 'pull')) {\n\t\tthrow new RegistryRequired(\n\t\t\tpush ? 'push' : 'pull',\n\t\t\timageRef(identity, ctx.apps[0] ?? workspace.name, undefined, tag),\n\t\t);\n\t}\n\n\t// The runnables' edges say which surface reaches which; the manifest the\n\t// run discovered has the declarations but not them.\n\tconst runnables: Record<string, string[]> = {};\n\tconst background: Record<string, string[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns: constructGlobs(workspace),\n\t\tcwd: root,\n\t\trunnables,\n\t\tbackground,\n\t});\n\n\tconst { secrets, generated } = await stageSecrets(ctx, manifest);\n\n\t// Where and with what the images are built — only asked when they are.\n\tconst layout = mode === 'build' ? imageLayout(workspace) : undefined;\n\n\tconst composed = composeStack({\n\t\tworkspace,\n\t\tmanifest,\n\t\trunnables,\n\t\tbackground,\n\t\tstage,\n\t\tidentity,\n\t\timages: {\n\t\t\tmode,\n\t\t\ttag,\n\t\t\t...(registry ? { registry } : {}),\n\t\t},\n\t\tsecrets,\n\t\t...(stage === workspace.stages.local\n\t\t\t? {\n\t\t\t\t\tlocalCredentials: (await loadLocalCredentials(workspace)).credentials,\n\t\t\t\t}\n\t\t\t: {}),\n\t\tallowDevServices: ctx.allowDevServices,\n\t\tports: edgePorts(deps.env),\n\t\t...(layout ? { layout } : {}),\n\t\t...(push ? { buildOnly: true } : {}),\n\t});\n\n\t// A cache is reached over the Redis wire protocol, and the client is the\n\t// project's own dependency: a build without it fails deep inside Docker.\n\tif (mode === 'build') assertRedisClient(workspace, composed);\n\n\t// No image embeds the stage's secrets: a backend reads them at runtime\n\t// from its env file, so one image built at a commit runs on every stage.\n\t// A pinned release runs each image at the digest its push reported.\n\tconst stack = options.pin\n\t\t? withPinnedImages(composed, options.pin.file, options.pin.digests)\n\t\t: composed;\n\n\t// A release is all of its images or none of them. A dry run asks nothing,\n\t// so it can be run without a registry login.\n\tif (mode === 'pull' && !ctx.dryRun) {\n\t\tawait assertImagesExist(deps.docker, tag, [\n\t\t\t...stack.apps,\n\t\t\t...stack.workers,\n\t\t]);\n\t}\n\n\tif (stack.redis && !stack.local) ctx.secrets.mask(stack.redis.password);\n\n\t// The log UI's root login and the header every backend signs in with:\n\t// secrets, unless they are the local stage's fixed ones.\n\tif (stack.logs && (!stack.local || stack.logs.passwordFromSecrets)) {\n\t\tctx.secrets.mask(stack.logs.password);\n\t\tctx.secrets.mask(stack.logs.appEnv.OTEL_EXPORTER_OTLP_HEADERS);\n\t}\n\n\tconst dir = join(root, stackDir(stage));\n\tconst override = stackOverrideFile(root, stage);\n\tconst overrides = existsSync(override) ? [override] : [];\n\tif (overrides.length > 0) {\n\t\tctx.logger.info(\n\t\t\t`🧩 Merging docker-compose.${stage}.yml over the generated stack`,\n\t\t);\n\t}\n\t// What each app ran before this release: its current release, by the same\n\t// record the Dokploy target keeps, so a rollback reads one shape for both.\n\t// A push changes no stage, so it reads none of its state either.\n\tconst recorded = push ? undefined : await ctx.state.read(stage);\n\tconst previous = Object.fromEntries(\n\t\tObject.entries(recorded?.state.releases ?? {}).map(\n\t\t\t([name, releases]): [string, DeployedImage] => {\n\t\t\t\tconst { ref, tag, digest } = releases.current;\n\t\t\t\treturn [\n\t\t\t\t\tname,\n\t\t\t\t\t{ ref, ...(tag ? { tag } : {}), ...(digest ? { digest } : {}) },\n\t\t\t\t];\n\t\t\t},\n\t\t),\n\t);\n\n\treturn {\n\t\tmode,\n\t\tpush,\n\t\tstack,\n\t\tdir,\n\t\tref: {\n\t\t\tproject: composeProject(identity),\n\t\t\tfile: join(dir, 'docker-compose.yml'),\n\t\t\t...(overrides.length > 0 ? { overrides } : {}),\n\t\t\tcwd: root,\n\t\t\toutput: ctx.childOutput,\n\t\t\tsignal: ctx.signal,\n\t\t},\n\t\tsecrets,\n\t\tgenerated,\n\t\tprevious,\n\t\tfiles: [],\n\t\timages: {},\n\t\tchanges: [],\n\t};\n}\n\n// ============================================================================\n// ready\n// ============================================================================\n\n/**\n * What only a compose deploy checks before it changes anything, once the\n * stage's own keys are: the stage's own certificate is there, and every\n * public host points at the stage's server — its records written where a\n * provider holds them, then confirmed — before Caddy or Traefik ask Let's\n * Encrypt for a certificate it could not issue. A build-only run never asks.\n */\nexport async function readyCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack } = run;\n\n\t// Read when the stack starts; one that is not there stops the run here,\n\t// before anything is written or started.\n\tif (stack.tls) {\n\t\tfor (const file of [stack.tls.certFile, stack.tls.keyFile]) {\n\t\t\tif (!existsSync(file)) throw new ComposeTlsFileMissing(ctx.stage, file);\n\t\t}\n\t}\n\n\tif (stack.local) return;\n\tawait stageHostsDns(\n\t\tctx,\n\t\tdeps,\n\t\tstackHosts(stack).filter((host) => !isLocalHost(host)),\n\t\trun.secrets?.custom,\n\t);\n}\n\n/** A stack whose caches are in Redis, built for an app that has no client. */\nexport class RedisClientMissing extends GkmError {\n\tconstructor(readonly apps: readonly string[]) {\n\t\tsuper(\n\t\t\t`The stack keeps every cache in Redis, and ${apps.join(', ')} ` +\n\t\t\t\t`${apps.length === 1 ? 'does' : 'do'} not depend on ioredis, the client ` +\n\t\t\t\t'the generated server reaches it with. Add it to the workspace: ' +\n\t\t\t\t'pnpm add ioredis',\n\t\t);\n\t\tthis.name = 'RedisClientMissing';\n\t}\n}\n\n/**\n * Every backend and worker image built for a stack with a cache can resolve\n * `ioredis` — listed by its app or a directory above it, the way Node and\n * the image's install find it.\n */\nfunction assertRedisClient(\n\tworkspace: NormalizedWorkspace,\n\tstack: ComposeStack,\n): void {\n\tif (!stack.plan.resources.some((r) => r.kind === 'cache')) return;\n\n\tconst hosts = new Set([\n\t\t...stack.apps.filter((app) => app.kind === 'rest-api').map((a) => a.name),\n\t\t...stack.workers.map((worker) => worker.host),\n\t]);\n\tconst missing = [...hosts]\n\t\t.filter((name) => {\n\t\t\tconst app = workspace.apps[name];\n\t\t\treturn app && !installedFrom(join(workspace.root, app.path), 'ioredis');\n\t\t})\n\t\t.sort();\n\tif (missing.length > 0) throw new RedisClientMissing(missing);\n}\n\n/**\n * The stage's secrets — and, for a deployed stage, everything it generates\n * once: its seed, and each declared secret and keyring. Kept only once the\n * run goes ahead (`provision`), so a dry run, or a tag that is not there,\n * leaves the stage's secrets as it found them.\n */\n/**\n * The deploy's DNS step, for a deployed stage: its server's address — required\n * where it serves a real domain — then its own hosts written through each\n * domain's provider in `dns` where they differ, read back from it, and\n * recorded in the stage's state; hosts no provider writes resolved with the\n * system resolver. A dry run prints the plan and writes nothing, and warns\n * rather than stops. What a deploy (`ready`) and `--resources-only` both run.\n *\n * @throws {ServerAddressMissing} when the stage has a domain and no address\n * @throws {ServerAddressInvalid} for a value that is not an address\n * @throws {HostNotPointingAtServer} when a host is not the server\n */\nasync function stageHostsDns(\n\tctx: ComposeContext,\n\tdeps: ComposeDeps,\n\thosts: readonly string[],\n\tcustom: Readonly<Record<string, string>> | undefined,\n): Promise<void> {\n\tconst { workspace, stage } = ctx;\n\tconst server = requiredServerAddress(\n\t\tstage,\n\t\tworkspace.domains?.[stage],\n\t\tcustom,\n\t);\n\tif (hosts.length === 0) return;\n\tif (ctx.skipDns) {\n\t\tctx.logger.info(\n\t\t\t'🌐 DNS skipped (--skip-dns): no record is written or checked',\n\t\t);\n\t\treturn;\n\t}\n\tif (ctx.skipResources) {\n\t\tctx.logger.info(\n\t\t\t'🌐 DNS skipped (--skip-resources): the --resources-only run wrote and confirmed the records',\n\t\t);\n\t\treturn;\n\t}\n\tif (!server) {\n\t\tctx.logger.info(\n\t\t\t`🌐 DNS skipped: no ${SERVER_IPV4_KEY} in '${stage}''s secrets — ${serverAddressHint(stage)}`,\n\t\t);\n\t\treturn;\n\t}\n\tconst log = (line: string) => ctx.logger.info(line);\n\tif (workspace.dns) {\n\t\tlog(\n\t\t\t`🌐 DNS for '${stage}' → ${server.ipv4}${server.ipv6 ? ` / ${server.ipv6}` : ''}${ctx.dryRun ? ' (dry run — nothing is written)' : ''}`,\n\t\t);\n\t}\n\ttry {\n\t\tconst result = await stageDns({\n\t\t\tstage,\n\t\t\thosts,\n\t\t\tserver,\n\t\t\tdns: workspace.dns,\n\t\t\tcredentials: ctx.credentials,\n\t\t\tlog,\n\t\t\tlookup: deps.lookup ?? systemLookup,\n\t\t\t...(ctx.dryRun ? { dryRun: true } : {}),\n\t\t\t...(deps.dnsProviderFor ? { providerFor: deps.dnsProviderFor } : {}),\n\t\t});\n\t\t// What it wrote, kept in the stage's state; what it deleted, forgotten.\n\t\tif (!ctx.dryRun) {\n\t\t\tconst journal = await DeployJournal.open(ctx.state, stage, () =>\n\t\t\t\tcreateComposeState(stage),\n\t\t\t);\n\t\t\tconst providers = new Map(\n\t\t\t\tresult.plan.domains.map((d) => [d.domain, d.provider]),\n\t\t\t);\n\t\t\tawait recordDnsChanges(journal, result.changes, (domain) =>\n\t\t\t\tproviders.get(domain),\n\t\t\t);\n\t\t}\n\t\tconst parts = [\n\t\t\tresult.confirmed.length > 0\n\t\t\t\t? `${result.confirmed.length} host${result.confirmed.length === 1 ? '' : 's'} confirmed by the DNS provider`\n\t\t\t\t: '',\n\t\t\tresult.resolved.length > 0\n\t\t\t\t? `${result.resolved.length} host${result.resolved.length === 1 ? '' : 's'} resolve${result.resolved.length === 1 ? 's' : ''} to ${server.ipv4}`\n\t\t\t\t: '',\n\t\t].filter(Boolean);\n\t\tif (parts.length > 0) log(`🌐 ${parts.join(', ')}`);\n\t} catch (error) {\n\t\tif (ctx.dryRun && error instanceof HostNotPointingAtServer) {\n\t\t\tctx.logger.warn(`⚠ ${error.message}`);\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * `--resources-only`: the stage's DNS records, from the hosts its stack would\n * serve — composed in memory, nothing written, no image asked for. What a CI\n * runner runs with the DNS provider's token, so the server never holds it.\n */\nexport async function resourcesCompose(\n\tctx: ComposeContext,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { workspace, stage } = ctx;\n\tif (stage === workspace.stages.local) return;\n\t// The DNS token was asked for before the providers ran.\n\tconst stored = await ctx.secrets.read();\n\tconst { composeStageHosts } = await import('../../providers/dns.js');\n\tconst hosts = await composeStageHosts({\n\t\tworkspace,\n\t\tstage,\n\t\tstored,\n\t\tmanifest: ctx.manifest,\n\t\trunnables: (ctx.runnables ?? {}) as Record<string, string[]>,\n\t\tbackground: (ctx.background ?? {}) as Record<string, string[]>,\n\t});\n\tawait stageHostsDns(\n\t\tctx,\n\t\tdeps,\n\t\thosts.filter((host) => !isLocalHost(host)),\n\t\tstored?.custom,\n\t);\n}\n\nasync function stageSecrets(\n\tctx: ComposeContext,\n\tmanifest: ConstructManifest,\n): Promise<{ secrets: StageSecrets | null; generated: string[] }> {\n\tconst stored = await ctx.secrets.read();\n\tif (ctx.stage === ctx.workspace.stages.local) {\n\t\t// The local stage's logins are this machine's, generated once with\n\t\t// `gkm dev`'s — not the stage's secrets.\n\t\treturn { secrets: stored, generated: [] };\n\t}\n\n\tconst { secrets, generated } = deployedStackSecrets(\n\t\tctx.workspace,\n\t\tctx.stage,\n\t\tstored,\n\t\tmanifest,\n\t);\n\t// Read through the store they are masked; made up here, they are not yet.\n\tif (secrets.seed) ctx.secrets.mask(secrets.seed);\n\tfor (const value of Object.values(secrets.custom ?? {})) {\n\t\tctx.secrets.mask(value);\n\t}\n\treturn { secrets, generated };\n}\n\n/**\n * The stack with each app's and worker's image pinned to the digest the file\n * names: the refs it is checked, pulled and recorded by, and the image each\n * compose service runs.\n */\nfunction withPinnedImages(\n\tstack: ComposeStack,\n\tfile: string,\n\tdigests: ImageDigests,\n): ComposeStack {\n\tconst apps = pinImages(file, digests, stack.apps);\n\tconst workers = pinImages(file, digests, stack.workers);\n\tconst services = { ...stack.compose.services };\n\tfor (const image of [...apps, ...workers]) {\n\t\tservices[image.name] = { ...services[image.name]!, image: image.ref };\n\t}\n\treturn {\n\t\t...stack,\n\t\tapps,\n\t\tworkers,\n\t\tcompose: { ...stack.compose, services },\n\t};\n}\n\n// ============================================================================\n// plan (dry run)\n// ============================================================================\n\n/**\n * A dry run: the stack's files, written so they can be read, and what a real\n * run would do — no image is built or pulled, no container touched, nothing\n * recorded and no secret kept.\n */\nexport async function planCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n): Promise<void> {\n\tif (run.generated.length > 0) {\n\t\tctx.logger.info(\n\t\t\t`🔑 \"${ctx.stage}\" has no ${run.generated.join(', ')} yet; this dry run used values it did not keep.`,\n\t\t);\n\t}\n\trun.files = await writeStack(ctx.cwd, run.dir, run.stack);\n\tprintPlan(ctx, run);\n\n\t// A push migrates and seeds nothing; a release runs every seed, every\n\t// time, so the list is the same whatever the database holds.\n\tif (!run.push && run.stack.infra.includes('postgres')) {\n\t\treportPlannedSeeds(\n\t\t\t(\n\t\t\t\tawait plannedSeeds({ root: ctx.workspace.root, manifest: ctx.manifest })\n\t\t\t).map(({ target, seeds }) => ({ folder: target.seeds, seeds })),\n\t\t\t(line) => ctx.logger.info(line),\n\t\t);\n\t}\n\n\tconst planned = (change: ResourceChange) => {\n\t\trun.changes.push(change);\n\t\tctx.emit({ type: 'resource.planned', ...change });\n\t};\n\tfor (const service of run.push ? [] : run.stack.infra) {\n\t\tplanned({\n\t\t\tkey: `service:${service}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t});\n\t}\n\tfor (const app of run.stack.apps) {\n\t\tplanned({\n\t\t\tkey: `image:${app.name}`,\n\t\t\tresourceType: 'image',\n\t\t\taction: run.mode === 'build' ? 'build' : 'reuse',\n\t\t\tid: app.ref,\n\t\t});\n\t\tif (run.push) continue;\n\t\tplanned({\n\t\t\tkey: `service:${app.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: run.previous[app.name] ? 'reuse' : 'create',\n\t\t});\n\t}\n\tfor (const worker of run.stack.workers) {\n\t\tplanned({\n\t\t\tkey: `image:${worker.name}`,\n\t\t\tresourceType: 'image',\n\t\t\taction: run.mode === 'build' ? 'build' : 'reuse',\n\t\t\tid: worker.ref,\n\t\t});\n\t\tif (run.push) continue;\n\t\tplanned({\n\t\t\tkey: `service:${worker.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: run.previous[worker.name] ? 'reuse' : 'create',\n\t\t});\n\t}\n\tif (!run.push) {\n\t\tplanned({\n\t\t\tkey:\n\t\t\t\trun.stack.proxy === 'caddy'\n\t\t\t\t\t? 'service:caddy'\n\t\t\t\t\t: `service:${EDGE_PROJECT}/${EDGE_SERVICE}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t});\n\t}\n}\n\n// ============================================================================\n// provision\n// ============================================================================\n\n/**\n * What the apps run on: the stage's generated secrets kept, the stack's files\n * written, its infrastructure started, and its databases, roles, grants and\n * migrations applied.\n */\nexport async function provisionCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack, ref } = run;\n\t// A push provisions nothing; its files are written where it builds.\n\tif (run.push) return;\n\n\tif (run.generated.length > 0 && run.secrets) {\n\t\tawait ctx.secrets.write(run.secrets);\n\t\tctx.logger.info(\n\t\t\t`🔑 Generated for \"${ctx.stage}\" (${ctx.secrets.store}): ${run.generated.join(', ')}`,\n\t\t);\n\t}\n\n\t// Nothing but the stack's own proxy may hold the edge's ports — checked\n\t// before a file is written or a container started.\n\tconst ports = edgePorts(deps.env);\n\tawait assertEdgePorts(deps.docker, {\n\t\tproject: stack.project,\n\t\tproxy: stack.proxy,\n\t\tports,\n\t});\n\n\trun.files = await writeStack(ctx.cwd, run.dir, stack);\n\tprintPlan(ctx, run);\n\n\t// The shared edge, and the network the stack's public services join —\n\t// before any of them, MinIO among them, is started.\n\tif (stack.proxy === 'traefik') {\n\t\tconst dir = edgeDir(deps.env);\n\t\tctx.logger.info(\n\t\t\t`\\n🌐 Starting the shared edge (${EDGE_PROJECT}) from ${dir}…`,\n\t\t);\n\t\trun.files.push(\n\t\t\t...(await ensureEdge(deps.docker, {\n\t\t\t\tdir,\n\t\t\t\tports,\n\t\t\t\tlogging: {\n\t\t\t\t\tdriver: LOG_ROTATION.driver,\n\t\t\t\t\toptions: { ...LOG_ROTATION.options },\n\t\t\t\t},\n\t\t\t\t...(ref.output ? { output: ref.output } : {}),\n\t\t\t\t...(ref.signal ? { signal: ref.signal } : {}),\n\t\t\t})),\n\t\t);\n\t\tapplied(ctx, run, {\n\t\t\tkey: `service:${EDGE_PROJECT}/${EDGE_SERVICE}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t\tid: `${EDGE_PROJECT}/${EDGE_SERVICE}`,\n\t\t\tvia: 'found',\n\t\t});\n\t}\n\n\tif (stack.infra.length > 0) {\n\t\tctx.logger.info(`\\n🗄️ Starting ${stack.infra.join(', ')}…`);\n\t\tawait deps.docker.up(ref, stack.infra);\n\t\tfor (const service of stack.infra) {\n\t\t\tapplied(ctx, run, {\n\t\t\t\tkey: `service:${service}`,\n\t\t\t\tresourceType: 'service',\n\t\t\t\taction: 'ensure',\n\t\t\t\tid: `${stack.project}/${service}`,\n\t\t\t\tvia: Object.keys(run.previous).length > 0 ? 'recorded' : 'created',\n\t\t\t});\n\t\t}\n\t}\n\n\tif (stack.infra.includes('postgres')) {\n\t\tawait prepareDatabases(ctx, run, deps);\n\t}\n\tif (stack.storage && stack.infra.includes('minio')) {\n\t\tawait prepareBuckets(ctx, run, deps);\n\t}\n}\n\n/**\n * Create each bucket the stack's MinIO serves, and the open paths of each\n * one a file server fronts — from this machine, on MinIO's loopback port,\n * the way `gkm dev` creates them.\n */\nasync function prepareBuckets(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst storage = run.stack.storage!;\n\tif (storage.buckets.length === 0) return;\n\n\tconst port = await deps.docker.port(run.ref, 'minio', 9000);\n\tconst client = deps.buckets(port, storage);\n\tconst done = [\n\t\t...(await applyBuckets(client, storage.buckets)),\n\t\t...(await applyPolicies(client, storage.policies)),\n\t];\n\tconst created = done.filter((entry) => entry.created).length;\n\tctx.logger.info(\n\t\t`🪣 Buckets: ${storage.buckets.join(', ')}${created ? ` (${created} change(s))` : ''}`,\n\t);\n}\n\n/**\n * Create what the plan names in the stack's Postgres, migrate it, then run\n * its seeds — every one, every time, as each construct's owner.\n */\nasync function prepareDatabases(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack } = run;\n\tconst workspace: NormalizedWorkspace = ctx.workspace;\n\tconst port = await deps.docker.port(run.ref, 'postgres', 5432);\n\n\t// A stack an older gkm started made its superuser under the old fixed\n\t// name, with the password this stage derives; it is moved to the\n\t// superuser named now — the local stage's from the old fixed login too.\n\tconst superuser = stack.credential.containers.postgres;\n\tconst login = await deps.logins({\n\t\tport,\n\t\tlogin: superuser,\n\t\tlegacy: [\n\t\t\t{ user: LEGACY_LOCAL_LOGIN.user, password: superuser.password },\n\t\t\t...(stack.local ? [LEGACY_LOCAL_LOGIN] : []),\n\t\t],\n\t});\n\tif (login.notice) ctx.logger.info(login.notice);\n\n\tconst statements = postgresStatements(\n\t\tstack.plan,\n\t\tworkspace.name,\n\t\tstack.credential.seed,\n\t);\n\tif (statements.length > 0) {\n\t\tctx.logger.info('🗄️ Creating databases, roles and grants…');\n\t\tawait applyPostgres(deps.sql(port, login.login), statements);\n\t}\n\n\t// Migrations run here, with the project's own Kysely, the way `gkm\n\t// migrate` runs them — so the constructs themselves are needed, which\n\t// only an in-process discovery hands back.\n\tconst sources: Record<string, ConstructSource> = {};\n\tconst manifest = await discover({\n\t\tpatterns: constructGlobs(workspace),\n\t\tcwd: workspace.root,\n\t\tsources,\n\t});\n\n\t// The owner URLs, on the port published to this machine.\n\tconst env = envFor(stack.plan, {\n\t\tports: { [primaryPortKey('postgres')]: port },\n\t\tproject: workspace.name,\n\t\tcredentials: {\n\t\t\t...stack.credential.containers,\n\t\t\tpostgres: login.login,\n\t\t},\n\t\tseed: stack.credential.seed,\n\t});\n\tconst options = { root: workspace.root, manifest, sources, env };\n\tconst runs = await deps.migrate(options);\n\n\t// Seeds after migrations, before any app starts: an app that boots with\n\t// its reference data missing fails on the first request that needs it.\n\tconst seeds = await deps\n\t\t.seed({ ...options, stage: ctx.stage })\n\t\t.catch((error: unknown) => {\n\t\t\tif (error instanceof SeedFailed) {\n\t\t\t\tthrow new DeploySeedsFailed(\n\t\t\t\t\tctx.stage,\n\t\t\t\t\terror.construct,\n\t\t\t\t\terror.seed,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\n\treportDatabaseRuns(\n\t\truns.map(({ target, applied }) => ({\n\t\t\tconstruct: target.id,\n\t\t\tfolder: target.migrations,\n\t\t\tapplied,\n\t\t})),\n\t\tseeds.map(({ target, seeded }) => ({\n\t\t\tconstruct: target.id,\n\t\t\tfolder: target.seeds,\n\t\t\tseeded,\n\t\t})),\n\t\t(line) => ctx.logger.info(line),\n\t\t(event) => ctx.emit(event),\n\t);\n}\n\n// ============================================================================\n// build\n// ============================================================================\n\n/**\n * Each app's image: built from this checkout — inside Docker, every one of\n * them, from a pruned slice of the build root — or pulled at the tag. Nothing\n * live changes.\n */\nexport async function buildCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack, ref } = run;\n\tconst images = [...stack.apps, ...stack.workers];\n\tconst apps = images.map((image) => image.app);\n\n\t// Nothing was provisioned, so nothing has written the files it builds from.\n\tif (run.push) {\n\t\trun.files = await writeStack(ctx.cwd, run.dir, stack);\n\t\tprintPlan(ctx, run);\n\t}\n\n\tif (run.mode === 'build') {\n\t\tctx.logger.info('\\n🐳 Building images…');\n\t\tawait deps.docker.build(ref, apps);\n\t} else {\n\t\tctx.logger.info(`\\n🐳 Pulling ${ctx.tag}…`);\n\t\tawait deps.docker.pull(ref, apps);\n\t}\n\n\tif (run.push) ctx.logger.info('\\n📤 Pushing images…');\n\n\t// What each tag resolved to: the registry's digest for a pushed or pulled\n\t// image, or — for one built here and never pushed — its content id.\n\tfor (const image of images) {\n\t\tconst digest = run.push\n\t\t\t? await deps.docker.push(ref, image.ref)\n\t\t\t: await deps.docker.digest(image.ref);\n\t\tif (run.push) {\n\t\t\tctx.logger.info(` ${image.app.padEnd(12)} ${image.ref}@${digest}`);\n\t\t}\n\t\trun.images[image.app] = {\n\t\t\tref: image.ref,\n\t\t\ttag: image.tag,\n\t\t\t...(digest ? { digest } : {}),\n\t\t};\n\t\tctx.emit({\n\t\t\ttype: 'artifact.built',\n\t\t\tapp: image.app,\n\t\t\timageRef: image.ref,\n\t\t\t...(digest ? { digest } : {}),\n\t\t});\n\t\trun.changes.push({\n\t\t\tkey: `image:${image.app}`,\n\t\t\tresourceType: 'image',\n\t\t\taction: run.mode === 'build' ? 'build' : 'reuse',\n\t\t\tid: digest ?? image.ref,\n\t\t});\n\t}\n}\n\n// ============================================================================\n// release\n// ============================================================================\n\n/**\n * The whole stack up — anything it no longer defines removed — and each\n * app's image recorded in the stage's state.\n */\nexport async function releaseCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack, ref } = run;\n\t// A push starts nothing and records nothing: a stage runs what it pulls.\n\tif (run.push) return;\n\n\tctx.logger.info('\\n🚀 Starting the stack…');\n\tawait deps.docker.up(ref);\n\n\t// Registered with the shared edge once its services are up, so the edge\n\t// never routes to a container that is not there yet. A stack on its own\n\t// Caddy leaves nothing behind there from a run on the edge.\n\tconst edge = edgeDir(deps.env);\n\tif (stack.proxy === 'traefik' && stack.traefik) {\n\t\tconst written = await writeEdgeRoutes(\n\t\t\tedge,\n\t\t\tstack.project,\n\t\t\tstack.traefik,\n\t\t\tstack.tls,\n\t\t);\n\t\trun.files.push(...written);\n\t\tctx.logger.info(\n\t\t\t`🌐 Registered ${stack.routes.length} route(s) with ${EDGE_PROJECT}: ${written.at(-1)}`,\n\t\t);\n\t} else {\n\t\tawait removeEdgeRoutes(edge, stack.project);\n\t}\n\n\tif (stack.local) {\n\t\t// Caddy's CA is generated on its first start. Copied out so a process —\n\t\t// `verify` among them — can trust it without installing anything.\n\t\tawait deps.docker\n\t\t\t.copyOut(\n\t\t\t\tref,\n\t\t\t\t'caddy',\n\t\t\t\t'/data/caddy/pki/authorities/local/root.crt',\n\t\t\t\tcaFile(run),\n\t\t\t)\n\t\t\t.catch(() => {});\n\t}\n\n\tawait recordImages(ctx, run);\n\n\tfor (const app of stack.apps) {\n\t\tconst image = run.images[app.name];\n\t\tapplied(ctx, run, {\n\t\t\tkey: `service:${app.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t\tid: `${stack.project}/${app.name}`,\n\t\t\tvia: run.previous[app.name] ? 'recorded' : 'created',\n\t\t});\n\t\tctx.emit({\n\t\t\ttype: 'app.deployed',\n\t\t\tapp: app.name,\n\t\t\tapplicationId: `${stack.project}/${app.name}`,\n\t\t\timageRef: image?.ref ?? app.ref,\n\t\t\turl: app.url,\n\t\t});\n\t}\n\n\t// A worker has no URL, so no `app.deployed`: its service, applied, is it.\n\tfor (const worker of stack.workers) {\n\t\tapplied(ctx, run, {\n\t\t\tkey: `service:${worker.name}`,\n\t\t\tresourceType: 'service',\n\t\t\taction: 'ensure',\n\t\t\tid: `${stack.project}/${worker.name}`,\n\t\t\tvia: run.previous[worker.name] ? 'recorded' : 'created',\n\t\t});\n\t}\n\n\tctx.logger.info(`\\n✅ ${stack.project} is running:`);\n\tfor (const app of stack.apps) {\n\t\tctx.logger.info(` ${app.name.padEnd(12)} ${app.url}`);\n\t}\n\tfor (const worker of stack.workers) {\n\t\tctx.logger.info(` ${worker.name.padEnd(12)} worker ${worker.id}`);\n\t}\n\tif (stack.local) {\n\t\tctx.logger.info(\n\t\t\t`\\n🔐 Certificates are from Caddy's local CA: NODE_EXTRA_CA_CERTS=${join(stackDir(ctx.stage), 'caddy-root.crt')}`,\n\t\t);\n\t}\n}\n\n/**\n * Each app's image in the stage's state — the same `images` a Dokploy deploy\n * records: the ref it runs, the tag it was released under, and the digest\n * the tag resolved to.\n */\nasync function recordImages(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n): Promise<void> {\n\tconst journal = await DeployJournal.open(ctx.state, ctx.stage, () =>\n\t\tcreateComposeState(ctx.stage),\n\t);\n\tconst by = currentActor();\n\tfor (const app of [...run.stack.apps, ...run.stack.workers]) {\n\t\tconst image = run.images[app.app] ?? { ref: app.ref, tag: app.tag };\n\t\trecordRelease(journal.state, app.app, image, by);\n\t}\n\tjournal.state.identity = ctx.identity.key;\n\tawait journal.save();\n}\n\n// ============================================================================\n// verify\n// ============================================================================\n\n/**\n * Each app asked through Caddy, over HTTPS, the certificate verified: an API\n * at `/health`, a site at `/`. On the local stage the edge is this machine and\n * its certificates are Caddy's internal CA's, so the CA `release` copied out\n * is the one trusted and the request goes to 127.0.0.1.\n */\nexport async function verifyCompose(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n): Promise<void> {\n\tconst { stack } = run;\n\tif (run.push) return;\n\tconst ca = stack.local\n\t\t? await readFile(caFile(run), 'utf-8').catch(() => undefined)\n\t\t: undefined;\n\n\tctx.logger.info(\n\t\t`\\n🩺 Checking each app through ${stack.proxy === 'caddy' ? 'Caddy' : 'the shared edge'}…`,\n\t);\n\t// The local stage's edge is this machine. So is the shared edge, by\n\t// construction — compose starts it here — so it is asked directly, on\n\t// its published port, with each host as SNI and Host: what is checked is\n\t// its routing and its certificate, whatever DNS or a NAT in front of\n\t// the server does with a request from the server to itself.\n\tconst edge =\n\t\tstack.local || stack.proxy === 'traefik'\n\t\t\t? {\n\t\t\t\t\tconnectTo: '127.0.0.1',\n\t\t\t\t\t...(stack.local ? {} : { connectPort: edgePorts(deps.env).https }),\n\t\t\t\t}\n\t\t\t: undefined;\n\tconst results = await Promise.all(\n\t\tstack.apps.map((app) => checkApp(ctx, app, deps, { ca, edge })),\n\t);\n\n\t// A worker has no route through the edge: its own health check, as Docker\n\t// reports it, is the answer.\n\tresults.push(\n\t\t...(await Promise.all(\n\t\t\tstack.workers.map((worker) =>\n\t\t\t\tcheckContainer(ctx, run, deps, worker.name),\n\t\t\t),\n\t\t)),\n\t);\n\tif (stack.logs) {\n\t\tresults.push(await checkContainer(ctx, run, deps, LOGS_SERVICE));\n\t}\n\n\tconst down = results\n\t\t.filter((result) => !result.healthy)\n\t\t.map(({ app, url, last }) => ({ app, url, last }));\n\tif (down.length > 0) {\n\t\tthrow new ComposeAppsUnhealthy(stack.project, down, stack.proxy);\n\t}\n\n\tif (stack.logs) reportLogs(ctx, stack.logs, stack.local);\n}\n\n/**\n * A container's own health check, as Docker reports it: a worker's, which\n * has no route through the edge, and OpenObserve's — by default it has no\n * host there, and served publicly it answers only the addresses it allows,\n * which need not include this one.\n */\nasync function checkContainer(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tdeps: ComposeDeps,\n\tservice: string,\n): Promise<{ app: string; url: string; last: string; healthy: boolean }> {\n\tconst url = `docker:${service}`;\n\tlet last = 'not asked';\n\n\tfor (let attempt = 1; attempt <= deps.healthAttempts; attempt++) {\n\t\tctx.signal.throwIfAborted();\n\t\tconst health = await deps.docker\n\t\t\t.health(run.ref, service)\n\t\t\t.catch((error: unknown) =>\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\n\t\tlast = health ?? 'not running';\n\t\tconst healthy = health === 'healthy';\n\t\tctx.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp: service,\n\t\t\turl,\n\t\t\thealthy,\n\t\t\tattempt,\n\t\t});\n\t\tif (healthy) {\n\t\t\tctx.logger.info(` ✓ ${service.padEnd(12)} ${url} (${last})`);\n\t\t\treturn { app: service, url, last, healthy };\n\t\t}\n\t\tif (attempt < deps.healthAttempts) {\n\t\t\tawait new Promise((resolve) =>\n\t\t\t\tsetTimeout(resolve, deps.healthIntervalMs),\n\t\t\t);\n\t\t}\n\t}\n\n\tctx.logger.warn(` ✗ ${service.padEnd(12)} ${url} (${last})`);\n\treturn { app: service, url, last, healthy: false };\n}\n\n/** How to open the logs, printed — and as an event, for a headless caller. */\nfunction reportLogs(\n\tctx: ComposeContext,\n\tlogs: StackLogs,\n\tlocal: boolean,\n): void {\n\tconst lines = logsAccess(logs, {\n\t\tstage: ctx.stage,\n\t\tlocal,\n\t\tuser: currentUser(),\n\t\thostname: hostname(),\n\t});\n\tctx.logger.info(`\\n${lines.join('\\n')}`);\n\tctx.emit({\n\t\ttype: 'logs.ready',\n\t\tservice: LOGS_SERVICE,\n\t\taccess: logs.public ? 'public' : 'tunnel',\n\t\turl: logs.url,\n\t\t...(logs.public ? { allow: [...logs.public.allow] } : { port: logs.port }),\n\t\temail: logs.email,\n\t});\n}\n\n/** This machine's user — a guess at who would SSH in. */\nfunction currentUser(): string {\n\ttry {\n\t\treturn userInfo().username;\n\t} catch {\n\t\treturn process.env.USER ?? 'user';\n\t}\n}\n\nasync function checkApp(\n\tctx: ComposeContext,\n\tapp: StackApp,\n\tdeps: ComposeDeps,\n\toptions: {\n\t\tca: string | undefined;\n\t\tedge?: { connectTo: string; connectPort?: number };\n\t},\n): Promise<{ app: string; url: string; last: string; healthy: boolean }> {\n\tconst url = `${app.url}${app.kind === 'site' ? '/' : '/health'}`;\n\tlet last = 'not asked';\n\n\tfor (let attempt = 1; attempt <= deps.healthAttempts; attempt++) {\n\t\tctx.signal.throwIfAborted();\n\t\tlet status: number | undefined;\n\t\ttry {\n\t\t\tstatus = await deps.probe({\n\t\t\t\turl,\n\t\t\t\t...(options.ca ? { ca: options.ca } : {}),\n\t\t\t\t...options.edge,\n\t\t\t\ttimeoutMs: 10_000,\n\t\t\t\tsignal: ctx.signal,\n\t\t\t});\n\t\t\tlast = `HTTP ${status}`;\n\t\t} catch (error) {\n\t\t\tlast = error instanceof Error ? error.message : String(error);\n\t\t}\n\n\t\tconst healthy = status !== undefined && isHealthy(status);\n\t\tctx.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp: app.name,\n\t\t\turl,\n\t\t\thealthy,\n\t\t\t...(status !== undefined ? { status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (healthy) {\n\t\t\tctx.logger.info(` ✓ ${app.name.padEnd(12)} ${url} (${last})`);\n\t\t\treturn { app: app.name, url, last, healthy };\n\t\t}\n\t\tif (attempt < deps.healthAttempts) {\n\t\t\tawait new Promise((resolve) =>\n\t\t\t\tsetTimeout(resolve, deps.healthIntervalMs),\n\t\t\t);\n\t\t}\n\t}\n\n\tctx.logger.warn(` ✗ ${app.name.padEnd(12)} ${url} (${last})`);\n\treturn { app: app.name, url, last, healthy: false };\n}\n\n// ============================================================================\n// result\n// ============================================================================\n\nexport function composeResult(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n): DeployResult {\n\tconst apps = [\n\t\t...run.stack.apps.map((app) => {\n\t\t\tconst image = run.images[app.name];\n\t\t\treturn {\n\t\t\t\tappName: app.name,\n\t\t\t\ttype: app.kind === 'site' ? ('web' as const) : ('backend' as const),\n\t\t\t\tsuccess: !ctx.dryRun,\n\t\t\t\tapplicationId: `${run.stack.project}/${app.name}`,\n\t\t\t\timageRef: image?.ref ?? app.ref,\n\t\t\t\t...(image?.digest ? { digest: image.digest } : {}),\n\t\t\t\turl: app.url,\n\t\t\t};\n\t\t}),\n\t\t...run.stack.workers.map((worker) => {\n\t\t\tconst image = run.images[worker.name];\n\t\t\treturn {\n\t\t\t\tappName: worker.name,\n\t\t\t\ttype: 'backend' as const,\n\t\t\t\tsuccess: !ctx.dryRun,\n\t\t\t\tapplicationId: `${run.stack.project}/${worker.name}`,\n\t\t\t\timageRef: image?.ref ?? worker.ref,\n\t\t\t\t...(image?.digest ? { digest: image.digest } : {}),\n\t\t\t};\n\t\t}),\n\t];\n\treturn {\n\t\tapps,\n\t\tprojectId: run.stack.project,\n\t\tsuccessCount: ctx.dryRun ? 0 : apps.length,\n\t\tfailedCount: 0,\n\t\tstage: ctx.stage,\n\t\tidentity: ctx.identity.key,\n\t\ttag: ctx.tag,\n\t\tdryRun: ctx.dryRun,\n\t\tenvironmentId: '',\n\t\tskipped: [...ctx.skipped],\n\t\turls: Object.fromEntries(run.stack.apps.map((app) => [app.name, app.url])),\n\t\tchanges: run.changes,\n\t};\n}\n\n// ============================================================================\n// Files\n// ============================================================================\n\nfunction caFile(run: ComposeRun): string {\n\treturn join(run.dir, 'caddy-root.crt');\n}\n\nfunction applied(\n\tctx: ComposeContext,\n\trun: ComposeRun,\n\tchange: ResourceChange & {\n\t\tid: string;\n\t\tvia: 'recorded' | 'resumed' | 'found' | 'created';\n\t},\n): void {\n\tconst { via, ...rest } = change;\n\trun.changes.push(rest);\n\tctx.emit({ type: 'resource.applied', ...rest, via });\n}\n\n/** Write the stack's files: owner-only, since the env files hold secrets. */\nasync function writeStack(\n\troot: string,\n\tdir: string,\n\tstack: ComposeStack,\n): Promise<string[]> {\n\tawait mkdir(dir, { recursive: true, mode: 0o700 });\n\tawait chmod(dir, 0o700);\n\n\tconst files: string[] = [];\n\tconst write = async (path: string, content: string, mode = 0o644) => {\n\t\tawait mkdir(dirname(path), { recursive: true });\n\t\tawait writeFile(path, content, { mode });\n\t\tawait chmod(path, mode);\n\t\tfiles.push(path);\n\t};\n\n\tawait write(join(dir, 'docker-compose.yml'), composeYaml(stack));\n\t// The proxy's configuration: the stack's own Caddy's, or — for reading —\n\t// a copy of what the stack registers with the shared edge. The other is\n\t// removed, so the directory never shows a proxy the stack does not use.\n\tif (stack.caddyfile !== undefined) {\n\t\tawait write(join(dir, 'Caddyfile'), stack.caddyfile);\n\t\tawait rm(join(dir, 'traefik.yml'), { force: true });\n\t} else {\n\t\tawait rm(join(dir, 'Caddyfile'), { force: true });\n\t}\n\tif (stack.traefik !== undefined) {\n\t\tawait write(join(dir, 'traefik.yml'), stack.traefik);\n\t}\n\t// The stage's own certificate, where Caddy mounts it.\n\tif (stack.proxy === 'caddy' && stack.tls) {\n\t\tawait mkdir(join(dir, 'tls'), { recursive: true, mode: 0o700 });\n\t\tawait write(\n\t\t\tjoin(dir, 'tls', 'cert.pem'),\n\t\t\tawait readFile(stack.tls.certFile, 'utf-8'),\n\t\t);\n\t\tawait write(\n\t\t\tjoin(dir, 'tls', 'key.pem'),\n\t\t\tawait readFile(stack.tls.keyFile, 'utf-8'),\n\t\t\t0o600,\n\t\t);\n\t} else {\n\t\tawait rm(join(dir, 'tls'), { recursive: true, force: true });\n\t}\n\tfor (const app of [...stack.apps, ...stack.workers]) {\n\t\tif (app.env)\n\t\t\tawait write(join(dir, `${app.name}.env`), envFile(app.env), 0o600);\n\t}\n\t// A stack that only builds reads no env file, so none is written.\n\tif (stack.logs && stack.compose.services[LOGS_SERVICE]?.env_file) {\n\t\tawait write(\n\t\t\tjoin(dir, `${LOGS_SERVICE}.env`),\n\t\t\tenvFile(stack.logs.env),\n\t\t\t0o600,\n\t\t);\n\t}\n\tif (stack.redis && stack.compose.services[REDIS_SERVICE]?.env_file) {\n\t\tawait write(\n\t\t\tjoin(dir, `${REDIS_SERVICE}.env`),\n\t\t\tenvFile(stack.redis.env),\n\t\t\t0o600,\n\t\t);\n\t}\n\t// Images no longer embed a stage's credentials. The ciphertexts an older\n\t// gkm left beside the compose file for them to embed are removed.\n\tfor (const entry of await readdir(dir)) {\n\t\tif (entry.endsWith('.credentials')) await rm(join(dir, entry));\n\t}\n\tfor (const [path, content] of Object.entries(stack.dockerfiles)) {\n\t\tawait write(join(root, path), content);\n\t}\n\n\t// The build context is the build root, and the env files are under it:\n\t// its ignore file is what keeps a stage's secrets out of every image's\n\t// context.\n\tawait ensureDockerignore(findBuildRoot(root));\n\n\treturn files;\n}\n\nfunction composeYaml(stack: ComposeStack): string {\n\tconst stage = ` --stage ${stack.stage}`;\n\treturn `# Generated by gkm compose from the construct manifest — do not edit.\n# The ${stack.stage} stage's APIs and sites behind ${stack.proxy === 'caddy' ? 'one Caddy' : `the shared Traefik edge (${EDGE_PROJECT})`}, and its workers.\n# Each backend and worker reads exactly the keys in its own env file beside\n# this one.\n#\n# gkm compose${stage} start or update it\n# gkm compose${stage} --down stop it\n${stringify(stack.compose, { lineWidth: 0, aliasDuplicateObjects: false })}`;\n}\n\nfunction printPlan(ctx: ComposeContext, run: ComposeRun): void {\n\tconst { stack, mode, files } = run;\n\tctx.logger.info(`\\n🧱 ${stack.project} — stage ${stack.stage}`);\n\tfor (const app of stack.apps) {\n\t\tctx.logger.info(\n\t\t\t` ${app.name.padEnd(12)} ${app.url.padEnd(40)} ${mode} ${app.ref}`,\n\t\t);\n\t}\n\tfor (const worker of stack.workers) {\n\t\tctx.logger.info(\n\t\t\t` ${worker.name.padEnd(12)} ${`worker ${worker.id} (no route)`.padEnd(40)} ${mode} ${worker.ref}`,\n\t\t);\n\t}\n\tif (stack.infra.length > 0) {\n\t\tctx.logger.info(` infrastructure: ${stack.infra.join(', ')}`);\n\t}\n\tctx.logger.info(\n\t\t`\\n📝 Wrote ${files.length} file(s) under ${stackDir(stack.stage)}/`,\n\t);\n}\n","/**\n * The built-in `compose` target: a stage as one Docker Compose stack behind\n * Caddy, on the machine that runs the deploy.\n *\n * ```bash\n * gkm deploy --target compose --stage production --tag v1.4.0 # what CI pushed\n * gkm deploy --target compose --stage production # built from here\n * gkm deploy --target compose --stage development # the local stage\n * ```\n *\n * - `validate`: the stack (`composeStack`, pure) and, for a tag, every image\n * looked up in the registry — `ImageTagNotFound` before anything changes\n * - `ready`: a deploy's own checks, after the stage's keys are — the stage's\n * certificate, its server's address, and every public host's DNS\n * - `plan`: the stack's files and what a run would create or reuse\n * - `provision`: generated secrets kept, files written, infrastructure up,\n * databases, roles, grants and migrations\n * - `build`: each backend bundled on the host and every image built — or, for\n * a tag, pulled\n * - `release`: `up --wait --remove-orphans`, and each app's image, tag and\n * digest in the stage's state\n * - `verify`: each app asked through Caddy over HTTPS\n *\n * With `push` (`gkm compose --build --push`), run with `buildOnly`, it builds\n * every image and pushes it to `deploy.registry`, and does nothing else: no\n * readiness check runs, so a stage whose keys the deploy has yet to write\n * still builds.\n *\n * `gkm compose` is this target with a few more switches (`--build`, `--pull`,\n * `--down`), run through the same `deploy()`.\n */\n\nimport { defineTarget } from '../define';\nimport type { DeployTarget } from '../types';\nimport {\n\tbuildCompose,\n\ttype ComposeDeps,\n\ttype ComposeRun,\n\ttype ComposeRunOptions,\n\tcomposeResult,\n\tdefaultDeps,\n\tplanCompose,\n\tprovisionCompose,\n\treadyCompose,\n\treleaseCompose,\n\tresourcesCompose,\n\tvalidateCompose,\n\tverifyCompose,\n} from './phases';\n\nexport {\n\tComposeAppsUnhealthy,\n\ttype HealthProbe,\n\ttype HealthRequest,\n\tHealthRequestTimedOut,\n} from './health';\nexport {\n\ttype ComposeDeps,\n\ttype ComposeImage,\n\tComposePinNeedsPull,\n\tComposePushNeedsBuild,\n\ttype ComposeRun,\n\ttype ComposeRunOptions,\n\tEdgePortInvalid,\n\tedgePorts,\n\tgitRevision,\n\tNoGitRevision,\n\tRedisClientMissing,\n\tstackOverrideFile,\n} from './phases';\n\nexport interface ComposeTargetOptions\n\textends Partial<ComposeDeps>,\n\t\tComposeRunOptions {\n\t/** Handed the finished run — `gkm compose` prints and returns from it. */\n\treport?: (run: ComposeRun) => void;\n}\n\n/** The compose target, with its Docker, bundler and probe as given. */\nexport function composeTarget(\n\toptions: ComposeTargetOptions = {},\n): DeployTarget<undefined, ComposeRun> {\n\tconst { mode, push, pin, report, ...given } = options;\n\tconst deps: ComposeDeps = { ...defaultDeps, ...given };\n\n\treturn defineTarget<undefined, ComposeRun>({\n\t\tname: 'compose',\n\t\truntime: 'server',\n\t\tcapabilities: {\n\t\t\trollback: false,\n\t\t\tmigrations: 'target',\n\t\t\timages: true,\n\t\t\t// The stack runs where the deploy does, so the local stage is one\n\t\t\t// it can run — the `gkm dev` hostnames, behind Caddy's own CA.\n\t\t\tlocalStage: true,\n\t\t\t// OpenObserve, in the stack, on loopback.\n\t\t\tselfHostedTelemetry: true,\n\t\t},\n\t\t// Images are pulled with this machine's own `docker login`.\n\t\tcredentials: [],\n\t\t// Built from the checkout, an image is named after its commit.\n\t\ttag: ({ cwd }) => deps.revision(cwd),\n\t\tvalidate: (ctx) =>\n\t\t\tvalidateCompose(ctx, deps, {\n\t\t\t\t...(mode ? { mode } : {}),\n\t\t\t\t...(push ? { push } : {}),\n\t\t\t\t...(pin ? { pin } : {}),\n\t\t\t}),\n\t\tready: (ctx, run) => readyCompose(ctx, run, deps),\n\t\tplan: (ctx, run) => planCompose(ctx, run),\n\t\tresources: (ctx) => resourcesCompose(ctx, deps),\n\t\tprovision: (ctx, run) => provisionCompose(ctx, run, deps),\n\t\tbuild: (ctx, run) => buildCompose(ctx, run, deps),\n\t\trelease: (ctx, run) => releaseCompose(ctx, run, deps),\n\t\tverify: (ctx, run) => verifyCompose(ctx, run, deps),\n\t\tresult: (ctx, run) => {\n\t\t\treport?.(run);\n\t\t\treturn composeResult(ctx, run);\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|