dockerme 1.0.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 +113 -0
- package/bin/dockerize.js +51 -0
- package/lib/analyzer.js +636 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Dockerize
|
|
2
|
+
|
|
3
|
+
Automatically generate Dockerfiles by analyzing your codebase. This npm package detects your project type and generates an appropriate Dockerfile for you.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Local Development
|
|
14
|
+
|
|
15
|
+
After installing dependencies, you can run:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm link
|
|
19
|
+
dockerize
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### As npx Package
|
|
23
|
+
|
|
24
|
+
Once published to npm, you can use it directly with:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx dockerize
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- 🔍 **Automatic Detection**: Analyzes your codebase to detect project type
|
|
33
|
+
- 🐳 **Smart Dockerfiles**: Generates optimized Dockerfiles for various frameworks
|
|
34
|
+
- 📦 **Multi-language Support**: Supports Node.js, Python, Java, Go, Rust, Ruby, PHP, and more
|
|
35
|
+
- ⚙️ **Framework-aware**: Detects specific frameworks like React, Next.js, Django, Flask, FastAPI, etc.
|
|
36
|
+
|
|
37
|
+
## Supported Project Types
|
|
38
|
+
|
|
39
|
+
### Node.js
|
|
40
|
+
- **React/Vite**: Multi-stage build with nginx
|
|
41
|
+
- **Next.js**: Optimized Next.js production build
|
|
42
|
+
- **Backend**: Express, Fastify, Koa, etc.
|
|
43
|
+
- **Generic Node.js**: Standard Node.js applications
|
|
44
|
+
|
|
45
|
+
### Python
|
|
46
|
+
- **Django**: Includes migrations and static files
|
|
47
|
+
- **Flask**: Uses Gunicorn for production
|
|
48
|
+
- **FastAPI**: Uses Uvicorn server
|
|
49
|
+
- **Generic Python**: Standard Python applications
|
|
50
|
+
|
|
51
|
+
### Java
|
|
52
|
+
- **Maven**: Multi-stage build with Maven
|
|
53
|
+
- **Gradle**: Multi-stage build with Gradle
|
|
54
|
+
|
|
55
|
+
### Other Languages
|
|
56
|
+
- **Go**: Multi-stage build with Go
|
|
57
|
+
- **Rust**: Multi-stage build with Cargo
|
|
58
|
+
- **Ruby**: Rails applications
|
|
59
|
+
- **PHP**: Apache with Composer
|
|
60
|
+
|
|
61
|
+
## Options
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
dockerize [options]
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
-V, --version Show version number
|
|
68
|
+
-o, --output <file> Output Dockerfile path (default: "Dockerfile")
|
|
69
|
+
-f, --force Overwrite existing Dockerfile
|
|
70
|
+
-h, --help Display help for command
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Examples
|
|
74
|
+
|
|
75
|
+
Generate a Dockerfile in the current directory:
|
|
76
|
+
```bash
|
|
77
|
+
dockerize
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Generate a Dockerfile with a custom name:
|
|
81
|
+
```bash
|
|
82
|
+
dockerize -o Dockerfile.prod
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Overwrite an existing Dockerfile:
|
|
86
|
+
```bash
|
|
87
|
+
dockerize --force
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## How It Works
|
|
91
|
+
|
|
92
|
+
1. **Analysis**: Scans your project directory for configuration files (package.json, requirements.txt, pom.xml, etc.)
|
|
93
|
+
2. **Detection**: Identifies the project type and framework based on detected files
|
|
94
|
+
3. **Generation**: Creates an optimized Dockerfile template for your specific project type
|
|
95
|
+
|
|
96
|
+
## Publishing to npm
|
|
97
|
+
|
|
98
|
+
To publish this package to npm:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm login
|
|
102
|
+
npm publish
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
After publishing, users can install and use it globally or via npx:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx dockerize
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
MIT
|
package/bin/dockerize.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { program } = require('commander');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const { analyzeCodebase, generateDockerfile } = require('../lib/analyzer');
|
|
8
|
+
|
|
9
|
+
program
|
|
10
|
+
.name('dockerize')
|
|
11
|
+
.description('Automatically generate Dockerfiles by analyzing your codebase')
|
|
12
|
+
.version('1.0.0')
|
|
13
|
+
.option('-o, --output <file>', 'Output Dockerfile path', 'Dockerfile')
|
|
14
|
+
.option('-f, --force', 'Overwrite existing Dockerfile', false)
|
|
15
|
+
.parse(process.argv);
|
|
16
|
+
|
|
17
|
+
const options = program.opts();
|
|
18
|
+
const projectRoot = process.cwd();
|
|
19
|
+
|
|
20
|
+
async function main() {
|
|
21
|
+
try {
|
|
22
|
+
console.log(chalk.blue('🔍 Analyzing codebase...'));
|
|
23
|
+
|
|
24
|
+
const analysis = analyzeCodebase(projectRoot);
|
|
25
|
+
|
|
26
|
+
console.log(chalk.green(`✓ Detected project type: ${chalk.bold(analysis.projectType)}`));
|
|
27
|
+
if (analysis.details) {
|
|
28
|
+
console.log(chalk.gray(` ${analysis.details}`));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const dockerfileContent = generateDockerfile(analysis);
|
|
32
|
+
|
|
33
|
+
const outputPath = path.join(projectRoot, options.output);
|
|
34
|
+
|
|
35
|
+
// Check if file exists
|
|
36
|
+
if (fs.existsSync(outputPath) && !options.force) {
|
|
37
|
+
console.log(chalk.red(`✗ Dockerfile already exists at ${options.output}`));
|
|
38
|
+
console.log(chalk.yellow(' Use --force to overwrite'));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fs.writeFileSync(outputPath, dockerfileContent);
|
|
43
|
+
console.log(chalk.green(`✓ Dockerfile generated successfully at ${options.output}`));
|
|
44
|
+
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error(chalk.red('✗ Error:'), error.message);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
main();
|
package/lib/analyzer.js
ADDED
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function detectProjectType(projectRoot) {
|
|
5
|
+
const files = fs.readdirSync(projectRoot);
|
|
6
|
+
|
|
7
|
+
// Check for package.json (Node.js)
|
|
8
|
+
if (files.includes('package.json')) {
|
|
9
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
|
|
10
|
+
const scripts = packageJson.scripts || {};
|
|
11
|
+
|
|
12
|
+
// Check for React/Vite
|
|
13
|
+
if (files.includes('vite.config.js') || files.includes('vite.config.ts') ||
|
|
14
|
+
files.includes('vite.config.mjs')) {
|
|
15
|
+
return { type: 'node-react-vite', packageJson };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Check for Next.js
|
|
19
|
+
if (files.includes('next.config.js') || files.includes('next.config.ts') ||
|
|
20
|
+
packageJson.dependencies?.next || packageJson.devDependencies?.next) {
|
|
21
|
+
return { type: 'node-nextjs', packageJson };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check for Express/Fastify/etc
|
|
25
|
+
if (packageJson.dependencies?.express || packageJson.dependencies?.fastify ||
|
|
26
|
+
packageJson.dependencies?.koa || scripts.start || scripts.dev) {
|
|
27
|
+
return { type: 'node-backend', packageJson };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return { type: 'node', packageJson };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Check for requirements.txt or setup.py (Python)
|
|
34
|
+
if (files.includes('requirements.txt') || files.includes('setup.py') ||
|
|
35
|
+
files.includes('pyproject.toml') || files.includes('Pipfile')) {
|
|
36
|
+
let pythonVersion = '3.11';
|
|
37
|
+
|
|
38
|
+
// Try to detect Python version from runtime.txt or .python-version
|
|
39
|
+
if (files.includes('runtime.txt')) {
|
|
40
|
+
const runtime = fs.readFileSync(path.join(projectRoot, 'runtime.txt'), 'utf8').trim();
|
|
41
|
+
const match = runtime.match(/python-(\d+\.\d+)/);
|
|
42
|
+
if (match) pythonVersion = match[1];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Check for Django
|
|
46
|
+
if (files.includes('manage.py')) {
|
|
47
|
+
return { type: 'python-django', pythonVersion };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check for Flask
|
|
51
|
+
if (files.includes('app.py') || files.includes('application.py')) {
|
|
52
|
+
const content = fs.readFileSync(path.join(projectRoot, files.includes('app.py') ? 'app.py' : 'application.py'), 'utf8');
|
|
53
|
+
if (content.includes('Flask') || content.includes('from flask')) {
|
|
54
|
+
return { type: 'python-flask', pythonVersion };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Check for FastAPI
|
|
59
|
+
if (files.includes('main.py')) {
|
|
60
|
+
const content = fs.readFileSync(path.join(projectRoot, 'main.py'), 'utf8');
|
|
61
|
+
if (content.includes('FastAPI') || content.includes('from fastapi')) {
|
|
62
|
+
return { type: 'python-fastapi', pythonVersion };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { type: 'python', pythonVersion };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check for pom.xml (Java Maven)
|
|
70
|
+
if (files.includes('pom.xml')) {
|
|
71
|
+
return { type: 'java-maven' };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check for build.gradle (Java Gradle)
|
|
75
|
+
if (files.includes('build.gradle') || files.includes('build.gradle.kts')) {
|
|
76
|
+
return { type: 'java-gradle' };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check for go.mod (Go)
|
|
80
|
+
if (files.includes('go.mod')) {
|
|
81
|
+
return { type: 'go' };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Check for Cargo.toml (Rust)
|
|
85
|
+
if (files.includes('Cargo.toml')) {
|
|
86
|
+
return { type: 'rust' };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Check for Gemfile (Ruby)
|
|
90
|
+
if (files.includes('Gemfile')) {
|
|
91
|
+
return { type: 'ruby' };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Check for composer.json (PHP)
|
|
95
|
+
if (files.includes('composer.json')) {
|
|
96
|
+
return { type: 'php' };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Default to generic
|
|
100
|
+
return { type: 'generic' };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function analyzeCodebase(projectRoot) {
|
|
104
|
+
const detection = detectProjectType(projectRoot);
|
|
105
|
+
|
|
106
|
+
let details = '';
|
|
107
|
+
|
|
108
|
+
switch (detection.type) {
|
|
109
|
+
case 'node-react-vite':
|
|
110
|
+
details = 'React application with Vite';
|
|
111
|
+
break;
|
|
112
|
+
case 'node-nextjs':
|
|
113
|
+
details = 'Next.js application';
|
|
114
|
+
break;
|
|
115
|
+
case 'node-backend':
|
|
116
|
+
details = 'Node.js backend application';
|
|
117
|
+
break;
|
|
118
|
+
case 'node':
|
|
119
|
+
details = 'Node.js application';
|
|
120
|
+
break;
|
|
121
|
+
case 'python-django':
|
|
122
|
+
details = 'Django web framework';
|
|
123
|
+
break;
|
|
124
|
+
case 'python-flask':
|
|
125
|
+
details = 'Flask web framework';
|
|
126
|
+
break;
|
|
127
|
+
case 'python-fastapi':
|
|
128
|
+
details = 'FastAPI web framework';
|
|
129
|
+
break;
|
|
130
|
+
case 'python':
|
|
131
|
+
details = 'Python application';
|
|
132
|
+
break;
|
|
133
|
+
case 'java-maven':
|
|
134
|
+
details = 'Java Maven project';
|
|
135
|
+
break;
|
|
136
|
+
case 'java-gradle':
|
|
137
|
+
details = 'Java Gradle project';
|
|
138
|
+
break;
|
|
139
|
+
case 'go':
|
|
140
|
+
details = 'Go application';
|
|
141
|
+
break;
|
|
142
|
+
case 'rust':
|
|
143
|
+
details = 'Rust application';
|
|
144
|
+
break;
|
|
145
|
+
case 'ruby':
|
|
146
|
+
details = 'Ruby application';
|
|
147
|
+
break;
|
|
148
|
+
case 'php':
|
|
149
|
+
details = 'PHP application';
|
|
150
|
+
break;
|
|
151
|
+
default:
|
|
152
|
+
details = 'Generic application';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
projectType: detection.type,
|
|
157
|
+
details,
|
|
158
|
+
...detection
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function generateDockerfile(analysis) {
|
|
163
|
+
const templates = {
|
|
164
|
+
'node-react-vite': generateNodeReactViteDockerfile,
|
|
165
|
+
'node-nextjs': generateNextJSDockerfile,
|
|
166
|
+
'node-backend': generateNodeBackendDockerfile,
|
|
167
|
+
'node': generateNodeDockerfile,
|
|
168
|
+
'python-django': generatePythonDjangoDockerfile,
|
|
169
|
+
'python-flask': generatePythonFlaskDockerfile,
|
|
170
|
+
'python-fastapi': generatePythonFastAPIDockerfile,
|
|
171
|
+
'python': generatePythonDockerfile,
|
|
172
|
+
'java-maven': generateJavaMavenDockerfile,
|
|
173
|
+
'java-gradle': generateJavaGradleDockerfile,
|
|
174
|
+
'go': generateGoDockerfile,
|
|
175
|
+
'rust': generateRustDockerfile,
|
|
176
|
+
'ruby': generateRubyDockerfile,
|
|
177
|
+
'php': generatePHPDockerfile,
|
|
178
|
+
'generic': generateGenericDockerfile
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const generator = templates[analysis.projectType] || generateGenericDockerfile;
|
|
182
|
+
return generator(analysis);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Node.js templates
|
|
186
|
+
function generateNodeDockerfile(analysis) {
|
|
187
|
+
const nodeVersion = analysis.packageJson?.engines?.node?.replace(/[^0-9.]/g, '') || '18';
|
|
188
|
+
const hasStartScript = analysis.packageJson?.scripts?.start;
|
|
189
|
+
|
|
190
|
+
return `FROM node:${nodeVersion}-alpine
|
|
191
|
+
|
|
192
|
+
WORKDIR /app
|
|
193
|
+
|
|
194
|
+
# Copy package files
|
|
195
|
+
COPY package*.json ./
|
|
196
|
+
|
|
197
|
+
# Install dependencies
|
|
198
|
+
RUN npm ci --only=production
|
|
199
|
+
|
|
200
|
+
# Copy application code
|
|
201
|
+
COPY . .
|
|
202
|
+
|
|
203
|
+
${hasStartScript ? '# Expose port (adjust if needed)\nEXPOSE 3000\n\n# Start application\nCMD ["npm", "start"]' : '# Add your start command here\n# CMD ["node", "index.js"]'}
|
|
204
|
+
`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function generateNodeReactViteDockerfile(analysis) {
|
|
208
|
+
const nodeVersion = analysis.packageJson?.engines?.node?.replace(/[^0-9.]/g, '') || '18';
|
|
209
|
+
|
|
210
|
+
return `# Build stage
|
|
211
|
+
FROM node:${nodeVersion}-alpine AS builder
|
|
212
|
+
|
|
213
|
+
WORKDIR /app
|
|
214
|
+
|
|
215
|
+
# Copy package files
|
|
216
|
+
COPY package*.json ./
|
|
217
|
+
|
|
218
|
+
# Install dependencies
|
|
219
|
+
RUN npm ci
|
|
220
|
+
|
|
221
|
+
# Copy application code
|
|
222
|
+
COPY . .
|
|
223
|
+
|
|
224
|
+
# Build application
|
|
225
|
+
RUN npm run build
|
|
226
|
+
|
|
227
|
+
# Production stage
|
|
228
|
+
FROM nginx:alpine
|
|
229
|
+
|
|
230
|
+
# Copy built files from builder
|
|
231
|
+
COPY --from=builder /app/dist /usr/share/nginx/html
|
|
232
|
+
|
|
233
|
+
# Copy nginx configuration (optional)
|
|
234
|
+
# COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
235
|
+
|
|
236
|
+
EXPOSE 80
|
|
237
|
+
|
|
238
|
+
CMD ["nginx", "-g", "daemon off;"]
|
|
239
|
+
`;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function generateNextJSDockerfile(analysis) {
|
|
243
|
+
const nodeVersion = analysis.packageJson?.engines?.node?.replace(/[^0-9.]/g, '') || '18';
|
|
244
|
+
|
|
245
|
+
return `FROM node:${nodeVersion}-alpine AS base
|
|
246
|
+
|
|
247
|
+
# Install dependencies only when needed
|
|
248
|
+
FROM base AS deps
|
|
249
|
+
RUN apk add --no-cache libc6-compat
|
|
250
|
+
WORKDIR /app
|
|
251
|
+
|
|
252
|
+
COPY package*.json ./
|
|
253
|
+
RUN npm ci
|
|
254
|
+
|
|
255
|
+
# Rebuild the source code only when needed
|
|
256
|
+
FROM base AS builder
|
|
257
|
+
WORKDIR /app
|
|
258
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
259
|
+
COPY . .
|
|
260
|
+
|
|
261
|
+
# Build Next.js
|
|
262
|
+
RUN npm run build
|
|
263
|
+
|
|
264
|
+
# Production image
|
|
265
|
+
FROM base AS runner
|
|
266
|
+
WORKDIR /app
|
|
267
|
+
|
|
268
|
+
ENV NODE_ENV production
|
|
269
|
+
|
|
270
|
+
RUN addgroup --system --gid 1001 nodejs
|
|
271
|
+
RUN adduser --system --uid 1001 nextjs
|
|
272
|
+
|
|
273
|
+
COPY --from=builder /app/public ./public
|
|
274
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
|
|
275
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
276
|
+
COPY --from=builder /app/package.json ./package.json
|
|
277
|
+
|
|
278
|
+
USER nextjs
|
|
279
|
+
|
|
280
|
+
EXPOSE 3000
|
|
281
|
+
|
|
282
|
+
ENV PORT 3000
|
|
283
|
+
|
|
284
|
+
CMD ["npm", "start"]
|
|
285
|
+
`;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function generateNodeBackendDockerfile(analysis) {
|
|
289
|
+
const nodeVersion = analysis.packageJson?.engines?.node?.replace(/[^0-9.]/g, '') || '18';
|
|
290
|
+
const port = analysis.packageJson?.port || 3000;
|
|
291
|
+
|
|
292
|
+
return `FROM node:${nodeVersion}-alpine
|
|
293
|
+
|
|
294
|
+
WORKDIR /app
|
|
295
|
+
|
|
296
|
+
# Copy package files
|
|
297
|
+
COPY package*.json ./
|
|
298
|
+
|
|
299
|
+
# Install dependencies
|
|
300
|
+
RUN npm ci --only=production
|
|
301
|
+
|
|
302
|
+
# Copy application code
|
|
303
|
+
COPY . .
|
|
304
|
+
|
|
305
|
+
EXPOSE ${port}
|
|
306
|
+
|
|
307
|
+
# Start application
|
|
308
|
+
CMD ["npm", "start"]
|
|
309
|
+
`;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Python templates
|
|
313
|
+
function generatePythonDockerfile(analysis) {
|
|
314
|
+
const pythonVersion = analysis.pythonVersion || '3.11';
|
|
315
|
+
|
|
316
|
+
return `FROM python:${pythonVersion}-slim
|
|
317
|
+
|
|
318
|
+
WORKDIR /app
|
|
319
|
+
|
|
320
|
+
# Install system dependencies
|
|
321
|
+
RUN apt-get update && apt-get install -y \\
|
|
322
|
+
gcc \\
|
|
323
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
324
|
+
|
|
325
|
+
# Copy requirements file
|
|
326
|
+
COPY requirements.txt .
|
|
327
|
+
|
|
328
|
+
# Install Python dependencies
|
|
329
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
330
|
+
|
|
331
|
+
# Copy application code
|
|
332
|
+
COPY . .
|
|
333
|
+
|
|
334
|
+
# Expose port (adjust if needed)
|
|
335
|
+
EXPOSE 8000
|
|
336
|
+
|
|
337
|
+
# Add your start command here
|
|
338
|
+
# CMD ["python", "app.py"]
|
|
339
|
+
`;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function generatePythonDjangoDockerfile(analysis) {
|
|
343
|
+
const pythonVersion = analysis.pythonVersion || '3.11';
|
|
344
|
+
|
|
345
|
+
return `FROM python:${pythonVersion}-slim
|
|
346
|
+
|
|
347
|
+
WORKDIR /app
|
|
348
|
+
|
|
349
|
+
# Install system dependencies
|
|
350
|
+
RUN apt-get update && apt-get install -y \\
|
|
351
|
+
gcc \\
|
|
352
|
+
postgresql-client \\
|
|
353
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
354
|
+
|
|
355
|
+
# Copy requirements file
|
|
356
|
+
COPY requirements.txt .
|
|
357
|
+
|
|
358
|
+
# Install Python dependencies
|
|
359
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
360
|
+
|
|
361
|
+
# Copy application code
|
|
362
|
+
COPY . .
|
|
363
|
+
|
|
364
|
+
# Collect static files
|
|
365
|
+
RUN python manage.py collectstatic --noinput || true
|
|
366
|
+
|
|
367
|
+
EXPOSE 8000
|
|
368
|
+
|
|
369
|
+
# Run migrations and start server
|
|
370
|
+
CMD python manage.py migrate && python manage.py runserver 0.0.0.0:8000
|
|
371
|
+
`;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function generatePythonFlaskDockerfile(analysis) {
|
|
375
|
+
const pythonVersion = analysis.pythonVersion || '3.11';
|
|
376
|
+
|
|
377
|
+
return `FROM python:${pythonVersion}-slim
|
|
378
|
+
|
|
379
|
+
WORKDIR /app
|
|
380
|
+
|
|
381
|
+
# Install system dependencies
|
|
382
|
+
RUN apt-get update && apt-get install -y \\
|
|
383
|
+
gcc \\
|
|
384
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
385
|
+
|
|
386
|
+
# Copy requirements file
|
|
387
|
+
COPY requirements.txt .
|
|
388
|
+
|
|
389
|
+
# Install Python dependencies
|
|
390
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
391
|
+
|
|
392
|
+
# Copy application code
|
|
393
|
+
COPY . .
|
|
394
|
+
|
|
395
|
+
EXPOSE 5000
|
|
396
|
+
|
|
397
|
+
ENV FLASK_APP=app.py
|
|
398
|
+
ENV FLASK_ENV=production
|
|
399
|
+
|
|
400
|
+
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
|
|
401
|
+
`;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function generatePythonFastAPIDockerfile(analysis) {
|
|
405
|
+
const pythonVersion = analysis.pythonVersion || '3.11';
|
|
406
|
+
|
|
407
|
+
return `FROM python:${pythonVersion}-slim
|
|
408
|
+
|
|
409
|
+
WORKDIR /app
|
|
410
|
+
|
|
411
|
+
# Install system dependencies
|
|
412
|
+
RUN apt-get update && apt-get install -y \\
|
|
413
|
+
gcc \\
|
|
414
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
415
|
+
|
|
416
|
+
# Copy requirements file
|
|
417
|
+
COPY requirements.txt .
|
|
418
|
+
|
|
419
|
+
# Install Python dependencies
|
|
420
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
421
|
+
|
|
422
|
+
# Copy application code
|
|
423
|
+
COPY . .
|
|
424
|
+
|
|
425
|
+
EXPOSE 8000
|
|
426
|
+
|
|
427
|
+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
428
|
+
`;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Java templates
|
|
432
|
+
function generateJavaMavenDockerfile(analysis) {
|
|
433
|
+
return `FROM maven:3.9-eclipse-temurin-17 AS builder
|
|
434
|
+
|
|
435
|
+
WORKDIR /app
|
|
436
|
+
|
|
437
|
+
# Copy pom.xml and download dependencies
|
|
438
|
+
COPY pom.xml .
|
|
439
|
+
RUN mvn dependency:go-offline
|
|
440
|
+
|
|
441
|
+
# Copy source code and build
|
|
442
|
+
COPY src ./src
|
|
443
|
+
RUN mvn clean package -DskipTests
|
|
444
|
+
|
|
445
|
+
# Runtime stage
|
|
446
|
+
FROM eclipse-temurin:17-jre-alpine
|
|
447
|
+
|
|
448
|
+
WORKDIR /app
|
|
449
|
+
|
|
450
|
+
# Copy built JAR
|
|
451
|
+
COPY --from=builder /app/target/*.jar app.jar
|
|
452
|
+
|
|
453
|
+
EXPOSE 8080
|
|
454
|
+
|
|
455
|
+
ENTRYPOINT ["java", "-jar", "app.jar"]
|
|
456
|
+
`;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function generateJavaGradleDockerfile(analysis) {
|
|
460
|
+
return `FROM gradle:7.6-jdk17 AS builder
|
|
461
|
+
|
|
462
|
+
WORKDIR /app
|
|
463
|
+
|
|
464
|
+
# Copy build files
|
|
465
|
+
COPY build.gradle* settings.gradle* ./
|
|
466
|
+
COPY gradle ./gradle
|
|
467
|
+
|
|
468
|
+
# Download dependencies
|
|
469
|
+
RUN gradle dependencies --no-daemon || true
|
|
470
|
+
|
|
471
|
+
# Copy source and build
|
|
472
|
+
COPY src ./src
|
|
473
|
+
RUN gradle build --no-daemon -x test
|
|
474
|
+
|
|
475
|
+
# Runtime stage
|
|
476
|
+
FROM eclipse-temurin:17-jre-alpine
|
|
477
|
+
|
|
478
|
+
WORKDIR /app
|
|
479
|
+
|
|
480
|
+
# Copy built JAR
|
|
481
|
+
COPY --from=builder /app/build/libs/*.jar app.jar
|
|
482
|
+
|
|
483
|
+
EXPOSE 8080
|
|
484
|
+
|
|
485
|
+
ENTRYPOINT ["java", "-jar", "app.jar"]
|
|
486
|
+
`;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Go template
|
|
490
|
+
function generateGoDockerfile(analysis) {
|
|
491
|
+
return `FROM golang:1.21-alpine AS builder
|
|
492
|
+
|
|
493
|
+
WORKDIR /app
|
|
494
|
+
|
|
495
|
+
# Copy go mod files
|
|
496
|
+
COPY go.mod go.sum ./
|
|
497
|
+
|
|
498
|
+
# Download dependencies
|
|
499
|
+
RUN go mod download
|
|
500
|
+
|
|
501
|
+
# Copy source code
|
|
502
|
+
COPY . .
|
|
503
|
+
|
|
504
|
+
# Build application
|
|
505
|
+
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
|
|
506
|
+
|
|
507
|
+
# Runtime stage
|
|
508
|
+
FROM alpine:latest
|
|
509
|
+
|
|
510
|
+
RUN apk --no-cache add ca-certificates
|
|
511
|
+
|
|
512
|
+
WORKDIR /root/
|
|
513
|
+
|
|
514
|
+
COPY --from=builder /app/app .
|
|
515
|
+
|
|
516
|
+
EXPOSE 8080
|
|
517
|
+
|
|
518
|
+
CMD ["./app"]
|
|
519
|
+
`;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Rust template
|
|
523
|
+
function generateRustDockerfile(analysis) {
|
|
524
|
+
return `FROM rust:1.75-alpine AS builder
|
|
525
|
+
|
|
526
|
+
WORKDIR /app
|
|
527
|
+
|
|
528
|
+
# Copy Cargo files
|
|
529
|
+
COPY Cargo.toml Cargo.lock ./
|
|
530
|
+
|
|
531
|
+
# Copy source code
|
|
532
|
+
COPY src ./src
|
|
533
|
+
|
|
534
|
+
# Build application
|
|
535
|
+
RUN cargo build --release
|
|
536
|
+
|
|
537
|
+
# Runtime stage
|
|
538
|
+
FROM alpine:latest
|
|
539
|
+
|
|
540
|
+
RUN apk --no-cache add ca-certificates libgcc
|
|
541
|
+
|
|
542
|
+
WORKDIR /root/
|
|
543
|
+
|
|
544
|
+
COPY --from=builder /app/target/release/* /root/app
|
|
545
|
+
|
|
546
|
+
EXPOSE 8080
|
|
547
|
+
|
|
548
|
+
CMD ["./app"]
|
|
549
|
+
`;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Ruby template
|
|
553
|
+
function generateRubyDockerfile(analysis) {
|
|
554
|
+
return `FROM ruby:3.2-alpine
|
|
555
|
+
|
|
556
|
+
WORKDIR /app
|
|
557
|
+
|
|
558
|
+
# Install system dependencies
|
|
559
|
+
RUN apk add --no-cache build-base
|
|
560
|
+
|
|
561
|
+
# Copy Gemfile
|
|
562
|
+
COPY Gemfile Gemfile.lock ./
|
|
563
|
+
|
|
564
|
+
# Install dependencies
|
|
565
|
+
RUN bundle install
|
|
566
|
+
|
|
567
|
+
# Copy application code
|
|
568
|
+
COPY . .
|
|
569
|
+
|
|
570
|
+
EXPOSE 3000
|
|
571
|
+
|
|
572
|
+
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
|
|
573
|
+
`;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// PHP template
|
|
577
|
+
function generatePHPDockerfile(analysis) {
|
|
578
|
+
return `FROM php:8.2-apache
|
|
579
|
+
|
|
580
|
+
WORKDIR /var/www/html
|
|
581
|
+
|
|
582
|
+
# Install system dependencies and PHP extensions
|
|
583
|
+
RUN apt-get update && apt-get install -y \\
|
|
584
|
+
libzip-dev \\
|
|
585
|
+
unzip \\
|
|
586
|
+
&& docker-php-ext-install zip pdo pdo_mysql \\
|
|
587
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
588
|
+
|
|
589
|
+
# Install Composer
|
|
590
|
+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
|
591
|
+
|
|
592
|
+
# Copy composer files
|
|
593
|
+
COPY composer.json composer.lock ./
|
|
594
|
+
|
|
595
|
+
# Install dependencies
|
|
596
|
+
RUN composer install --no-dev --optimize-autoloader
|
|
597
|
+
|
|
598
|
+
# Copy application code
|
|
599
|
+
COPY . .
|
|
600
|
+
|
|
601
|
+
# Set permissions
|
|
602
|
+
RUN chown -R www-data:www-data /var/www/html
|
|
603
|
+
|
|
604
|
+
EXPOSE 80
|
|
605
|
+
|
|
606
|
+
CMD ["apache2-foreground"]
|
|
607
|
+
`;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// Generic template
|
|
611
|
+
function generateGenericDockerfile(analysis) {
|
|
612
|
+
return `# Generic Dockerfile
|
|
613
|
+
# Please customize this based on your application needs
|
|
614
|
+
|
|
615
|
+
FROM alpine:latest
|
|
616
|
+
|
|
617
|
+
WORKDIR /app
|
|
618
|
+
|
|
619
|
+
# Copy application files
|
|
620
|
+
COPY . .
|
|
621
|
+
|
|
622
|
+
# Add your build and run commands here
|
|
623
|
+
# Example:
|
|
624
|
+
# RUN apk add --no-cache <your-dependencies>
|
|
625
|
+
# CMD ["./your-app"]
|
|
626
|
+
|
|
627
|
+
EXPOSE 8080
|
|
628
|
+
|
|
629
|
+
CMD ["echo", "Please customize this Dockerfile for your application"]
|
|
630
|
+
`;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
module.exports = {
|
|
634
|
+
analyzeCodebase,
|
|
635
|
+
generateDockerfile
|
|
636
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dockerme",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Automatically generate Dockerfiles by analyzing your codebase",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dockerize": "./bin/dockerize.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"docker",
|
|
14
|
+
"dockerfile",
|
|
15
|
+
"codebase",
|
|
16
|
+
"analysis",
|
|
17
|
+
"automation"
|
|
18
|
+
],
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"commander": "^11.1.0",
|
|
23
|
+
"chalk": "^4.1.2"
|
|
24
|
+
}
|
|
25
|
+
}
|