Skip to content

Commit 6a075b8

Browse files
feat: migrate to scratch-based Docker image
- Replace alpine base with scratch for minimal 16MB image - Remove docker_start.sh (no shell in scratch) - Use ENTRYPOINT + CMD for direct binary execution - Add CA certificates for HTTPS connections to LAPI - Add docker/README.md with comprehensive usage documentation
1 parent 383d8f6 commit 6a075b8

File tree

3 files changed

+191
-40
lines changed

3 files changed

+191
-40
lines changed

Dockerfile

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,30 @@ FROM golang:${GOVERSION}-alpine AS build
44

55
WORKDIR /go/src/cs-spoa-bouncer
66

7-
RUN apk add --update --no-cache make git
7+
RUN apk add --update --no-cache make git ca-certificates
88
COPY . .
99

1010
RUN make build DOCKER_BUILD=1
1111

12-
FROM alpine:latest
13-
COPY --from=build /go/src/cs-spoa-bouncer/crowdsec-spoa-bouncer /usr/local/bin/crowdsec-spoa-bouncer
14-
COPY --from=build /go/src/cs-spoa-bouncer/config/crowdsec-spoa-bouncer.yaml /etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml
15-
COPY --from=build /go/src/cs-spoa-bouncer/docker/docker_start.sh /docker_start.sh
16-
17-
# Set permissions for config file and binary
18-
RUN chmod 644 /etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml && \
19-
chmod 755 /usr/local/bin/crowdsec-spoa-bouncer
20-
21-
## Add the same haproxy user as the official haproxy image
22-
RUN addgroup -g 99 -S haproxy && adduser -S -D -H -u 99 -h /var/lib/haproxy -s /sbin/nologin -G haproxy -g haproxy haproxy
23-
## Add worker user
24-
RUN addgroup -S crowdsec-spoa && adduser -S -D -H -s /sbin/nologin -g crowdsec-spoa crowdsec-spoa
12+
# Final minimal image
13+
FROM scratch
2514

26-
## Create a socket for the spoa to inherit crowdsec-spoa:haproxy user from official haproxy image
27-
RUN mkdir -p /run/crowdsec-spoa/ && chown crowdsec-spoa:haproxy /run/crowdsec-spoa/ && chmod 770 /run/crowdsec-spoa/
15+
# Copy CA certificates for HTTPS connections to LAPI
16+
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
2817

