dokku-compose 0.6.9 → 0.6.11
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 +8 -6
- package/dist/index.js +53 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -176,7 +176,7 @@ apps:
|
|
|
176
176
|
|
|
177
177
|
### Docker Options
|
|
178
178
|
|
|
179
|
-
Add custom Docker options per build phase (`build`, `deploy`, `run`).
|
|
179
|
+
Add custom Docker options per build phase (`build`, `deploy`, `run`). Options are converged with targeted add/remove — only changed options are modified, preserving entries managed by other resources (e.g. `--link`, `--build-arg`).
|
|
180
180
|
|
|
181
181
|
```yaml
|
|
182
182
|
apps:
|
|
@@ -411,8 +411,10 @@ dokku-compose down --force # Destroy all configured apps
|
|
|
411
411
|
|--------|-------------|
|
|
412
412
|
| `--file <path>` | Config file (default: `dokku-compose.yml`) |
|
|
413
413
|
| `--dry-run` | Print commands without executing |
|
|
414
|
+
| `--sensitive` | Show sensitive values in output (masked by default) |
|
|
414
415
|
| `--fail-fast` | Stop on first error (default: continue to next app) |
|
|
415
416
|
| `--remove-orphans` | Destroy services and networks not in config |
|
|
417
|
+
| `--verbose` | Show git-style +/- diff (diff command only) |
|
|
416
418
|
| `--help` | Show usage |
|
|
417
419
|
| `--version` | Show version |
|
|
418
420
|
|
|
@@ -429,14 +431,14 @@ dokku-compose ps # Show status
|
|
|
429
431
|
## Execution Modes
|
|
430
432
|
|
|
431
433
|
```bash
|
|
432
|
-
# Run
|
|
433
|
-
dokku-compose up
|
|
434
|
-
|
|
435
|
-
# Run remotely over SSH
|
|
434
|
+
# Run remotely over SSH (recommended)
|
|
436
435
|
DOKKU_HOST=my-server.example.com dokku-compose up
|
|
436
|
+
|
|
437
|
+
# Run on the Dokku server itself (use DOKKU_HOST=localhost for best compatibility)
|
|
438
|
+
DOKKU_HOST=localhost dokku-compose up
|
|
437
439
|
```
|
|
438
440
|
|
|
439
|
-
When `DOKKU_HOST` is set, all Dokku commands are sent over SSH. This is the
|
|
441
|
+
When `DOKKU_HOST` is set, all Dokku commands are sent over SSH. This is the recommended mode — it works both remotely from your local machine and directly on the server. SSH mode avoids compatibility issues with Dokku's basher environment that can affect some commands when called directly from Node.js. SSH key access to the Dokku server is required.
|
|
440
442
|
|
|
441
443
|
## What `up` Does
|
|
442
444
|
|
package/dist/index.js
CHANGED
|
@@ -1062,6 +1062,37 @@ async function runExport(ctx, opts) {
|
|
|
1062
1062
|
return config;
|
|
1063
1063
|
}
|
|
1064
1064
|
|
|
1065
|
+
// src/core/mask.ts
|
|
1066
|
+
var SENSITIVE_RE = /(?:TOKEN|SECRET|PASSWORD|KEY|AUTH|CREDENTIAL)/i;
|
|
1067
|
+
function maskValue(value) {
|
|
1068
|
+
if (value.length <= 4) return "****";
|
|
1069
|
+
return `****${value.slice(-4)}`;
|
|
1070
|
+
}
|
|
1071
|
+
function maskSensitiveArgs(cmd) {
|
|
1072
|
+
return cmd.replace(/([^\s=]*(?:TOKEN|SECRET|PASSWORD|KEY|AUTH|CREDENTIAL)[^\s=]*)=(\S+)/gi, (_, key, value) => {
|
|
1073
|
+
return `${key}=${maskValue(value)}`;
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
function maskSensitiveData(data) {
|
|
1077
|
+
if (data === null || data === void 0) return data;
|
|
1078
|
+
if (typeof data === "string") return data;
|
|
1079
|
+
if (Array.isArray(data)) return data.map(maskSensitiveData);
|
|
1080
|
+
if (typeof data === "object") {
|
|
1081
|
+
const result = {};
|
|
1082
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1083
|
+
if (typeof value === "string" && SENSITIVE_RE.test(key)) {
|
|
1084
|
+
result[key] = maskValue(value);
|
|
1085
|
+
} else if (typeof value === "object" && value !== null) {
|
|
1086
|
+
result[key] = maskSensitiveData(value);
|
|
1087
|
+
} else {
|
|
1088
|
+
result[key] = value;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
return result;
|
|
1092
|
+
}
|
|
1093
|
+
return data;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1065
1096
|
// src/commands/diff.ts
|
|
1066
1097
|
import chalk2 from "chalk";
|
|
1067
1098
|
async function computeDiff(ctx, config) {
|
|
@@ -1106,6 +1137,21 @@ async function computeDiff(ctx, config) {
|
|
|
1106
1137
|
}
|
|
1107
1138
|
return result;
|
|
1108
1139
|
}
|
|
1140
|
+
function maskDiffResult(diff) {
|
|
1141
|
+
const masked = { apps: {}, services: diff.services, inSync: diff.inSync };
|
|
1142
|
+
for (const [app, appDiff] of Object.entries(diff.apps)) {
|
|
1143
|
+
const maskedAppDiff = {};
|
|
1144
|
+
for (const [feature, d] of Object.entries(appDiff)) {
|
|
1145
|
+
maskedAppDiff[feature] = {
|
|
1146
|
+
status: d.status,
|
|
1147
|
+
desired: maskSensitiveData(d.desired),
|
|
1148
|
+
current: maskSensitiveData(d.current)
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
masked.apps[app] = maskedAppDiff;
|
|
1152
|
+
}
|
|
1153
|
+
return masked;
|
|
1154
|
+
}
|
|
1109
1155
|
function formatSummary(diff) {
|
|
1110
1156
|
const lines = [""];
|
|
1111
1157
|
for (const [app, appDiff] of Object.entries(diff.apps)) {
|
|
@@ -1214,14 +1260,6 @@ function validate(filePath) {
|
|
|
1214
1260
|
return { errors, warnings };
|
|
1215
1261
|
}
|
|
1216
1262
|
|
|
1217
|
-
// src/core/mask.ts
|
|
1218
|
-
function maskSensitiveArgs(cmd) {
|
|
1219
|
-
return cmd.replace(/([^\s=]*(?:TOKEN|SECRET|PASSWORD|KEY|AUTH|CREDENTIAL)[^\s=]*)=(\S+)/gi, (_, key, value) => {
|
|
1220
|
-
if (value.length <= 4) return `${key}=****`;
|
|
1221
|
-
return `${key}=****${value.slice(-4)}`;
|
|
1222
|
-
});
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
1263
|
// src/index.ts
|
|
1226
1264
|
var require2 = createRequire(import.meta.url);
|
|
1227
1265
|
var { version } = require2("../package.json");
|
|
@@ -1279,13 +1317,14 @@ ${result.errors.length} error(s), ${result.warnings.length} warning(s)`);
|
|
|
1279
1317
|
console.log("Valid.");
|
|
1280
1318
|
}
|
|
1281
1319
|
});
|
|
1282
|
-
program.command("export").description("Export server state to dokku-compose.yml format").option("--app <app>", "Export only a specific app").option("-o, --output <path>", "Write to file instead of stdout").action(async (opts) => {
|
|
1320
|
+
program.command("export").description("Export server state to dokku-compose.yml format").option("--app <app>", "Export only a specific app").option("-o, --output <path>", "Write to file instead of stdout").option("--sensitive", "Show sensitive values (masked by default)").action(async (opts) => {
|
|
1283
1321
|
const runner = makeRunner({});
|
|
1284
1322
|
const ctx = createContext(runner);
|
|
1285
1323
|
try {
|
|
1286
|
-
const
|
|
1324
|
+
const rawResult = await runExport(ctx, {
|
|
1287
1325
|
appFilter: opts.app ? [opts.app] : void 0
|
|
1288
1326
|
});
|
|
1327
|
+
const result = opts.sensitive ? rawResult : maskSensitiveData(rawResult);
|
|
1289
1328
|
const out = yaml3.dump(result, { lineWidth: 120 });
|
|
1290
1329
|
if (opts.output) {
|
|
1291
1330
|
fs3.writeFileSync(opts.output, out);
|
|
@@ -1297,15 +1336,16 @@ program.command("export").description("Export server state to dokku-compose.yml
|
|
|
1297
1336
|
await ctx.close();
|
|
1298
1337
|
}
|
|
1299
1338
|
});
|
|
1300
|
-
program.command("diff").description("Show what is out of sync between config and server").option("-f, --file <path>", "Config file", "dokku-compose.yml").option("--verbose", "Show git-style +/- diff").action(async (opts) => {
|
|
1339
|
+
program.command("diff").description("Show what is out of sync between config and server").option("-f, --file <path>", "Config file", "dokku-compose.yml").option("--verbose", "Show git-style +/- diff").option("--sensitive", "Show sensitive values (masked by default)").action(async (opts) => {
|
|
1301
1340
|
const desired = loadConfig(opts.file);
|
|
1302
1341
|
const runner = makeRunner({});
|
|
1303
1342
|
const ctx = createContext(runner);
|
|
1304
1343
|
try {
|
|
1305
|
-
const
|
|
1344
|
+
const rawDiff = await computeDiff(ctx, desired);
|
|
1345
|
+
const diff = opts.sensitive ? rawDiff : maskDiffResult(rawDiff);
|
|
1306
1346
|
const output = opts.verbose ? formatVerbose(diff) : formatSummary(diff);
|
|
1307
1347
|
process.stdout.write(output);
|
|
1308
|
-
process.exit(
|
|
1348
|
+
process.exit(rawDiff.inSync ? 0 : 1);
|
|
1309
1349
|
} finally {
|
|
1310
1350
|
await ctx.close();
|
|
1311
1351
|
}
|