dokku-compose 0.13.0 → 0.14.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 CHANGED
@@ -30,7 +30,7 @@ Like Docker Compose, but for Dokku.
30
30
  npm install -g dokku-compose
31
31
  ```
32
32
 
33
- Requires Node.js >= 20. See the [Installation Reference](docs/reference/install.md) for details.
33
+ Requires Node.js >= 20 and a server running Dokku >= 0.38.29 (every server command stops on an older one; dokku-compose never installs or upgrades Dokku). See the [Installation Reference](docs/reference/install.md) for details.
34
34
 
35
35
  ### 1. Export your existing server
36
36
 
@@ -58,6 +58,8 @@ dokku-compose diff
58
58
  1 resource(s) out of sync.
59
59
  ```
60
60
 
61
+ When `diff` says a box is in sync, `up` runs no command on it. `diff` also covers the top-level `domains:`, `logs:` and `nginx:` (under `global`; log sinks are masked), shared networks missing on the server, and a replaced `ssl.certfile` (compared with the installed certificate). `diff --verbose` prints `Everything in sync.` when nothing differs. `diff` also notes, by name only, each app env key the file does not declare (a key set by hand or by a script); a note is not drift and never changes the exit code. List the keys something else sets under the app's `env_external:` and `diff` stops noting them ([config](docs/reference/config.md#keys-set-elsewhere-appsappenv_external)).
62
+
61
63
  ### 3. Preview changes
62
64
 
