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.
- package/README.md +1 -0
- package/dist/index.js +50 -10
- 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
|
-
|
|
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
|
-
|
|
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;
|