dokku-compose 0.9.2 → 0.10.0

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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +50 -10
  3. package/package.json +1 -1
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
@@ -68,15 +68,15 @@ var AppSchema = z.object({
68
68
  git: GitSchema.optional()
69
69
  });
70
70
  var ServiceBackupAuthSchema = z.object({
71
- access_key_id: z.string(),
72
- secret_access_key: z.string(),
73
- region: z.string(),
74
- signature_version: z.string(),
75
- endpoint: z.string()
71
+ access_key_id: z.string().min(1),
72
+ secret_access_key: z.string().min(1),
73
+ region: z.string().min(1),
74
+ signature_version: z.string().min(1),
75
+ endpoint: z.string().min(1)
76
76
  });
77
77
  var ServiceBackupSchema = z.object({
78
- schedule: z.string(),
79
- bucket: z.string(),
78
+ schedule: z.string().min(1),
79
+ bucket: z.string().min(1),
80
80
  auth: ServiceBackupAuthSchema
81
81
  });
82
82
  var PostgresSchema = z.object({
@@ -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(),
@@ -113,7 +118,22 @@ function parseConfig(raw) {
113
118
 
114
119
  // src/core/config.ts
115
120
  function interpolateEnvVars(content) {
116
- return content.replace(/\$\{([^}]+)\}/g, (_, name) => process.env[name] ?? "");
121
+ const missing = [];
122
+ const result = content.replace(/\$\{([^}]+)\}/g, (_, name) => {
123
+ const value = process.env[name];
124
+ if (value === void 0 || value === "") {
125
+ missing.push(name);
126
+ return "";
127
+ }
128
+ return value;
129
+ });
130
+ if (missing.length > 0) {
131
+ const unique = Array.from(new Set(missing));
132
+ throw new Error(
133
+ `Unset environment variable(s) referenced in config: ${unique.join(", ")}`
134
+ );
135
+ }
136
+ return result;
117
137
  }
118
138
  function loadConfig(filePath) {
119
139
  if (!fs.existsSync(filePath)) {
@@ -790,6 +810,15 @@ async function ensurePlugins(ctx, plugins) {
790
810
  }
791
811
  }
792
812
 
813
+ // src/modules/docker-auth.ts
814
+ async function ensureDockerAuth(ctx, config) {
815
+ for (const [server, creds] of Object.entries(config)) {
816
+ logAction("docker-auth", `Logging in to ${server} as ${creds.username}`);
817
+ await ctx.run("registry:login", server, creds.username, creds.password);
818
+ logDone();
819
+ }
820
+ }
821
+
793
822
  // src/modules/network.ts
794
823
  async function ensureNetworks(ctx, networks) {
795
824
  for (const net of networks) {
@@ -844,7 +873,6 @@ async function ensurePostgresBackups(ctx, services) {
844
873
  continue;
845
874
  }
846
875
  const { schedule, bucket, auth } = config.backup;
847
- await ctx.run("postgres:backup-deauth", name);
848
876
  await ctx.run(
849
877
  "postgres:backup-auth",
850
878
  name,
@@ -855,6 +883,12 @@ async function ensurePostgresBackups(ctx, services) {
855
883
  auth.endpoint
856
884
  );
857
885
  await ctx.run("postgres:backup-schedule", name, schedule, bucket);
886
+ const cronOutput = await ctx.query("postgres:backup-schedule-cat", name);
887
+ if (!parseBackupSchedule(cronOutput)) {
888
+ throw new Error(
889
+ `Backup schedule for ${name} was not installed after backup-schedule ran`
890
+ );
891
+ }
858
892
  await ctx.run("config:set", "--global", `${hashKey}=${desiredHash}`);
859
893
  logDone();
860
894
  }
@@ -1061,6 +1095,7 @@ async function ensureGlobalNginx(ctx, nginx) {
1061
1095
  async function runUp(ctx, config, appFilter) {
1062
1096
  const apps = appFilter.length > 0 ? appFilter : Object.keys(config.apps);
1063
1097
  if (config.plugins) await ensurePlugins(ctx, config.plugins);
1098
+ if (config.docker_auth) await ensureDockerAuth(ctx, config.docker_auth);
1064
1099
  if (config.domains !== void 0) await ensureGlobalDomains(ctx, config.domains);
1065
1100
  if (config.env !== void 0) await ensureGlobalConfig(ctx, config.env);
1066
1101
  if (config.logs !== void 0) await ensureGlobalLogs(ctx, config.logs);
@@ -1220,9 +1255,14 @@ function maskValue(value) {
1220
1255
  return `****${value.slice(-4)}`;
1221
1256
  }
1222
1257
  function maskSensitiveArgs(cmd) {
1223
- return cmd.replace(/([^\s=]*(?:TOKEN|SECRET|PASSWORD|KEY|AUTH|CREDENTIAL)[^\s=]*)=(\S+)/gi, (_, key, value) => {
1258
+ let masked = cmd.replace(/([^\s=]*(?:TOKEN|SECRET|PASSWORD|KEY|AUTH|CREDENTIAL)[^\s=]*)=(\S+)/gi, (_, key, value) => {
1224
1259
  return `${key}=${maskValue(value)}`;
1225
1260
  });
1261
+ masked = masked.replace(
1262
+ /^(registry:login\s+\S+\s+\S+\s+)(\S+)/,
1263
+ (_, prefix, password) => `${prefix}${maskValue(password)}`
1264
+ );
1265
+ return masked;
1226
1266
  }
1227
1267
  function maskSensitiveData(data) {
1228
1268
  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.2",
3
+ "version": "0.10.0",
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",