dockerbrain 1.0__py3-none-any.whl

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.
core/templates.py ADDED
@@ -0,0 +1,559 @@
1
+ from __future__ import annotations
2
+
3
+ TEMPLATES: dict[str, dict[str, str]] = {
4
+
5
+ # Python
6
+ "fastapi": {
7
+ "name": "FastAPI",
8
+ "description": "Python FastAPI with uvicorn",
9
+ "dockerfile": """\
10
+ FROM python:3.12-slim
11
+
12
+ WORKDIR /app
13
+
14
+ COPY requirements.txt .
15
+ RUN pip install --no-cache-dir -r requirements.txt
16
+
17
+ COPY . .
18
+
19
+ EXPOSE 8000
20
+
21
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
22
+ """,
23
+ },
24
+
25
+ "flask": {
26
+ "name": "Flask",
27
+ "description": "Python Flask with gunicorn",
28
+ "dockerfile": """\
29
+ FROM python:3.12-slim
30
+
31
+ WORKDIR /app
32
+
33
+ COPY requirements.txt .
34
+ RUN pip install --no-cache-dir -r requirements.txt
35
+
36
+ COPY . .
37
+
38
+ EXPOSE 5000
39
+
40
+ CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
41
+ """,
42
+ },
43
+
44
+ "django": {
45
+ "name": "Django",
46
+ "description": "Python Django with gunicorn",
47
+ "dockerfile": """\
48
+ FROM python:3.12-slim
49
+
50
+ WORKDIR /app
51
+
52
+ COPY requirements.txt .
53
+ RUN pip install --no-cache-dir -r requirements.txt
54
+
55
+ COPY . .
56
+
57
+ RUN python manage.py collectstatic --noinput
58
+
59
+ EXPOSE 8000
60
+
61
+ CMD ["gunicorn", "--bind", "0.0.0.0:8000", "config.wsgi:application"]
62
+ """,
63
+ },
64
+
65
+ # JavaScript / Node.js
66
+ "node": {
67
+ "name": "Node.js",
68
+ "description": "Node.js (Express / generic)",
69
+ "dockerfile": """\
70
+ FROM node:22-alpine
71
+
72
+ WORKDIR /app
73
+
74
+ COPY package*.json ./
75
+ RUN npm ci --omit=dev
76
+
77
+ COPY . .
78
+
79
+ EXPOSE 3000
80
+
81
+ CMD ["node", "index.js"]
82
+ """,
83
+ },
84
+
85
+ "nextjs": {
86
+ "name": "Next.js",
87
+ "description": "Next.js with standalone output",
88
+ "dockerfile": """\
89
+ FROM node:22-alpine AS deps
90
+ WORKDIR /app
91
+ COPY package*.json ./
92
+ RUN npm ci
93
+
94
+ FROM node:22-alpine AS builder
95
+ WORKDIR /app
96
+ COPY --from=deps /app/node_modules ./node_modules
97
+ COPY . .
98
+ RUN npm run build
99
+
100
+ FROM node:22-alpine AS runner
101
+ WORKDIR /app
102
+ ENV NODE_ENV=production
103
+
104
+ COPY --from=builder /app/public ./public
105
+ COPY --from=builder /app/.next/standalone ./
106
+ COPY --from=builder /app/.next/static ./.next/static
107
+
108
+ EXPOSE 3000
109
+
110
+ CMD ["node", "server.js"]
111
+ """,
112
+ },
113
+
114
+ "react": {
115
+ "name": "React",
116
+ "description": "React (Vite/CRA) with nginx",
117
+ "dockerfile": """\
118
+ FROM node:22-alpine AS build
119
+ WORKDIR /app
120
+ COPY package*.json ./
121
+ RUN npm ci
122
+ COPY . .
123
+ RUN npm run build
124
+
125
+ FROM nginx:alpine
126
+ COPY --from=build /app/dist /usr/share/nginx/html
127
+ EXPOSE 80
128
+ CMD ["nginx", "-g", "daemon off;"]
129
+ """,
130
+ },
131
+
132
+ "vue": {
133
+ "name": "Vue.js",
134
+ "description": "Vue.js with nginx",
135
+ "dockerfile": """\
136
+ FROM node:22-alpine AS build
137
+ WORKDIR /app
138
+ COPY package*.json ./
139
+ RUN npm ci
140
+ COPY . .
141
+ RUN npm run build
142
+
143
+ FROM nginx:alpine
144
+ COPY --from=build /app/dist /usr/share/nginx/html
145
+ EXPOSE 80
146
+ CMD ["nginx", "-g", "daemon off;"]
147
+ """,
148
+ },
149
+
150
+ "angular": {
151
+ "name": "Angular",
152
+ "description": "Angular with nginx",
153
+ "dockerfile": """\
154
+ FROM node:22-alpine AS build
155
+ WORKDIR /app
156
+ COPY package*.json ./
157
+ RUN npm ci
158
+ COPY . .
159
+ RUN npm run build --configuration=production
160
+
161
+ FROM nginx:alpine
162
+ COPY --from=build /app/dist/*/browser /usr/share/nginx/html
163
+ EXPOSE 80
164
+ CMD ["nginx", "-g", "daemon off;"]
165
+ """,
166
+ },
167
+
168
+ # TypeScript runtimes
169
+ "bun": {
170
+ "name": "Bun",
171
+ "description": "Bun runtime",
172
+ "dockerfile": """\
173
+ FROM oven/bun:1-alpine
174
+
175
+ WORKDIR /app
176
+
177
+ COPY package.json bun.lockb ./
178
+ RUN bun install --frozen-lockfile --production
179
+
180
+ COPY . .
181
+
182
+ EXPOSE 3000
183
+
184
+ CMD ["bun", "run", "index.ts"]
185
+ """,
186
+ },
187
+
188
+ "deno": {
189
+ "name": "Deno",
190
+ "description": "Deno runtime",
191
+ "dockerfile": """\
192
+ FROM denoland/deno:latest
193
+
194
+ WORKDIR /app
195
+
196
+ COPY . .
197
+
198
+ RUN deno cache main.ts
199
+
200
+ EXPOSE 8000
201
+
202
+ CMD ["deno", "run", "--allow-net", "--allow-read", "--allow-env", "main.ts"]
203
+ """,
204
+ },
205
+
206
+ # Go
207
+ "go": {
208
+ "name": "Go",
209
+ "description": "Go with multi-stage build",
210
+ "dockerfile": """\
211
+ FROM golang:1.23-alpine AS builder
212
+ WORKDIR /app
213
+ COPY go.mod go.sum ./
214
+ RUN go mod download
215
+ COPY . .
216
+ RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /server .
217
+
218
+ FROM alpine:3.20
219
+ RUN apk --no-cache add ca-certificates
220
+ COPY --from=builder /server /server
221
+
222
+ EXPOSE 8080
223
+
224
+ CMD ["/server"]
225
+ """,
226
+ },
227
+
228
+ # Rust
229
+ "rust": {
230
+ "name": "Rust",
231
+ "description": "Rust with multi-stage build",
232
+ "dockerfile": """\
233
+ FROM rust:1.80-slim AS builder
234
+ WORKDIR /app
235
+ COPY Cargo.toml Cargo.lock ./
236
+ RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release && rm -rf src
237
+ COPY . .
238
+ RUN cargo build --release
239
+
240
+ FROM debian:bookworm-slim
241
+ RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*
242
+ COPY --from=builder /app/target/release/app /usr/local/bin/app
243
+
244
+ EXPOSE 8080
245
+
246
+ CMD ["app"]
247
+ """,
248
+ },
249
+
250
+ # Java
251
+ "spring": {
252
+ "name": "Spring Boot",
253
+ "description": "Spring Boot (Maven)",
254
+ "dockerfile": """\
255
+ FROM eclipse-temurin:21-jdk-alpine AS builder
256
+ WORKDIR /app
257
+ COPY pom.xml mvnw ./
258
+ COPY .mvn .mvn
259
+ RUN ./mvnw dependency:resolve
260
+ COPY src src
261
+ RUN ./mvnw package -DskipTests
262
+
263
+ FROM eclipse-temurin:21-jre-alpine
264
+ WORKDIR /app
265
+ COPY --from=builder /app/target/*.jar app.jar
266
+
267
+ EXPOSE 8080
268
+
269
+ CMD ["java", "-jar", "app.jar"]
270
+ """,
271
+ },
272
+
273
+ "gradle": {
274
+ "name": "Java (Gradle)",
275
+ "description": "Java app with Gradle",
276
+ "dockerfile": """\
277
+ FROM eclipse-temurin:21-jdk-alpine AS builder
278
+ WORKDIR /app
279
+ COPY build.gradle settings.gradle gradlew ./
280
+ COPY gradle gradle
281
+ RUN ./gradlew dependencies
282
+ COPY src src
283
+ RUN ./gradlew bootJar
284
+
285
+ FROM eclipse-temurin:21-jre-alpine
286
+ WORKDIR /app
287
+ COPY --from=builder /app/build/libs/*.jar app.jar
288
+
289
+ EXPOSE 8080
290
+
291
+ CMD ["java", "-jar", "app.jar"]
292
+ """,
293
+ },
294
+
295
+ # Ruby
296
+ "rails": {
297
+ "name": "Ruby on Rails",
298
+ "description": "Rails with Puma",
299
+ "dockerfile": """\
300
+ FROM ruby:3.3-slim
301
+
302
+ RUN apt-get update -qq && \\
303
+ apt-get install -y --no-install-recommends build-essential libpq-dev nodejs && \\
304
+ rm -rf /var/lib/apt/lists/*
305
+
306
+ WORKDIR /app
307
+
308
+ COPY Gemfile Gemfile.lock ./
309
+ RUN bundle install --without development test
310
+
311
+ COPY . .
312
+
313
+ RUN bundle exec rake assets:precompile
314
+
315
+ EXPOSE 3000
316
+
317
+ CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
318
+ """,
319
+ },
320
+
321
+ # PHP
322
+ "laravel": {
323
+ "name": "Laravel",
324
+ "description": "PHP Laravel with Apache",
325
+ "dockerfile": """\
326
+ FROM php:8.3-apache
327
+
328
+ RUN a2enmod rewrite && \\
329
+ apt-get update && apt-get install -y --no-install-recommends \\
330
+ libpng-dev libzip-dev unzip && \\
331
+ docker-php-ext-install pdo_mysql gd zip && \\
332
+ rm -rf /var/lib/apt/lists/*
333
+
334
+ COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
335
+
336
+ WORKDIR /var/www/html
337
+
338
+ COPY . .
339
+ RUN composer install --no-dev --optimize-autoloader
340
+
341
+ RUN chown -R www-data:www-data storage bootstrap/cache
342
+
343
+ ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
344
+ RUN sed -ri 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/000-default.conf
345
+
346
+ EXPOSE 80
347
+
348
+ CMD ["apache2-foreground"]
349
+ """,
350
+ },
351
+
352
+ # .NET
353
+ "dotnet": {
354
+ "name": ".NET",
355
+ "description": "ASP.NET Core",
356
+ "dockerfile": """\
357
+ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
358
+ WORKDIR /src
359
+ COPY *.csproj ./
360
+ RUN dotnet restore
361
+ COPY . .
362
+ RUN dotnet publish -c Release -o /app/publish
363
+
364
+ FROM mcr.microsoft.com/dotnet/aspnet:8.0
365
+ WORKDIR /app
366
+ COPY --from=build /app/publish .
367
+
368
+ EXPOSE 8080
369
+
370
+ CMD ["dotnet", "App.dll"]
371
+ """,
372
+ },
373
+
374
+ # Elixir
375
+ "phoenix": {
376
+ "name": "Elixir Phoenix",
377
+ "description": "Phoenix Framework",
378
+ "dockerfile": """\
379
+ FROM elixir:1.16-alpine AS builder
380
+ RUN apk add --no-cache build-base git
381
+ WORKDIR /app
382
+
383
+ ENV MIX_ENV=prod
384
+ RUN mix local.hex --force && mix local.rebar --force
385
+
386
+ COPY mix.exs mix.lock ./
387
+ RUN mix deps.get --only prod && mix deps.compile
388
+
389
+ COPY . .
390
+ RUN mix assets.deploy && mix release
391
+
392
+ FROM alpine:3.20
393
+ RUN apk add --no-cache libstdc++ openssl ncurses-libs
394
+ WORKDIR /app
395
+ COPY --from=builder /app/_build/prod/rel/app ./
396
+
397
+ EXPOSE 4000
398
+
399
+ CMD ["bin/app", "start"]
400
+ """,
401
+ },
402
+
403
+ # Static / Nginx
404
+ "static": {
405
+ "name": "Static Site",
406
+ "description": "Static HTML/CSS/JS with nginx",
407
+ "dockerfile": """\
408
+ FROM nginx:alpine
409
+
410
+ COPY . /usr/share/nginx/html
411
+
412
+ EXPOSE 80
413
+
414
+ CMD ["nginx", "-g", "daemon off;"]
415
+ """,
416
+ },
417
+
418
+ # Python ML
419
+ "python-ml": {
420
+ "name": "Python ML",
421
+ "description": "Python ML/Data Science with Jupyter",
422
+ "dockerfile": """\
423
+ FROM python:3.12-slim
424
+
425
+ WORKDIR /app
426
+
427
+ RUN apt-get update && apt-get install -y --no-install-recommends \\
428
+ build-essential && rm -rf /var/lib/apt/lists/*
429
+
430
+ COPY requirements.txt .
431
+ RUN pip install --no-cache-dir -r requirements.txt
432
+
433
+ COPY . .
434
+
435
+ EXPOSE 8888
436
+
437
+ CMD ["jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]
438
+ """,
439
+ },
440
+
441
+ # SvelteKit
442
+ "sveltekit": {
443
+ "name": "SvelteKit",
444
+ "description": "SvelteKit with Node adapter",
445
+ "dockerfile": """\
446
+ FROM node:22-alpine AS builder
447
+ WORKDIR /app
448
+ COPY package*.json ./
449
+ RUN npm ci
450
+ COPY . .
451
+ RUN npm run build
452
+
453
+ FROM node:22-alpine
454
+ WORKDIR /app
455
+ COPY --from=builder /app/build ./build
456
+ COPY --from=builder /app/package*.json ./
457
+ RUN npm ci --omit=dev
458
+
459
+ EXPOSE 3000
460
+
461
+ CMD ["node", "build"]
462
+ """,
463
+ },
464
+
465
+ # Nuxt.js
466
+ "nuxtjs": {
467
+ "name": "Nuxt.js",
468
+ "description": "Nuxt.js with SSR output",
469
+ "dockerfile": """\
470
+ FROM node:22-alpine AS builder
471
+ WORKDIR /app
472
+ COPY package*.json ./
473
+ RUN npm ci
474
+ COPY . .
475
+ RUN npm run build
476
+
477
+ FROM node:22-alpine
478
+ WORKDIR /app
479
+ COPY --from=builder /app/.output ./
480
+
481
+ EXPOSE 3000
482
+
483
+ CMD ["node", "server/index.mjs"]
484
+ """,
485
+ },
486
+
487
+ # Astro
488
+ "astro": {
489
+ "name": "Astro",
490
+ "description": "Astro static site with nginx",
491
+ "dockerfile": """\
492
+ FROM node:22-alpine AS builder
493
+ WORKDIR /app
494
+ COPY package*.json ./
495
+ RUN npm ci
496
+ COPY . .
497
+ RUN npm run build
498
+
499
+ FROM nginx:alpine
500
+ COPY --from=builder /app/dist /usr/share/nginx/html
501
+ EXPOSE 80
502
+ CMD ["nginx", "-g", "daemon off;"]
503
+ """,
504
+ },
505
+
506
+ # Streamlit
507
+ "streamlit": {
508
+ "name": "Streamlit",
509
+ "description": "Python Streamlit data app",
510
+ "dockerfile": """\
511
+ FROM python:3.12-slim
512
+
513
+ WORKDIR /app
514
+
515
+ COPY requirements.txt .
516
+ RUN pip install --no-cache-dir -r requirements.txt
517
+
518
+ COPY . .
519
+
520
+ EXPOSE 8501
521
+
522
+ CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
523
+ """,
524
+ },
525
+
526
+ # NestJS
527
+ "nestjs": {
528
+ "name": "NestJS",
529
+ "description": "NestJS backend with multi-stage build",
530
+ "dockerfile": """\
531
+ FROM node:22-alpine AS builder
532
+ WORKDIR /app
533
+ COPY package*.json ./
534
+ RUN npm ci
535
+ COPY . .
536
+ RUN npm run build
537
+
538
+ FROM node:22-alpine
539
+ WORKDIR /app
540
+ COPY --from=builder /app/dist ./dist
541
+ COPY --from=builder /app/package*.json ./
542
+ RUN npm ci --omit=dev
543
+
544
+ EXPOSE 3000
545
+
546
+ CMD ["node", "dist/main"]
547
+ """,
548
+ },
549
+
550
+ }
551
+
552
+ def get_template_names() -> list[str]:
553
+ """Return sorted list of template keys."""
554
+ return sorted(TEMPLATES.keys())
555
+
556
+
557
+ def get_template(name: str) -> dict[str, str] | None:
558
+ """Return template dict by key, or None."""
559
+ return TEMPLATES.get(name.lower())
core/utils.py ADDED
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+ import sys
3
+
4
+ def format_bytes(b: int | float) -> str:
5
+ """Human-readable byte string (e.g. 1.23 GiB)."""
6
+ for unit in ("B", "KiB", "MiB", "GiB", "TiB"):
7
+ if abs(b) < 1024:
8
+ return f"{b:.2f} {unit}"
9
+ b /= 1024
10
+ return f"{b:.2f} PiB"
11
+
12
+
13
+ def calc_cpu_percent(stats: dict) -> float:
14
+ """Calculate CPU usage percentage from Docker stats JSON.
15
+
16
+ Uses the same formula as ``docker stats``:
17
+ delta_container / delta_system * num_cpus * 100
18
+ """
19
+ cpu = stats.get("cpu_stats", {})
20
+ precpu = stats.get("precpu_stats", {})
21
+
22
+ container_delta = cpu.get("cpu_usage", {}).get("total_usage", 0) - precpu.get("cpu_usage", {}).get("total_usage", 0)
23
+ system_delta = cpu.get("system_cpu_usage", 0) - precpu.get("system_cpu_usage", 0)
24
+ num_cpus = cpu.get("online_cpus") or len(cpu.get("cpu_usage", {}).get("percpu_usage", []) or [1])
25
+
26
+ if system_delta > 0 and container_delta > 0:
27
+ return (container_delta / system_delta) * num_cpus * 100.0
28
+ return 0.0
29
+
30
+
31
+ def get_docker_offline_hint() -> str:
32
+ """Return an OS-specific hint for starting Docker."""
33
+ if sys.platform == "win32":
34
+ return "Make sure Docker Desktop is running, then try again."
35
+ elif sys.platform == "darwin":
36
+ return "Make sure Docker Desktop (or OrbStack/Colima) is running, then try again."
37
+ else:
38
+ return "Make sure the Docker daemon is running (e.g. `sudo systemctl start docker`), then try again."