Skip to main content

Building a CI/CD Pipeline for Java WebApps on Tomcat with GitHub Actions

Updated 3 min readMarkdown

This guide outlines the process of automating the deployment of a Java web application to an Apache Tomcat server using GitHub Actions. By leveraging CI/CD, developers can ensure that every code commit is automatically built, tested, and deployed, significantly reducing manual overhead and minimizing deployment errors in production or staging environments.

Prerequisites

Before setting up the pipeline, ensure you have the following:

A Java project managed by Maven or Gradle.

A GitHub repository containing your source code.

A remote Tomcat server accessible via SSH.

SSH credentials (private key) stored securely in your GitHub repository secrets.

Configuring GitHub Secrets

To keep your deployment secure, never hardcode sensitive information in your workflow files. Navigate to your GitHub repository, go to Settings, then Secrets and variables, and add the following:

SSH_HOST: The IP address or domain of your Tomcat server.

SSH_USER: The username for the server.

SSH_PRIVATE_KEY: The private key used to authenticate with the server.

Creating the Workflow File

Create a file in your repository at .github/workflows/deploy.yml. This file defines the automation steps. The workflow will trigger on every push to the main branch.

Defining the Build and Deploy Steps

The workflow consists of two main phases: building the artifact and deploying it to the server.

name: Java CI/CD to Tomcat

on: push: branches: [ main ]

jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' - name: Build with Maven run: mvn clean package - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: webapp path: target/*.war

deploy: needs: build runs-on: ubuntu-latest steps: - name: Download Artifact uses: actions/download-artifact@v3 with: name: webapp - name: Deploy to Tomcat via SCP uses: appleboy/scp-action@master with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} source: "*.war" target: "/opt/tomcat/webapps/" - name: Restart Tomcat uses: appleboy/ssh-action@master with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} script: sudo systemctl restart tomcat

Understanding the Pipeline Logic

Build Phase: The pipeline uses the ubuntu-latest runner to check out the code, set up the Java environment, and run the Maven package command. This generates the WAR file. The artifact is then uploaded to GitHub so it can be passed to the next job.

Deploy Phase: The pipeline downloads the WAR file and uses the appleboy/scp-action to securely copy the file to the Tomcat webapps directory.

Restart Phase: Finally, the pipeline executes a remote SSH command to restart the Tomcat service, ensuring the new version of the application is loaded.

Best Practices for Production

For production environments, consider adding a testing step after the build phase to run unit tests. Additionally, instead of restarting the entire Tomcat service, you can use the Tomcat Manager API to deploy the WAR file without downtime. Always ensure your server has restricted firewall rules, allowing SSH access only from trusted IP addresses.

1 view

About the author

  • DevOps Engineer with 5+ years of experience and 10+ years overall experience in AWS Cloud Infrastructure, CI/CD, Infrastructure as Code (Terraform), Docker, Kubernetes, Jenkins, Linux, and Middleware Technologies. I enjoy solving infrastructure challenges, automating deployments, and building reliable cloud solutions. Currently exploring DevOps, Cloud Infrastructure, and Platform Engineering opportunities. I focus on automating processes, improving system performance, and making networks scalable and secure in cloud environments. #OpenToWork #DevOps #AWS #Terraform #Kubernetes #Jenkins #CloudComputing #Linux #PlatformEngineering

insightful