@git.zone/tsdocker 1.15.1 โ†’ 1.17.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
@@ -1,6 +1,6 @@
1
1
  # @git.zone/tsdocker
2
2
 
3
- > ๐Ÿณ The ultimate Docker development toolkit for TypeScript projects โ€” build, test, and ship containerized applications with ease.
3
+ > ๐Ÿณ The ultimate Docker development toolkit for TypeScript projects โ€” build, test, and ship multi-arch containerized applications with zero friction.
4
4
 
5
5
  ## Issue Reporting and Security
6
6
 
@@ -8,15 +8,18 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
8
8
 
9
9
  ## What is tsdocker?
10
10
 
11
- **tsdocker** is a comprehensive Docker development and building tool that handles everything from testing npm packages in clean environments to building and pushing multi-architecture Docker images across multiple registries.
11
+ **tsdocker** is a comprehensive Docker development and build tool that handles everything from testing npm packages in clean environments to building and pushing multi-architecture Docker images across multiple registries โ€” all from a single CLI.
12
12
 
13
13
  ### ๐ŸŽฏ Key Capabilities
14
14
 
15
15
  - ๐Ÿงช **Containerized Testing** โ€” Run your tests in pristine Docker environments
16
16
  - ๐Ÿ—๏ธ **Smart Docker Builds** โ€” Automatically discover, sort, and build Dockerfiles by dependency
17
- - ๐Ÿš€ **Multi-Registry Push** โ€” Ship to Docker Hub, GitLab, GitHub Container Registry, and more
18
- - ๐Ÿ”ง **Multi-Architecture** โ€” Build for `amd64` and `arm64` with Docker Buildx
19
- - โšก **Zero Config Start** โ€” Works out of the box, scales with your needs
17
+ - ๐ŸŒ **True Multi-Architecture** โ€” Build for `amd64` and `arm64` simultaneously with Docker Buildx
18
+ - ๐Ÿš€ **Multi-Registry Push** โ€” Ship to Docker Hub, GitLab, GitHub Container Registry, and more via OCI Distribution API
19
+ - โšก **Parallel Builds** โ€” Level-based parallel builds with configurable concurrency
20
+ - ๐Ÿ—„๏ธ **Persistent Local Registry** โ€” All images flow through a local OCI registry with persistent storage
21
+ - ๐Ÿ“ฆ **Build Caching** โ€” Skip unchanged Dockerfiles with content-hash caching
22
+ - ๐Ÿ”ง **Zero Config Start** โ€” Works out of the box, scales with your needs
20
23
 
21
24
  ## Installation
22
25
 
@@ -53,6 +56,7 @@ tsdocker will:
53
56
  2. ๐Ÿ“Š Analyze `FROM` dependencies between them
54
57
  3. ๐Ÿ”„ Sort them topologically
55
58
  4. ๐Ÿ—๏ธ Build each image in the correct order
59
+ 5. ๐Ÿ“ฆ Push every image to a persistent local registry (`.nogit/docker-registry/`)
56
60
 
57
61
  ### ๐Ÿ“ค Push to Registries
58
62
 
@@ -63,33 +67,52 @@ Ship your images to one or all configured registries:
63
67
  tsdocker push
64
68
 
65
69
  # Push to a specific registry
66
- tsdocker push registry.gitlab.com
70
+ tsdocker push --registry=registry.gitlab.com
67
71
  ```
68
72
 
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.
74
+
69
75
  ## CLI Commands
70
76
 
71
77
  | Command | Description |
72
78
  |---------|-------------|
73
- | `tsdocker` | Run tests in a fresh Docker container |
79
+ | `tsdocker` | Run tests in a fresh Docker container (legacy mode) |
74
80
  | `tsdocker build` | Build all Dockerfiles with dependency ordering |
75
- | `tsdocker push [registry]` | Push images to configured registries |
81
+ | `tsdocker push` | Build + push images to configured registries |
76
82
  | `tsdocker pull <registry>` | Pull images from a specific registry |
77
- | `tsdocker test` | Run container test scripts (test_*.sh) |
83
+ | `tsdocker test` | Build + run container test scripts (`test_*.sh`) |
78
84
  | `tsdocker login` | Authenticate with configured registries |
79
85
  | `tsdocker list` | Display discovered Dockerfiles and their dependencies |
80
- | `tsdocker clean --all` | โš ๏ธ Aggressively clean Docker environment |
86
+ | `tsdocker clean` | Interactively clean Docker environment |
81
87
  | `tsdocker vscode` | Launch containerized VS Code in browser |
82
88
 
89
+ ### Build Flags
90
+
91
+ | Flag | Description |
92
+ |------|-------------|
93
+ | `--platform=linux/arm64` | Override build platform for a single architecture |
94
+ | `--timeout=600` | Build timeout in seconds |
95
+ | `--no-cache` | Force rebuild without Docker layer cache |
96
+ | `--cached` | Skip unchanged Dockerfiles (content-hash based) |
97
+ | `--verbose` | Stream raw `docker build` output |
98
+ | `--parallel` | Enable level-based parallel builds (default concurrency: 4) |
99
+ | `--parallel=8` | Parallel builds with custom concurrency |
100
+ | `--context=mycontext` | Use a specific Docker context |
101
+
102
+ ### Clean Flags
103
+
104
+ | Flag | Description |
105
+ |------|-------------|
106
+ | `--all` | Include all images and volumes (not just dangling) |
107
+ | `-y` | Auto-confirm all prompts |
108
+
83
109
  ## Configuration
84
110
 
85
- Configure tsdocker in your `package.json` or `npmextra.json`:
111
+ Configure tsdocker in your `package.json` or `npmextra.json` under the `@git.zone/tsdocker` key:
86
112
 
87
113
  ```json
