container-magic 0.1.0__tar.gz
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.
- container_magic-0.1.0/LICENSE +21 -0
- container_magic-0.1.0/PKG-INFO +372 -0
- container_magic-0.1.0/README.md +338 -0
- container_magic-0.1.0/pyproject.toml +82 -0
- container_magic-0.1.0/setup.cfg +4 -0
- container_magic-0.1.0/src/container_magic/__init__.py +3 -0
- container_magic-0.1.0/src/container_magic/cli/__init__.py +1 -0
- container_magic-0.1.0/src/container_magic/cli/main.py +520 -0
- container_magic-0.1.0/src/container_magic/core/__init__.py +1 -0
- container_magic-0.1.0/src/container_magic/core/cache.py +142 -0
- container_magic-0.1.0/src/container_magic/core/config.py +381 -0
- container_magic-0.1.0/src/container_magic/core/runtime.py +60 -0
- container_magic-0.1.0/src/container_magic/core/templates.py +78 -0
- container_magic-0.1.0/src/container_magic/generators/__init__.py +1 -0
- container_magic-0.1.0/src/container_magic/generators/build_script.py +41 -0
- container_magic-0.1.0/src/container_magic/generators/dockerfile.py +262 -0
- container_magic-0.1.0/src/container_magic/generators/justfile.py +97 -0
- container_magic-0.1.0/src/container_magic/generators/run_script.py +55 -0
- container_magic-0.1.0/src/container_magic/generators/standalone_commands.py +81 -0
- container_magic-0.1.0/src/container_magic/templates/Dockerfile.j2 +99 -0
- container_magic-0.1.0/src/container_magic/templates/Justfile.j2 +232 -0
- container_magic-0.1.0/src/container_magic/templates/build.sh.j2 +95 -0
- container_magic-0.1.0/src/container_magic/templates/custom_command.j2 +85 -0
- container_magic-0.1.0/src/container_magic/templates/run.sh.j2 +109 -0
- container_magic-0.1.0/src/container_magic/templates/standalone_command.sh.j2 +57 -0
- container_magic-0.1.0/src/container_magic.egg-info/PKG-INFO +372 -0
- container_magic-0.1.0/src/container_magic.egg-info/SOURCES.txt +29 -0
- container_magic-0.1.0/src/container_magic.egg-info/dependency_links.txt +1 -0
- container_magic-0.1.0/src/container_magic.egg-info/entry_points.txt +4 -0
- container_magic-0.1.0/src/container_magic.egg-info/requires.txt +12 -0
- container_magic-0.1.0/src/container_magic.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mark Hedley Jones
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: container-magic
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A tool for rapidly creating containerised development environments
|
|
5
|
+
Author-email: Mark Hedley Jones <mark@hedleyjones.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/markhedleyjones/container-magic
|
|
8
|
+
Project-URL: Repository, https://github.com/markhedleyjones/container-magic
|
|
9
|
+
Project-URL: Issues, https://github.com/markhedleyjones/container-magic/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: pyyaml>=6.0
|
|
23
|
+
Requires-Dist: jinja2>=3.1.0
|
|
24
|
+
Requires-Dist: click>=8.1.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0.0
|
|
26
|
+
Requires-Dist: requests>=2.31.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
32
|
+
Requires-Dist: python-semantic-release>=8.0.0; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
<div align="center">
|
|
36
|
+
<img src="https://raw.githubusercontent.com/markhedleyjones/container-magic-artwork/main/sparkles/original-vector.svg" alt="Container Magic - Sparkles the Otter" width="200"/>
|
|
37
|
+
|
|
38
|
+
# container-magic
|
|
39
|
+
|
|
40
|
+
A tool for rapidly creating containerised development environments. Configure once in YAML, use anywhere with Docker or Podman.
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
## What It Does
|
|
44
|
+
|
|
45
|
+
Container-magic takes a single YAML configuration file and generates:
|
|
46
|
+
1. A **Dockerfile** with multi-stage builds
|
|
47
|
+
2. A **Justfile** for development (with live workspace mounting)
|
|
48
|
+
3. Standalone **build.sh** and **run.sh** scripts for production
|
|
49
|
+
|
|
50
|
+
The Dockerfile and standalone scripts are committed to your repository, so anyone can use your project with just `docker` or `podman` - no need to install container-magic or just.
|
|
51
|
+
|
|
52
|
+
## Key Features
|
|
53
|
+
|
|
54
|
+
* **YAML configuration** - Single source of truth for your container setup
|
|
55
|
+
* **Transparent execution** - Run commands in container from anywhere in your repo with path translation
|
|
56
|
+
* **Custom commands** - Define commands once, use in both dev and prod
|
|
57
|
+
* **Smart features** - GPU, display (X11/Wayland), and audio support
|
|
58
|
+
* **Multi-stage builds** - Separate base, development, and production stages
|
|
59
|
+
* **Live workspace mounting** - Edit code on host, run in container (development)
|
|
60
|
+
* **Standalone scripts** - Production needs only docker/podman (no dependencies)
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Install
|
|
66
|
+
pip install container-magic
|
|
67
|
+
|
|
68
|
+
# Create a new project
|
|
69
|
+
cm init python my-project
|
|
70
|
+
cd my-project
|
|
71
|
+
|
|
72
|
+
# Build the container
|
|
73
|
+
build
|
|
74
|
+
|
|
75
|
+
# Run commands inside the container
|
|
76
|
+
run python --version
|
|
77
|
+
run bash -c "echo Hello from container"
|
|
78
|
+
run # starts an interactive shell
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The `run` command works from anywhere in your repository and translates your working directory automatically. When using the `run` alias (not `just run` directly), path translation ensures the container's working directory matches your position in the repository.
|
|
82
|
+
|
|
83
|
+
## Workflow
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
┌─────────────────────┐
|
|
87
|
+
│ cm.yaml │ ← You edit this
|
|
88
|
+
│ (central config) │
|
|
89
|
+
└──────────┬──────────┘
|
|
90
|
+
│
|
|
91
|
+
│ cm init / cm update
|
|
92
|
+
│
|
|
93
|
+
├─────────────┬──────────────────┬──────────────────┐
|
|
94
|
+
▼ ▼ ▼ ▼
|
|
95
|
+
Dockerfile Development Production Command Scripts
|
|
96
|
+
┌───────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
97
|
+
│ • Justfile │ │ • build.sh │ │ • <cmd>.sh │
|
|
98
|
+
│ │ │ • run.sh │ │ (optional) │
|
|
99
|
+
│ (mounts live │ │ │ │ │
|
|
100
|
+
│ workspace) │ │ (standalone, │ │ (standalone, │
|
|
101
|
+
└───────────────┘ │ no cm deps) │ │ no cm deps) │
|
|
102
|
+
└──────────────┘ └──────────────┘
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Production files (Dockerfile, build.sh, run.sh, command scripts) are committed to git.
|
|
106
|
+
The Justfile is generated locally for developers.
|
|
107
|
+
|
|
108
|
+
## Basic Example
|
|
109
|
+
|
|
110
|
+
A minimal `cm.yaml`:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
project:
|
|
114
|
+
name: my-project
|
|
115
|
+
workspace: workspace
|
|
116
|
+
|
|
117
|
+
stages:
|
|
118
|
+
base:
|
|
119
|
+
from: python:3.11-slim
|
|
120
|
+
packages:
|
|
121
|
+
apt: [git, build-essential]
|
|
122
|
+
pip: [numpy, pandas]
|
|
123
|
+
|
|
124
|
+
development:
|
|
125
|
+
from: base
|
|
126
|
+
|
|
127
|
+
production:
|
|
128
|
+
from: base
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This generates everything you need to build and run your project.
|
|
132
|
+
|
|
133
|
+
## Example with Features
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
project:
|
|
137
|
+
name: ml-training
|
|
138
|
+
workspace: workspace
|
|
139
|
+
auto_update: true
|
|
140
|
+
|
|
141
|
+
runtime:
|
|
142
|
+
features:
|
|
143
|
+
- gpu # NVIDIA GPU
|
|
144
|
+
- display # X11/Wayland
|
|
145
|
+
|
|
146
|
+
stages:
|
|
147
|
+
base:
|
|
148
|
+
from: pytorch/pytorch
|
|
149
|
+
packages:
|
|
150
|
+
pip: [transformers, datasets]
|
|
151
|
+
env:
|
|
152
|
+
HF_HOME: /models
|
|
153
|
+
|
|
154
|
+
development:
|
|
155
|
+
from: base
|
|
156
|
+
packages:
|
|
157
|
+
pip: [pytest, ipython]
|
|
158
|
+
|
|
159
|
+
production:
|
|
160
|
+
from: base
|
|
161
|
+
|
|
162
|
+
commands:
|
|
163
|
+
train:
|
|
164
|
+
command: python workspace/train.py
|
|
165
|
+
description: Train the model
|
|
166
|
+
standalone: true # Generate dedicated train.sh script
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Development:**
|
|
170
|
+
```bash
|
|
171
|
+
build
|
|
172
|
+
run train # Use custom command directly (from anywhere)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Production:**
|
|
176
|
+
```bash
|
|
177
|
+
./build.sh
|
|
178
|
+
./run.sh train # Run via run.sh
|
|
179
|
+
./train.sh # Or use dedicated standalone script
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## YAML Reference
|
|
183
|
+
|
|
184
|
+
### Project
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
project:
|
|
188
|
+
name: my-project # Required: image name
|
|
189
|
+
workspace: workspace # Required: directory with your code
|
|
190
|
+
auto_update: true # Optional: auto-regenerate on config changes
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Runtime
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
runtime:
|
|
197
|
+
backend: auto # docker, podman, or auto
|
|
198
|
+
privileged: false # privileged mode
|
|
199
|
+
features:
|
|
200
|
+
- gpu # NVIDIA GPU
|
|
201
|
+
- display # X11/Wayland
|
|
202
|
+
- audio # PulseAudio/PipeWire
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Stages
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
stages:
|
|
209
|
+
base:
|
|
210
|
+
from: python:3.11-slim # Any Docker Hub image
|
|
211
|
+
packages:
|
|
212
|
+
apt: [git, curl]
|
|
213
|
+
pip: [numpy, pandas]
|
|
214
|
+
env:
|
|
215
|
+
VAR: value
|
|
216
|
+
|
|
217
|
+
development:
|
|
218
|
+
from: base # Inherit from base
|
|
219
|
+
packages:
|
|
220
|
+
pip: [pytest]
|
|
221
|
+
|
|
222
|
+
production:
|
|
223
|
+
from: base
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
You can use any image from Docker Hub as your base (e.g., `python:3.11`, `ubuntu:22.04`, `pytorch/pytorch`, `nvidia/cuda:12.4.0-runtime-ubuntu22.04`).
|
|
227
|
+
|
|
228
|
+
### Commands
|
|
229
|
+
|
|
230
|
+
Define custom commands that work in both dev and prod:
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
commands:
|
|
234
|
+
train:
|
|
235
|
+
command: python workspace/train.py
|
|
236
|
+
description: Train model
|
|
237
|
+
env:
|
|
238
|
+
CUDA_VISIBLE_DEVICES: "0"
|
|
239
|
+
standalone: false # Default: false (no dedicated script)
|
|
240
|
+
|
|
241
|
+
deploy:
|
|
242
|
+
command: bash workspace/deploy.sh
|
|
243
|
+
description: Deploy the model
|
|
244
|
+
standalone: true # Generates deploy.sh script
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The `standalone` flag (default: `false`) controls script generation:
|
|
248
|
+
- **`standalone: false`** (default) - Command available via `run <command>` and `./run.sh <command>` only
|
|
249
|
+
- **`standalone: true`** - Also generates a dedicated `<command>.sh` script for direct execution
|
|
250
|
+
|
|
251
|
+
**Development:**
|
|
252
|
+
- `run train` - from anywhere in your repository
|
|
253
|
+
- `just train` - from repository root (if you have `just` installed)
|
|
254
|
+
|
|
255
|
+
**Production (standalone: false):**
|
|
256
|
+
- `./run.sh train` - only way to run
|
|
257
|
+
|
|
258
|
+
**Production (standalone: true):**
|
|
259
|
+
- `./run.sh deploy` - via run.sh
|
|
260
|
+
- `./deploy.sh` - dedicated standalone script
|
|
261
|
+
|
|
262
|
+
### Build Script
|
|
263
|
+
|
|
264
|
+
Configure the standalone `build.sh` script behaviour:
|
|
265
|
+
|
|
266
|
+
```yaml
|
|
267
|
+
build_script:
|
|
268
|
+
default_target: production # Optional: default stage to build (default: production)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The `build.sh` script can build any defined stage:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
./build.sh # Builds the default target (production) → tagged as 'latest'
|
|
275
|
+
./build.sh production # Builds production stage → tagged as 'latest'
|
|
276
|
+
./build.sh testing # Builds testing stage → tagged as 'testing'
|
|
277
|
+
./build.sh development # Builds development stage → tagged as 'development'
|
|
278
|
+
./build.sh --help # Shows all available targets
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Image Tagging:**
|
|
282
|
+
- Production stage is tagged as `<project-name>:latest`
|
|
283
|
+
- All other stages are tagged as `<project-name>:<stage-name>`
|
|
284
|
+
|
|
285
|
+
This is useful when you have multiple build targets beyond just development and production (e.g., testing, staging, or platform-specific builds).
|
|
286
|
+
|
|
287
|
+
## CLI Commands
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# Create new project
|
|
291
|
+
cm init <image> <name>
|
|
292
|
+
cm init --here <image> # Initialize in current dir
|
|
293
|
+
cm init --compact <image> # Use cm.yaml instead of container-magic.yaml
|
|
294
|
+
|
|
295
|
+
# Regenerate files after editing YAML
|
|
296
|
+
cm update
|
|
297
|
+
|
|
298
|
+
# Development (aliases)
|
|
299
|
+
build
|
|
300
|
+
run <command>
|
|
301
|
+
|
|
302
|
+
# Production (standalone scripts)
|
|
303
|
+
./build.sh
|
|
304
|
+
./run.sh <command>
|
|
305
|
+
./run.sh <custom-command>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The `<image>` can be any Docker Hub image like `python:3.11`, `ubuntu:22.04`, `pytorch/pytorch`, etc.
|
|
309
|
+
|
|
310
|
+
**Note:** Both `just` and the `build`/`run` aliases work from anywhere in your project by searching upward for the Justfile/config. For basic development, you only need `just` installed. Installing container-magic is recommended primarily for generating and regenerating files from your YAML config. As a bonus, it also provides command aliases with automatic working directory translation - the `run` alias (not `just run`) adjusts the container's working directory to match your position in the repository, making it feel like you're running commands on the host.
|
|
311
|
+
|
|
312
|
+
## Using `just` vs `run` Alias
|
|
313
|
+
|
|
314
|
+
**When calling `just` directly:**
|
|
315
|
+
- Paths must be relative to the project root (where the Justfile is)
|
|
316
|
+
- Works from anywhere, but you must always specify paths from the project root
|
|
317
|
+
- Limitation: `just` changes to the Justfile directory, losing context of where you ran the command
|
|
318
|
+
|
|
319
|
+
**When using the `run` alias (requires container-magic installed):**
|
|
320
|
+
- Automatically translates your working directory to the container
|
|
321
|
+
- Paths can be relative to your current location
|
|
322
|
+
- The container's working directory matches your position in the repository
|
|
323
|
+
|
|
324
|
+
**Example:**
|
|
325
|
+
```bash
|
|
326
|
+
# From project root - both work the same:
|
|
327
|
+
just run workspace/script.py # ✓ Works
|
|
328
|
+
run workspace/script.py # ✓ Works
|
|
329
|
+
|
|
330
|
+
# Now cd into workspace/ subdirectory:
|
|
331
|
+
cd workspace
|
|
332
|
+
|
|
333
|
+
# just fails because it looks for paths from project root:
|
|
334
|
+
just run script.py # ❌ Fails - looks for script.py in project root (not workspace/)
|
|
335
|
+
|
|
336
|
+
# run works because it translates your working directory:
|
|
337
|
+
run script.py # ✓ Works - finds script.py in current dir
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Note:** You can make `just` work from subdirectories by always using full paths from the project root (e.g., `just run workspace/script.py` would work from anywhere).
|
|
341
|
+
|
|
342
|
+
## Development vs Production
|
|
343
|
+
|
|
344
|
+
**Development:**
|
|
345
|
+
- Workspace mounted from host (edit code live, not baked into image)
|
|
346
|
+
- Runs as your user (correct permissions)
|
|
347
|
+
- Includes dev dependencies
|
|
348
|
+
|
|
349
|
+
**Production** (build.sh/run.sh):
|
|
350
|
+
- Workspace baked into image
|
|
351
|
+
- Standalone scripts (only need docker/podman)
|
|
352
|
+
- Minimal dependencies
|
|
353
|
+
|
|
354
|
+
## Project Structure
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
my-project/
|
|
358
|
+
├── cm.yaml # Your config (committed)
|
|
359
|
+
├── Dockerfile # Generated (committed)
|
|
360
|
+
├── build.sh # Generated (committed)
|
|
361
|
+
├── run.sh # Generated (committed)
|
|
362
|
+
├── <command>.sh # Generated for each command where standalone: true (committed)
|
|
363
|
+
├── Justfile # Generated locally for dev (gitignored)
|
|
364
|
+
├── workspace/ # Your code
|
|
365
|
+
└── .cm-cache/ # Downloaded assets (gitignored)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Command scripts (e.g., `train.sh`, `deploy.sh`) are only generated for commands with `standalone: true` and are committed to the repository.
|
|
369
|
+
|
|
370
|
+
## Contributing
|
|
371
|
+
|
|
372
|
+
Container-magic is in early development. Contributions and feedback welcome!
|