Use an appropriate base image
Shows a GitHub Actions workflow that builds shared libraries before building and pushing Docker images for a Next.js client and Node.js server.
What this file does
Shows a GitHub Actions workflow that builds shared libraries before building and pushing Docker images for a Next.js client and Node.js server.
When to use it
- You have a monorepo with shared libraries and separate Docker images for client and server
- You need to ensure libraries are built before Docker image creation in CI
- You want to pass build arguments to Dockerfiles for library paths
- You are setting up automated Docker image builds triggered by version tags
Assumes this stack
To ensure that the libraries are properly installed and built before building the Docker images for your Next.js client and Node.js server, you need to make sure that the client and server Dockerfiles are set up correctly to use the built libraries.
Here's an updated workflow to install and build libraries, followed by building the server and client images, ensuring that libraries are available:
Updated GitHub Actions Workflow
name: Build and Push Docker Images
on:
push:
tags:
- v* # Trigger on version tags like v1.0.0
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up QEMU for multi-platform builds
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16' # Specify your Node.js version
- name: Install dependencies and build libraries
run: |
cd ./packages/libs # Change to your libs directory
npm install # Install library dependencies
npm run build # Build the libraries
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build and push Next.js Docker image
uses: docker/build-push-action@v3
with:
context: ./packages/client # Adjust to your Next.js app path
file: ./packages/client/Dockerfile # Adjust to your Dockerfile path
build-args: |
LIB_PATH=./libs # Pass the library path as a build argument
push: true
tags: |
sa2avroo/nextjs-standalone-new:latest
sa2avroo/nextjs-standalone-new:${{ github.sha }}
sa2avroo/nextjs-standalone-new:${{ github.ref_name }}
- name: Build and push Node.js server Docker image
uses: docker/build-push-action@v3
with:
context: ./packages/server # Adjust to your Node.js server path
file: ./packages/server/Dockerfile # Adjust to your Dockerfile path
build-args: |
LIB_PATH=./libs # Pass the library path as a build argument
push: true
tags: |
sa2avroo/nodejs-server:latest
sa2avroo/nodejs-server:${{ github.sha }}
sa2avroo/nodejs-server:${{ github.ref_name }}
- name: Logout from Docker Hub
run: docker logout
Key Adjustments:
-
Library Installation:
- The step to install and build the libraries remains unchanged, ensuring the libraries are built before building the Docker images.
-
Build Args:
- Added
build-argsto both the client and server build steps. This allows you to pass the library path to your Dockerfiles.
- Added
Example Dockerfile for Client and Server
You need to adjust your Dockerfile for both the client and the server to use the LIB_PATH build argument. Here’s an example of what your Dockerfiles might look like:
Client Dockerfile (./packages/client/Dockerfile)
# Use an appropriate base image
FROM node:16 AS build
# Set the working directory
WORKDIR /app
# Copy the package.json and package-lock.json
COPY package.json package-lock.json ./
# Install dependencies
RUN npm install
# Copy libraries built earlier
COPY ${LIB_PATH} ./libs # Adjust the path as needed
COPY . .
# Build the Next.js app
RUN npm run build
# Start the app
CMD ["npm", "start"]
Server Dockerfile (./packages/server/Dockerfile)
# Use an appropriate base image
FROM node:16 AS build
# Set the working directory
WORKDIR /app
# Copy the package.json and package-lock.json
COPY package.json package-lock.json ./
# Install dependencies
RUN npm install
# Copy libraries built earlier
COPY ${LIB_PATH} ./libs # Adjust the path as needed
COPY . .
# Start the server
CMD ["npm", "start"]
Important Notes:
- Ensure that the
LIB_PATHin the Dockerfiles matches the directory structure where your libraries are built. - You may need to adapt the
COPYcommands in the Dockerfiles depending on where the libraries are located after the build step. - Make sure to test locally to confirm the library paths are set up correctly before pushing to your CI/CD pipeline.
It looks like you've set up a GitHub Actions workflow to build and push Docker images. However, you mentioned that the action is not running and asked how to push a new release version. Here are some tips to help you troubleshoot and ensure that your action runs correctly when pushing a new release version:
Key Points to Check:
-
Triggering the Action:
- Your workflow is set to trigger on version tags (e.g.,
v1.0.0). Make sure you create a tag that follows your specified structure. For example:git tag v1.0.1 git push origin v1.0.1 - Ensure that there are no spaces or invalid characters in your tag name.
- Your workflow is set to trigger on version tags (e.g.,
-
Workflow Location:
- Make sure that your workflow YAML file is located in the correct directory, typically
.github/workflows/in your repository.
- Make sure that your workflow YAML file is located in the correct directory, typically
-
Branch Protection Rules:
- Check if there are any branch protection rules on the default branch that might prevent the GitHub Actions workflows from triggering.
-
Permissions and Secrets:
- Ensure that the
DOCKER_USERNAMEandDOCKER_TOKENsecrets are correctly set in your repository settings. If the secrets are not set, the login step will fail, and the image will not be pushed.
- Ensure that the
-
Check Your Actions Logs:
- After trying to push a new tag, go to the "Actions" tab in your GitHub repository to see if the action was triggered. If it was, you can check the logs for errors.
-
Logs for Debugging:
- You may want to add a step to print out the current GitHub context to verify variables like
${{ github.sha }}and${{ github.ref_name }}if you're facing issues.
- name: Print GitHub context run: echo "SHA: ${{ github.sha }}, Ref Name: ${{ github.ref_name }}" - You may want to add a step to print out the current GitHub context to verify variables like
-
Using 'Latest' Tag:
- If you want to always push a new version with the
latesttag, ensure that there’s a strategy in place to handle that, as pushing alatesttag every time might not be ideal if you're also tagging with version numbers.
- If you want to always push a new version with the
Example Steps to Create a New Release:
Assuming your current branch is main, here are the steps you can follow:
-
Create a new tag:
git checkout main # Make sure you're on the main branch git pull origin main # Update your branch with the latest changes git tag v1.0.1 # Replace with your new version git push origin v1.0.1 # Push the tag to GitHub -
After pushing the tag, navigate to the "Actions" tab in your repository to observe the build and push actions being executed.
Final Note:
If you continue to face issues, you could consider enabling "Actions" for your repository if they are not already enabled, and review any logs or step outputs for helpful debugging information.
What's inside
One workflow YAML with 9 steps, two Dockerfile examples, and troubleshooting tips for tag-based triggers
Change this for your project
- Replace
sa2avroo/nextjs-standalone-newwith your Docker Hub repository name - Replace
sa2avroo/nodejs-serverwith your Docker Hub repository name - Replace
./packages/libswith the path to your shared libraries directory - Replace
./packages/clientand./packages/serverwith your app directory paths
Where it goes
A standard operating procedure. Keep where the team or agent running the process will find it.
Worth borrowing
- Using build-args to pass library paths into Dockerfiles keeps the CI flexible for different directory structures
- Installing and building libraries in a separate step before Docker build avoids rebuilding them inside each image
Related Documents
Comprehensive AI Assistant Tools Reference
Lists 80+ tools with MCP server associations, bulk support, parallel capability, resource impact, and execution type for AI agent workflows.
iOS Deployment Guide
Walks through setting up an iOS development environment, building a Tauri app for iOS, and publishing to the App Store or alternative channels.
How to Add Resources to Your FastMCP Server
Teaches how to add static and dynamic MCP resources to a FastMCP server, with six ready-to-copy examples for a GitHub crawler.
Continue.dev MCP Integration Setup Guide
Walks through configuring Continue.dev to connect an MCP server for spatial transcriptomics tasks, with local and remote setup options.