CHECKING STATUS
I AM LISTENING TO
|

Day 17: Shields.io – Self-Hosted SVG Badges – 7 Days of Docker

10. March 2025
.SHARE

Table of Contents

Introduction to Shields.io

Shields.io is a popular service that provides concise, consistent, and legible badges for your GitHub projects, documentation, and websites. These badges are useful for displaying various metrics like build status, version numbers, downloads, license information, and more. They help make your repositories more informative and professional by providing visual indicators of your project’s status and other key information.

Some common use cases for Shields.io badges include:

  • Displaying build status (passing/failing)
  • Showing package version numbers
  • Indicating code coverage percentages
  • Displaying download counts
  • Showing license information
  • Custom status badges for any project metric

While Shields.io offers a free public service, there are several compelling reasons to self-host your own instance:

  1. Reliability: Your badges remain accessible even if the public Shields.io service experiences downtime
  2. Privacy: Access to private repositories and services without exposing credentials to a third party
  3. Performance: Reduced latency, especially for internal projects
  4. Customization: Full control over the instance configuration and appearance
  5. No rate limits: Avoid hitting the public service rate limits, especially for GitHub API requests

In this guide, we’ll walk you through setting up your own Shields.io instance using Docker, which makes deployment straightforward and portable.

Prerequisites

Before getting started, make sure you have:

  • A server or VM with Docker installed
  • Docker Compose (recommended for easier management)
  • Basic knowledge of Docker and containerization
  • Any API tokens or credentials for services you want to use with Shields.io (GitHub, GitLab, etc.)

Self-Hosting Using Docker

Shields.io provides official Docker images that make deployment straightforward. There are two main approaches to running your Shields.io instance with Docker:

  1. Using the official image directly
  2. Using Docker Compose for more flexibility

Option 1: Using the Official Docker Image

The Shields.io team maintains official Docker images on both DockerHub and GitHub Container Registry:

To run a basic Shields.io instance, you can use the following command:

docker run --rm -p 8080:8080 --env PORT=8080 --name shields shieldsio/shields:next

This command will:

  • Pull the latest development build from the Docker registry
  • Run the container named “shields”
  • Map port 8080 on your host to port 8080 in the container
  • Remove the container when it stops (using the --rm flag)

Once running, you can access your Shields.io instance at http://localhost:8080/.

Option 2: Using Docker Compose (Recommended)

For a more robust deployment, you can use Docker Compose to manage your Shields.io instance. Here’s a basic docker-compose.yml file to get you started:

version: '3'

services:
  shields:
    image: shieldsio/shields:next
    container_name: shields
    restart: always
    ports:
      - "8080:8080"
    environment:
      - PORT=8080
      # Uncomment and update the following if you want to use GitHub authentication
      # - GH_TOKEN=your-github-token
    volumes:
      # Optional volume for local configuration
      - ./config:/usr/local/shields/config

  # Optional: Add a caching layer with Varnish
  varnish:
    image: varnish:stable
    container_name: shields-varnish
    restart: always
    ports:
      - "80:80"
    depends_on:
      - shields
    environment:
      - VARNISH_SIZE=2G
    volumes:
      - ./varnish/default.vcl:/etc/varnish/default.vcl

To run your Shields.io instance with Docker Compose:

docker-compose up -d

This will start both the Shields.io service and a Varnish caching layer in detached mode.

Configuration Options

Shields.io offers numerous configuration options that can be set via environment variables. Here are some of the most important ones:

Core Settings

  • PORT: The port the server will listen on (default: 80)
  • REDIRECT_URI: Where to redirect the server root (useful with CDN hosting)
  • BASE_URL: URL where your Shields instance is deployed, used for building badge URLs

Service Authentication

To avoid rate limits and access private repositories, you can add authentication tokens for various services. Here are some common ones:

GitHub

environment:
  - GH_TOKEN=your-github-personal-access-token

GitHub has a rate limit of 60 requests per hour for unauthenticated requests, which can be quickly exhausted. Adding a GitHub token significantly increases this limit and allows access to private repositories. Create a Personal Access Token (PAT) with at least the repo scope.

GitLab

environment:
  - GITLAB_ORIGINS=https://gitlab.example.com
  - GITLAB_TOKEN=your-gitlab-personal-access-token

Docker Hub

environment:
  - DOCKERHUB_USER=your-dockerhub-username
  - DOCKERHUB_PAT=your-dockerhub-personal-access-token

NPM

environment:
  - NPM_TOKEN=your-npm-token

Server Secrets

For more complex configurations, you can create a config/local.yml file:

public:
  services:
    github:
      baseUri: https://github.example.com/api/v3/
    gitlab:
      authorizedOrigins: ['https://gitlab.example.com']

