Dockerizing Multi-Platform Astro SSR Apps using GitHub Actions

  • #Astro
  • #Bun
  • #Docker
  • #GitHubActions
  • #SSR

Astro provides a fantastic developer experience for building sites and applications with server-side rendering (SSR). For a side project I chose Astro and Vue.js to get started quickly. When I started this project, I was building my Docker images manually and pushing new versions to Docker Hub by hand. But it was definitely time for a change. Enter GitHub Actions.

In this guide, you’ll learn how I use GitHub Actions to build, package, and push my Bun-powered Astro SSR application to the GitHub Container Registry (ghcr.io). Let’s dive in.

Rocket launching into a star-filled night sky with three astronauts in spacesuits watching from the ground, surrounded by colorful clouds and a large planet in the background.
Launching Your Astro SSR App with Bun and GitHub Actions

Quick Recap: Why Astro SSR and Bun?

Astro’s server-side rendering (SSR) capabilities allow your applications to handle dynamic content, authentication, and database interactions beyond the typical static page generation (yes, you can build things other than blogs with Astro 😜). Combined with Bun - a blazingly fast JavaScript runtime and package manager - I was off to a great start.

While it got me up and running quickly, building, tagging and pushing new versions by hand started to get really annoying. When it’s time to deploy, we want efficiency, minimal downtime, and easy scalability. That’s where Docker and GitHub Actions come in.

Diving Into GitHub Actions for Docker-Based Deployment

GitHub Actions allows us to automate deployment processes in a simple, declarative workflow. Here’s how we’ll set this up for an Astro SSR app built with Bun:

Overview of our GitHub Actions Workflow

We’ll create a GitHub Action workflow that triggers when we push a new release tag (like v1.0.0). Our workflow does the following:

  • Checks out the latest code.
  • Builds a Docker image optimized for Astro SSR with Bun.
  • Publishes the image to GitHub Container Registry (ghcr.io) tagged with the version and latest.

Below is our full GitHub Action YAML configuration:

.github/workflows/docker-publish.yml
name: Docker Publish
on:
push:
tags:
- 'v*'
permissions:
contents: read
packages: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Extract tag name
id: extract_tag
run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: docker-container
- name: Build and Push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/${{ github.repository }}/astro-ssr-app:${{ steps.extract_tag.outputs.tag }}
ghcr.io/${{ github.repository }}/astro-ssr-app:latest
outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=Organize your projects with the Eisenhower matrix.

Understanding the Key Steps

Let’s break down what’s happening in the workflow step-by-step.

Checkout Code

- name: Checkout code
uses: actions/checkout@v3

We begin by pulling in the latest code of your Astro application from GitHub. This ensures all Docker build steps have access to a fresh snapshot of your repository.

Extracting the Version Tag

- name: Extract tag name
id: extract_tag
run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT

This step automatically extracts the version number from the pushed tag, simplifying versioning for your Docker images.

Logging into GitHub Container Registry (ghcr.io)

- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

Securely authenticate with GitHub Container Registry to prepare for pushing your Docker images.

☝️ Good To Know: Your GITHUB_TOKEN secret is provided automatically by GitHub Actions—no additional setup is needed!

Docker Buildx and QEMU for Multi-Platform Support

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: docker-container

These steps enable building Docker images for multiple architectures (like amd64 or arm64). This ensures the Docker image runs on multiple platforms like ARM-based web servers as well as traditional x86 servers or - if needed - macOS or Windows machines.

Building and Pushing the Image

- name: Build and Push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/${{ github.repository }}/astro-ssr-app:${{ steps.extract_tag.outputs.tag }}
ghcr.io/${{ github.repository }}/astro-ssr-app:latest
outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=Organize your projects with the Eisenhower matrix.

This tells Docker to build and push your image, tagging it with both the specific version and the latest tag. The annotation-index contains descriptive metadata that makes your image more discoverable and maintainable.

☝️ Attention: Make sure to set permissions: packages: write in order to allow the workflow to write to the underlying Docker registry!

Deploying your Image

With your Docker images securely published to GitHub Container Registry, deploying the image to your hosting provider or infrastructure (such as your own VPS) becomes straightforward.

For example, simply pull your newly built image:

Terminal window
docker pull ghcr.io/your-github-username/astro-ssr-app:latest

Wrap-Up and Considerations

Deploying your Astro SSR applications should be as much fun as building them - and using GitHub Actions alongside Docker and Bun makes that a reality. This powerful automated workflow lets you iterate quickly, build multi-architecture images reliably, and ensure each release is smooth and secure.

Additional Resources