Skip to content

Commit bdfa553

Browse files
committed
feat: Create a dockerfile for cachew
1 parent ecf5911 commit bdfa553

3 files changed

Lines changed: 232 additions & 15 deletions

File tree

Dockerfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
ARG ALPINE_VERSION=3.21
2+
FROM alpine:${ALPINE_VERSION}
3+
4+
ARG TARGETARCH
5+
ARG TARGETPLATFORM
6+
7+
SHELL ["/bin/sh", "-o", "pipefail", "-c"]
8+
9+
# Install runtime dependencies for git operations and TLS
10+
RUN apk add --no-cache ca-certificates git
11+
12+
# Set working directory (config uses relative paths like ./state/cache)
13+
WORKDIR /app
14+
15+
# Copy pre-built binary for the target architecture
16+
COPY dist/cachewd-linux-${TARGETARCH} /usr/local/bin/cachewd
17+
18+
# Copy default configuration file
19+
COPY cachew.hcl /app/cachew.hcl
20+
21+
# Bind to all interfaces in Docker (can be overridden with CACHEW_BIND env var)
22+
ENV CACHEW_BIND=0.0.0.0:8080
23+
24+
ENTRYPOINT ["/usr/local/bin/cachewd"]
25+
CMD ["--config", "/app/cachew.hcl"]

Justfile

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
set positional-arguments := true
22
set shell := ["bash", "-c"]
33

4+
# Configuration
5+
6+
VERSION := `git describe --tags --always --dirty 2>/dev/null || echo "dev"`
7+
GIT_COMMIT := `git rev-parse HEAD 2>/dev/null || echo "unknown"`
8+
TAG := `git rev-parse --short HEAD 2>/dev/null || echo "dev"`
9+
RELEASE := "dist"
10+
REGISTRY := env_var_or_default("REGISTRY", "268271485387.dkr.ecr.us-west-2.amazonaws.com")
11+
IMAGE_NAME := "cachew"
12+
IMAGE_REF := REGISTRY + "/" + IMAGE_NAME + ":" + TAG
13+
IMAGE_LATEST := REGISTRY + "/" + IMAGE_NAME + ":latest"
14+
415
_help:
516
@just -l
617

