Automating Docusaurus Deployment with Portainer and Jenkins in a Home Lab

Managing a home lab requires seamless documentation, and automating deployments is key to efficiency. In this guide, we walk through setting up a Docusaurus documentation site with Docker Swarm, Portainer, and Jenkins, ensuring that every change made in Git is automatically deployed. From containerizing Docusaurus to integrating Portainer’s Git-based stacks and Jenkins pipelines, this tutorial covers everything needed for a hands-off CI/CD workflow. Say goodbye to manual updates and hello to fully automated documentation deployment!

Are you managing a home lab and need a streamlined way to deploy and update your documentation site? Docusaurus is a powerful static site generator, but manually deploying updates can be time-consuming. In this guide, you’ll learn how to automate the Docusaurus deployment process using Jenkins, Docker Swarm, and Portainer. This step-by-step tutorial will show you how to set up an efficient CI/CD pipeline so every change in Git is automatically deployed. With this setup, your documentation will always be up to date without manual intervention.

Why Automate Docusaurus Deployment?

Keeping documentation updated is crucial. However, manual deployments slow things down. With automated deployment, you can:

  • Save time by eliminating manual updates.
  • Ensure every commit to your repository is instantly reflected in production.
  • Improve reliability with a standardized deployment process.
  • Leverage Docker Swarm, Portainer, and Jenkins for seamless integration.

Technologies Used

TechnologyPurpose
DocusaurusStatic site generator for documentation
Docker SwarmCluster management for containerized services
PortainerGUI-based container management
JenkinsCI/CD automation
Cloudflare TunnelSecure public access to the documentation site
DockerHub (Private Repository)Hosting the container images

Step 1: Setting Up Docusaurus Locally

Before deploying, you first need to set up Docusaurus on your local machine.

npx create-docusaurus@latest my-docs classic
cd my-docs
npm run start

This command generates a new documentation site and runs it locally at http://localhost:3000. If everything looks good, proceed to containerizing the site.

Creating a Dockerfile for Docusaurus

FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN yarn install
COPY . .
RUN yarn build
EXPOSE 3000
CMD ["yarn", "serve", "--host", "0.0.0.0"]

Step 2: Deploying Docusaurus with Portainer & Docker Swarm

Now that we have the Docusaurus container, we deploy it using Portainer.

Creating the Stack in Portainer

  1. Log in to Portainer and go to StacksAdd Stack.
  2. Use the following docker-compose.yml:
version: "3.8"

services:
  docusaurus:
    image: your-dockerhub-username/my-docusaurus:latest
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.role == manager
    ports:
      - "3000:3000"
    networks:
      - web
    x-registry-auth: true

networks:
  web:
    driver: overlay
  1. Enable Git Repository Deployment and enter your GitHub/GitLab repo URL.
  2. Add Git Credentials (GitHub PAT or SSH key).
  3. Click Deploy the Stack.

Step 3: Automating Deployment with Jenkins

To make this setup truly hands-free, we configure Jenkins to build the Docker image and trigger a Portainer Stack Update.

Jenkins Pipeline for CI/CD Automation

pipeline {
    agent any

    environment {
        REGISTRY = 'your-dockerhub-username'
        IMAGE_NAME = 'my-docusaurus'
        PORTAINER_URL = 'https://portainer.local.shaloo.io:9443/api/stacks'
        STACK_ID = '15'  // Update with actual stack ID
        ENDPOINT_ID = '1'  // Verify via /api/endpoints
    }

    stages {
        stage('Clone Repository') {
            steps {
                git 'https://your-git-repo.git'
            }
        }

        stage('Authenticate with DockerHub') {
            steps {
                script {
                    withCredentials([usernamePassword(credentialsId: 'dockerhub-credentials', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
                        sh "docker login -u $DOCKER_USER -p $DOCKER_PASS"
                    }
                }
            }
        }

        stage('Build & Push Docker Image') {
            steps {
                script {
                    sh """
                    docker build --platform linux/amd64 -t ${REGISTRY}/${IMAGE_NAME}:latest .
                    docker push ${REGISTRY}/${IMAGE_NAME}:latest
                    """
                }
            }
        }

        stage('Trigger Portainer Stack Redeployment') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'portainer-api-key', variable: 'PORTAINER_API_KEY')]) {
                        sh """
                        curl -k -X PUT "${PORTAINER_URL}/${STACK_ID}/git/redeploy?endpointId=${ENDPOINT_ID}" \
                            -H "X-API-Key: ${PORTAINER_API_KEY}" \
                            -H "Content-Type: application/json"
                        """
                    }
                }
            }
        }
    }

    post {
        success {
            echo 'Deployment successful!'
        }
        failure {
            echo 'Deployment failed.'
        }
    }
}

Step 4: Verifying the Deployment

After Jenkins completes the deployment, verify the process by:

  • Checking Portainer → Stacks → Docusaurus (Last Deployment Time).
  • Running docker service ps docusaurus on the Swarm manager.
  • Visiting http://your-home-lab-ip:3000 to ensure the latest changes are live.

Conclusion

By integrating Docusaurus, Docker Swarm, Portainer, and Jenkins, we have built a fully automated documentation deployment pipeline. Now, every update in Git is instantly deployed without manual intervention.

Next Steps:

  • Add Cloudflare Tunnel for external access.
  • Implement Backup & Rollback strategies.
  • Extend the setup to other home lab services.

With this optimized DevOps workflow, keeping documentation up-to-date has never been easier! Let me know if you found this guide helpful.

More From My Blog