diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 00000000..61e4f8c2 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,70 @@ +name: Docker Publish + +on: + push: + tags: + - 'redisctl-v*' + branches: + - main + workflow_dispatch: + +env: + REGISTRY: docker.io + IMAGE_NAME: joshrotenberg/redisctl + +jobs: + build-and-push: + name: Build and Push Docker Image + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}},value=${{ github.ref_name }} + type=semver,pattern={{major}}.{{minor}},value=${{ github.ref_name }} + type=semver,pattern={{major}},value=${{ github.ref_name }} + type=sha,prefix=sha- + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.publish + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + RUST_VERSION=1.89 + + - name: Update Docker Hub Description + uses: peter-evans/dockerhub-description@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + repository: ${{ env.IMAGE_NAME }} + short-description: "Unified CLI for Redis Cloud and Enterprise management" + readme-filepath: ./README.md \ No newline at end of file diff --git a/Dockerfile.publish b/Dockerfile.publish new file mode 100644 index 00000000..a3c8ecab --- /dev/null +++ b/Dockerfile.publish @@ -0,0 +1,50 @@ +# Redis CLI Docker Image - Optimized for Docker Hub +# Multi-platform build with minimal size + +ARG RUST_VERSION=1.89 +FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION} AS builder + +# Install cross-compilation tools +RUN apt-get update && apt-get install -y \ + gcc-aarch64-linux-gnu \ + gcc-x86-64-linux-gnu \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /build + +# Copy workspace files +COPY Cargo.toml ./ +COPY crates/ ./crates/ + +# Set up for cross-compilation +ARG TARGETPLATFORM +RUN case "$TARGETPLATFORM" in \ + "linux/amd64") echo "x86_64-unknown-linux-gnu" > /target.txt ;; \ + "linux/arm64") echo "aarch64-unknown-linux-gnu" > /target.txt ;; \ + *) echo "Unsupported platform: $TARGETPLATFORM" && exit 1 ;; \ + esac + +# Build for the target platform +RUN export TARGET=$(cat /target.txt) && \ + rustup target add $TARGET && \ + cargo build --release --target $TARGET --bin redisctl && \ + cp target/$TARGET/release/redisctl /redisctl + +# Runtime stage - distroless for minimal size and security +FROM gcr.io/distroless/cc-debian12:nonroot + +# Copy the binary +COPY --from=builder /redisctl /usr/local/bin/redisctl + +# Set environment variables +ENV REDIS_ENTERPRISE_URL="" +ENV REDIS_ENTERPRISE_USER="" +ENV REDIS_ENTERPRISE_PASSWORD="" +ENV REDIS_CLOUD_API_KEY="" +ENV REDIS_CLOUD_SECRET_KEY="" + +# Use the nonroot user +USER nonroot + +ENTRYPOINT ["redisctl"] +CMD ["--help"] \ No newline at end of file diff --git a/README.md b/README.md index a527e422..14fab71f 100644 --- a/README.md +++ b/README.md @@ -83,16 +83,58 @@ cargo build --release --features enterprise-only --bin redis-enterprise cargo build --release --bin redisctl ``` -### Using Docker (for Enterprise testing) +### Using Docker Hub Image + +The official Docker images are available on Docker Hub at [joshrotenberg/redisctl](https://hub.docker.com/r/joshrotenberg/redisctl): + +#### Available Tags +- `latest` - Latest stable release +- `v0.1.0`, `v0.2.0`, etc. - Specific version tags +- `main` - Latest development build from main branch + +```bash +# Pull the latest image +docker pull joshrotenberg/redisctl:latest + +# Or pull a specific version +docker pull joshrotenberg/redisctl:v0.1.0 + +# Run a command directly +docker run --rm joshrotenberg/redisctl:latest --help + +# Use with environment variables for Redis Cloud +docker run --rm \ + -e REDIS_CLOUD_API_KEY="your-key" \ + -e REDIS_CLOUD_API_SECRET="your-secret" \ + joshrotenberg/redisctl:latest cloud subscription list + +# Use with environment variables for Redis Enterprise +docker run --rm \ + -e REDIS_ENTERPRISE_URL="https://your-cluster:9443" \ + -e REDIS_ENTERPRISE_USER="admin@example.com" \ + -e REDIS_ENTERPRISE_PASSWORD="your-password" \ + -e REDIS_ENTERPRISE_INSECURE="true" \ + joshrotenberg/redisctl:latest enterprise cluster info + +# Run interactively with a shell +docker run -it --rm \ + -e REDIS_ENTERPRISE_URL="https://your-cluster:9443" \ + -e REDIS_ENTERPRISE_USER="admin@example.com" \ + -e REDIS_ENTERPRISE_PASSWORD="your-password" \ + --entrypoint /bin/sh \ + joshrotenberg/redisctl:latest +``` + +### Local Development with Docker Compose ```bash # Start Redis Enterprise cluster with initialization docker compose up -d # Check cluster status -docker compose logs init +docker compose logs init-cluster -# Access interactive CLI -docker compose run --rm cli +# Watch logs +docker compose logs -f # Clean up docker compose down -v