๐Ÿ“˜ Automated CI/CD Deployment Handbook


Part 1: Server-Side Setup (Do this ONCE)

Location: Ubuntu(EC2) Server

We need to leave a script on the server that GitHub can "press" remotely.

1. Create the Deployment Script SSH into the server and create the file:

Bash

nano deploy.sh

2. The Automation Logic

Bash

#!/bin/bash
#--- CONFIGURATION --- 
IMAGE_NAME="nnnanannn/my-journey-blog:latest" 
CONTAINER_NAME="my-journey-blog" 
PORT_MAPPING="80:8080"
# ---------------------

echo "๐Ÿš€ GitHub Actions triggered deployment..."
#1. Pull the new image from Docker Hub
echo"โฌ‡๏ธ Pulling latest image..." 
docker pull $IMAGE_NAME

# 2. Stop and remove the old container
echo "๐Ÿ›‘ Stopping old container..." 
docker stop $CONTAINER_NAME || true 
docker rm $CONTAINER_NAME || true

# 3. Start the new container
echo "โœ… Starting new container..." 
docker run -d --name $CONTAINER_NAME --restart always -p $PORT_MAPPING $IMAGE_NAME

# 4. Clean up old images to save disk space
echo "๐Ÿงน Cleaning up..." 
docker image prune -f 

echo "๐ŸŽ‰ Deployed Successfully!"

3. Make it Executable (CRITICAL)

Bash

chmod +x deploy.sh


Part 2: GitHub Secrets Setup (Do this ONCE)

Location: GitHub Website

GitHub needs permission to access your Docker Hub and your Server.

  1. Go to your Repository on GitHub.
  2. Click Settings $\rightarrow$ Secrets and variables $\rightarrow$ Actions.
  3. Click New repository secret and add these five:


______________________________________________

Secret Name | Value to Paste

______________________________________________

DOCKER_USERNAME | Docker Hub ID (nnnanannn)

______________________________________________

DOCKER_PASSWORD | Docker Hub Password

______________________________________________

SERVER_HOST | Server IP (e.g., 35.77.253.208)

______________________________________________

SERVER_USER | SSH username (ubuntu)

______________________________________________

SSH_PRIVATE_KEY | The entire content of local .pem or private key file.

______________________________________________


Part 3: The Workflow File (Do this ONCE)

Location: Local Computer (VS Code/IntelliJ)

This file tells GitHub how to deploy your app.

1. Create the Directory Inside project root, create this specific folder path: .github/workflows/

2. Create the File Name it deploy.yml.

3. Paste the Configuration

YAML

name: CI/CD Pipeline

on:
  # Trigger the workflow on push to the main branch
  push:
    branches: [ "main" ]

jobs:
  # JOB 1: BUILD CODE & PUSH IMAGE
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile
          push: true
          # Docker Hub repo name
          tags: ${{ secrets.DOCKER_USERNAME }}/my-journey-blog:latest
          # This helps speed up future builds
          cache-from: type=gha
          cache-to: type=gha,mode=max

  # JOB 2: DEPLOY TO SERVER
  deploy:
    needs: build-and-push # Wait for Job 1 to finish
    runs-on: ubuntu-latest
    if: success() # Only run if build succeeded
    steps:
      - name: Execute Deploy Script on Server
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          # This runs the script in deploy.sh file on the server
          script: ./deploy.sh


Dockerfile

# --- STAGE 1: Build the Application ---
# JDK to compile the code
FROM maven:3.9-eclipse-temurin-17-alpine AS builder
WORKDIR /app

# Copy target JUST for local computer
# COPY target/*.jar app.jar
# 1. Copy just the Maven wrapper and pom.xml first (for caching)
COPY .mvn/ .mvn
COPY mvnw pom.xml ./

# 2. Download dependencies (this step is cached if pom.xml doesn't change)
RUN mvn dependency:go-offline

# 3. Copy source code and build
COPY src ./src
RUN mvn clean package -DskipTests

# --- STAGE 2: Run the Application ---
# JRE (Runtime Environment) which is smaller and safer
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app

# Copy the JAR file from the "builder" stage above
COPY --from=builder /app/target/*.jar app.jar

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]



Part 4: The Routine (Everyday Use)

Location: Your Local Computer

Now that the system is built, here is your new workflow. You no longer need to run Maven or Docker manually.

1. Write Code Make your changes in your Java files.

2. Push to GitHub

Bash

# Example
git add .
git commit -m "Fixed bug in login feature"
git push origin main

3. Watch the Magic

  • Go to your GitHub Repo $\rightarrow$ Actions tab.
  • You will see a yellow spinning circle.
  • Wait for it to turn Green.
  • Once Green, your server is updated!
โ† Back to Learning Journey