@git.zone/tsdocker 1.17.4 → 2.1.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 (37) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/classes.dockerfile.d.ts +2 -0
  3. package/dist_ts/classes.dockerfile.js +7 -1
  4. package/dist_ts/classes.globalconfig.d.ts +13 -0
  5. package/dist_ts/classes.globalconfig.js +66 -0
  6. package/dist_ts/classes.sshtunnel.d.ts +23 -0
  7. package/dist_ts/classes.sshtunnel.js +66 -0
  8. package/dist_ts/classes.tsdockermanager.d.ts +21 -1
  9. package/dist_ts/classes.tsdockermanager.js +74 -3
  10. package/dist_ts/interfaces/index.d.ts +15 -7
  11. package/dist_ts/tsdocker.cli.js +140 -33
  12. package/dist_ts/tsdocker.config.d.ts +1 -4
  13. package/dist_ts/tsdocker.config.js +3 -22
  14. package/dist_ts/tsdocker.paths.d.ts +0 -1
  15. package/dist_ts/tsdocker.paths.js +1 -2
  16. package/dist_ts/tsdocker.plugins.d.ts +1 -5
  17. package/dist_ts/tsdocker.plugins.js +2 -6
  18. package/package.json +8 -20
  19. package/readme.hints.md +1 -10
  20. package/readme.md +227 -78
  21. package/ts/00_commitinfo_data.ts +1 -1
  22. package/ts/classes.dockerfile.ts +7 -1
  23. package/ts/classes.globalconfig.ts +76 -0
  24. package/ts/classes.sshtunnel.ts +77 -0
  25. package/ts/classes.tsdockermanager.ts +97 -3
  26. package/ts/interfaces/index.ts +17 -8
  27. package/ts/tsdocker.cli.ts +145 -37
  28. package/ts/tsdocker.config.ts +4 -29
  29. package/ts/tsdocker.paths.ts +0 -1
  30. package/ts/tsdocker.plugins.ts +0 -8
  31. package/assets/Dockerfile +0 -6
  32. package/dist_ts/tsdocker.docker.d.ts +0 -2
  33. package/dist_ts/tsdocker.docker.js +0 -145
  34. package/dist_ts/tsdocker.snippets.d.ts +0 -5
  35. package/dist_ts/tsdocker.snippets.js +0 -26
  36. package/ts/tsdocker.docker.ts +0 -169
  37. package/ts/tsdocker.snippets.ts +0 -34
@@ -9,5 +9,4 @@ export let cwd = process.cwd();
9
9
  export let packageBase = plugins.path.join(__dirname, '../');
10
10
  export let assets = plugins.path.join(packageBase, 'assets/');
11
11
  fs.mkdirSync(assets, { recursive: true });
12
- export let npmdockerFile = plugins.path.join(cwd, 'npmdocker');
13
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNkb2NrZXIucGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy90c2RvY2tlci5wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvQixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFFdEMsY0FBYztBQUNkLE1BQU0sQ0FBQyxJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDL0IsTUFBTSxDQUFDLElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM3RCxNQUFNLENBQUMsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzlELEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDMUMsTUFBTSxDQUFDLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQyJ9
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNkb2NrZXIucGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy90c2RvY2tlci5wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvQixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFFdEMsY0FBYztBQUNkLE1BQU0sQ0FBQyxJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDL0IsTUFBTSxDQUFDLElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM3RCxNQUFNLENBQUMsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzlELEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMifQ==
@@ -2,16 +2,12 @@ import * as lik from '@push.rocks/lik';
2
2
  import * as npmextra from '@push.rocks/npmextra';
3
3
  import * as path from 'path';
4
4
  import * as projectinfo from '@push.rocks/projectinfo';
5
- import * as smartpromise from '@push.rocks/smartpromise';
6
- import * as qenv from '@push.rocks/qenv';
7
5
  import * as smartcli from '@push.rocks/smartcli';
8
6
  import { SmartFs } from '@push.rocks/smartfs';
9
7
  import * as smartlog from '@push.rocks/smartlog';
10
8
  import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
11
9
  import * as smartlogSouceOra from '@push.rocks/smartlog-source-ora';
12
- import * as smartopen from '@push.rocks/smartopen';
13
10
  import * as smartinteract from '@push.rocks/smartinteract';
14
11
  import * as smartshell from '@push.rocks/smartshell';
15
- import * as smartstring from '@push.rocks/smartstring';
16
12
  export declare const smartfs: SmartFs;
17
- export { lik, npmextra, path, projectinfo, smartpromise, qenv, smartcli, smartinteract, smartlog, smartlogDestinationLocal, smartlogSouceOra, smartopen, smartshell, smartstring };
13
+ export { lik, npmextra, path, projectinfo, smartcli, smartinteract, smartlog, smartlogDestinationLocal, smartlogSouceOra, smartshell, };
@@ -3,18 +3,14 @@ import * as lik from '@push.rocks/lik';
3
3
  import * as npmextra from '@push.rocks/npmextra';