88
114
  {
89
115
  "@git.zone/tsdocker": {
90
- "baseImage": "node:20",
91
- "command": "npm test",
92
- "dockerSock": false,
93
116
  "registries": ["registry.gitlab.com", "docker.io"],
94
117
  "registryRepoMap": {
95
118
  "registry.gitlab.com": "myorg/myproject"
@@ -98,7 +121,6 @@ Configure tsdocker in your `package.json` or `npmextra.json`:
98
121
  "NODE_VERSION": "NODE_VERSION"
99
122
  },
100
123
  "platforms": ["linux/amd64", "linux/arm64"],
101
- "push": false,
102
124
  "testDir": "./test"
103
125
  }
104
126
  }
@@ -106,24 +128,73 @@ Configure tsdocker in your `package.json` or `npmextra.json`:
106
128
 
107
129
  ### Configuration Options
108
130
 
109
- #### Testing Options (Legacy)
131
+ #### Build & Push Options
110
132
 
111
- | Option | Type | Description |
112
- |--------|------|-------------|
113
- | `baseImage` | `string` | Docker image for test environment (default: `hosttoday/ht-docker-node:npmdocker`) |
114
- | `command` | `string` | Command to run inside container (default: `npmci npm test`) |
115
- | `dockerSock` | `boolean` | Mount Docker socket for DinD scenarios (default: `false`) |
133
+ | Option | Type | Default | Description |
134
+ |--------|------|---------|-------------|
135
+ | `registries` | `string[]` | `[]` | Registry URLs to push to |
136
+ | `registryRepoMap` | `object` | `{}` | Map registries to different repository paths |
137
+ | `buildArgEnvMap` | `object` | `{}` | Map Docker build ARGs to environment variables |
138
+ | `platforms` | `string[]` | `["linux/amd64"]` | Target architectures for multi-arch builds |
139
+ | `testDir` | `string` | `./test` | Directory containing test scripts |
116
140
 
117
- #### Build & Push Options
141
+ #### Legacy Testing Options
118
142
 
119
- | Option | Type | Description |
120
- |--------|------|-------------|
121
- | `registries` | `string[]` | Registry URLs to push to |
122
- | `registryRepoMap` | `object` | Map registries to different repository paths |
123
- | `buildArgEnvMap` | `object` | Map Docker build ARGs to environment variables |
124
- | `platforms` | `string[]` | Target architectures (default: `["linux/amd64"]`) |
125
- | `push` | `boolean` | Auto-push after build (default: `false`) |
126
- | `testDir` | `string` | Directory containing test scripts |
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
+ ## Architecture: How tsdocker Works
152
+
153
+ 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.
154
+
155
+ ### ๐Ÿ“ Build Flow
156
+
157
+ ```
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
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
170
+ ```
171
+
172
+ ### ๐Ÿ“ค Push Flow
173
+
174
+ ```
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
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
188
+ ```
189
+
190
+ ### ๐Ÿ”‘ Why a Local Registry?
191
+
192
+ | Problem | Solution |
193
+ |---------|----------|
194
+ | `docker buildx --load` fails for multi-arch images | `buildx --push` to local registry works for any number of platforms |
195
+ | `docker push` only pushes single-platform manifests | OCI API copy preserves full manifest lists (multi-arch) |
196
+ | Images lost between build and push phases | Persistent storage at `.nogit/docker-registry/` survives restarts |
197
+ | Redundant blob uploads on incremental pushes | HEAD checks skip blobs that already exist on the remote |
127
198
 