29-
## Copy Lua files (matching Debian/RPM paths)
30-
RUN mkdir -p /usr/lib/crowdsec-haproxy-spoa-bouncer/lua
31-
COPY --from=build /go/src/cs-spoa-bouncer/lua/* /usr/lib/crowdsec-haproxy-spoa-bouncer/lua/
18+
# Copy the static binary
19+
COPY --from=build /go/src/cs-spoa-bouncer/crowdsec-spoa-bouncer /crowdsec-spoa-bouncer
3220

33-
## Copy templates (matching Debian/RPM paths)
34-
RUN mkdir -p /var/lib/crowdsec-haproxy-spoa-bouncer/html
35-
COPY --from=build /go/src/cs-spoa-bouncer/templates/* /var/lib/crowdsec-haproxy-spoa-bouncer/html/
36-
37-
RUN chown -R root:haproxy /usr/lib/crowdsec-haproxy-spoa-bouncer/lua /var/lib/crowdsec-haproxy-spoa-bouncer/html
21+
# Copy default config file
22+
COPY --from=build /go/src/cs-spoa-bouncer/config/crowdsec-spoa-bouncer.yaml /etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml
3823

39-
VOLUME [ "/usr/lib/crowdsec-haproxy-spoa-bouncer/lua/", "/var/lib/crowdsec-haproxy-spoa-bouncer/html/" ]
24+
# Copy Lua files for HAProxy integration
25+
COPY --from=build /go/src/cs-spoa-bouncer/lua/ /usr/lib/crowdsec-haproxy-spoa-bouncer/lua/
4026

41-
RUN chmod +x /docker_start.sh
27+
# Copy HTML templates for ban/captcha pages
28+
COPY --from=build /go/src/cs-spoa-bouncer/templates/ /var/lib/crowdsec-haproxy-spoa-bouncer/html/
4229

43-
# Run as user
44-
USER crowdsec-spoa
30+
EXPOSE 9000
4531

46-
ENTRYPOINT ["/docker_start.sh"]
32+
ENTRYPOINT ["/crowdsec-spoa-bouncer"]
33+
CMD ["-c", "/etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml"]

docker/README.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# CrowdSec HAProxy SPOA Bouncer Docker Image
2+
3+
This is a minimal scratch-based Docker image containing only the statically-linked bouncer binary and essential files.
4+
5+
## Image Contents
6+
7+
```
8+
/crowdsec-spoa-bouncer # The bouncer binary
9+
/etc/ssl/certs/ca-certificates.crt # CA certs for HTTPS to LAPI
10+
/etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml # Default config
11+
/usr/lib/crowdsec-haproxy-spoa-bouncer/lua/ # Lua files for HAProxy
12+
/var/lib/crowdsec-haproxy-spoa-bouncer/html/ # Ban/captcha templates
13+
```
14+
15+
## Quick Start
16+
17+
```bash
18+
docker run -d \
19+
--name crowdsec-spoa-bouncer \
20+
-e API_KEY=your-api-key \
21+
-p 9000:9000 \
22+
crowdsec/haproxy-spoa-bouncer
23+
```
24+
25+
## Configuration
26+
27+
### Environment Variables
28+
29+
The default config supports environment variable substitution for `API_KEY`. For other settings, mount a custom config file.
30+
31+
### Custom Configuration
32+
33+
```bash
34+
docker run -d \
35+
--name crowdsec-spoa-bouncer \
36+
-v /path/to/your/config.yaml:/etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml:ro \
37+
-p 9000:9000 \
38+
crowdsec/haproxy-spoa-bouncer
39+
```
40+
41+
Or specify a different config path:
42+
43+
```bash
44+
docker run -d \
45+
--name crowdsec-spoa-bouncer \
46+
-v /path/to/config.yaml:/config.yaml:ro \
47+
-p 9000:9000 \
48+
crowdsec/haproxy-spoa-bouncer -c /config.yaml
49+
```
50+
51+
### Unix Socket (Recommended for Same-Host HAProxy)
52+
53+
```bash
54+
docker run -d \
55+
--name crowdsec-spoa-bouncer \
56+
-v /path/to/config.yaml:/etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml:ro \
57+
-v /run/crowdsec-spoa:/run/crowdsec-spoa \
58+
crowdsec/haproxy-spoa-bouncer
59+
```
60+
61+
Ensure the socket directory exists and has appropriate permissions for HAProxy to connect.
62+
63+
## Docker Compose Example
64+
65+
```yaml
66+
services:
67+
crowdsec-spoa-bouncer:
68+
image: crowdsec/haproxy-spoa-bouncer
69+
restart: unless-stopped
70+
environment:
71+
- API_KEY=${CROWDSEC_API_KEY}
72+
volumes:
73+
- ./config/crowdsec-spoa-bouncer.yaml:/etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml:ro
74+
- spoa-socket:/run/crowdsec-spoa
75+
# Optional: resource limits
76+
deploy:
77+
resources:
78+
limits:
79+
memory: 256M
80+
# Optional: set GOMEMLIMIT for better memory management
81+
# environment:
82+
# - GOMEMLIMIT=200MiB
83+
84+
haproxy:
85+
image: haproxy:latest
86+
volumes:
87+
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
88+
- spoa-socket:/run/crowdsec-spoa
89+
ports:
90+
- "80:80"
91+
- "443:443"
92+
depends_on:
93+
- crowdsec-spoa-bouncer
94+
95+
volumes:
96+
spoa-socket:
97+
```
98+
99+
## Running as Non-Root
100+
101+
The scratch image runs as root by default. To run as a specific user:
102+
103+
```bash
104+
docker run -d \
105+
--user 1000:1000 \
106+
--name crowdsec-spoa-bouncer \
107+
-p 9000:9000 \
108+
crowdsec/haproxy-spoa-bouncer
109+
```
110+
111+
Note: Ensure mounted volumes have appropriate permissions for the specified user.
112+
113+
## Health Checks
114+
115+
The bouncer exposes Prometheus metrics when enabled in config:
116+
117+
```yaml
118+
prometheus:
119+
enabled: true
120+
listen_addr: 0.0.0.0
121+
listen_port: 60601
122+
```
123+
124+
Then use for health checks:
125+
126+
```bash
127+
docker run -d \
128+
--name crowdsec-spoa-bouncer \
129+
--health-cmd="wget -q --spider http://localhost:60601/metrics || exit 1" \
130+
--health-interval=30s \
131+
-p 9000:9000 \
132+
-p 60601:60601 \
133+
crowdsec/haproxy-spoa-bouncer
134+
```
135+
136+
Note: Since this is a scratch image, `wget` is not available. Use an external health check or a sidecar container for HTTP health probes.
137+
138+
## Ports
139+
140+
| Port | Description |
141+
|------|-------------|
142+
| 9000 | SPOA TCP listener (default) |
143+
| 60601 | Prometheus metrics (when enabled) |
144+
| 6060 | pprof debug endpoint (when enabled) |
145+
146+
## Troubleshooting
147+
148+
### View Logs
149+
150+
```bash
151+
docker logs -f crowdsec-spoa-bouncer
152+
```
153+
154+
### Debug Mode
155+
156+
Set `log_level: debug` in your config file for verbose logging.
157+
158+
### Connection Issues
159+
160+
1. Verify LAPI is reachable from the container
161+
2. Check API key is correct
162+
3. Ensure HAProxy can reach the SPOA listener (TCP port or Unix socket)
163+
164+
## Building the Image
165+
166+
```bash
167+
docker build -t crowdsec/haproxy-spoa-bouncer .
168+
```
169+
170+
### Build Arguments
171+
172+
| Argument | Default | Description |
173+
|----------|---------|-------------|
174+
| GOVERSION | 1.25 | Go version for build stage |
175+

docker/docker_start.sh

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)