63
65
  ```bash
@@ -81,6 +83,29 @@ dokku-compose up
81
83
 
82
84
  Running `up` again produces no changes — every step checks current state before acting.
83
85
 
86
+ #### Apps that need a restart
87
+
88
+ `up` applies env, storage, links and Docker options without restarting anything, so the changes wait for a restart. It ends by listing each app it changed that way, with the exact command (`dokku ps:rebuild <app>` for settings only a rebuild applies, which replaces the restart line for an app needing both) (`would need` on `--dry-run`, also after a partial failure). It never runs the restart and has no `--restart` flag.
89
+
90
+ ```
91
+ # Apps that need a restart or rebuild:
92
+ dokku ps:restart worker # env, storage
93
+ ```
94
+
95
+ | Change | Listed | Evidence (Dokku 0.38.31) |
96
+ |--------|--------|--------------------------|
97
+ | `env` set or unset, per app | yes | applied with `--no-restart` |
98
+ | top-level `env:` | yes, every app the run processes, when a global key is set or unset | global env is read when a container starts |
99
+ | `storage` mount or unmount | yes | persistent-storage docs: "the app requires a restart" |
100
+ | `docker_options` deploy and run | yes | docker-options docs: applies "only to containers created after" the change |
101
+ | `links` link or unlink | yes | applied with `--no-restart` |
102
+ | `network` `tld`, `bind_all_interfaces` | yes | read when containers start |
103
+ | `networks`, `network` `attach_post_create`, `initial_network` | rebuild: `dokku ps:rebuild <app>` | network docs (network.md:210): "A change in these values will require an app deploy or rebuild" |
104
+ | `docker_options` build, `build.args`, `build.dockerfile`, `app_json`, `context` | rebuild | read by a build, which a restart does not run |
105
+ | `ports` | no | `ports:set` fires `post-proxy-ports-update`, which rebuilds the nginx config |
106
+ | `domains`, `nginx`, `proxy`, `certs`, `logs`, `checks`, `registry`, `scheduler` | no | applied live or read at deploy |
107
+ | `scale`, `ps` | no | `--skip-deploy`: takes effect on the next deploy |
108
+
84
109
  ## Commands
85
110
 
86
111
  | Command | Description |
@@ -108,21 +133,23 @@ Running `up` again produces no changes — every step checks current state befor
108
133
  ### Settings removed from the file
109
134
 
110
135
  `diff` marks with a red `-` every setting the server still has that the file no longer declares
111
- (managed env keys, nginx, logs, registry, scheduler, checks, `ps` and network properties, build
112
- args, and entries missing from a declared list), including when the whole block is gone. Only
136
+ (managed env keys, nginx, logs, registry, scheduler, checks, `ps`, network, proxy and git
137
+ properties, build settings and args, and entries missing from a declared list), including when the whole block is gone. Only
113
138
  settable keys count, never read-only report lines, and a `-` counts as drift. It also warns when
114
139
  an app has no `links:` but has services linked on the server, because `up` unlinks them.
115
140
 
116
- `up` always unsets env keys removed from the file. For every other removal it leaves the setting in place and prints a one-line count per app of the leftovers it noticed in the blocks you declare; it does not look at removed whole blocks or checks. Run `dokku-compose diff` for the full list.
141
+ `up` always unsets env keys removed from the file. For every other removal it leaves the setting in place and prints a one-line count per app of the leftovers it noticed in the blocks you declare; it does not look at removed whole blocks, and does not count checks. Run `dokku-compose diff` for the full list.
117
142
 
118
143
  **`up --prune`** resets those leftovers. Read `diff` first: every `-` it shows for the resources below is what `--prune` will reset, and there is no prompt (`diff` is the preview, the flag is the consent). Add `--dry-run` to print the reset commands without running them.
119
144
 
120
145
  | Resource | Reset command |
121
146
  |----------|---------------|
122
- | `nginx`, `logs`, `registry`, `ps` | `<plugin>:set <app> <key>` with no value (Dokku's default); nginx then rebuilds the proxy config |
123
- | `scheduler` | `scheduler:set <app> selected` |
147
+ | `nginx`, `logs`, `registry`, `ps`, `git` (not Dokku-written keys: `ps` `restore`, git `deploy-branch` and `source-image`) | `<plugin>:set <app> <key>` with no value (Dokku's default); nginx then rebuilds the proxy config |
148
+ | `scheduler` | `scheduler:set <app> selected` or `shell` |
149
+ | `proxy` properties | `proxy:set <app> type` with no value (`proxy-port` and `proxy-ssl-port` are written by Dokku) |
124
150
  | `network` properties | `network:set <app> <key>` with no value (`attach_post_create` becomes `attach-post-create`, and so on) |
125
- | `checks` | `checks:enable <app> <types>` for the process types of a removed `disabled`/`skipped` list that the file declares in no list (a type the file does declare is left, with a warning naming the command to run by hand), `checks:set <app> wait-to-retire` |
151
+ | `checks` | `checks:enable <app> <type,type>` for the process types of a removed `disabled`/`skipped` list that the file declares in no list (a type the file does declare is left, with a warning naming the command to run by hand), `checks:set <app> wait-to-retire` |
152
+ | `build.selected`, `build.skip_cleanup` | `builder:set <app> selected` / `skip-cleanup` with no value |
126
153
  | `build.args` | `docker-options:remove <app> build "--build-arg KEY=VALUE"` for each stale key, by the exact option text (every occurrence); other build options stay |
127
154
 
128
155
  It covers a block that is gone from the file as well as keys removed from a declared block, and it reads the app once more for a block the file no longer has. `--prune` never destroys an app, service or network, never uninstalls a plugin, never changes `scale`, and does not clear whole `domains`, `ports`, `storage` or `networks` lists because their key is missing (those already prune inside a block the file declares). `proxy` is not a removal. `networks:` owns `attach-post-deploy`: `--prune` does not touch it, and a missing `networks:` key does not clear it (that could detach a running app from its network on the next deploy); `networks: []` does. After `up --prune`, `diff` shows no `-` for the resources above, except for checks that were skipped with a warning (their `-` lines stay).
@@ -152,18 +179,19 @@ All features are idempotent — running `up` twice produces no changes.
152
179
  | Networks | Create shared Docker networks, attach to apps | [network](docs/reference/network.md) |
153
180
  | Domains | Configure domains per app or globally | [domains](docs/reference/domains.md) |
154
181
  | Port Mappings | Map external ports to container ports | [ports](docs/reference/ports.md) |
155
- | SSL Certificates | Add or remove SSL certs | [certs](docs/reference/certs.md) |
182
+ | SSL Certificates | Add, replace or remove SSL certs | [certs](docs/reference/certs.md) |
156
183
  | Proxy | Enable/disable proxy, select implementation | [proxy](docs/reference/proxy.md) |
157
184
  | Storage | Persistent bind mounts with full convergence (keys removed from the YAML are unset) | [storage](docs/reference/storage.md) |
158
185
  | Nginx | Set any nginx property per app or globally | [nginx](docs/reference/nginx.md) |
186
+ | Scheduler, Registry, Git | `scheduler` (`selected`, `shell`), `registry` and `git` properties per app; every app-scope `:set` key of Dokku 0.38.31 (audit F5), keys Dokku refuses fail `validate` | [logs](docs/reference/logs.md#removal), [audit](docs/dokku-audit.md) |
159
187
  | Zero-Downtime Checks | Configure deploy checks, disable per process type | [checks](docs/reference/checks.md) |
160
188
  | Log Management | Log retention and vector sink configuration | [logs](docs/reference/logs.md) |
161
189
  | Plugins | Install Dokku plugins at pinned versions, updating forward only | [plugins](docs/reference/plugins.md) |
162
190
  | Process Scale & ps | Declare process counts (`ps:scale`) and ps properties (`ps:set`) | [scale](docs/reference/scale.md) |
163
191
  | 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) |
164
- | Postgres | Postgres services with optional S3 backups | [postgres](docs/reference/postgres.md) |
192
+ | Postgres | Postgres services with optional S3 backups, read from `postgres:info` so backup drift shows in `diff`; a changed version or image shows in `diff` | [postgres](docs/reference/postgres.md) |
165
193
  | Redis | Redis service instances | [redis](docs/reference/redis.md) |
166
- | Service Links | Link postgres/redis services to apps | [plugins](docs/reference/plugins.md#linking-services-to-apps-appsapplinks) |
194
+ | Service Links | Link postgres/redis services to apps, with `alias`, `env_var` or `querystring` | [plugins](docs/reference/plugins.md#linking-services-to-apps-appsapplinks) |
167
195
 
168
196
  ## Variable interpolation
169
197
 
@@ -0,0 +1,89 @@
1
+ // src/modules/version.ts
2
+ import { createRequire } from "module";
3
+
4
+ // src/core/logger.ts
5
+ import chalk from "chalk";
6
+ function logAction(context, message) {
7
+ process.stdout.write(chalk.blue(`[${context.padEnd(12)}]`) + ` ${message}`);
8
+ }
9
+ function logDone() {
10
+ console.log(`... ${chalk.green("done")}`);
11
+ }
12
+ function logSkip() {
13
+ console.log(`... ${chalk.yellow("already configured")}`);
14
+ }
15
+ function logError(context, message) {
16
+ console.error(chalk.red(`[${context.padEnd(12)}] ERROR: ${message}`));
17
+ }
18
+ function logWarn(context, message) {
19
+ console.warn(chalk.yellow(`[${context.padEnd(12)}] WARN: ${message}`));
20
+ }
21
+
22
+ // src/modules/version.ts
23
+ var MIN_DOKKU_VERSION = "0.38.29";
24
+ var SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)/;
25
+ function parseSemver(input) {
26
+ const m = input.match(SEMVER_RE);
27
+ if (!m) throw new Error(`Cannot parse version: ${input}`);
28
+ return [Number(m[1]), Number(m[2]), Number(m[3])];
29
+ }
30
+ function extractServerVersion(output) {
31
+ const match = output.match(/(\d+\.\d+\.\d+)/);
32
+ return match ? match[1] : null;
33
+ }
34
+ function compareSemver(a, b) {
35
+ const [aMaj, aMin, aPatch] = parseSemver(a);
36
+ const [bMaj, bMin, bPatch] = parseSemver(b);
37
+ if (aMaj !== bMaj) return aMaj < bMaj ? -1 : 1;
38
+ if (aMin !== bMin) return aMin < bMin ? -1 : 1;
39
+ if (aPatch !== bPatch) return aPatch < bPatch ? -1 : 1;
40
+ return 0;
41
+ }
42
+ function toolVersion() {
43
+ const require2 = createRequire(import.meta.url);
44
+ for (const p of ["../package.json", "../../package.json"]) {
45
+ try {
46
+ return require2(p).version;
47
+ } catch {
48
+ }
49
+ }
50
+ return "unknown";
51
+ }
52
+ async function assertDokkuSupported(ctx) {
53
+ const output = await ctx.query("version");
54
+ const server = extractServerVersion(output);
55
+ if (!server) {
56
+ throw new Error(`Cannot parse Dokku server version from output: ${output}`);
57
+ }
58
+ if (compareSemver(server, MIN_DOKKU_VERSION) === -1) {
59
+ throw new Error(
60
+ `dokku-compose ${toolVersion()} needs Dokku >= ${MIN_DOKKU_VERSION}; this server runs ${server}. Upgrade Dokku first.`
61
+ );
62
+ }
63
+ return server;
64
+ }
65
+ function compareToFile(server, file) {
66
+ if (!file) return "none";
67
+ const c = compareSemver(server, file);
68
+ return c === 0 ? "equal" : c < 0 ? "older" : "newer";
69
+ }
70
+ function enforceFileVersion(server, file) {
71
+ const rel = compareToFile(server, file);
72
+ if (rel === "older") {
73
+ throw new Error(`Dokku server is v${server} but the file requires >= v${file}. Upgrade Dokku or lower dokku.version.`);
74
+ }
75
+ if (rel === "newer") {
76
+ logWarn("dokku", `server is v${server}, newer than dokku.version ${file} in the file; update the file when ready`);
77
+ }
78
+ }
79
+
80
+ export {
81
+ logAction,
82
+ logDone,
83
+ logSkip,
84
+ logError,
85
+ logWarn,
86
+ assertDokkuSupported,
87
+ compareToFile,
88
+ enforceFileVersion
89
+ };