private:
  gh_token: 'your-github-token'
  gitlab_token: 'your-gitlab-token'

Mount this file as a volume in your Docker container:

volumes:
  - ./config:/usr/local/shields/config

PNG Badge Support with Raster Server

Shields.io primarily serves SVG badges, but if you need PNG badges, you can set up a raster server:

  1. In your raster instance, set BASE_URL to your Shields instance, e.g., https://shields.example.com
  2. In your Shields instance, configure RASTER_URL to point to your raster server, e.g., https://raster.example.com

This will enable Shields to redirect legacy raster URLs to your raster server.

Advanced Configuration

Monitoring with Prometheus

Shields.io supports Prometheus metrics, which can be enabled with:

environment:
  - METRICS_PROMETHEUS_ENABLED=true
  - METRICS_PROMETHEUS_ENDPOINT_ENABLED=true

Metrics will be available at the /metrics endpoint.

Sentry Integration

For error tracking, you can integrate with Sentry:

environment:
  - SENTRY_DSN=https://{PUBLIC_KEY}:{SECRET_KEY}@sentry.io/{PROJECT_ID}

CDN / Frontend Hosting

You can host the frontend separately if desired:

  1. Build the frontend pointing to your server: BASE_URL=https://your-server.example.com npm run build
  2. Copy the contents of the public/ folder to your static hosting or CDN
  3. Configure the Shields server to redirect to your CDN: environment: - REDIRECT_URI=https://your-cdn.example.com/

Security Considerations

When self-hosting Shields.io, keep these security considerations in mind:

  1. API Tokens: Use tokens with the minimum required permissions. For GitHub, a read-only token is sufficient.
  2. HTTPS: Always use HTTPS for your Shields instance to protect tokens and credentials.
  3. Restrictive Network Access: Consider restricting access to your Shields instance to your internal network if it’s only used internally.
  4. Regular Updates: Keep your Docker images updated to get security patches.

Troubleshooting

Common Issues

  1. Badge Not Found (404): Check if the requested service is properly configured and has the necessary tokens.
  2. Rate Limit Exceeded: Verify that your API tokens are correctly configured.
  3. Authentication Errors: Ensure your tokens have the correct permissions and haven’t expired.
  4. Connectivity Issues: Make sure your server can reach the external services needed for badge generation.

Logs

To view logs for your Shields.io instance:

docker logs shields
# Or with Docker Compose
docker-compose logs shields

Thoughts

Self-hosting Shields.io with Docker provides flexibility, privacy, and reliability for your badges. Whether you’re using it for public or private repositories, having your own instance ensures your badges are always available and don’t suffer from rate limiting issues.

By following this guide, you should have a fully functional Shields.io instance running in Docker that can be customized to suit your specific needs. The combination of Docker containerization and Shields.io’s flexible configuration options makes for a powerful and maintainable badge service.

For more detailed information, refer to the official Shields.io documentation and the Docker image repository.

Resources

Let’s Talk!

Looking for a reliable partner to bring your project to the next level? Whether it’s development, design, security, or ongoing support—I’d love to chat and see how I can help.

Get in touch,
and let’s create something amazing together!

RELATED POSTS

This is my own task / project / workflow solution fully integrated into WordPress, which I began developing in 2025. After the recent cloud outages—and following a significant investment in the Asana ecosystem—I decided to build a robust, self-hosted WordPress solution featuring an almost complete Asana Sync API integration. I don’t have plans to make […]

UPDATED: Asana is a great project management tool, but for those who prioritize data privacy, control, and customization, self-hosted alternatives are a better option. In 2026, there are several robust and feature-rich self-hosted project management tools that can effectively replace Asana while giving you full control over your data. Here’s a look at some of […]

Inspired byGutenberg Blocks in Gravity Forms: Seamless Widget IntegrationGutenberg Blocks in Elementor: Seamless Widget IntegrationMeet the Isolated Block Editor – Gutenberg, Untethered – Integrated into Elementor The idea took over Once you start working on an idea its hard not to see all the other possibilities ;) The plugin automatically detects and replaces TinyMCE textareas […]

Alexander

I am a full-stack developer. My expertise include:

  • Server, Network and Hosting Environments
  • Data Modeling / Import / Export
  • Business Logic
  • API Layer / Action layer / MVC
  • User Interfaces
  • User Experience
  • Understand what the customer and the business needs


I have a deep passion for programming, design, and server architecture—each of these fuels my creativity, and I wouldn’t feel complete without them.

With a broad range of interests, I’m always exploring new technologies and expanding my knowledge wherever needed. The tech world evolves rapidly, and I love staying ahead by embracing the latest innovations.

Beyond technology, I value peace and surround myself with like-minded individuals.

I firmly believe in the principle: Help others, and help will find its way back to you when you need it.