4
4
  import * as path from 'path';
5
5
  import * as projectinfo from '@push.rocks/projectinfo';
6
- import * as smartpromise from '@push.rocks/smartpromise';
7
- import * as qenv from '@push.rocks/qenv';
8
6
  import * as smartcli from '@push.rocks/smartcli';
9
7
  import { SmartFs, SmartFsProviderNode } from '@push.rocks/smartfs';
10
8
  import * as smartlog from '@push.rocks/smartlog';
11
9
  import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
12
10
  import * as smartlogSouceOra from '@push.rocks/smartlog-source-ora';
13
- import * as smartopen from '@push.rocks/smartopen';
14
11
  import * as smartinteract from '@push.rocks/smartinteract';
15
12
  import * as smartshell from '@push.rocks/smartshell';
16
- import * as smartstring from '@push.rocks/smartstring';
17
13
  // Create smartfs instance
18
14
  export const smartfs = new SmartFs(new SmartFsProviderNode());
19
- export { lik, npmextra, path, projectinfo, smartpromise, qenv, smartcli, smartinteract, smartlog, smartlogDestinationLocal, smartlogSouceOra, smartopen, smartshell, smartstring };
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNkb2NrZXIucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3RzZG9ja2VyLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsbUJBQW1CO0FBQ25CLE9BQU8sS0FBSyxHQUFHLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxLQUFLLFFBQVEsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxZQUFZLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEtBQUssUUFBUSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNuRSxPQUFPLEtBQUssUUFBUSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pELE9BQU8sS0FBSyx3QkFBd0IsTUFBTSx3Q0FBd0MsQ0FBQztBQUNuRixPQUFPLEtBQUssZ0JBQWdCLE1BQU0saUNBQWlDLENBQUM7QUFDcEUsT0FBTyxLQUFLLFNBQVMsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRCxPQUFPLEtBQUssYUFBYSxNQUFNLDJCQUEyQixDQUFDO0FBQzNELE9BQU8sS0FBSyxVQUFVLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxLQUFLLFdBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUV2RCwwQkFBMEI7QUFDMUIsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO0FBRTlELE9BQU8sRUFDTCxHQUFHLEVBQ0gsUUFBUSxFQUNSLElBQUksRUFDSixXQUFXLEVBQ1gsWUFBWSxFQUNaLElBQUksRUFDSixRQUFRLEVBQ1IsYUFBYSxFQUNiLFFBQVEsRUFDUix3QkFBd0IsRUFDeEIsZ0JBQWdCLEVBQ2hCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsV0FBVyxFQUNaLENBQUMifQ==
15
+ export { lik, npmextra, path, projectinfo, smartcli, smartinteract, smartlog, smartlogDestinationLocal, smartlogSouceOra, smartshell, };
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNkb2NrZXIucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3RzZG9ja2VyLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsbUJBQW1CO0FBQ25CLE9BQU8sS0FBSyxHQUFHLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxLQUFLLFFBQVEsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsT0FBTyxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25FLE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsT0FBTyxLQUFLLHdCQUF3QixNQUFNLHdDQUF3QyxDQUFDO0FBQ25GLE9BQU8sS0FBSyxnQkFBZ0IsTUFBTSxpQ0FBaUMsQ0FBQztBQUNwRSxPQUFPLEtBQUssYUFBYSxNQUFNLDJCQUEyQixDQUFDO0FBQzNELE9BQU8sS0FBSyxVQUFVLE1BQU0sd0JBQXdCLENBQUM7QUFFckQsMEJBQTBCO0FBQzFCLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxJQUFJLG1CQUFtQixFQUFFLENBQUMsQ0FBQztBQUU5RCxPQUFPLEVBQ0wsR0FBRyxFQUNILFFBQVEsRUFDUixJQUFJLEVBQ0osV0FBVyxFQUNYLFFBQVEsRUFDUixhQUFhLEVBQ2IsUUFBUSxFQUNSLHdCQUF3QixFQUN4QixnQkFBZ0IsRUFDaEIsVUFBVSxHQUNYLENBQUMifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@git.zone/tsdocker",
3
- "version": "1.17.4",
3
+ "version": "2.1.0",
4
4
  "private": false,
5
5
  "description": "develop npm modules cross platform with docker",
6
6
  "main": "dist_ts/index.js",
@@ -11,13 +11,6 @@
11
11
  "scripts": {
12
12
  "test": "(npm run build)",
13
13
  "build": "(tsbuild)",
14
- "testIntegration": "(npm run clean && npm run setupCheck && npm run testStandard)",
15
- "testStandard": "(cd test/ && tsx ../ts/index.ts)",
16
- "testClean": "(cd test/ && tsx ../ts/index.ts clean --all)",
17
- "testVscode": "(cd test/ && tsx ../ts/index.ts vscode)",
18
- "clean": "(rm -rf test/)",
19
- "compile": "(npmts --notest)",
20
- "setupCheck": "(git clone https://gitlab.com/sandboxzone/sandbox-npmts.git test/)",
21
14
  "buildDocs": "tsdoc"
22
15
  },
