Files
vincent 7116fff888
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Adding release notes and weekly build support (to pull latest nginx release)
2026-08-01 14:26:55 +02:00

5.4 KiB

Unprivileged Nginx Redirect Docker Image

Build Status

A lightweight, secure, and reusable Docker image based on nginxinc/nginx-unprivileged:alpine-slim designed to redirect HTTP requests to any configurable target domain/path with customizable HTTP status codes.

It is designed to be built via Drone CI directly onto the host server's Docker daemon, allowing multiple containers to run on the host system using the single tagged image.


Features

  • Ultra-Lightweight & Secure: Based on nginxinc/nginx-unprivileged:alpine-slim (~12 MB), running as non-root user (UID 101).
  • Environment Variable Configuration: Leverages native Nginx startup template rendering (envsubst).
  • Path & Query String Preservation: Support for preserving request paths (e.g. $request_uri).
  • Built-in Health Checks:/healthz endpoint returns 200 OK for orchestrator probe support without triggering a redirect.
  • Drone CI Host Integration: Pipeline builds directly onto the host machine's Docker engine via host Docker socket binding (/var/run/docker.sock).

Environment Variables

Variable Default Value Description
REDIRECT_TARGET https://example.com Target URL or domain for redirection. Add $request_uri to preserve path & query parameters.
REDIRECT_CODE 301 HTTP status code for redirection (e.g. 301, 302, 307, 308).
LISTEN_PORT 8080 Internal HTTP listening port (unprivileged standard).

Drone CI Integration

The included .drone.yml pipeline mounts the host Docker socket (/var/run/docker.sock) into a docker:cli container step. This builds and tags the image directly on the host host's Docker daemon.

kind: pipeline
type: docker
name: build-host-redirect-image

steps:
  - name: build-and-tag-host-image
    image: docker:cli
    volumes:
      - name: dockersock
        path: /var/run/docker.sock
    commands:
      - docker build --pull -t redirect:latest .
      - |
        if [ -n "$DRONE_COMMIT_SHA" ]; then
          SHORT_SHA=$(echo $DRONE_COMMIT_SHA | cut -c1-7)
          docker tag redirect:latest redirect:$SHORT_SHA
        fi
      - |
        if [ -n "$DRONE_TAG" ]; then
          docker tag redirect:latest redirect:$DRONE_TAG
        fi
      - |
        apk add --no-cache git 2>/dev/null || true
        git fetch --tags 2>/dev/null || true
        LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
        if [ -n "$LATEST_TAG" ]; then
          docker tag redirect:latest redirect:$LATEST_TAG
        fi

volumes:
  - name: dockersock
    host:
      path: /var/run/docker.sock

trigger:
  event:
    - push
    - tag
    - cron

Note

: Ensure your Drone runner environment allows mounting the host socket volume.

Tagging a Release with Git

When you create and push a Git tag to your repository:

# Create a tag locally
git tag v1.0.0

# Push the tag to your git remote
git push origin v1.0.0
  1. Git sends a tag webhook event to Drone CI.
  2. Drone automatically populates $DRONE_TAG with the tag value (e.g. v1.0.0) and triggers the pipeline.
  3. The pipeline builds and tags the host image as redirect:v1.0.0 (as well as redirect:latest and redirect:<short_sha>).

Weekly Scheduled Rebuilds (weekly-build)

To keep your Docker images updated with upstream OS/Nginx security patches:

  1. In the Drone CI UI (or via Drone CLI), navigate to Repository Settings -> Cron Jobs.
  2. Add a new Cron job named weekly-build set to trigger weekly (e.g., @weekly or 0 0 * * 0).
  3. When the cron event triggers:
    • The pipeline executes docker build --pull -t redirect:latest . to fetch updated base layers from Alpine/Nginx.
    • It fetches the latest Git release tag (git describe --tags --abbrev=0) and automatically updates redirect:<latest_tag> (e.g., redirect:v1.0.0) on the host daemon.

Quick Start & Usage

1. Manual Build (Local Testing)

# Bash
./build-and-tag.sh redirect latest

# PowerShell
.\build-and-tag.ps1 -ImageName redirect -Tag latest

2. Run Single Containers

Basic Domain Redirect (301 Permanent Redirect)

docker run -d \
  --name redirect-domain \
  -p 8080:8080 \
  -e REDIRECT_TARGET="https://destination.com" \
  -e REDIRECT_CODE="301" \
  redirect:latest

Path & Query Parameter Preserving Redirect (302 Found)

docker run -d \
  --name redirect-path \
  -p 8081:8080 \
  -e REDIRECT_TARGET="https://destination.com\$request_uri" \
  -e REDIRECT_CODE="302" \
  redirect:latest

3. Multi-Container Setup with Docker Compose

To deploy multiple redirect services side-by-side using the host-tagged image:

services:
  site-a-redirect:
    image: redirect:latest
    container_name: site-a-redirect
    ports:
      - "8081:8080"
    environment:
      - REDIRECT_TARGET=https://site-a.com
      - REDIRECT_CODE=301

  site-b-redirect:
    image: redirect:latest
    container_name: site-b-redirect
    ports:
      - "8082:8080"
    environment:
      - REDIRECT_TARGET=https://site-b.com$request_uri
      - REDIRECT_CODE=302

Run compose stack:

docker compose up -d

Health Check Endpoint

All requests to /healthz bypass redirection and return an HTTP 200 OK response with text body OK.

curl http://localhost:8080/healthz
# Response: HTTP 200 OK -> "OK"