Chattingo Mini Hackathon Application Deployment

π Introduction
Hackathons are not just about coding β theyβre about solving problems quickly, learning new tools, and delivering something production-ready. In the Chattingo Mini Hackathon, my mission was to take a vanilla full-stack chat app (React + Spring Boot + MySQL + WebSocket) and make it production-ready with Docker, Nginx, SSL, Security Sacnning and a Jenkins CI/CD pipeline on a VPS.
Hereβs my journey β step by step.
π₯οΈ Step 1: VPS Setup
We got access to a Hostinger VPS with Ubuntu. The very first step was creating a Hostinger account and purchasing the server. However, through the community, we received a coupon code that allowed us to get the server free for one month. After that, we generated the SSH keys, added them to the console, and then connected to the server via SSH. Finally, we updated the server.


ssh -i ubuntu-vps root@srv996876.hstgr.cloud
sudo apt update && sudo apt upgrade -y

Next, I generated SSH keys, added them to the Hostinger console, and connected to the server via SSH. Once inside, I updated the system and installed some essential tools:
Docker & Docker Compose β For containerization
net-tools, zip β For debugging and utilities
Trivy β For vulnerability scanning
With these basics in place, the VPS was ready for further setup and deployments.
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install net-tools and zip
sudo apt install -y net-tools zip curl git apt-transport-https ca-certificates software-properties-common
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add current user to docker group (so you donβt need sudo for docker commands)
sudo usermod -aG docker $USER
newgrp docker
# Install Docker Compose (latest release)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Verify installation
docker --version
docker-compose --version
# Install Trivy
sudo apt install -y wget
wget https://github.com/aquasecurity/trivy/releases/latest/download/trivy_0.55.0_Linux-64bit.deb
sudo dpkg -i trivy_0.55.0_Linux-64bit.deb
# Verify Trivy
trivy --version
π οΈ Step 2: Cloning & Running the Application
After preparing the VPS, I cloned the Chattingo repository:
git clone <repo_url>
cd chattingo
Then I spin up the core stack with containers:
MySQL on port
3306Backend on port
8080Frontend on port
3000
I first updated the .env files in frontend and backend to store sensitive configs like DB credentials and API URLs. Example:
π₯οΈ Frontend (frontend/.env.example) make sure these are not the real update according to it
# API Configuration
REACT_APP_API_URL=http://localhost:8080
# For production deployment
# REACT_APP_API_URL=https://your-domain.com
# Optional: Analytics and monitoring
# REACT_APP_GOOGLE_ANALYTICS_ID=your-ga-id
# REACT_APP_SENTRY_DSN=your-sentry-dsn
βοΈ Backend (backend/.env.example)
# JWT Configuration
JWT_SECRET=sdd4OUI3mQs/ANIdg5s1hs1jTjNr/2c8J+BSDGHkP7AQ+123sdYGY9XmdYOwao0S1YRzGSuyNzpx05/x4biWKQ==
# Database Configuration
SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/chattingo_db?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME=root
SPRING_DATASOURCE_PASSWORD=securerootpassword123456789
# CORS Configuration
CORS_ALLOWED_ORIGINS=http://65.2.166.204, http://localhost:3000, http://localhost, http://mini.awscloudshop.online, https://mini.awscloudshop.online
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS
CORS_ALLOWED_HEADERS=*
# Application Configuration
SPRING_PROFILES_ACTIVE=development
SERVER_PORT=8080
# Production Database (for Docker/VPS deployment)
MYSQL_ROOT_PASSWORD=securerootpassword123456789
MYSQL_DATABASE=chattingo_db
MYSQL_USER=chattingo
MYSQL_PASSWORD=chatpassworddd123456789
use this command to generate JWT_SECRET
openssl rand -base64 64
π In your repo, you can commit only .env.example files (never the actual .env with real secrets). Developers or DevOps engineers can copy them:
cp frontend/.env.example frontend/.env
cp backend/.env.example backend/.env
Then update values as needed for local development or production deployment.
Then we create Dockerfile for frontend react
# Stage 1: Node.js build environment
FROM node:18-alpine AS build-env
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production
# Stage 2: Build React application
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 3: Lightweight runtime with built files
FROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=build /app/build ./build
RUN npm install -g serve
EXPOSE 3000
CMD ["serve", "-s", "build", "-l", "3000"]
After that we create backend spring boot Dockerfile
# Stage 1: Maven build environment
FROM maven:3.9.6-eclipse-temurin-17 AS build-env
WORKDIR /app
COPY pom.xml ./
RUN mvn dependency:go-offline
# Stage 2: Build Spring Boot application
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml ./
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 3: JRE runtime
FROM eclipse-temurin:17-jre-alpine AS runtime
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
Wrote a docker-compose.yml file to orchestrate everything.
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root passowrd
MYSQL_DATABASE: chattingo_db
MYSQL_USER: username
MYSQL_PASSWORD: userpassword
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- chattingo-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
backend:
build: ./backend
env_file:
- ./backend/.env
depends_on:
mysql:
condition: service_healthy
ports:
- "8080:8080"
networks:
- chattingo-network
restart: unless-stopped
frontend:
build: ./frontend
env_file:
- ./frontend/.env
ports:
- "3000:3000"
networks:
- chattingo-network
restart: unless-stopped
volumes:
mysql_data:
networks:
chattingo-network:
driver: bridge
π Step 3: Nginx & SSL Setup
To expose the application to the world:
Installed Nginx as a reverse proxy.
Created a virtual host for my domain.
Secured it with Letβs Encrypt SSL (
certbot).
Got it π You want a single command panel (copyβpaste friendly) to install Certbot, configure Nginx, and enable SSL.
Hereβs a ready-to-use script you can run on your Ubuntu VPS (just replace chattingo.example.com with your domain):
# Update system and install Certbot with Nginx plugin
sudo apt update && sudo apt install -y nginx certbot python3-certbot-nginx
# Create Nginx config for your domain (replace chattingo.example.com with your domain)
sudo bash -c 'cat > /etc/nginx/sites-available/chattingo <<EOF
# HTTP server only
server {
listen 80;
server_name mini.awscloudshop.online;
# Block access to hidden files
location ~ /\.(?!well-known) {
deny all;
}
# Frontend
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
# Backend API
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
EOF'
# Enable site and test Nginx config
sudo ln -s /etc/nginx/sites-available/chattingo /etc/nginx/sites-enabled/ || true
sudo nginx -t && sudo systemctl reload nginx
# Obtain and install SSL certificate with Certbot
sudo certbot --nginx -d chattingo.example.com --non-interactive --agree-tos -m your-email@example.com
# Test auto-renewal
sudo certbot renew --dry-run
β This will serve only HTTP (port 80) with reverse proxying to:
Frontend β 3000
Backend API/Auth/WebSocket β 8080
π Step 5: Debugging API & Proxy Issues
Initially, API requests werenβt working in the browser.
The problem? Nginx needed proper proxy routes:
/apiβ backend:8080/authβ backend:8080/wsβ backend WebSocket
After adjusting the nginx.conf, login/signup and chat APIs started working.
#add in nginx configuratiom
# Auth endpoints
location /auth/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
# WebSocket endpoints
location /ws/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 86400;
}
Now update the .env for both frontend and backend after proxy and nginx virtual hosting.
π₯οΈ Frontend (frontend/.env.example) make sure these are not the real update according to it
# API Configuration
#REACT_APP_API_URL=http://localhost:8080
# For production deployment
REACT_APP_API_URL=https://your-domain.com
# Optional: Analytics and monitoring
# REACT_APP_GOOGLE_ANALYTICS_ID=your-ga-id
# REACT_APP_SENTRY_DSN=your-sentry-dsn
βοΈ Backend (backend/.env.example)
# JWT Configuration
JWT_SECRET=sdd4OUI3mQs/ANIdg5s1hs1jTjNr/2c8J+BSDGHkP7AQ+123sdYGY9XmdYOwao0S1YRzGSuyNzpx05/x4biWKQ==
# Database Configuration
SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/chattingo_db?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME=root
SPRING_DATASOURCE_PASSWORD=securerootpassword123456789
# CORS Configuration
CORS_ALLOWED_ORIGINS=https://your-domain.com
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS
CORS_ALLOWED_HEADERS=*
# Application Configuration
SPRING_PROFILES_ACTIVE=development
SERVER_PORT=8080
# Production Database (for Docker/VPS deployment)
MYSQL_ROOT_PASSWORD=securerootpassword123456789
MYSQL_DATABASE=chattingo_db
MYSQL_USER=chattingo
MYSQL_PASSWORD=chatpassworddd123456789
π Step 6: Code Fixes
During testing, we noticed two major issues:
JWT Authentication Bug β Tokens were not being validated correctly.
Signup Flow Issue β The frontend went blank (white screen) after submitting the signup form.
We patched the code in both backend and frontend to fix these problems.
After making the changes, we rebuilt and restarted the containers:
docker compose build
docker compose up -d
β With these fixes, the application finally worked end-to-end β from signup/login with JWT authentication to smooth navigation in the frontend.
π Secure Access Setup: IAM User + S3 Bucket Policies Done Right
We created a new IAM user with a custom inline policy. After that, we set up an S3 bucket, updated the inline policy to grant access, and then updated the bucket policy accordingly.