@@ -18,3 +29,140 @@ fmt:
1829
just --unstable --fmt
1930
golangci-lint fmt
2031
go mod tidy
32+
33+
# ============================================================================
34+
# Build
35+
# ============================================================================
36+
37+
# Build for current platform
38+
build:
39+
@mkdir -p {{ RELEASE }}
40+
@go build -trimpath -o {{ RELEASE }}/cachewd \
41+
-ldflags "-s -w -X main.version={{ VERSION }} -X main.gitCommit={{ GIT_COMMIT }}" \
42+
./cmd/cachewd
43+
@echo "✓ Built {{ RELEASE }}/cachewd"
44+
45+
# Build for Linux (current arch)
46+
build-linux:
47+
#!/usr/bin/env bash
48+
set -e
49+
mkdir -p {{ RELEASE }}
50+
ARCH=$(uname -m)
51+
[[ "$ARCH" == "x86_64" ]] && ARCH="amd64"
52+
[[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]] && ARCH="arm64"
53+
echo "Building for linux/${ARCH}..."
54+
GOOS=linux GOARCH=${ARCH} go build -trimpath \
55+
-o {{ RELEASE }}/cachewd-linux-${ARCH} \
56+
-ldflags "-s -w -X main.version={{ VERSION }} -X main.gitCommit={{ GIT_COMMIT }}" \
57+
./cmd/cachewd
58+
echo "✓ Built {{ RELEASE }}/cachewd-linux-${ARCH}"
59+
60+
# Build all platforms
61+
build-all:
62+
@mkdir -p {{ RELEASE }}
63+
@echo "Building all platforms..."
64+
@GOOS=darwin GOARCH=arm64 go build -trimpath -o {{ RELEASE }}/cachewd-darwin-arm64 -ldflags "-s -w -X main.version={{ VERSION }} -X main.gitCommit={{ GIT_COMMIT }}" ./cmd/cachewd
65+
@GOOS=darwin GOARCH=amd64 go build -trimpath -o {{ RELEASE }}/cachewd-darwin-amd64 -ldflags "-s -w -X main.version={{ VERSION }} -X main.gitCommit={{ GIT_COMMIT }}" ./cmd/cachewd
66+
@GOOS=linux GOARCH=arm64 go build -trimpath -o {{ RELEASE }}/cachewd-linux-arm64 -ldflags "-s -w -X main.version={{ VERSION }} -X main.gitCommit={{ GIT_COMMIT }}" ./cmd/cachewd
67+
@GOOS=linux GOARCH=amd64 go build -trimpath -o {{ RELEASE }}/cachewd-linux-amd64 -ldflags "-s -w -X main.version={{ VERSION }} -X main.gitCommit={{ GIT_COMMIT }}" ./cmd/cachewd
68+
@echo "✓ Built all platforms"
69+
70+
# ============================================================================
71+
# Docker
72+
# ============================================================================
73+
74+
# Build single-arch Docker image
75+
docker-build: build-linux
76+
#!/usr/bin/env bash
77+
set -e
78+
ARCH=$(uname -m)
79+
[[ "$ARCH" == "x86_64" ]] && ARCH="amd64"
80+
[[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]] && ARCH="arm64"
81+
echo "Building Docker image for linux/${ARCH}..."
82+
docker build --platform linux/${ARCH} -t {{ IMAGE_NAME }}:local .
83+
echo "✓ Built {{ IMAGE_NAME }}:local"
84+
85+
# Build multi-arch Docker image
86+
docker-build-multi: build-all
87+
#!/usr/bin/env bash
88+
set -e
89+
BUILDER="multi-arch-{{ IMAGE_NAME }}"
90+
docker buildx create --driver docker-container --driver-opt image=moby/buildkit:v0.17.3 --name "$BUILDER" 2>/dev/null || true
91+
docker buildx use "$BUILDER"
92+
echo "Building multi-arch image..."
93+
docker buildx build --platform linux/amd64,linux/arm64 \
94+
-t {{ IMAGE_REF }} -t {{ IMAGE_LATEST }} .
95+
echo "✓ Built multi-arch image"
96+
97+
# ============================================================================
98+
# Run
99+
# ============================================================================
100+
101+
# Run natively
102+
run: build
103+
@echo "→ Starting cachew at http://localhost:8080"
104+
@mkdir -p state
105+
@{{ RELEASE }}/cachewd --config cachew.hcl
106+
107+
# Run in Docker (optionally with debug: just docker-run debug)
108+
docker-run log_level="info": docker-build
109+
@echo "→ Starting cachew at http://localhost:8080 (log-level={{ log_level }})"
110+
@docker run --rm -it -p 8080:8080 -v $(pwd)/state:/app/state --name {{ IMAGE_NAME }} {{ IMAGE_NAME }}:local --log-level={{ log_level }}
111+
112+
# Clean up build artifacts and Docker images
113+
docker-clean:
114+
@echo "Cleaning..."
115+
@rm -rf {{ RELEASE }}
116+
@docker rmi {{ IMAGE_NAME }}:local 2>/dev/null || true
117+
@docker rmi {{ IMAGE_REF }} 2>/dev/null || true
118+
@docker rmi {{ IMAGE_LATEST }} 2>/dev/null || true
119+
@echo "✓ Cleaned"
120+
121+
# ============================================================================
122+
# ECR Push
123+
# ============================================================================
124+
125+
# Push to ECR
126+
image-push tag="latest": build-all
127+
#!/usr/bin/env bash
128+
set -e
129+
130+
# Login to ECR
131+
echo "→ Authenticating to ECR..."
132+
aws-creds sync
133+
export AWS_REGION="us-west-2"
134+
export AWS_PROFILE=block-coder-comp-staging--dx-admin-operator
135+
136+
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
137+
ECR_REGISTRY="${AWS_ACCOUNT_ID}.dkr.ecr.us-west-2.amazonaws.com"
138+
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY
139+
aws ecr create-repository --repository-name {{ IMAGE_NAME }} --region $AWS_REGION 2>/dev/null || true
140+
141+
# Build and push
142+
BUILDER="multi-arch-{{ IMAGE_NAME }}"
143+
docker buildx rm "$BUILDER" 2>/dev/null || true
144+
docker buildx create --driver docker-container --driver-opt image=moby/buildkit:v0.17.3 --name "$BUILDER"
145+
docker buildx use "$BUILDER"
146+
147+
TAGS="-t {{ IMAGE_REF }}"
148+
[[ "{{ tag }}" == "latest" ]] && TAGS="$TAGS -t {{ IMAGE_LATEST }}"
149+
150+
echo "→ Pushing multi-arch image..."
151+
docker buildx build --platform linux/amd64,linux/arm64 $TAGS --push .
152+
echo "✓ Pushed to ECR"
153+
154+
# Push to ECR (CI - no login)
155+
image-push-ci tag="latest": build-all
156+
#!/usr/bin/env bash
157+
set -e
158+
BUILDER="multi-arch-{{ IMAGE_NAME }}"
159+
docker buildx rm "$BUILDER" 2>/dev/null || true
160+
docker buildx create --driver docker-container --driver-opt image=moby/buildkit:v0.17.3 --name "$BUILDER"
161+
docker buildx use "$BUILDER"
162+
163+
TAGS="-t {{ IMAGE_REF }}"
164+
[[ "{{ tag }}" == "latest" ]] && TAGS="$TAGS -t {{ IMAGE_LATEST }}"
165+
166+
echo "→ Pushing multi-arch image..."
167+
docker buildx build --platform linux/amd64,linux/arm64 $TAGS --push .
168+
echo "✓ Pushed to ECR"

