S3 / MinIO
Driver: s3
This storage driver stores the cache in a S3 compatible storage, e.g. AWS S3 or MinIO.
Configuration
docker-compose MinIO example
version: '3.9'
services:
cache-server:
image: ghcr.io/falcondev-oss/github-actions-cache-server:latest
ports:
- '3000:3000'
environment:
API_BASE_URL: http://localhost:3000
STORAGE_DRIVER: s3
STORAGE_S3_BUCKET: gh-actions-cache
AWS_ACCESS_KEY_ID: access_key
AWS_SECRET_ACCESS_KEY: secret_key
AWS_ENDPOINT_URL: http://minio:9000
volumes:
- cache-data:/app/.data
minio:
image: quay.io/minio/minio
ports:
- '9000:9000'
environment:
MINIO_ROOT_USER: access_key
MINIO_ROOT_PASSWORD: secret_key
volumes:
cache-data:docker-compose AWS S3 example
This example assumes that credentials are being provided by the environment, e.g. via an instance profile or EKS IRSA.
version: '3.9'
services:
cache-server:
image: ghcr.io/falcondev-oss/github-actions-cache-server:latest
ports:
- '3000:3000'
environment:
API_BASE_URL: http://localhost:3000
STORAGE_DRIVER: s3
STORAGE_S3_BUCKET: gh-actions-cache
volumes:
- cache-data:/app/.data
volumes:
cache-data:Environment Variables
The only required S3-related environment variables are STORAGE_DRIVER: s3 and STORAGE_S3_BUCKET. The rest of the environment variables are optional and depend on your S3-compatible storage provider.
The AWS SDK will automatically use any AWS credentials available in the environment, e.g. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION. Outside of AWS, these environment variables can still be used to authenticate with S3-compatible storage, as seen in the Minio example above.
Common environment variables are listed below. For a full list of configuration options, see the AWS SDK documentation.
STORAGE_S3_BUCKET
Example: gh-actions-cache
The name of the S3 bucket used for storage. This environment variable is always required.
AWS_REGION
Example: us-east-1
The AWS SDK relies on this variable being set. In the cache server, it defaults to us-east-1 if not provided. This has no effect if you are using a non-AWS S3-compatible storage provider, such as MinIO.
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
Example: AWS_ACCESS_KEY_ID: access_keyAWS_SECRET_ACCESS_KEY: secret_key
This is the access key/secret key used to authenticate with S3-compatible storage. If required to authenticate with your provider, these should be provided by the provider. Alternatively, you can use the AWS_PROFILE environment variable to specify a profile from your AWS credentials file.
AWS_PROFILE
Example: my-profile
If you wish to run the cache server locally and utilize a profile from your AWS credentials file or local AWS CLI configuration, you can set the AWS_PROFILE environment variable to the name of the profile. Note that this will also require mounting the AWS credentials file into the container in order for the SDK to be able to find it.
version: '3.9'
services:
cache-server:
image: ghcr.io/falcondev-oss/github-actions-cache-server:latest
ports:
- '3000:3000'
environment:
API_BASE_URL: http://localhost:3000
STORAGE_DRIVER: s3
STORAGE_S3_BUCKET: gh-actions-cache
AWS_PROFILE: my-profile
volumes:
- cache-data:/app/.data
# Mount the AWS CLI credentials and config into the container
- ~/.aws:/root/.aws:ro
volumes:
cache-data:AWS_ENDPOINT_URL
Example: http://minio:9000
This is the endpoint URL for the S3-compatible storage. This is only required if you are using a non-AWS S3-compatible storage provider, such as MinIO.
Minimal IAM permissions
The cache server only ever touches objects under the gh-actions-cache/ prefix in the bucket. These are all the actions it performs:
| Action | Used for |
|---|---|
s3:ListBucket | Startup bucket check, listing/counting cache objects |
s3:GetObject | Downloading cache entries, existence checks |
s3:PutObject | Uploading cache entries (multipart) |
s3:AbortMultipartUpload | Cleaning up failed multipart uploads |
s3:DeleteObject | Cache cleanup and abandoned uploads |
A minimal policy, scoped to the bucket and prefix (replace YOUR_BUCKET):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "github-actions-cache-server-bucket",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::YOUR_BUCKET"
},
{
"Sid": "github-actions-cache-server-objects",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:AbortMultipartUpload", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::YOUR_BUCKET/gh-actions-cache/*"
}
]
}Troubleshooting
Checksum errors with S3-compatible storage (Garage, MinIO)
Symptoms
Large cache entries fail to restore and the download hangs, with the runner eventually reporting a Premature close. Smaller entries work fine. Server logs show:
Checksum mismatch: expected "…" but received "…" in response header "x-amz-checksum-crc32"Cause
The cache server uploads larger entries as multipart objects. Some S3-compatible backends — notably Garage and some MinIO setups — compute multipart checksums differently from AWS S3. On download, the AWS SDK (which validates checksums by default) recomputes the checksum over the body, disagrees, and rejects the response mid-stream. Entries under the 5 MB multipart threshold aren't stored as multipart objects, which is why small caches are unaffected.
Fix
Tell the AWS SDK to only apply checksums when strictly required, restoring the behavior these backends expect:
environment:
AWS_REQUEST_CHECKSUM_CALCULATION: WHEN_REQUIRED
AWS_RESPONSE_CHECKSUM_VALIDATION: WHEN_REQUIRED