23
16
  "repository": {
@@ -34,27 +27,22 @@
34
27
  },
35
28
  "homepage": "https://gitlab.com/gitzone/tsdocker#readme",
36
29
  "devDependencies": {
37
- "@git.zone/tsbuild": "^4.1.2",
30
+ "@git.zone/tsbuild": "^4.3.0",
38
31
  "@git.zone/tsrun": "^2.0.1",
39
- "@git.zone/tstest": "^3.1.6",
40
- "@types/node": "^25.0.9"
32
+ "@git.zone/tstest": "^3.3.2",
33
+ "@types/node": "^25.5.0"
41
34
  },
42
35
  "dependencies": {
43
- "@push.rocks/lik": "^6.2.2",
36
+ "@push.rocks/lik": "^6.3.1",
44
37
  "@push.rocks/npmextra": "^5.3.3",
45
38
  "@push.rocks/projectinfo": "^5.0.2",
46
- "@push.rocks/qenv": "^6.1.3",
47
- "@push.rocks/smartanalytics": "^2.0.15",
48
39
  "@push.rocks/smartcli": "^4.0.20",
49
- "@push.rocks/smartfs": "^1.3.1",
40
+ "@push.rocks/smartfs": "^1.5.0",
50
41
  "@push.rocks/smartinteract": "^2.0.16",
51
- "@push.rocks/smartlog": "^3.1.10",
42
+ "@push.rocks/smartlog": "^3.2.1",
52
43
  "@push.rocks/smartlog-destination-local": "^9.0.2",
53
44
  "@push.rocks/smartlog-source-ora": "^1.0.9",
54
- "@push.rocks/smartopen": "^2.0.0",
55
- "@push.rocks/smartpromise": "^4.2.3",
56
- "@push.rocks/smartshell": "^3.3.0",
57
- "@push.rocks/smartstring": "^4.1.0"
45
+ "@push.rocks/smartshell": "^3.3.7"
58
46
  },
59
47
  "packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34",
60
48
  "type": "module",
package/readme.hints.md CHANGED
@@ -3,7 +3,6 @@
3
3
  ## Module Purpose
4
4
 
5
5
  tsdocker is a comprehensive Docker development and building tool. It provides:
6
- - Testing npm modules in clean Docker environments (legacy feature)
7
6
  - Building Dockerfiles with dependency ordering
8
7
  - Multi-registry push/pull support
9
8
  - Multi-architecture builds (amd64/arm64)
@@ -12,7 +11,7 @@ tsdocker is a comprehensive Docker development and building tool. It provides:
12
11
 
13
12
  | Command | Description |
14
13
  |---------|-------------|
15
- | `tsdocker` | Run tests in container (legacy default behavior) |
14
+ | `tsdocker` | Show usage / man page |
16
15
  | `tsdocker build` | Build all Dockerfiles with dependency ordering |
17
16
  | `tsdocker push [registry]` | Push images to configured registries |
18
17
  | `tsdocker pull <registry>` | Pull images from registry |
@@ -20,7 +19,6 @@ tsdocker is a comprehensive Docker development and building tool. It provides:
20
19
  | `tsdocker login` | Login to configured registries |
21
20
  | `tsdocker list` | List discovered Dockerfiles and dependencies |
22
21
  | `tsdocker clean --all` | Clean up Docker environment |
23
- | `tsdocker vscode` | Start VS Code in Docker |
24
22
 
25
23
  ## Configuration
26
24
 
@@ -45,9 +43,6 @@ Configure in `package.json` under `@git.zone/tsdocker`:
45
43
 
46
44
  ### Configuration Options
47
45
 
48
- - `baseImage`: Base Docker image for testing (legacy)
49
- - `command`: Command to run in container (legacy)
50
- - `dockerSock`: Mount Docker socket (legacy)
51
46
  - `registries`: Array of registry URLs to push to
52
47
  - `registryRepoMap`: Map registry URLs to different repo paths
53
48
  - `buildArgEnvMap`: Map Docker build ARGs to environment variables
@@ -78,8 +73,6 @@ ts/
78
73
  ├── tsdocker.cli.ts (CLI commands)
79
74
  ├── tsdocker.config.ts (configuration)
80
75
  ├── tsdocker.plugins.ts (plugin imports)
81
- ├── tsdocker.docker.ts (legacy test runner)
82
- ├── tsdocker.snippets.ts (Dockerfile generation)
83
76
  ├── classes.dockerfile.ts (Dockerfile management)
84
77
  ├── classes.dockerregistry.ts (registry authentication)
85
78
  ├── classes.registrystorage.ts (registry storage)
@@ -123,8 +116,6 @@ The `config.push` field is now a no-op (kept for backward compat).
123
116
  ## Build Status
