GitHub Actions
This guide demonstrates how to set up a GitHub Actions workflow to deploy your application using deploy4j.
Using GitHub Actions with deploy4j allows you to automate your deployment process, ensuring that your application is deployed consistently every time you push changes to your repository.
Prerequisites
- A working deploy4j configuration in your repository (see Spring Boot guide)
- A Maven project to build your application, package into a Docker image, and push to a Docker registry.
- SSH access to your deployment server
- GitHub repository secrets configured for sensitive values
Setting Up GitHub Secrets
Before creating the workflow, you need to store your sensitive deployment credentials as GitHub repository secrets. Go to your repository Settings > Secrets and variables > Actions and add the following secrets:
| Secret Name | Description |
|---|---|
SSH_PRIVATE_KEY |
Your SSH private key for connecting to the server |
SSH_PRIVATE_KEY_PASSPHRASE |
Passphrase for your SSH key (if applicable) |
SSH_KNOWN_HOSTS |
Contents of your known_hosts file for the target server |
DOCKER_USERNAME |
Your Docker registry username |
DOCKER_PASSWORD |
Your Docker registry password or access token |
To get the known_hosts entry for your server, run (replace <your-server-ip> with your actual server IP):
ssh-keyscan -H <your-server-ip>
Creating the Workflow File
Create a new workflow file at .github/workflows/deploy.yml in your repository:
name: Deploy with deploy4j
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package -DskipTests
# deploy to Docker Hub
- name: Log in to Docker Hub
uses: docker/login-action@v3.1.0
with:
username: $
password: $
- name: Build and push Docker image
run: mvn -B docker:build docker:push -DskipTests
# setup JBang
- name: Setup JBang
uses: jbangdev/setup-jbang@main
# configure java versions for jbang
- name: Configure java
run: jbang jdk install 21 $
- name: Set up SSH credentials
run: |
echo "$" > /tmp/ssh_key
chmod 600 /tmp/ssh_key
echo "$" > /tmp/known_hosts
- name: Set up deploy4j secrets
run: |
mkdir -p .deploy4j
cat > .deploy4j/secrets << EOF
DOCKER_USERNAME=$DOCKER_USERNAME
DOCKER_PASSWORD=$DOCKER_PASSWORD
PRIVATE_KEY=/tmp/ssh_key
PRIVATE_KEY_PASSPHRASE=$PRIVATE_KEY_PASSPHRASE
KNOWN_HOSTS_PATH=/tmp/known_hosts
EOF
chmod 600 .deploy4j/secrets
# deploy application using deploy4j
- name: Deploy application with deploy4j via jbang
env:
DOCKER_USERNAME: $
DOCKER_PASSWORD: $
PRIVATE_KEY_PASSPHRASE: $
run: jbang --java 21 dev.deploy4j:deploy4j-cli:0.0.6 deploy --version $
Workflow Breakdown
Triggers
The workflow is configured to run on:
- Push to main: Automatically deploys when changes are pushed to the main branch
- Manual dispatch: Allows you to trigger the deployment manually from the GitHub Actions UI
on:
push:
branches:
- main
workflow_dispatch:
Build Steps
The workflow performs the following steps:
- Checkout code: Clones your repository
- Set up JDK: Configures Java 21 with Maven caching
- Build with Maven: Compiles and packages your application
- Build and push Docker image: Creates and pushes the Docker image to your registry
Deploy4j Setup
The workflow sets up deploy4j by:
- Creating secrets file: Writes deployment secrets to
.deploy4j/secrets - Setting up SSH credentials: Writes SSH key and known_hosts to temporary files
- Installing deploy4j: Downloads and installs the deploy4j CLI
Deployment
Finally, the workflow runs deploy4j deploy with the Git commit SHA as the version tag, ensuring each deployment is traceable to a specific commit.
Advanced Configuration
Deploying to Multiple Environments
You can deploy to different environments (staging, production) by using environment-specific secrets and workflow inputs:
name: Deploy with deploy4j
on:
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
jobs:
deploy:
runs-on: ubuntu-latest
environment: $
steps:
# ... previous steps ...
- name: Deploy application
run: |
if [ "$" = "production" ]; then
deploy4j deploy --version $ -d config/deploy.production.yml
else
deploy4j deploy --version $ -d config/deploy.staging.yml
fi
Using GitHub Container Registry
If you prefer to use GitHub Container Registry (ghcr.io) instead of Docker Hub:
- Update your
config/deploy.yml:
image: ghcr.io/your-username/your-app
registry:
server: ghcr.io
username:
- DOCKER_USERNAME
password:
- DOCKER_PASSWORD
- Update the workflow to use
GITHUB_TOKEN:
- name: Build and push Docker image
run: |
echo "$" | docker login ghcr.io -u $ --password-stdin
mvn -B docker:build docker:push -DskipTests
- name: Set up deploy4j secrets
run: |
mkdir -p .deploy4j
cat > .deploy4j/secrets << EOF
DOCKER_USERNAME=$
DOCKER_PASSWORD=$
# ... rest of secrets ...
EOF
chmod 600 .deploy4j/secrets
Running on Tags
To deploy only when a release tag is created:
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# ... previous steps ...
- name: Deploy application
run: deploy4j deploy --version $
Security Considerations
- Never commit secrets: Always use GitHub Secrets for sensitive values
- Use environment protection rules: Configure deployment protection rules for production environments
- Limit SSH key permissions: Use a dedicated deployment key with minimal required permissions
- Review workflow changes: Require pull request reviews for changes to workflow files
Troubleshooting
SSH Connection Failures
If you encounter SSH connection issues:
- Verify your SSH key format (should be OpenSSH format)
- Check that the known_hosts entry matches your server
- Ensure the SSH key has appropriate permissions (600)
- name: Debug SSH connection
run: |
ssh -vvv -i /tmp/ssh_key -o UserKnownHostsFile=/tmp/known_hosts root@<your-server-ip> "echo 'Connection successful'"
Replace <your-server-ip> with your actual server IP address.
Docker Registry Authentication
If Docker push fails:
- Verify your Docker credentials
- Check that your Docker username has push permissions to the repository
- For GitHub Container Registry, ensure the package visibility settings are correct
Deploy4j Command Errors
If deploy4j commands fail:
- Check that
config/deploy.ymlexists and is valid - Verify all required secrets are set
- Run with verbose output for more details:
- name: Deploy application
run: deploy4j deploy --version $ --verbose