128
199
  ## Registry Authentication
129
200
 
@@ -140,13 +211,17 @@ export DOCKER_REGISTRY_USER="username"
140
211
  export DOCKER_REGISTRY_PASSWORD="password"
141
212
  ```
142
213
 
214
+ ### Docker Config Fallback
215
+
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.
217
+
143
218
  ### Login Command
144
219
 
145
220
  ```bash
146
221
  tsdocker login
147
222
  ```
148
223
 
149
- Authenticates with all configured registries.
224
+ Authenticates with all configured registries using the provided environment variables.
150
225
 
151
226
  ## Advanced Usage
152
227
 
@@ -162,7 +237,27 @@ Build for multiple platforms using Docker Buildx:
162
237
  }
163
238
  ```
164
239
 
165
- tsdocker automatically sets up a Buildx builder when multiple platforms are specified.
240
+ tsdocker automatically:
241
+ - Sets up a Buildx builder with `--driver-opt network=host` (so buildx can reach the local registry)
242
+ - Pushes multi-platform images to the local registry via `buildx --push`
243
+ - Copies the full manifest list (including all platform variants) to remote registries on `tsdocker push`
244
+
245
+ ### โšก Parallel Builds
246
+
247
+ Speed up builds by building independent images concurrently:
248
+
249
+ ```bash
250
+ # Default concurrency (4 workers)
251
+ tsdocker build --parallel
252
+
253
+ # Custom concurrency
254
+ tsdocker build --parallel=8
255
+
256
+ # Works with caching too
257
+ tsdocker build --parallel --cached
258
+ ```
259
+
260
+ tsdocker groups Dockerfiles into **dependency levels** using topological analysis. Images within the same level have no dependencies on each other and build in parallel. Each level completes before the next begins.
166
261
 
167
262
  ### ๐Ÿ“ฆ Dockerfile Naming Conventions
168
263
 
@@ -190,7 +285,7 @@ COPY . .
190
285
  RUN npm run build
191
286
  ```
192
287
 
193
- tsdocker automatically detects that `Dockerfile_app` depends on `Dockerfile_base` and builds them in the correct order.
288
+ tsdocker automatically detects that `Dockerfile_app` depends on `Dockerfile_base`, builds them in the correct order, and makes the base image available to dependent builds via the local registry (using `--build-context` for buildx).
194
289
 
195
290
  ### ๐Ÿงช Container Test Scripts
196
291
 
@@ -210,6 +305,8 @@ Run with:
210
305
  tsdocker test
211
306
  ```
212
307
 
308
+ This builds all images, starts the local registry (so multi-arch images can be pulled), and runs each matching test script inside a container.
309
+
213
310
  ### ๐Ÿ”ง Build Args from Environment
214
311
 
215
312
  Pass environment variables as Docker build arguments:
@@ -232,6 +329,24 @@ FROM node:${NODE_VERSION}
232
329
  RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
233
330
  ```
234
331
 
332
+ ### ๐Ÿ—บ๏ธ Registry Repo Mapping
333
+
334
+ Use different repository names for different registries:
335
+
336
+ ```json
337
+ {
338
+ "@git.zone/tsdocker": {
339
+ "registries": ["registry.gitlab.com", "docker.io"],
340
+ "registryRepoMap": {
341
+ "registry.gitlab.com": "mygroup/myproject",
342
+ "docker.io": "myuser/myproject"
343
+ }
344
+ }
345
+ }
346
+ ```
347
+
348
+ 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
+
235
350
  ### ๐Ÿณ Docker-in-Docker Testing
236
351
 
237
352
  Test Docker-related tools by mounting the Docker socket:
@@ -259,59 +374,33 @@ Output:
259
374
  Discovered Dockerfiles:
260
375
  ========================
261
376
 
262
- 1. Dockerfile_base
377
+ 1. /path/to/Dockerfile_base
263
378
  Tag: myproject:base
264
379
  Base Image: node:20-alpine
265
380
  Version: base
266
381
 
267
- 2. Dockerfile_app
382
+ 2. /path/to/Dockerfile_app
268
383
  Tag: myproject:app
269
384
  Base Image: myproject:base
270
385
  Version: app
271
386
  Depends on: myproject:base
272
387
  ```
273
388
 
274
- ### ๐Ÿ—บ๏ธ Registry Repo Mapping
389
+ ## Examples
275
390
 
276
- Use different repository names for different registries:
391
+ ### Minimal Build & Push
277
392
 