generate access keys and secret access keys.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::chattingo-app"
},
{
"Sid": "AllowReadWriteObjects",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::chattingo-app/*"
}
]
}
bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowJenkinsUserAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::980921730778:user/chattingo-app-user"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::chattingo-app/jenkins-chattingo-app-scanning/*"
}
]
}
π οΈ Step 7: Jenkins Setup
To streamline builds and deployments, we installed Jenkins on the same VPS and integrated it with our stack.
1οΈβ£ Install Jenkins
# Update packages and install dependencies
sudo apt update && sudo apt upgrade -y
sudo apt install -y openjdk-17-jdk wget gnupg2 apt-transport-https unzip
# Add Jenkins repo and key
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
# Install Jenkins
sudo apt update
sudo apt install -y jenkins
sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins
Since our backend already runs on 8080, we changed Jenkins to port 8000:
sudo nano /etc/default/jenkins
change port 8080 to 8000
HTTP_PORT=8000
sudo systemctl restart jenkins
#Get the initial admin password:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Login with the password, then install Suggested Plugins.
Git Plugin
Pipeline Plugin
Docker Plugin
Credentials Binding Plugin
Blue Ocean (optional for UI)






Configure Secrets
Go to Manage Jenkins β Credentials β System β Global credentials and add:
GitHub Access Token
DockerHub Username/Password
Any other API keys (if needed)

Create a Pipeline Job:
Example Jenkinsfile for your project:
In the given pipeline, if AWS_CREDENTIALS are not created, the pipeline will fail. After the filesystem and Docker image scans are completed, the results are uploaded to an S3 bucket, and pre-signed URLs are generated to access the vulnerability reports.
After Jenkisns file we have provided aws part below.
NOTE:
Make sure that when the code comes into /var/lib/jenkins/workspace/chattingo-pipeline/, the .env files inside both frontend and backend are updated.
pipeline {
agent any
environment {
DOCKER_HUB_CREDENTIALS = credentials('docker-hub-credentials')
AWS_CREDENTIALS = credentials('aws-cred')
REGISTRY = "chattingo-app"
IMAGE_TAG = "${BUILD_NUMBER}"
AWS_DEFAULT_REGION = "ap-south-1"
S3_BUCKET = "chattingo-app"
}
stages {
stage('Git Clone') {
steps {
git branch: 'mini-hackathon', url: 'https://github.com/dushyantkumark/chattingo.git'
}
}
stage('Image Build') {
steps {
sh """
docker build -t ${REGISTRY}/frontend:${IMAGE_TAG} ./frontend
docker build -t ${REGISTRY}/backend:${IMAGE_TAG} ./backend
"""
}
}
stage('Filesystem Scan') {
steps {
sh """
echo "Starting filesystem security scan..." > filesystem-scan-results.txt
trivy fs . >> filesystem-scan-results.txt 2>&1
echo "Filesystem scan completed at \$(date)" >> filesystem-scan-results.txt
"""
}
}
stage('Image Scan') {
steps {
sh """
echo "Starting Docker image security scan..." > docker-scan-results.txt
echo "Scanning frontend image..." >> docker-scan-results.txt
trivy image ${REGISTRY}/frontend:${IMAGE_TAG} >> docker-scan-results.txt 2>&1
echo "Scanning backend image..." >> docker-scan-results.txt
trivy image ${REGISTRY}/backend:${IMAGE_TAG} >> docker-scan-results.txt 2>&1
echo "Docker image scan completed at \$(date)" >> docker-scan-results.txt
"""
}
}
stage('Upload Scans to S3') {
steps {
script {
def timestamp = new Date().format("yyyy-MM-dd-HH-mm-ss")
withCredentials([[
$class: 'AmazonWebServicesCredentialsBinding',
credentialsId: 'aws-cred'
]]) {
sh """
docker run --rm \
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
-e AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION} \
-v \$(pwd):/workspace \
amazon/aws-cli s3 cp /workspace/filesystem-scan-results.txt s3://${S3_BUCKET}/jenkins-chattingo-app-scanning/filesystem-scan-${timestamp}.txt
docker run --rm \
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
-e AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION} \
-v \$(pwd):/workspace \
amazon/aws-cli s3 cp /workspace/docker-scan-results.txt s3://${S3_BUCKET}/jenkins-chattingo-app-scanning/docker-scan-${timestamp}.txt
"""
def filesystemUrl = sh(
script: """docker run --rm \
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
-e AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION} \
amazon/aws-cli s3 presign s3://${S3_BUCKET}/jenkins-chattingo-app-scanning/filesystem-scan-${timestamp}.txt --expires-in 300""",
returnStdout: true
).trim()
def dockerUrl = sh(
script: """docker run --rm \
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
-e AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION} \
amazon/aws-cli s3 presign s3://${S3_BUCKET}/jenkins-chattingo-app-scanning/docker-scan-${timestamp}.txt --expires-in 300""",
returnStdout: true
).trim()
echo "=== SCAN RESULTS URLS (Valid for 5 minutes) ==="
echo "Filesystem Scan: ${filesystemUrl}"
echo "Docker Scan: ${dockerUrl}"
writeFile file: 'scan-urls.txt', text: """Filesystem Scan: ${filesystemUrl}
Docker Scan: ${dockerUrl}
Generated: ${new Date()}
Expires: 5 minutes"""
}
}
}
}
stage('Push to Registry') {
steps {
script {
docker.withRegistry('https://index.docker.io/v1/', 'docker-hub-credentials') {
sh """
docker push ${REGISTRY}/frontend:${IMAGE_TAG}
docker push ${REGISTRY}/backend:${IMAGE_TAG}
"""
}
}
}
}
stage('Update Compose') {
steps {
sh """
sed -i 's|image: ${REGISTRY}/frontend:.*|image: ${REGISTRY}/frontend:${IMAGE_TAG}|g' docker-compose.yml
sed -i 's|image: ${REGISTRY}/backend:.*|image: ${REGISTRY}/backend:${IMAGE_TAG}|g' docker-compose.yml
"""
}
}
stage('Deploy') {
steps {
sh """
cd /home/ubuntu/mini/chattingo
docker-compose pull
docker-compose up -d
"""
}
}
}
post {
always {
archiveArtifacts artifacts: 'filesystem-scan-results.txt,docker-scan-results.txt,scan-urls.txt', allowEmptyArchive: true
sh 'docker system prune -f'
}
}
}
After Jenkins file creation completed now itβs time to test the jenkins file, we get multiple issues then finall our pipeline run successfully, above jenkinsfile work correctly.


Our docker containers are up and running.

Now we have implement virtual hosting and ssl for jenkins.
If you want to remove SSL parts and let Certbot handle it automatically, you should start with a plain HTTP config first. make sure use your domain.
# Navigate to Nginx sites-enabled directory
cd /etc/nginx/sites-enabled
# Create symbolic link (enable site)
sudo ln -s /etc/nginx/sites-available/jenkins.your-domain.com jenkins.your-domain.com
# Test Nginx configuration
sudo nginx -t
# Reload Nginx to apply changes
sudo systemctl reload nginx
server {
listen 80;
server_name jenkins.awscloudshop.online;
location / {
proxy_pass http://127.0.0.1:8000; # Jenkins is running here
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Steps to Apply SSL via Certbot
# Test your nginx config before reload
sudo nginx -t
sudo systemctl reload nginx
# Run certbot for your domain
sudo certbot --nginx -d jenkins.your-domain.com
β‘Step 8: Application Testing
Now we are creating user through UI. Click on sigh up button.

Create new user in the UI. User created successfully

Now login through john user from the UI.


π¦ Step 9: Jenkins Shared Library
To make our Jenkins pipelines cleaner and reusable, we created a separate GitHub repository for a Jenkins Shared Library. This allows us to store common functions, scripts, and pipeline steps in one place and call them from multiple pipelines.
Steps we followed:
Created a GitHub repo specifically for shared pipeline code.
Configured the library in Jenkins under Manage Jenkins β Global Pipeline Libraries.
Updated the Jenkinsfile to use shared functions instead of repeating code.
For shared library :
Manage Jenkins β Configure System β Global Pipeline Libraries
Click Add
Name:
my-shared-libraryDefault Version:
main(or branch name)Retrieval Method:
Modern SCMβGitProject Repository:
https://github.com/your-org/your-library.gitCredentials: (if private repo)
Save configuration


Now updated Jenkinsfile
@Library('jenkins-shared-library') _
pipeline {
agent any
environment {
DOCKER_HUB_CREDENTIALS = credentials('docker-hub-credentials')
AWS_CREDENTIALS = credentials('aws-cred')
FRONTEND_REPO = credentials('frontend-repo')
BACKEND_REPO = credentials('backend-repo')
IMAGE_TAG = "${BUILD_NUMBER}"
AWS_DEFAULT_REGION = credentials('my-region')
S3_BUCKET = credentials('bucket')
}
stages {
stage('Git Clone') {
steps {
git branch: 'mini-hackathon', url: 'https://github.com/dushyantkumark/chattingo.git'
}
}
stage('Build Images') {
steps {
script {
buildImages([
frontendRepo: env.FRONTEND_REPO,
backendRepo: env.BACKEND_REPO,
imageTag: env.IMAGE_TAG
])
}
}
}
stage('Scan Filesystem') {
steps {
script {
scanFilesystem()
}
}
}
stage('Scan Images') {
steps {
script {
scanImages([
frontendRepo: env.FRONTEND_REPO,
backendRepo: env.BACKEND_REPO,
imageTag: env.IMAGE_TAG
])
}
}
}
stage('Upload Scans to S3') {
steps {
script {
uploadScansToS3([
awsCredentialsId: 'aws-cred',
awsRegion: env.AWS_DEFAULT_REGION,
s3Bucket: env.S3_BUCKET
])
}
}
}
stage('Push Images') {
steps {
script {
pushImages([
frontendRepo: env.FRONTEND_REPO,
backendRepo: env.BACKEND_REPO,
imageTag: env.IMAGE_TAG,
dockerCredentialsId: 'docker-hub-credentials'
])
}
}
}
stage('Update Compose') {
steps {
script {
updateCompose([
frontendRepo: env.FRONTEND_REPO,
backendRepo: env.BACKEND_REPO,
imageTag: env.IMAGE_TAG
])
}
}
}
stage('Deploy Application') {
steps {
script {
deployApp([
deploymentPath: '/home/ubuntu/mini/chattingo/'
])
}
}
}
}
post {
always {
script {
cleanupResources([
imageTag: env.IMAGE_TAG
])
}
}
}
}
Below are the docker hub repository for both frontend and backend.


Now after configuring the jenkins shared library part letβs check our pipeline ui.

At the top we can check our vulnerablity files also we can check at presigned urls, image are shown below.
First one is the file-scan-report.

First one is the frontend-scan-report.

First one is the backend-scan-report.

Same files are available in s3 bucket.

We have created multiple users in the chattingo application, now start chatting with multiple users.
Chatting between naman and amar.


π Verify MySQL Data Inside Container
After running the application and registering users, you can check if data is being saved in the MySQL database.

Follow below commands:
# Step 1: Access MySQL container
docker exec -it <mysql_container_name> /bin/sh
# Step 2: Login into MySQL
mysql -u root -p
# Step 3: Inside MySQL shell - run the following commands
SHOW DATABASES;
USE chattingo;
SHOW TABLES;
SELECT * FROM user;
SELECT * FROM message;




π Results
After completing all the iterations and setup steps, we achieved the following milestones:
Live Chat App Deployment:
The Chattingo application is fully live and accessible at mini.awscloudshop.online. Both the frontend and backend are running in Docker containers, orchestrated viadocker-compose.Secure Jenkins CI/CD Pipeline:
Jenkins is set up on jenkins.cloudshop.online with SSL, reverse proxy, and a shared library for reusable pipeline steps. Automated builds, Trivy security scans, Docker image pushes, and deployment updates are all integrated into a single workflow.Automated Builds, Scans, and Deployments:
Every commit triggers a pipeline that:Clones the repo
Builds frontend and backend Docker images
Runs filesystem and Docker image security scans using Trivy
Pushes Docker images to the registry
Updates
docker-compose.ymlDeploys the updated stack to the VPS
Pre-signed URLs for scan reports are automatically generated for secure access.
Hands-on DevOps Experience:
This hackathon gave a compact but practical exposure to real-world DevOps workflows β from server provisioning to automated CI/CD pipelines.
π‘ Conclusion
Deploying Chattingo was far more than just coding a chat application; it was a full end-to-end DevOps challenge. Key takeaways include:
Infrastructure Setup: VPS provisioning, SSH key management, and Nginx configuration.
Containerization: Multi-stage Docker builds for frontend and backend, environment variable management, and container orchestration with
docker-compose.Continuous Integration & Delivery: Jenkins pipeline automation, shared libraries for reusable code, automated security scans, and registry management.
Security & Reliability: SSL via Certbot, secure access using IAM and S3, vulnerability scanning with Trivy.
Debugging & Iterative Development: Solving JWT authentication bugs, frontend white screen issues, and network/proxy configurations in real time.
Advice for hackathon participants:
Break down complex tasks into small, manageable steps.
Debug iteratively and test each component before integrating.
Automate repetitive tasks wherever possible using CI/CD.
Keep security and deployment best practices in mind from day one.
Hackathons are short, but the lessons you learn β especially in DevOps, automation, and full-stack deployment β last far longer than the competition. πͺπ
π Project Resources
Chattingo Source Code (GitHub): github.com/your-org/chattingo
Jenkins Shared Library (GitHub): github.com/your-org/jenkins-shared-library
Docker Hub Repository:
Backend : dushyantkumark/chattingo-app-backend (tag available : 28-33)
Frontend : dushyantkumark/chattingo-app-frontend (tag available : 28-33)
Follow for many such contents:
LinkedIn: linkedin.com/in/dushyant-kumar-dk
Blog: dashboard-blog-link