124
117
 
125
118
  - Build: ✅ Passes
126
- - Legacy test functionality preserved
127
- - New Docker build functionality added
128
119
 
129
120
  ## Previous Upgrades (2025-11-22)
130
121
 
package/readme.md CHANGED
@@ -12,13 +12,15 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
12
12
 
13
13
  ### 🎯 Key Capabilities
14
14
 
15
- - 🧪 **Containerized Testing** — Run your tests in pristine Docker environments
16
15
  - 🏗️ **Smart Docker Builds** — Automatically discover, sort, and build Dockerfiles by dependency
17
16
  - 🌍 **True Multi-Architecture** — Build for `amd64` and `arm64` simultaneously with Docker Buildx
18
17
  - 🚀 **Multi-Registry Push** — Ship to Docker Hub, GitLab, GitHub Container Registry, and more via OCI Distribution API
19
18
  - ⚡ **Parallel Builds** — Level-based parallel builds with configurable concurrency
20
19
  - 🗄️ **Persistent Local Registry** — All images flow through a local OCI registry with persistent storage
21
20
  - 📦 **Build Caching** — Skip unchanged Dockerfiles with content-hash caching
21
+ - 🎯 **Dockerfile Filtering** — Build or push only specific Dockerfiles using glob patterns
22
+ - 🔁 **Resilient Push** — Automatic retry with exponential backoff, timeouts, and token refresh for rock-solid pushes
23
+ - 🏭 **CI-Safe Isolation** — Unique sessions per invocation prevent collisions in parallel CI pipelines
22
24
  - 🔧 **Zero Config Start** — Works out of the box, scales with your needs
23
25
 
24
26
  ## Installation
@@ -33,16 +35,6 @@ pnpm install --save-dev @git.zone/tsdocker
33
35
 
34
36
  ## Quick Start
35
37
 
36
- ### 🧪 Run Tests in Docker
37
-
38
- The simplest use case — run your tests in a clean container:
39
-
40
- ```bash
41
- tsdocker
42
- ```
43
-
44
- This pulls your configured base image, mounts your project, and executes your test command in isolation.
45
-
46
38
  ### 🏗️ Build Docker Images
47
39
 
48
40
  Got `Dockerfile` files? Build them all with automatic dependency ordering:
@@ -68,28 +60,47 @@ tsdocker push
68
60
 
69
61
  # Push to a specific registry
70
62
  tsdocker push --registry=registry.gitlab.com
63
+
64
+ # Push without rebuilding (use existing images in local registry)
65
+ tsdocker push --no-build
71
66
  ```
72
67
 
73
- Under the hood, `tsdocker push` uses the **OCI Distribution API** to copy images directly from the local registry to remote registries. This means multi-arch manifest lists are preserved end-to-end — no more single-platform-only pushes.
68
+ Under the hood, `tsdocker push` uses the **OCI Distribution API** to copy images directly from the local registry to remote registries. This means multi-arch manifest lists are preserved end-to-end — no more single-platform-only pushes. Every request is protected with **automatic retry** (up to 6 attempts with exponential backoff) and **5-minute timeouts**, so transient network issues don't kill your push mid-transfer.
69
+
70
+ ### 🎯 Build Only Specific Dockerfiles
71
+
72
+ Target specific Dockerfiles by name pattern — dependencies are resolved automatically:
73
+
74
+ ```bash
75
+ # Build only the base image
76
+ tsdocker build Dockerfile_base
77
+
78
+ # Build anything matching a glob pattern
79
+ tsdocker build Dockerfile_app*
80
+
81
+ # Push specific images only (skip build phase)
82
+ tsdocker push --no-build Dockerfile_api Dockerfile_web
83
+ ```
74
84
 
75
85
  ## CLI Commands
76
86
 
77
87
  | Command | Description |
78
88
  |---------|-------------|
79
- | `tsdocker` | Run tests in a fresh Docker container (legacy mode) |
89
+ | `tsdocker` | Show usage / man page |
80
90
  | `tsdocker build` | Build all Dockerfiles with dependency ordering |
81
91
  | `tsdocker push` | Build + push images to configured registries |
82
92
  | `tsdocker pull <registry>` | Pull images from a specific registry |
83
93
  | `tsdocker test` | Build + run container test scripts (`test_*.sh`) |
84
94
  | `tsdocker login` | Authenticate with configured registries |
85
95
  | `tsdocker list` | Display discovered Dockerfiles and their dependencies |
96
+ | `tsdocker config` | Manage global tsdocker configuration (remote builders, etc.) |
86
97
  | `tsdocker clean` | Interactively clean Docker environment |
87
- | `tsdocker vscode` | Launch containerized VS Code in browser |
88
98
 
89
99
  ### Build Flags
90
100
 
91
101
  | Flag | Description |
92
102
  |------|-------------|
103
+ | `<patterns>` | Positional Dockerfile name patterns (e.g. `Dockerfile_base`, `Dockerfile_app*`) |
93
104
  | `--platform=linux/arm64` | Override build platform for a single architecture |
94
105
  | `--timeout=600` | Build timeout in seconds |
95
106
  | `--no-cache` | Force rebuild without Docker layer cache |
@@ -99,6 +110,32 @@ Under the hood, `tsdocker push` uses the **OCI Distribution API** to copy images
99
110
  | `--parallel=8` | Parallel builds with custom concurrency |
100
111
  | `--context=mycontext` | Use a specific Docker context |
101
112
 
113
+ ### Push Flags
114
+
115
+ | Flag | Description |
116
+ |------|-------------|
117
+ | `<patterns>` | Positional Dockerfile name patterns to select which images to push |
118
+ | `--registry=<url>` | Push to a single specific registry instead of all configured |
119
+ | `--no-build` | Skip the build phase; only push existing images from local registry |
120
+
121
+ ### Config Subcommands
122
+
123
+ | Subcommand | Description |
124
+ |------------|-------------|
125
+ | `add-builder` | Add or update a remote builder node |
126
+ | `remove-builder` | Remove a remote builder by name |
127
+ | `list-builders` | List all configured remote builders |
128
+ | `show` | Show the full global configuration |
129
+
130
+ **`add-builder` flags:**
131
+
132
+ | Flag | Description |
133
+ |------|-------------|
134
+ | `--name=<name>` | Builder name (e.g. `arm64-builder`) |
135
+ | `--host=<user@ip>` | SSH host (e.g. `armbuilder@192.168.1.100`) |
136
+ | `--platform=<p>` | Target platform (e.g. `linux/arm64`) |
137
+ | `--ssh-key=<path>` | SSH key path (optional, uses SSH agent/config by default) |
138
+
102
139
  ### Clean Flags
103
140
 
104
141
  | Flag | Description |
@@ -138,16 +175,6 @@ Configure tsdocker in your `package.json` or `npmextra.json` under the `@git.zon
138
175
  | `platforms` | `string[]` | `["linux/amd64"]` | Target architectures for multi-arch builds |
