From f0b9858459d90f829992820df46fa2ee9545efa7 Mon Sep 17 00:00:00 2001 From: Nikolay Karadzhov Date: Thu, 4 Dec 2025 15:12:50 +0200 Subject: [PATCH] feat: add standalone Docker support and update release workflow - add standalone.Dockerfile for single-container deployment - add start.sh script for container initialization - update release workflow to build and publish standalone image - update README with standalone deployment instructions - remove cluster docker-compose example --- .github/workflows/release.yml | 34 +++++++++++++-- README.md | 65 +++++++++++++++++++++++------ examples/cluster/docker-compose.yml | 54 ------------------------ standalone.Dockerfile | 23 ++++++++++ start.sh | 17 ++++++++ 5 files changed, 124 insertions(+), 69 deletions(-) delete mode 100644 examples/cluster/docker-compose.yml create mode 100644 standalone.Dockerfile create mode 100644 start.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 408ddbe..fb5fd60 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -51,10 +51,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - - name: Build and push Docker image + - name: Build and push base Docker image uses: docker/build-push-action@v6 with: context: . + file: ./Dockerfile platforms: linux/amd64,linux/arm64 push: true tags: | @@ -63,6 +64,21 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max + - name: Build and push standalone Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./standalone.Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + BASE_IMAGE=${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.VERSION }} + tags: | + ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE }}:standalone + ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE }}:standalone-${{ steps.version.outputs.VERSION }} + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Create GitHub Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -72,12 +88,18 @@ jobs: # If GitHub's generation worked and has content beyond just "Full Changelog" if [[ "$GENERATED_NOTES" != *"**Full Changelog**"* ]] && [[ -n "$GENERATED_NOTES" ]]; then - RELEASE_BODY="## Docker Image + RELEASE_BODY="## Docker Images + **Base Image (Proxy only):** \`\`\`bash docker pull ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.VERSION }} \`\`\` + **Standalone Image (Proxy + Embedded Redis):** + \`\`\`bash + docker pull ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE }}:standalone-${{ steps.version.outputs.VERSION }} + \`\`\` + $GENERATED_NOTES" else # Fallback to commit-based notes @@ -90,12 +112,18 @@ jobs: CHANGELOG_LINK="" fi - RELEASE_BODY="## Docker Image + RELEASE_BODY="## Docker Images + **Base Image (Proxy only):** \`\`\`bash docker pull ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.VERSION }} \`\`\` + **Standalone Image (Proxy + Embedded Redis):** + \`\`\`bash + docker pull ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE }}:standalone-${{ steps.version.outputs.VERSION }} + \`\`\` + ## What's Changed $COMMIT_NOTES diff --git a/README.md b/README.md index 2bcbdc4..bdfee76 100644 --- a/README.md +++ b/README.md @@ -133,23 +133,61 @@ Key Endpoints: `POST /send-to-client/{id}`, `POST /send-to-all-clients`, `GET /c ### Basic Usage #### Docker (Recommended) -Use the official docker [image](https://hub.docker.com/r/redislabs/client-resp-proxy) or + +**Two image variants available:** + +1. **Base Image** (`redislabs/client-resp-proxy:latest`) - Proxy only, requires external Redis +2. **Standalone Image** (`redislabs/client-resp-proxy:standalone`) - Proxy + embedded Redis in one container + +##### Using Base Image (with external Redis) ```bash -# Build the docker image first -docker build -t resp-proxy . +# Pull from Docker Hub +docker pull redislabs/client-resp-proxy:latest + +# Run with Docker - connects to Redis on host +docker run -d \ + -p 6379:6379 -p 3000:3000 \ + -e TARGET_HOST=host.docker.internal \ + -e TARGET_PORT=6380 \ + redislabs/client-resp-proxy ``` +##### Using Standalone Image (embedded Redis) + +Perfect for development, demos, or mocked clusters: + ```bash -# Run with Docker - connects to Redis on host +# Pull standalone image +docker pull redislabs/client-resp-proxy:standalone + +# Run with embedded Redis docker run -d \ - -p 6379:6379 \ # the proxy will listen for incoming connections on this port - -p 3000:3000 \ # the rest api will listen for http requests on this port - -e TARGET_HOST=host.docker.internal \ #<-- redis server host ( the proxy target ) - -e TARGET_PORT=6380 \ # redis server port - -e LISTEN_PORT=6379 \ # proxy listen port - -e API_PORT = 3000 \ # rest api port - resp-proxy + -p 6379:6379 -p 3000:3000 \ + redislabs/client-resp-proxy:standalone +``` + +##### Mocked Cluster Mode (Standalone Image) + +Run a mocked multi-node Redis cluster in a single container: + +```bash +docker run -d \ + -p 6379:6379 -p 6380:6380 -p 6381:6381 -p 3000:3000 \ + -e LISTEN_PORT="6379,6380,6381" \ + -e DEFAULT_INTERCEPTORS="cluster,logger" \ + -e ENABLE_LOGGING=true \ + redislabs/client-resp-proxy:standalone +``` + +##### Building Images Locally + +```bash +# Build base image +docker build -t cae-resp-proxy:latest -f Dockerfile . + +# Build standalone image (extends base) +docker build -t cae-resp-proxy:standalone -f standalone.Dockerfile . ``` ### Local Development @@ -197,11 +235,14 @@ bun run proxy | Parameter | CLI Flag | Environment Variable | Default | Description | |-----------|----------|---------------------|---------|-------------| -| Listen Port | `--listenPort` | `LISTEN_PORT` | `6379` | Port for Redis clients to connect to | +| Listen Port | `--listenPort` | `LISTEN_PORT` | `6379` | Port(s) for Redis clients (comma-separated for multiple) | | Listen Host | `--listenHost` | `LISTEN_HOST` | `127.0.0.1` | Host interface to bind to | | Timeout | `--timeout` | `TIMEOUT` | - | Connection timeout (ms) | | Enable Logging | `--enableLogging` | `ENABLE_LOGGING` | `false` | Verbose logging | | API Port | `--apiPort` | `API_PORT` | `3000` | HTTP API port | +| Default Interceptors | - | `DEFAULT_INTERCEPTORS` | - | Comma-separated interceptors (e.g., "cluster,logger") | +| Redis Port | - | `REDIS_PORT` | `4000` | Port for embedded Redis (standalone image only) | + ## HTTP API Reference diff --git a/examples/cluster/docker-compose.yml b/examples/cluster/docker-compose.yml deleted file mode 100644 index 4a771b4..0000000 --- a/examples/cluster/docker-compose.yml +++ /dev/null @@ -1,54 +0,0 @@ -networks: - redis-net: - driver: bridge - -services: - redis: - image: redislabs/client-libs-test:8.2 - container_name: redis - ports: - - "3000:3000" - networks: - - redis-net - healthcheck: - test: ["CMD", "redis-cli", "-p", "3000", "PING"] - interval: 10s - timeout: 3s - retries: 5 - - resp-proxy: - image: redislabs/client-resp-proxy - container_name: resp-proxy - environment: - LISTEN_HOST: "0.0.0.0" - LISTEN_PORT: "6379,6380,6381" - TARGET_HOST: "redis" - TARGET_PORT: "3000" - API_PORT: "4000" - ENABLE_LOGGING: true - DEFAULT_INTERCEPTORS: 'cluster, hitless, logger' - ports: - - "6379:6379" - - "6380:6380" - - "6381:6381" - - "4000:4000" - depends_on: - - redis - networks: - - redis-net - healthcheck: - test: ["CMD", "sh", "-c", "wget -qO- http://localhost:4000/stats || exit 1"] - interval: 10s - timeout: 3s - retries: 5 - - # debug: - # image: nicolaka/netshoot:latest - # container_name: debug - # depends_on: - # - resp-proxy - # networks: - # - redis-net - # command: sleep infinity - # stdin_open: true - # tty: true diff --git a/standalone.Dockerfile b/standalone.Dockerfile new file mode 100644 index 0000000..77daf23 --- /dev/null +++ b/standalone.Dockerfile @@ -0,0 +1,23 @@ +ARG BASE_IMAGE=redislabs/client-resp-proxy:latest + +FROM ${BASE_IMAGE} + +# Install Redis +RUN apk add --no-cache redis + +# Override environment variables for standalone mode +ENV LISTEN_HOST="0.0.0.0" +ENV TARGET_HOST="127.0.0.1" +ENV TARGET_PORT="4000" +ENV REDIS_PORT="4000" +ENV API_PORT="3000" + +# Expose Redis and API ports +EXPOSE 4000 3000 + +# Copy startup script +COPY start.sh . + +RUN chmod +x /app/start.sh + +ENTRYPOINT ["/app/start.sh"] diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..98b70d0 --- /dev/null +++ b/start.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# Start Redis server in background +redis-server --port ${REDIS_PORT} --bind 127.0.0.1 & + +# Wait for Redis to be ready +timeout=10 +while [ $timeout -gt 0 ]; do + if redis-cli -p ${REDIS_PORT} PING >/dev/null 2>&1; then + echo "Redis is ready on port ${REDIS_PORT}" + break + fi + timeout=$((timeout - 1)) + sleep 1 +done + +# Start the proxy +exec ./resp-proxy