k8s-deploy-helper 0.1.1 β 1.2.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 +160 -1
- package/bin/cli.js +11 -4
- package/package.json +1 -1
- package/src/docker/buildPush.js +9 -7
- package/src/index.js +34 -13
- package/src/init/generateFiles.js +49 -0
- package/src/init/initProject.js +11 -0
- package/src/k8s/deployment.js +10 -6
- package/src/preflight/checkFiles.js +16 -0
package/README.md
CHANGED
|
@@ -1 +1,160 @@
|
|
|
1
|
-
|
|
1
|
+
k8s-deploy-helper π
|
|
2
|
+
|
|
3
|
+
k8s-deploy-helper is a simple and beginner-friendly CLI tool that helps you build Docker images and deploy applications to Kubernetes using a guided and automated workflow.
|
|
4
|
+
|
|
5
|
+
It is designed to reduce the learning curve of Kubernetes while still supporting real-world DevOps practices.
|
|
6
|
+
|
|
7
|
+
-----
|
|
8
|
+
|
|
9
|
+
PROBLEM THIS TOOL SOLVES π§©
|
|
10
|
+
|
|
11
|
+
Deploying an application to Kubernetes usually involves many manual steps:
|
|
12
|
+
|
|
13
|
+
β’ Creating and maintaining a Dockerfile
|
|
14
|
+
β’ Writing Kubernetes YAML files (Deployment, Service, etc.)
|
|
15
|
+
β’ Understanding kubectl commands
|
|
16
|
+
β’ Managing Docker registry authentication
|
|
17
|
+
β’ Debugging unclear or low-level runtime errors
|
|
18
|
+
|
|
19
|
+
For beginners and even intermediate developers, this process can be confusing, time-consuming, and error-prone.
|
|
20
|
+
|
|
21
|
+
k8s-deploy-helper removes this complexity by automating these steps and guiding the user through a clear, predictable workflow.
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
WHAT THIS TOOL DOES βοΈ
|
|
26
|
+
|
|
27
|
+
k8s-deploy-helper automates the full deployment process by:
|
|
28
|
+
|
|
29
|
+
β’ Automatically generating missing Docker and Kubernetes configuration files
|
|
30
|
+
β’ Building Docker images for your application
|
|
31
|
+
β’ Supporting local deployments without pushing images to Docker Hub
|
|
32
|
+
β’ Generating Kubernetes Deployment and Service YAML files automatically
|
|
33
|
+
β’ Applying Kubernetes resources using kubectl
|
|
34
|
+
β’ Detecting missing setup early and displaying clear, actionable error messages
|
|
35
|
+
|
|
36
|
+
You focus on building your application.
|
|
37
|
+
The tool handles the deployment.
|
|
38
|
+
|
|
39
|
+
-----
|
|
40
|
+
|
|
41
|
+
REQUIREMENTS (BEGINNER FRIENDLY) π οΈ
|
|
42
|
+
|
|
43
|
+
Minimum setup for local usage:
|
|
44
|
+
|
|
45
|
+
β’ Docker Desktop installed
|
|
46
|
+
β’ Kubernetes enabled inside Docker Desktop
|
|
47
|
+
|
|
48
|
+
Docker Desktop already includes:
|
|
49
|
+
β’ Docker
|
|
50
|
+
β’ kubectl
|
|
51
|
+
β’ A local Kubernetes cluster
|
|
52
|
+
|
|
53
|
+
To verify Kubernetes is running:
|
|
54
|
+
|
|
55
|
+
kubectl get nodes
|
|
56
|
+
|
|
57
|
+
-----
|
|
58
|
+
|
|
59
|
+
INSTALLATION π¦
|
|
60
|
+
|
|
61
|
+
Install the package globally using npm:
|
|
62
|
+
npm install -g k8s-deploy-helper
|
|
63
|
+
|
|
64
|
+
Verify the installation:
|
|
65
|
+
k8s-deploy --version
|
|
66
|
+
|
|
67
|
+
-----
|
|
68
|
+
|
|
69
|
+
HOW TO USE (STEP-BY-STEP) βΆοΈ
|
|
70
|
+
|
|
71
|
+
STEP 1: INITIALIZE THE PROJECT β
|
|
72
|
+
|
|
73
|
+
If your project does not already have a Dockerfile or k8s.config.json,
|
|
74
|
+
run:
|
|
75
|
+
k8s-deploy init
|
|
76
|
+
|
|
77
|
+
This command will:
|
|
78
|
+
β’ Create a basic Dockerfile
|
|
79
|
+
β’ Create a k8s.config.json configuration file
|
|
80
|
+
β’ Prepare your project for Kubernetes deployment
|
|
81
|
+
|
|
82
|
+
You can modify these files later to match your application needs.
|
|
83
|
+
|
|
84
|
+
STEP 2: DEPLOY LOCALLY (RECOMMENDED FOR BEGINNERS) π§ͺ
|
|
85
|
+
|
|
86
|
+
For first-time users, deploy without using Docker Hub or any container registry:
|
|
87
|
+
k8s-deploy deploy --local
|
|
88
|
+
|
|
89
|
+
What happens during local deployment:
|
|
90
|
+
β’ The Docker image is built locally
|
|
91
|
+
β’ Image push to a registry is skipped
|
|
92
|
+
β’ Kubernetes uses the local image
|
|
93
|
+
β’ The application is deployed to the local Kubernetes cluster
|
|
94
|
+
|
|
95
|
+
No Docker Hub account or login is required.
|
|
96
|
+
|
|
97
|
+
STEP 3: STANDARD DEPLOYMENT (OPTIONAL) π
|
|
98
|
+
|
|
99
|
+
Once you are comfortable and logged into a container registry,
|
|
100
|
+
run:
|
|
101
|
+
k8s-deploy deploy
|
|
102
|
+
|
|
103
|
+
This will:
|
|
104
|
+
β’ Build the Docker image
|
|
105
|
+
β’ Push the image to the configured registry
|
|
106
|
+
β’ Deploy the application to Kubernetes
|
|
107
|
+
|
|
108
|
+
-----
|
|
109
|
+
|
|
110
|
+
FILES CREATED BY THE TOOL π
|
|
111
|
+
|
|
112
|
+
After running the commands, the following files will exist in your project:
|
|
113
|
+
|
|
114
|
+
Dockerfile
|
|
115
|
+
k8s.config.json
|
|
116
|
+
deployment.yaml
|
|
117
|
+
service.yaml
|
|
118
|
+
|
|
119
|
+
These files can be:
|
|
120
|
+
β’ Reviewed
|
|
121
|
+
β’ Modified
|
|
122
|
+
β’ Committed to Git
|
|
123
|
+
β’ Used independently if needed
|
|
124
|
+
|
|
125
|
+
-----
|
|
126
|
+
|
|
127
|
+
WHAT HAPPENS INTERNALLY π
|
|
128
|
+
|
|
129
|
+
When you run the deploy command, the tool performs the following steps:
|
|
130
|
+
|
|
131
|
+
β’ Checks for required files
|
|
132
|
+
β’ Verifies Docker and Kubernetes availability
|
|
133
|
+
β’ Builds the Docker image
|
|
134
|
+
β’ Generates Kubernetes YAML files
|
|
135
|
+
β’ Applies resources using kubectl
|
|
136
|
+
|
|
137
|
+
Each step is logged clearly so you can understand what is happening.
|
|
138
|
+
|
|
139
|
+
-----
|
|
140
|
+
|
|
141
|
+
WHY THIS TOOL IS VALUABLE β
|
|
142
|
+
|
|
143
|
+
Without this tool:
|
|
144
|
+
β’ You manually write Kubernetes YAML
|
|
145
|
+
β’ You manage Docker commands yourself
|
|
146
|
+
β’ You deal with registry authentication issues
|
|
147
|
+
β’ Kubernetes feels complex and fragile
|
|
148
|
+
|
|
149
|
+
With this tool:
|
|
150
|
+
β’ One-command deployment
|
|
151
|
+
β’ Beginner-safe defaults
|
|
152
|
+
β’ Hands-on Kubernetes experience
|
|
153
|
+
β’ Production-ready deployment workflow
|
|
154
|
+
|
|
155
|
+
-----
|
|
156
|
+
|
|
157
|
+
AUTHOR π¨βπ»
|
|
158
|
+
|
|
159
|
+
Lokesh Shimpi
|
|
160
|
+
Built to simplify Kubernetes deployment and demonstrate real-world DevOps engineering.
|
package/bin/cli.js
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { runDeploy } from '../src/index.js';
|
|
4
|
+
import { initProject } from '../src/init/initProject.js';
|
|
4
5
|
|
|
5
6
|
const program = new Command();
|
|
6
7
|
|
|
7
8
|
program
|
|
8
9
|
.name('k8s-deploy')
|
|
9
10
|
.description('Build and deploy apps to Kubernetes')
|
|
10
|
-
.version('0.
|
|
11
|
+
.version('0.3.0');
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.command('init')
|
|
15
|
+
.description('Initialize Dockerfile and k8s.config.json')
|
|
16
|
+
.action(initProject);
|
|
11
17
|
|
|
12
18
|
program
|
|
13
19
|
.command('deploy')
|
|
14
|
-
.description('Build
|
|
20
|
+
.description('Build and deploy app to Kubernetes')
|
|
15
21
|
.option('-c, --config <path>', 'Config file path', 'k8s.config.json')
|
|
22
|
+
.option('--local', 'Deploy using local Docker image (skip push)')
|
|
16
23
|
.action(runDeploy);
|
|
17
24
|
|
|
18
|
-
program.parse();
|
|
25
|
+
program.parse(process.argv);
|
package/package.json
CHANGED
package/src/docker/buildPush.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { execa } from 'execa';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
|
|
4
|
-
export async function buildAndPushImage(config) {
|
|
4
|
+
export async function buildAndPushImage(config, isLocal) {
|
|
5
5
|
const { image, tag, context, dockerfile } = config.docker;
|
|
6
|
-
|
|
6
|
+
const fullImageName = `${image}:${tag}`;
|
|
7
7
|
const dockerfilePath = dockerfile || 'Dockerfile';
|
|
8
8
|
|
|
9
9
|
if (!fs.existsSync(dockerfilePath)) {
|
|
10
|
-
throw new Error(`Dockerfile not found at
|
|
10
|
+
throw new Error(`Dockerfile not found at ${dockerfilePath}`);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
console.log(`\nπ³ Building Docker image: ${fullImageName}`);
|
|
13
|
+
console.log(`π³ Building Docker image: ${fullImageName}`);
|
|
16
14
|
|
|
17
15
|
await execa(
|
|
18
16
|
'docker',
|
|
@@ -20,8 +18,12 @@ export async function buildAndPushImage(config) {
|
|
|
20
18
|
{ stdio: 'inherit' }
|
|
21
19
|
);
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
if (isLocal) {
|
|
22
|
+
console.log('π¦ Local mode enabled β skipping image push');
|
|
23
|
+
return fullImageName;
|
|
24
|
+
}
|
|
24
25
|
|
|
26
|
+
console.log(`π€ Pushing Docker image: ${fullImageName}`);
|
|
25
27
|
await execa('docker', ['push', fullImageName], { stdio: 'inherit' });
|
|
26
28
|
|
|
27
29
|
return fullImageName;
|
package/src/index.js
CHANGED
|
@@ -1,27 +1,48 @@
|
|
|
1
1
|
import { loadConfig } from './config/loadConfig.js';
|
|
2
2
|
import { validateConfig } from './config/validateConfig.js';
|
|
3
|
+
|
|
4
|
+
import { checkRequiredFiles } from './preflight/checkFiles.js';
|
|
5
|
+
import { checkEnvironment } from './preflight/checkEnvironment.js';
|
|
6
|
+
|
|
3
7
|
import { buildAndPushImage } from './docker/buildPush.js';
|
|
8
|
+
|
|
4
9
|
import { generateDeployment } from './k8s/deployment.js';
|
|
5
10
|
import { generateService } from './k8s/service.js';
|
|
6
11
|
import { applyKubernetes } from './k8s/apply.js';
|
|
7
12
|
|
|
8
13
|
export async function runDeploy(options) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
try {
|
|
15
|
+
console.log('π Checking required files...');
|
|
16
|
+
checkRequiredFiles();
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
console.log('π Checking environment...');
|
|
19
|
+
await checkEnvironment();
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
const configPath = options.config || 'k8s.config.json';
|
|
22
|
+
const isLocal = options.local === true;
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
console.log('π Loading configuration...');
|
|
25
|
+
const config = loadConfig(configPath);
|
|
26
|
+
validateConfig(config);
|
|
27
|
+
|
|
28
|
+
console.log(`π Deploying application: ${config.appName}`);
|
|
29
|
+
if (isLocal) {
|
|
30
|
+
console.log('π¦ Local mode enabled (image push will be skipped)');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const image = await buildAndPushImage(config, isLocal);
|
|
22
34
|
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
console.log('π Generating Kubernetes manifests...');
|
|
36
|
+
generateDeployment(config, image, isLocal);
|
|
37
|
+
generateService(config);
|
|
25
38
|
|
|
26
|
-
|
|
39
|
+
console.log('βΈοΈ Applying resources to Kubernetes...');
|
|
40
|
+
await applyKubernetes(config);
|
|
41
|
+
|
|
42
|
+
console.log('\nβ
Deployment completed successfully');
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.error('\nβ Deployment failed');
|
|
45
|
+
console.error(err.message || err);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
27
48
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
export function generateDockerfile() {
|
|
4
|
+
if (fs.existsSync('Dockerfile')) return;
|
|
5
|
+
|
|
6
|
+
const dockerfile = `
|
|
7
|
+
FROM node:18-alpine
|
|
8
|
+
WORKDIR /app
|
|
9
|
+
COPY server/package*.json ./
|
|
10
|
+
RUN npm install
|
|
11
|
+
COPY server .
|
|
12
|
+
EXPOSE 5000
|
|
13
|
+
CMD ["npm", "start"]
|
|
14
|
+
`.trim();
|
|
15
|
+
|
|
16
|
+
fs.writeFileSync('Dockerfile', dockerfile);
|
|
17
|
+
console.log('β
Dockerfile created');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function generateK8sConfig() {
|
|
21
|
+
if (fs.existsSync('k8s.config.json')) return;
|
|
22
|
+
|
|
23
|
+
const config = {
|
|
24
|
+
appName: 'my-app',
|
|
25
|
+
namespace: 'default',
|
|
26
|
+
docker: {
|
|
27
|
+
image: 'your-docker-username/my-app',
|
|
28
|
+
tag: 'latest',
|
|
29
|
+
context: '.',
|
|
30
|
+
dockerfile: 'Dockerfile'
|
|
31
|
+
},
|
|
32
|
+
kubernetes: {
|
|
33
|
+
replicas: 1,
|
|
34
|
+
containerPort: 5000,
|
|
35
|
+
servicePort: 80,
|
|
36
|
+
serviceType: 'ClusterIP'
|
|
37
|
+
},
|
|
38
|
+
env: {
|
|
39
|
+
NODE_ENV: 'production'
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
fs.writeFileSync(
|
|
44
|
+
'k8s.config.json',
|
|
45
|
+
JSON.stringify(config, null, 2)
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
console.log('β
k8s.config.json created');
|
|
49
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { generateDockerfile, generateK8sConfig } from './generateFiles.js';
|
|
2
|
+
|
|
3
|
+
export function initProject() {
|
|
4
|
+
console.log('π§ Initializing project for Kubernetes deployment...\n');
|
|
5
|
+
|
|
6
|
+
generateDockerfile();
|
|
7
|
+
generateK8sConfig();
|
|
8
|
+
|
|
9
|
+
console.log('\nπ Initialization complete');
|
|
10
|
+
console.log('π Update k8s.config.json with your Docker username');
|
|
11
|
+
}
|
package/src/k8s/deployment.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import yaml from 'js-yaml';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
|
|
4
|
-
export function generateDeployment(config, image) {
|
|
4
|
+
export function generateDeployment(config, image, isLocal = false) {
|
|
5
5
|
const deployment = {
|
|
6
6
|
apiVersion: 'apps/v1',
|
|
7
7
|
kind: 'Deployment',
|
|
@@ -10,7 +10,7 @@ export function generateDeployment(config, image) {
|
|
|
10
10
|
namespace: config.namespace || 'default'
|
|
11
11
|
},
|
|
12
12
|
spec: {
|
|
13
|
-
replicas: config.kubernetes.replicas,
|
|
13
|
+
replicas: config.kubernetes.replicas || 1,
|
|
14
14
|
selector: {
|
|
15
15
|
matchLabels: {
|
|
16
16
|
app: config.appName
|
|
@@ -27,15 +27,19 @@ export function generateDeployment(config, image) {
|
|
|
27
27
|
{
|
|
28
28
|
name: config.appName,
|
|
29
29
|
image,
|
|
30
|
+
imagePullPolicy: isLocal ? 'IfNotPresent' : 'Always',
|
|
30
31
|
ports: [
|
|
31
32
|
{
|
|
32
33
|
containerPort: config.kubernetes.containerPort
|
|
33
34
|
}
|
|
34
35
|
],
|
|
35
36
|
env: Object.entries(config.env || {}).map(
|
|
36
|
-
([key, value]) => ({
|
|
37
|
+
([key, value]) => ({
|
|
38
|
+
name: key,
|
|
39
|
+
value: String(value)
|
|
40
|
+
})
|
|
37
41
|
),
|
|
38
|
-
resources: config.resources
|
|
42
|
+
resources: config.resources || undefined
|
|
39
43
|
}
|
|
40
44
|
]
|
|
41
45
|
}
|
|
@@ -43,8 +47,8 @@ export function generateDeployment(config, image) {
|
|
|
43
47
|
}
|
|
44
48
|
};
|
|
45
49
|
|
|
46
|
-
const yamlContent = yaml.dump(deployment);
|
|
50
|
+
const yamlContent = yaml.dump(deployment, { noRefs: true });
|
|
47
51
|
fs.writeFileSync('deployment.yaml', yamlContent);
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
console.log('π deployment.yaml generated');
|
|
50
54
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
export function checkRequiredFiles() {
|
|
4
|
+
const missing = [];
|
|
5
|
+
|
|
6
|
+
if (!fs.existsSync('Dockerfile')) missing.push('Dockerfile');
|
|
7
|
+
if (!fs.existsSync('k8s.config.json')) missing.push('k8s.config.json');
|
|
8
|
+
|
|
9
|
+
if (missing.length) {
|
|
10
|
+
console.error('\nβ Missing required files:');
|
|
11
|
+
missing.forEach(f => console.error(` - ${f}`));
|
|
12
|
+
|
|
13
|
+
console.error('\nπ Run: k8s-deploy init');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
}
|