139
176
  | `testDir` | `string` | `./test` | Directory containing test scripts |
140
177
 
141
- #### Legacy Testing Options
142
-
143
- These options configure the `tsdocker` default command (containerized test runner):
144
-
145
- | Option | Type | Default | Description |
146
- |--------|------|---------|-------------|
147
- | `baseImage` | `string` | `hosttoday/ht-docker-node:npmdocker` | Docker image for test environment |
148
- | `command` | `string` | `npmci npm test` | Command to run inside the container |
149
- | `dockerSock` | `boolean` | `false` | Mount Docker socket for DinD scenarios |
150
-
151
178
  ## Architecture: How tsdocker Works
152
179
 
153
180
  tsdocker uses a **local OCI registry** as the canonical store for all built images. This design solves fundamental problems with Docker's local daemon, which cannot hold multi-architecture manifest lists.
@@ -155,36 +182,37 @@ tsdocker uses a **local OCI registry** as the canonical store for all built imag
155
182
  ### 📐 Build Flow
156
183
 
157
184
  ```
158
- ┌─────────────────────────────────────────────────┐
159
- │ tsdocker build
160
-
161
- │ 1. Start local registry (localhost:5234)
162
- │ └── Persistent volume: .nogit/docker-registry/
163
-
164
- │ 2. For each Dockerfile (topological order):
165
- │ ├── Multi-platform: buildx --push → registry
166
- │ └── Single-platform: docker build → registry
167
-
168
- │ 3. Stop local registry (data persists on disk)
169
- └─────────────────────────────────────────────────┘
185
+ ┌─────────────────────────────────────────────────────┐
186
+ │ tsdocker build
187
+
188
+ │ 1. Start local registry (localhost:<dynamic-port>)
189
+ │ └── Persistent volume: .nogit/docker-registry/
190
+
191
+ │ 2. For each Dockerfile (topological order):
192
+ │ ├── Multi-platform: buildx --push → registry
193
+ │ └── Single-platform: docker build → registry
194
+
195
+ │ 3. Stop local registry (data persists on disk)
196
+ └─────────────────────────────────────────────────────┘
170
197
  ```
171
198
 
172
199
  ### 📤 Push Flow
173
200
 
174
201
  ```
175
- ┌──────────────────────────────────────────────────┐
176
- │ tsdocker push
177
-
178
- │ 1. Start local registry (loads persisted data)
179
-
180
- │ 2. For each image × each remote registry:
181
- │ └── OCI Distribution API copy:
182
- │ ├── Fetch manifest (single or multi-arch)
183
- │ ├── Copy blobs (skip if already exist)
184
- └── Push manifest with destination tag
185
-
186
- 3. Stop local registry
187
- └──────────────────────────────────────────────────┘
202
+ ┌────────────────────────────────────────────────────────┐
203
+ │ tsdocker push
204
+
205
+ │ 1. Start local registry (loads persisted data)
206
+
207
+ │ 2. For each image × each remote registry:
208
+ │ └── OCI Distribution API copy (with retry):
209
+ │ ├── Fetch manifest (single or multi-arch)
210
+ │ ├── Copy blobs (skip if already exist)
211
+ ├── Retry up to 6× with exponential backoff
212
+ └── Push manifest with destination tag
213
+
214
+ │ 3. Stop local registry │
215
+ └────────────────────────────────────────────────────────┘
188
216
  ```