README.md

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,73 @@ Cachew is a server and tooling for incredibly efficient, protocol-aware caching.
44
designed to be used at scale, with minimal impact on upstream systems. By "protocol-aware", we mean that the proxy isn't
55
just a naive HTTP proxy, it is aware of the higher level protocol being proxied (Git, Docker, etc.) and can make more efficient decisions.
66

7-
## Git
7+
## Quick Start
88

9-
Git causes a number of problems for us, but the most obvious are:
9+
### Local Development
1010

11-
1. Rate limiting by service providers.
12-
2. `git clone` is very slow, even discounting network overhead
11+
**Run natively (fastest for development):**
12+
```bash
13+
just run # Build and run on localhost:8080
14+
```
15+
16+
**Run in Docker:**
17+
```bash
18+
just docker-run # Build and run in container
19+
just docker-run debug # Run with debug logging
20+
```
21+
22+
### Using the Cache
23+
24+
The `cachew` CLI client interacts with the `cachewd` server:
25+
26+
```bash
27+
# Upload to cache
28+
cachew put my-key myfile.txt --ttl 24h
29+
30+
# Download from cache
31+
cachew get my-key -o myfile.txt
1332

14-
To solve this we apply two different strategies on the server:
33+
# Check if cached
34+
cachew stat my-key
1535

16-
1. Periodic full `.tar.zst` snapshots of the repository. These snapshots restore 4-5x faster than `git clone`.
17-
2. Passthrough caching of the packs returned by `POST /repo.git/git-upload-pack` to support incremental pulls.
36+
# Snapshot a directory
37+
cachew snapshot deps-cache ./node_modules --ttl 7d
1838

19-
On the client we redirect git to the proxy:
39+
# Restore a directory
40+
cachew restore deps-cache ./node_modules
41+
```
42+
43+
### Building and Testing
2044

21-
```ini
22-
[url "https://cachew.local/github/"]
23-
insteadOf = https://github.com/
45+
```bash
46+
just build # Build for current platform
47+
just build-linux # Build for Linux (for Docker)
48+
just build-all # Build all platforms
49+
just test # Run tests
50+
just lint # Lint code
51+
just fmt # Format code
2452
```
2553

26-
As Git itself isn't aware of the snapshots, Git-specific code in the Cachew CLI can be used to reconstruct a repository.
54+
## Docker Images
2755

28-
## Docker
56+
### Build Images
57+
58+
```bash
59+
just docker-build # Single-arch local image (fast)
60+
just docker-build-multi # Multi-arch image for ECR
61+
```
62+
63+
### Push to ECR
64+
65+
**Push from local machine:**
66+
```bash
67+
just image-push # Push with commit SHA tag
68+
just image-push latest # Push :latest and commit SHA tags
69+
```
70+
## Configuration
2971

30-
## Hermit
72+
The default configuration is in `cachew.hcl`. Key settings:
3173

32-
Hermit
74+
- **Disk cache**: `./state/cache` (250GB limit, 8h TTL)
75+
- **Git mirrors**: `./state/git-mirrors`
76+
- **Bind address**: `0.0.0.0:8080` (in Docker), `127.0.0.1:8080` (native)

0 commit comments

Comments
 (0)