278
393
  ```json
279
394
  {
280
395
  "@git.zone/tsdocker": {
281
- "registries": ["registry.gitlab.com", "docker.io"],
282
- "registryRepoMap": {
283
- "registry.gitlab.com": "mygroup/myproject",
284
- "docker.io": "myuser/myproject"
285
- }
396
+ "registries": ["docker.io"],
397
+ "platforms": ["linux/amd64"]
286
398
  }
287
399
  }
288
400
  ```
289
401
 
290
- ## Environment Variables
291
-
292
- ### qenv Integration
293
-
294
- tsdocker automatically loads environment variables from `qenv.yml`:
295
-
296
- ```yaml
297
- # qenv.yml
298
- API_KEY: your-api-key
299
- DATABASE_URL: postgres://localhost/test
300
- ```
301
-
302
- These are injected into your test container automatically.
303
-
304
- ## Examples
305
-
306
- ### Basic Test Configuration
307
-
308
- ```json
309
- {
310
- "@git.zone/tsdocker": {
311
- "baseImage": "node:20",
312
- "command": "npm test"
313
- }
314
- }
402
+ ```bash
403
+ tsdocker push
315
404
  ```
316
405
 
317
406
  ### Full Production Setup
@@ -319,8 +408,6 @@ These are injected into your test container automatically.
319
408
  ```json