189
217
 
190
218
  ### 🔑 Why a Local Registry?
@@ -196,6 +224,49 @@ tsdocker uses a **local OCI registry** as the canonical store for all built imag
196
224
  | Images lost between build and push phases | Persistent storage at `.nogit/docker-registry/` survives restarts |
197
225
  | Redundant blob uploads on incremental pushes | HEAD checks skip blobs that already exist on the remote |
198
226
 
227
+ ### 🔁 Resilient Push
228
+
229
+ The OCI Distribution API client wraps every HTTP request with:
230
+
231
+ - **Timeouts** — 5-minute timeout for blob operations, 30-second timeout for auth/metadata calls via `AbortSignal.timeout()`
232
+ - **Automatic Retry** — Up to 6 attempts with exponential backoff (1s → 2s → 4s → 8s → 16s → 32s)
233
+ - **Smart Retry Logic** — Retries on network errors (`ECONNRESET`, `fetch failed`) and 5xx server errors; does NOT retry 4xx client errors
234
+ - **Token Refresh** — On 401 responses, the cached auth token is cleared so the next retry re-authenticates automatically
235
+
236
+ This means transient issues like stale connection pools, brief network blips, or token expiry during long multi-arch pushes (56+ blob operations) are handled gracefully instead of killing the entire transfer.
237
+
238
+ ### 🏭 CI-Safe Session Isolation
239
+
240
+ Every tsdocker invocation gets its own **session** with unique:
241
+
242
+ - **Session ID** — Random 8-char hex (override with `TSDOCKER_SESSION_ID`)
243
+ - **Registry port** — Dynamically allocated (override with `TSDOCKER_REGISTRY_PORT`)
244
+ - **Registry container** — Named `tsdocker-registry-<sessionId>`
245
+ - **Builder suffix** — In CI, the buildx builder gets a `-<sessionId>` suffix to prevent collisions
246
+
247
+ This prevents resource conflicts when multiple CI jobs run tsdocker in parallel. Auto-detected CI systems:
248
+
249
+ | Environment Variable | CI System |
250
+ |---------------------|-----------|
251
+ | `GITEA_ACTIONS` | Gitea Actions |
252
+ | `GITHUB_ACTIONS` | GitHub Actions |
253
+ | `GITLAB_CI` | GitLab CI |
254
+ | `CI` | Generic CI |
255
+
256
+ In local dev, no suffix is added — keeping a persistent builder for faster rebuilds.
257
+
258
+ ### 🔍 Docker Context & Topology Detection
259
+
260
+ tsdocker automatically detects your Docker environment topology:
261
+
262
+ | Topology | Detection | Meaning |
263
+ |----------|-----------|---------|
264
+ | `local` | Default | Standard Docker installation on the host |
265
+ | `socket-mount` | `/.dockerenv` exists | Running inside a container with Docker socket mounted |
266
+ | `dind` | `DOCKER_HOST` starts with `tcp://` | Docker-in-Docker setup |
267
+
268
+ Context-aware builder names (`tsdocker-builder-<context>`) prevent conflicts across Docker contexts. Rootless Docker configurations trigger appropriate warnings.
269
+
199
270
  ## Registry Authentication
200
271
 
201
272
  ### Environment Variables
@@ -213,7 +284,7 @@ export DOCKER_REGISTRY_PASSWORD="password"
213
284
 
214
285
  ### Docker Config Fallback
215
286
 
216
- When pushing, tsdocker will also read credentials from `~/.docker/config.json` if no explicit credentials are provided via environment variables. This means `docker login` credentials work automatically.
287
+ When pushing, tsdocker will also read credentials from `~/.docker/config.json` if no explicit credentials are provided via environment variables. This means `docker login` credentials work automatically. Docker Hub special cases (`docker.io`, `index.docker.io`, `registry-1.docker.io`) are all recognized.
217
288
 
218
289
  ### Login Command
219
290
 
@@ -242,6 +313,51 @@ tsdocker automatically:
242
313
  - Pushes multi-platform images to the local registry via `buildx --push`
243
314
  - Copies the full manifest list (including all platform variants) to remote registries on `tsdocker push`
244
315
 
