diff --git a/Dockerfile b/Dockerfile index 53651de..340d1e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,18 @@ -FROM node:6.10.3 +FROM node:18-alpine -# Create app directory -RUN mkdir -p /usr/src/app WORKDIR /usr/src/app -# Install app dependencies -COPY package.json /usr/src/app/ +# Copy package.json and package-lock.json first for caching +COPY package*.json ./ + +# Install dependencies (including dev if you need nodemon in container) RUN npm install -# Bundle app source -COPY . /usr/src/app +# Copy application source code +COPY . . +# Expose the application port EXPOSE 9000 -CMD [ "npm", "start" ] -#helo + +# Start the app +CMD ["npm", "start"] diff --git a/README.md b/README.md index eb17994..e2f5ab0 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,4 @@ hello + Jenkins diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..cc7873e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3.8' + +services: + app: + build: + context: . + dockerfile: Dockerfile + image: sample-node-app:latest + container_name: sample-node-app + ports: + - "9000:9000" + env_file: + - .env + restart: unless-stopped diff --git a/index.js b/index.js index 7a7c29c..afa90a2 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,15 @@ const express = require('express'); +require('dotenv').config(); // ๐Ÿ‘ˆ Load env variables + const app = express(); -const port = 9000; +const port = process.env.PORT || 9000; +const message = process.env.CUSTOM_MESSAGE || 'Hello World!'; + app.get('/', (req, res) => { - res.send('

Hello World from Docker and Node.js!

'); + res.send(`

${message}

`); }); -app.listen(port, () => { - console.log(`Listening on port ${port}`); + +app.listen(port, '0.0.0.0', () => { + console.log(`๐Ÿš€ Server running on port ${port}`); }); + diff --git a/jenkins b/jenkins new file mode 100644 index 0000000..ed09374 --- /dev/null +++ b/jenkins @@ -0,0 +1,117 @@ +pipeline { + agent none + + environment { + AWS_ACCOUNT_ID = '951042686423' + AWS_REGION = 'ap-south-1' + REPO_NAME = 'sample-node-app' + IMAGE_TAG = 'latest' + ECR_REGISTRY = "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" + IMAGE_URI = "${ECR_REGISTRY}/${REPO_NAME}:${IMAGE_TAG}" + GIT_REPO = 'https://github.com/MANIKANDAN242221/sample-node-app.git' + AWS_CREDENTIALS_ID = 'aws-jenkins-creds' + } + + stages { + stage('Clone Repository') { + agent { label 'master' } + steps { + git url: "${GIT_REPO}", branch: 'main' + } + } + + stage('Ensure .env File') { + agent { label 'master' } + steps { + sh ''' + echo "PORT=9000" > .env + echo "NODE_ENV=production" >> .env + echo "CUSTOM_MESSAGE=Hello from Jenkins pipeline" >> .env + ''' + } + } + + stage('Install Dependencies & Build UI') { + agent { label 'master' } + steps { + sh ''' + echo "๐Ÿ“ฆ Installing Node.js dependencies..." + npm install + + echo "๐Ÿ—๏ธ Building frontend..." + npm run build + ''' + } + } + + stage('Build Docker Image') { + agent { label 'master' } + steps { + sh ''' + echo "๐Ÿ—‘๏ธ Removing old Docker image..." + docker rmi -f ${REPO_NAME}:latest || true + + echo "๐Ÿณ Building new Docker image..." + docker-compose build --no-cache + ''' + } + } + + stage('Tag Image for ECR') { + agent { label 'master' } + steps { + sh "docker tag ${REPO_NAME}:latest ${IMAGE_URI}" + } + } + + stage('Login to ECR') { + agent { label 'master' } + steps { + withCredentials([ + usernamePassword( + credentialsId: "${AWS_CREDENTIALS_ID}", + usernameVariable: 'AWS_ACCESS_KEY_ID', + passwordVariable: 'AWS_SECRET_ACCESS_KEY' + ) + ]) { + sh ''' + aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID + aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY + aws configure set default.region ${AWS_REGION} + aws ecr get-login-password --region ${AWS_REGION} \ + | docker login --username AWS --password-stdin ${ECR_REGISTRY} + ''' + } + } + } + + stage('Push Image to ECR') { + agent { label 'master' } + steps { + sh "docker push ${IMAGE_URI}" + } + } + + stage('Deploy Container on Agent') { + agent { label 'agent' } + steps { + sh ''' + docker-compose down || true + docker-compose up -d + ''' + } + } + } + + post { + always { + echo '๐Ÿงน Cleaning up...' + } + success { + echo 'โœ… Pipeline executed successfully!' + } + failure { + echo 'โŒ Pipeline failed!' + } + } +} diff --git a/node-app/deployment.yaml b/node-app/deployment.yaml index e0ee286..1322cbe 100644 --- a/node-app/deployment.yaml +++ b/node-app/deployment.yaml @@ -14,7 +14,7 @@ spec: spec: containers: - name: node-app - image: arunmagi/node-app + image: techdocker24/node-app ports: - containerPort: 9000 --- diff --git a/package.json b/package.json index a114d3f..1edd8ba 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,20 @@ { "name": "docker-node-example", "version": "1.0.0", + "description": "Sample Node.js Express app for Docker & Jenkins", "main": "index.js", "scripts": { - "start": "nodemon index.js" + "start": "node index.js", + "dev": "nodemon index.js", + "build": "echo 'No build step needed for backend API'" }, "dependencies": { - "express": "^4.15.3", - "nodemon": "^1.11.0" - } + "express": "^4.18.2", + "dotenv": "^16.0.0" + }, + "devDependencies": { + "nodemon": "^3.0.2" + }, + "author": "", + "license": "ISC" }