320
409
  {
321
410
  "@git.zone/tsdocker": {
322
- "baseImage": "node:20-alpine",
323
- "command": "pnpm test",
324
411
  "registries": ["registry.gitlab.com", "ghcr.io", "docker.io"],
325
412
  "registryRepoMap": {
326
413
  "registry.gitlab.com": "myorg/myapp",
@@ -338,57 +425,37 @@ These are injected into your test container automatically.
338
425
 
339
426
  ### CI/CD Integration
340
427
 
428
+ **GitLab CI:**
429
+
341
430
  ```yaml
342
- # .gitlab-ci.yml
343
- build:
431
+ build-and-push:
344
432
  stage: build
345
433
  script:
346
434
  - npm install -g @git.zone/tsdocker
347
- - tsdocker build
348
435
  - tsdocker push
436
+ variables:
437
+ DOCKER_REGISTRY_1: "registry.gitlab.com|$CI_REGISTRY_USER|$CI_REGISTRY_PASSWORD"
438
+ ```
439
+
440
+ **GitHub Actions:**
349
441
 
350
- # GitHub Actions
442
+ ```yaml
351
443
  - name: Build and Push
352
444
  run: |
353
445
  npm install -g @git.zone/tsdocker
354
446
  tsdocker login
355
- tsdocker build
356
447
  tsdocker push
357
448
  env:
358
449
  DOCKER_REGISTRY_1: "ghcr.io|${{ github.actor }}|${{ secrets.GITHUB_TOKEN }}"
359
450
  ```
360
451
 
361
- ## Requirements
362
-
363
- - **Docker** โ€” Docker Engine or Docker Desktop must be installed
364
- - **Node.js** โ€” Version 18 or higher (ESM support required)
365
- - **Docker Buildx** โ€” Required for multi-architecture builds (included in Docker Desktop)
366
-
367
- ## Why tsdocker?
368
-
369
- ### ๐ŸŽฏ The Problem
370
-
371
- Managing Docker workflows manually is tedious:
372
- - Remembering build order for dependent images
373
- - Pushing to multiple registries with different credentials
374
- - Setting up Buildx for multi-arch builds
375
- - Ensuring consistent test environments
376
-
377
- ### โœจ The Solution
378
-
379
- tsdocker automates the entire workflow:
380
- - **One command** to build all images in dependency order
381
- - **One command** to push to all registries
382
- - **Automatic** Buildx setup for multi-platform builds
383
- - **Consistent** containerized test environments
384
-
385
452
  ## TypeScript API
386
453
 
387
- tsdocker exposes its types for programmatic use:
454
+ tsdocker can also be used programmatically:
388
455
 
389
456
  ```typescript
390
- import type { ITsDockerConfig } from '@git.zone/tsdocker/dist_ts/interfaces/index.js';
391
457
  import { TsDockerManager } from '@git.zone/tsdocker/dist_ts/classes.tsdockermanager.js';
458
+ import type { ITsDockerConfig } from '@git.zone/tsdocker/dist_ts/interfaces/index.js';
392
459
 
393
460
  const config: ITsDockerConfig = {
394
461
  baseImage: 'node:20',
@@ -396,15 +463,21 @@ const config: ITsDockerConfig = {
396
463
  dockerSock: false,
397
464
  keyValueObject: {},
398
465
  registries: ['docker.io'],
399
- platforms: ['linux/amd64'],
466
+ platforms: ['linux/amd64', 'linux/arm64'],
400
467
  };
401
468
 
402
469
  const manager = new TsDockerManager(config);
403
470
  await manager.prepare();
404
- await manager.build();
471
+ await manager.build({ parallel: true });
405
472
  await manager.push();
406
473
  ```
407
474
 
475
+ ## Requirements
476
+
477
+ - **Docker** โ€” Docker Engine 20+ or Docker Desktop
478
+ - **Node.js** โ€” Version 18 or higher (for native `fetch` and ESM support)
479
+ - **Docker Buildx** โ€” Required for multi-architecture builds (included in Docker Desktop)
480
+
408
481
  ## Troubleshooting
409
482
 
410
483
  ### "docker not found"
@@ -417,11 +490,10 @@ docker --version
417
490
 
418
491
  ### Multi-arch build fails
419
492
 
420
- Make sure Docker Buildx is available:
493
+ Make sure Docker Buildx is available. tsdocker will set up the builder automatically, but you can verify:
421
494
 
422
495
  ```bash
423
496
  docker buildx version
424
- docker buildx create --use
425
497
  ```
426
498
 
427
499
  ### Registry authentication fails
@@ -433,19 +505,22 @@ echo $DOCKER_REGISTRY_1
433
505
  tsdocker login
434
506
  ```
435
507
 
508
+ tsdocker also falls back to `~/.docker/config.json` โ€” ensure you've run `docker login` for your target registries.
509
+
436
510
  ### Circular dependency detected
437
511
 
438
512
  Review your Dockerfiles' `FROM` statements โ€” you have images depending on each other in a loop.
439
513
 
440
- ## Performance Tips
441
-
442
- ๐Ÿš€ **Use specific tags**: `node:20-alpine` is smaller and faster than `node:latest`
514
+ ### Build context too large
443
515
 
444
- ๐Ÿš€ **Leverage caching**: Docker layers are cached โ€” your builds get faster over time
516
+ Use a `.dockerignore` file to exclude `node_modules`, `.git`, `.nogit`, and other large directories:
445
517
 
446
- ๐Ÿš€ **Prune regularly**: `docker system prune` reclaims disk space
447
-
448
- ๐Ÿš€ **Use .dockerignore**: Exclude `node_modules`, `.git`, etc. from build context
518
+ ```
519
+ node_modules
520
+ .git
521
+ .nogit
522
+ dist_ts
523
+ ```
449
524
 
450
525
  ## Migration from Legacy
451
526
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@git.zone/tsdocker',
6
- version: '1.15.1',
6
+ version: '1.17.0',
7
7
  description: 'develop npm modules cross platform with docker'
8
8
  }
@@ -1,4 +1,5 @@
1
1
  import * as plugins from './tsdocker.plugins.js';
2
+ import * as fs from 'fs';
2
3
  import { logger } from './tsdocker.logging.js';
3
4
  import type { IDockerContextInfo } from './interfaces/index.js';
4
5
 
@@ -38,19 +39,28 @@ export class DockerContext {
38
39
  isRootless = infoResult.stdout.includes('name=rootless');
39
40
  }
40
41
 
41
- this.contextInfo = { name, endpoint, isRootless, dockerHost: process.env.DOCKER_HOST };
42
+ // Detect topology
43
+ let topology: 'socket-mount' | 'dind' | 'local' = 'local';
44
+ if (process.env.DOCKER_HOST && process.env.DOCKER_HOST.startsWith('tcp://')) {
45
+ topology = 'dind';
46
+ } else if (fs.existsSync('/.dockerenv')) {
47
+ topology = 'socket-mount';
48
+ }
49
+
50
+ this.contextInfo = { name, endpoint, isRootless, dockerHost: process.env.DOCKER_HOST, topology };
42
51
  return this.contextInfo;
43
52
  }
44
53
 
45
54
  /** Logs context info prominently. */
46
55
  public logContextInfo(): void {
47
56
  if (!this.contextInfo) return;
48
- const { name, endpoint, isRootless, dockerHost } = this.contextInfo;
57
+ const { name, endpoint, isRootless, dockerHost, topology } = this.contextInfo;
49
58
  logger.log('info', '=== DOCKER CONTEXT ===');
50
59
  logger.log('info', `Context: ${name}`);
51
60
  logger.log('info', `Endpoint: ${endpoint}`);
52
61
  if (dockerHost) logger.log('info', `DOCKER_HOST: ${dockerHost}`);
53
62
  logger.log('info', `Rootless: ${isRootless ? 'yes' : 'no'}`);
63
+ logger.log('info', `Topology: ${topology || 'local'}`);
54
64
  }
55
65
 
56
66
  /** Emits rootless-specific warnings. */