316
+ ### 🖥️ Native Remote Builders
317
+
318
+ Instead of relying on slow QEMU emulation for cross-platform builds, tsdocker can use **native remote machines** via SSH as build nodes. For example, use a real arm64 machine for `linux/arm64` builds:
319
+
320
+ ```bash
321
+ # Add a remote arm64 builder
322
+ tsdocker config add-builder \
323
+ --name=arm64-builder \
324
+ --host=armbuilder@192.168.1.100 \
325
+ --platform=linux/arm64 \
326
+ --ssh-key=~/.ssh/id_ed25519
327
+
328
+ # List configured builders
329
+ tsdocker config list-builders
330
+
331
+ # Remove a builder
332
+ tsdocker config remove-builder --name=arm64-builder
333
+
334
+ # Show full global config
335
+ tsdocker config show
336
+ ```
337
+
338
+ Global configuration is stored at `~/.git.zone/tsdocker/config.json`.
339
+
340
+ **How it works:**
341
+
342
+ When remote builders are configured and the project's `platforms` includes a matching platform, tsdocker automatically:
343
+
344
+ 1. Creates a **multi-node buildx builder** — local node for `linux/amd64`, remote SSH node for `linux/arm64`
345
+ 2. Opens **SSH reverse tunnels** so the remote builder can push to the local staging registry
346
+ 3. Builds natively on each platform's hardware — no QEMU overhead
347
+ 4. Tears down tunnels after the build completes
348
+
349
+ ```
350
+ [Local machine] [Remote arm64 machine]
351
+ registry:2 on localhost:PORT <──── SSH reverse tunnel ──── localhost:PORT
352
+ BuildKit (amd64) ──push──> BuildKit (arm64) ──push──>
353
+ localhost:PORT localhost:PORT (tunneled)
354
+ ```
355
+
356
+ **Prerequisites for the remote machine:**
357
+ - Docker installed and running
358
+ - A user with Docker group access (no sudo needed)
359
+ - SSH key access configured
360
+
245
361
  ### ⚡ Parallel Builds
246
362
 
247
363
  Speed up builds by building independent images concurrently:
@@ -270,6 +386,26 @@ tsdocker discovers files matching `Dockerfile*`:
270
386
  | `Dockerfile_alpine` | `alpine` |
271
387
  | `Dockerfile_##version##` | Uses `package.json` version |
272
388
 
389
+ ### 🎯 Dockerfile Filtering
390
+
391
+ Build or push only the Dockerfiles you need. Positional arguments are matched against Dockerfile basenames as glob patterns:
392
+
393
+ ```bash
394
+ # Build a single Dockerfile
395
+ tsdocker build Dockerfile_base
396
+
397
+ # Glob patterns with * and ? wildcards
398
+ tsdocker build Dockerfile_app*
399
+
400
+ # Multiple patterns
401
+ tsdocker build Dockerfile_base Dockerfile_web
402
+
403
+ # Push specific images without rebuilding
404
+ tsdocker push --no-build Dockerfile_api
405
+ ```
406
+
407
+ When filtering for `build`, **dependencies are auto-resolved**: if `Dockerfile_app` depends on `Dockerfile_base`, specifying only `Dockerfile_app` will automatically include `Dockerfile_base` in the build order.
408
+
273
409
  ### 🔗 Dependency-Aware Builds
274
410
 
275
411
  If you have multiple Dockerfiles that depend on each other:
@@ -347,20 +483,6 @@ Use different repository names for different registries:
347
483
 
348
484
  When pushing, tsdocker maps the local repo name to the registry-specific path. For example, a locally built `myproject:latest` becomes `registry.gitlab.com/mygroup/myproject:latest` and `docker.io/myuser/myproject:latest`.
349
485
 
350
- ### 🐳 Docker-in-Docker Testing
351
-
352
- Test Docker-related tools by mounting the Docker socket:
353
-
354
- ```json
355
- {
356
- "@git.zone/tsdocker": {
357
- "baseImage": "docker:latest",
358
- "command": "docker version && docker ps",
359
- "dockerSock": true
360
- }
361
- }
362
- ```
363
-
364
486
  ### 📋 Listing Dockerfiles
365
487
 
366
488
  Inspect your project's Dockerfiles and their relationships:
@@ -449,6 +571,19 @@ build-and-push:
449
571
  DOCKER_REGISTRY_1: "ghcr.io|${{ github.actor }}|${{ secrets.GITHUB_TOKEN }}"
450
572
  ```
451
573
 
574
+ **Gitea Actions:**
575
+
576
+ ```yaml
577
+ - name: Build and Push
578
+ run: |
579
+ npm install -g @git.zone/tsdocker
580
+ tsdocker push
581
+ env:
582
+ DOCKER_REGISTRY_1: "gitea.example.com|${{ secrets.REGISTRY_USER }}|${{ secrets.REGISTRY_PASSWORD }}"
583
+ ```
584
+
585
+ tsdocker auto-detects all three CI systems and enables session isolation automatically — no extra configuration needed.
586
+
452
587
  ## TypeScript API
453
588
 
454
589
  tsdocker can also be used programmatically:
@@ -458,10 +593,6 @@ import { TsDockerManager } from '@git.zone/tsdocker/dist_ts/classes.tsdockermana
458
593
  import type { ITsDockerConfig } from '@git.zone/tsdocker/dist_ts/interfaces/index.js';
459
594
 
460
595
  const config: ITsDockerConfig = {
461
- baseImage: 'node:20',
462
- command: 'npm test',
463
- dockerSock: false,
464
- keyValueObject: {},
465
596
  registries: ['docker.io'],
466
597
  platforms: ['linux/amd64', 'linux/arm64'],
467
598
  };
@@ -472,6 +603,25 @@ await manager.build({ parallel: true });
472
603
  await manager.push();
473
604
  ```
