dokku-compose 0.9.3 → 0.10.1

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/README.md CHANGED
@@ -124,6 +124,7 @@ All features are idempotent — running `up` twice produces no changes.
124
124
  | Zero-Downtime Checks | Configure deploy checks, disable per process type | [checks](docs/reference/checks.md) |
125
125
  | Log Management | Log retention and vector sink configuration | [logs](docs/reference/logs.md) |
126
126
  | Plugins | Install Dokku plugins declaratively | [plugins](docs/reference/plugins.md) |
127
+ | Docker Auth | Authenticate the host docker daemon to private registries (e.g. ghcr.io) for `git:from-image` flows | [docker_auth](docs/reference/docker_auth.md) |
127
128
  | Postgres | Postgres services with optional S3 backups | [postgres](docs/reference/postgres.md) |
128
129
  | Redis | Redis service instances | [redis](docs/reference/redis.md) |
129
130
  | Service Links | Link postgres/redis services to apps | [plugins](docs/reference/plugins.md#linking-services-to-apps-appsapplinks) |
package/dist/index.js CHANGED
@@ -92,11 +92,16 @@ var PluginSchema = z.object({
92
92
  url: z.string().url(),
93
93
  version: z.string().optional()
94
94
  });
95
+ var DockerAuthEntrySchema = z.object({
96
+ username: z.string().min(1),
97
+ password: z.string().min(1)
98
+ });
95
99
  var ConfigSchema = z.object({
96
100
  dokku: z.object({
97
101
  version: z.string().optional()
98
102
  }).optional(),
99
103
  plugins: z.record(z.string(), PluginSchema).optional(),
104
+ docker_auth: z.record(z.string(), DockerAuthEntrySchema).optional(),
100
105
  networks: z.array(z.string()).optional(),
101
106
  postgres: z.record(z.string(), PostgresSchema).optional(),
102
107
  redis: z.record(z.string(), RedisSchema).optional(),
@@ -149,6 +154,7 @@ function createRunner(opts = {}) {
149
154
  const controlPath = opts.host ? path.join(os.tmpdir(), `dc-${createHash("sha1").update(opts.host).digest("hex").slice(0, 16)}.sock`) : null;
150
155
  const sshControlFlags = controlPath ? ["-o", "ControlMaster=auto", "-o", `ControlPath=${controlPath}`, "-o", "ControlPersist=60"] : [];
151
156
  function shellQuote(arg) {
157
+ if (/^[A-Za-z0-9_\-:.,/=@]+$/.test(arg)) return arg;
152
158
  return `'${arg.replace(/'/g, "'\\''")}'`;
153
159
  }
154
160
  async function execDokku(args) {
@@ -387,18 +393,21 @@ var Domains = {
387
393
  for (const d of added) await ctx.run("domains:add", target, d);
388
394
  }
389
395
  };
396
+ function parseDeployMounts(raw) {
397
+ return raw.split(/\s+/).filter((s) => s && s !== "-v");
398
+ }
390
399
  var Storage = {
391
400
  key: "storage",
392
401
  read: async (ctx, target) => {
393
- const raw = await ctx.query("storage:report", target, "--storage-mounts");
394
- return splitLines(raw);
402
+ const raw = await ctx.query("storage:report", target, "--storage-deploy-mounts");
403
+ return parseDeployMounts(raw);
395
404
  },
396
405
  readAll: async (ctx) => {
397
406
  const raw = await ctx.query("storage:report");
398
407
  const bulk = parseBulkReport(raw, "storage");
399
408
  const result = /* @__PURE__ */ new Map();
400
409
  for (const [app, report] of bulk) {
401
- result.set(app, report["mounts"] ? splitLines(report["mounts"]) : []);
410
+ result.set(app, report["deploy-mounts"] ? parseDeployMounts(report["deploy-mounts"]) : []);
402
411
  }
403
412
  return result;
404
413
  },
@@ -805,6 +814,15 @@ async function ensurePlugins(ctx, plugins) {
805
814
  }
806
815
  }
807
816
 
817
+ // src/modules/docker-auth.ts
818
+ async function ensureDockerAuth(ctx, config) {
819
+ for (const [server, creds] of Object.entries(config)) {
820
+ logAction("docker-auth", `Logging in to ${server} as ${creds.username}`);
821
+ await ctx.run("registry:login", server, creds.username, creds.password);
822
+ logDone();
823
+ }
824
+ }
825
+
808
826
  // src/modules/network.ts
809
827
  async function ensureNetworks(ctx, networks) {
810
828
  for (const net of networks) {
@@ -1081,6 +1099,7 @@ async function ensureGlobalNginx(ctx, nginx) {
1081
1099
  async function runUp(ctx, config, appFilter) {
1082
1100
  const apps = appFilter.length > 0 ? appFilter : Object.keys(config.apps);
1083
1101
  if (config.plugins) await ensurePlugins(ctx, config.plugins);
1102
+ if (config.docker_auth) await ensureDockerAuth(ctx, config.docker_auth);
1084
1103
  if (config.domains !== void 0) await ensureGlobalDomains(ctx, config.domains);
1085
1104
  if (config.env !== void 0) await ensureGlobalConfig(ctx, config.env);
1086
1105
  if (config.logs !== void 0) await ensureGlobalLogs(ctx, config.logs);
@@ -1240,9 +1259,14 @@ function maskValue(value) {
1240
1259
  return `****${value.slice(-4)}`;
1241
1260
  }
1242
1261
  function maskSensitiveArgs(cmd) {
1243
- return cmd.replace(/([^\s=]*(?:TOKEN|SECRET|PASSWORD|KEY|AUTH|CREDENTIAL)[^\s=]*)=(\S+)/gi, (_, key, value) => {
1262
+ let masked = cmd.replace(/([^\s=]*(?:TOKEN|SECRET|PASSWORD|KEY|AUTH|CREDENTIAL)[^\s=]*)=(\S+)/gi, (_, key, value) => {
1244
1263
  return `${key}=${maskValue(value)}`;
1245
1264
  });
1265
+ masked = masked.replace(
1266
+ /^(registry:login\s+\S+\s+\S+\s+)(\S+)/,
1267
+ (_, prefix, password) => `${prefix}${maskValue(password)}`
1268
+ );
1269
+ return masked;
1246
1270
  }
1247
1271
  function maskSensitiveData(data) {
1248
1272
  if (data === null || data === void 0) return data;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dokku-compose",
3
- "version": "0.9.3",
3
+ "version": "0.10.1",
4
4
  "description": "Docker Compose for Dokku — declare your entire server in a single YAML file.",
5
5
  "main": "dist/index.js",
6
6
  "exports": "./dist/index.js",