Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@ COPY script script

RUN CGO_ENABLED=0 GOOS=linux go build -o /go/bin/ratelimit -ldflags="-w -s" -v github.com/envoyproxy/ratelimit/src/service_cmd

FROM alpine:3.22.2@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412 AS final
RUN apk --no-cache add ca-certificates && apk --no-cache update
FROM gcr.io/distroless/static-debian12:nonroot@sha256:e8a4044e0b4ae4257efa45fc026c0bc30ad320d43bd4c1a7d5271bd241e386d0
COPY --from=build /go/bin/ratelimit /bin/ratelimit
34 changes: 31 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

- [Overview](#overview)
- [Docker Image](#docker-image)
- [Distroless Base Image](#distroless-base-image)
- [Benefits of Distroless:](#benefits-of-distroless)
- [Debugging with Distroless:](#debugging-with-distroless)
- [Supported Envoy APIs](#supported-envoy-apis)
- [API Deprecation History](#api-deprecation-history)
- [Building and Testing](#building-and-testing)
Expand Down Expand Up @@ -80,6 +83,32 @@ decision is then returned to the caller.

For every main commit, an image is pushed to [Dockerhub](https://hub.docker.com/r/envoyproxy/ratelimit/tags?page=1&ordering=last_updated). There is currently no versioning (post v1.4.0) and tags are based on commit sha.

## Distroless Base Image

The Docker image uses Google's [distroless](https://github.com/GoogleContainerTools/distroless) base image (`gcr.io/distroless/static-debian12:nonroot`) for enhanced security and minimal attack surface. Distroless images contain only the application and its runtime dependencies, omitting unnecessary OS components like package managers, shells, and other utilities.

The image is pinned to a specific SHA digest for deterministic builds and uses the `nonroot` variant to run as a non-privileged user, following security best practices.

### Benefits of Distroless:

- **Enhanced Security**: Minimal attack surface with no unnecessary components
- **Smaller Image Size**: Significantly smaller than traditional base images
- **Reduced Vulnerabilities**: Fewer components means fewer potential security issues
- **Better Compliance**: Meets security requirements for minimal base images
- **Non-root Execution**: Runs as a non-privileged user (UID 65532) for enhanced security
- **Deterministic Builds**: Pinned to specific SHA digest ensures reproducible builds

### Debugging with Distroless:

For debugging purposes, you can use the debug variant of the distroless image:

```dockerfile
FROM gcr.io/distroless/static-debian12:debug
COPY --from=build /go/bin/ratelimit /bin/ratelimit
```

This provides shell access and debugging tools while maintaining the security benefits of distroless.

# Supported Envoy APIs

[v3 rls.proto](https://github.com/envoyproxy/data-plane-api/blob/master/envoy/service/ratelimit/v3/rls.proto) is currently supported.
Expand Down Expand Up @@ -132,14 +161,13 @@ Support for [v2 rls proto](https://github.com/envoyproxy/data-plane-api/blob/mas

## Docker-compose setup

The docker-compose setup has three containers: redis, ratelimit-build, and ratelimit. In order to run the docker-compose setup from the root of the repo, run
The docker-compose setup uses a distroless-based container for the ratelimit service. In order to run the docker-compose setup from the root of the repo, run

```bash
docker-compose up
```

The ratelimit-build container will build the ratelimit binary. Then via a shared volume the binary will be shared with the ratelimit container. This dual container setup is used in order to use a
a minimal container to run the application, rather than the heftier container used to build it.
The ratelimit service is built using the main Dockerfile which uses Google's distroless base image for enhanced security and minimal attack surface. The distroless image contains only the application and its runtime dependencies, omitting unnecessary OS components like package managers and shells.

If you want to run with [two redis instances](#two-redis-instances), you will need to modify
the docker-compose.yml file to run a second redis container, and change the environment variables
Expand Down
30 changes: 4 additions & 26 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,20 @@ services:
networks:
- ratelimit-network

# minimal container that builds the ratelimit service binary and exits.
ratelimit-build:
image: golang:1.23.9-alpine
working_dir: /go/src/github.com/envoyproxy/ratelimit
command: go build -o /usr/local/bin/ratelimit ./src/service_cmd/main.go
volumes:
- .:/go/src/github.com/envoyproxy/ratelimit
- binary:/usr/local/bin/

ratelimit-client-build:
image: golang:1.23.9-alpine
working_dir: /go/src/github.com/envoyproxy/ratelimit
command: go build -o /usr/local/bin/ratelimit_client ./src/client_cmd/main.go
volumes:
- .:/go/src/github.com/envoyproxy/ratelimit
- binary:/usr/local/bin/

ratelimit:
image: alpine:3.6
command: >
sh -c "until test -f /usr/local/bin/ratelimit; do sleep 5; done; /usr/local/bin/ratelimit"
build:
context: .
dockerfile: Dockerfile
command: /bin/ratelimit
ports:
- 8080:8080
- 8081:8081
- 6070:6070
depends_on:
- redis
- ratelimit-build
- ratelimit-client-build
networks:
- ratelimit-network
volumes:
- binary:/usr/local/bin/
- ./examples:/data
environment:
- USE_STATSD=false
Expand All @@ -63,6 +44,3 @@ services:

networks:
ratelimit-network:

volumes:
binary:
Loading