474
605
 
606
+ ## Environment Variables
607
+
608
+ ### CI & Session Control
609
+
610
+ | Variable | Description |
611
+ |----------|-------------|
612
+ | `TSDOCKER_SESSION_ID` | Override the auto-generated session ID (default: random 8-char hex) |
613
+ | `TSDOCKER_REGISTRY_PORT` | Override the dynamically allocated local registry port |
614
+ | `CI` | Generic CI detection (also `GITHUB_ACTIONS`, `GITLAB_CI`, `GITEA_ACTIONS`) |
615
+
616
+ ### Registry Credentials
617
+
618
+ | Variable | Description |
619
+ |----------|-------------|
620
+ | `DOCKER_REGISTRY_1` through `DOCKER_REGISTRY_10` | Pipe-delimited: `registry\|username\|password` |
621
+ | `DOCKER_REGISTRY_URL` | Registry URL for single-registry setup |
622
+ | `DOCKER_REGISTRY_USER` | Username for single-registry setup |
623
+ | `DOCKER_REGISTRY_PASSWORD` | Password for single-registry setup |
624
+
475
625
  ## Requirements
476
626
 
477
627
  - **Docker** — Docker Engine 20+ or Docker Desktop
@@ -507,6 +657,15 @@ tsdocker login
507
657
 
508
658
  tsdocker also falls back to `~/.docker/config.json` — ensure you've run `docker login` for your target registries.
509
659
 
660
+ ### Push fails with "fetch failed"
661
+
662
+ tsdocker automatically retries failed requests up to 6 times with exponential backoff. If pushes still fail:
663
+
664
+ - Check network connectivity to the target registry
665
+ - Verify your credentials haven't expired
666
+ - Look for retry log messages (`fetch failed (attempt X/6)`) to diagnose the pattern
667
+ - Large layers may need longer timeouts — the default 5-minute timeout per request should cover most cases
668
+
510
669
  ### Circular dependency detected
511
670
 
512
671
  Review your Dockerfiles' `FROM` statements — you have images depending on each other in a loop.
@@ -522,16 +681,6 @@ node_modules
522
681
  dist_ts
523
682
  ```
524
683
 
525
- ## Migration from Legacy
526
-
527
- Previously published as `npmdocker`, now `@git.zone/tsdocker`:
528
-
529
- | Old | New |
530
- |-----|-----|
531
- | `npmdocker` command | `tsdocker` command |
532
- | `"npmdocker"` config key | `"@git.zone/tsdocker"` config key |
533
- | CommonJS | ESM with `.js` imports |
534
-
535
684
  ## License and Legal Information
536
685
 
537
686
  This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@git.zone/tsdocker',
6
- version: '1.17.4',
6
+ version: '2.1.0',
7
7
  description: 'develop npm modules cross platform with docker'
8
8
  }
@@ -266,12 +266,15 @@ export class Dockerfile {
266
266
  public static async buildDockerfiles(
267
267
  sortedArrayArg: Dockerfile[],
268
268
  session: TsDockerSession,
269
- options?: { platform?: string; timeout?: number; noCache?: boolean; verbose?: boolean; isRootless?: boolean; parallel?: boolean; parallelConcurrency?: number },
269
+ options?: { platform?: string; timeout?: number; noCache?: boolean; verbose?: boolean; isRootless?: boolean; parallel?: boolean; parallelConcurrency?: number; onRegistryStarted?: () => Promise<void>; onBeforeRegistryStop?: () => Promise<void> },
270
270
  ): Promise<Dockerfile[]> {
271
271
  const total = sortedArrayArg.length;
272
272
  const overallStart = Date.now();
273
273
 
274
274
  await Dockerfile.startLocalRegistry(session, options?.isRootless);
275
+ if (options?.onRegistryStarted) {
276
+ await options.onRegistryStarted();
277
+ }
275
278
 
276
279
  try {
277
280
  if (options?.parallel) {
@@ -351,6 +354,9 @@ export class Dockerfile {
351
354
  }
352
355
  }
353
356
  } finally {
357
+ if (options?.onBeforeRegistryStop) {
358
+ await options.onBeforeRegistryStop();
359
+ }
354
360
  await Dockerfile.stopLocalRegistry(session);
355
361
  }
356
362