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
34 changes: 34 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Keep the build context to what `go build` actually needs.

# VCS / CI / editor tooling
.git
.github
.claude
.vscode
.idea
.DS_Store

# Docs, examples, fixtures, generated output
docs
example
output
test
*.md
LICENSE

# Test sources (ignored by `go build` anyway)
**/*_test.go

# Local build artifacts / coverage / databases
mmdb-cli
dist
coverage.out
*.out
*.mmdb

# Release tooling config (not used by the Docker build)
.goreleaser.yml

# The Docker build files themselves
Dockerfile
.dockerignore
106 changes: 106 additions & 0 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Docker Image

on:
push:
branches:
- main
tags:
- "v*.*.*"
pull_request:
branches:
- main
workflow_dispatch:

permissions:
contents: read
packages: write

concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 0

# GHCR image always mirrors the repository path, lower-cased.
- name: Resolve image name
id: images
run: echo "ghcr=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"

- name: Set up QEMU
uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # v4.3.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0

- name: Log in to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: ${{ steps.images.outputs.ghcr }}
# `latest` tracks the main branch
# Release tags publish immutable X.Y.Z tags
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,format=short,enable={{is_default_branch}}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
flavor: |
latest=false
labels: |
org.opencontainers.image.title=mmdb-cli
org.opencontainers.image.description=Command-line toolkit to create, transform, export and inspect MMDB files

- name: Compute build version
id: version
run: |
if [ "${{ github.ref_type }}" = "tag" ]; then
echo "value=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
else
echo "value=edge-$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
fi

- name: Build and push
id: build
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
build-args: |
VERSION=${{ steps.version.outputs.value }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
sbom: true

- name: Summary
if: github.event_name != 'pull_request'
run: |
{
echo "### Docker image published"
echo
echo '```'
echo "${{ steps.meta.outputs.tags }}"
echo '```'
echo
echo "Digest: \`${{ steps.build.outputs.digest }}\`"
} >> "$GITHUB_STEP_SUMMARY"
47 changes: 47 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FROM --platform=${BUILDPLATFORM} golang:1.26-alpine AS build

# Provided automatically by buildx for each target in the manifest list
ARG TARGETOS
ARG TARGETARCH

# Version string baked into `mmdb-cli version`. Defaults to the in-repo placeholder
# CI passes the git tag or an "edge-<sha>" value
ARG VERSION=v0.0.0

WORKDIR /src

COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download

COPY . .

# Mirrors .github/pre-release-hook.sh
RUN if [ "${VERSION}" != "v0.0.0" ]; then \
sed -i "s/v0.0.0/${VERSION}/" internal/metadata/metadata.go; \
fi

RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS="${TARGETOS}" GOARCH="${TARGETARCH}" \
go build -trimpath -ldflags="-s -w" -o /out/mmdb-cli .

FROM alpine:3

WORKDIR /data

RUN apk add --no-cache ca-certificates tzdata \
&& adduser -D -u 1000 -h /home/infraz infraz \
&& chown infraz:infraz /data

COPY --from=build /out/mmdb-cli /usr/local/bin/mmdb-cli

LABEL org.opencontainers.image.title="mmdb-cli" \
org.opencontainers.image.description="Command-line toolkit to create, transform, export and inspect MMDB files" \
org.opencontainers.image.source="https://github.com/InfraZ/mmdb-cli" \
org.opencontainers.image.documentation="https://docs.infraz.io/docs/mmdb-cli" \
org.opencontainers.image.licenses="Apache-2.0"

USER infraz
ENTRYPOINT ["mmdb-cli"]
CMD ["--help"]
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,41 @@ brew install infraz/tap/mmdb-cli
mmdb-cli --version
```

## Container Image

Pre-built multi-arch images (`linux/amd64`, `linux/arm64`) are published to
the GitHub Container Registry:

| Reference | Points to |
| :-- | :-- |
| `ghcr.io/infraz/mmdb-cli:latest` | Latest commit on `main` |
| `ghcr.io/infraz/mmdb-cli:1.2.3` (also `:1.2`, `:1`) | Tagged release `v1.2.3` |
| `ghcr.io/infraz/mmdb-cli:sha-abc1234` | A specific `main` commit |

The image `ENTRYPOINT` is `mmdb-cli` and the working directory is `/data`, so
mount your files there:

```bash
# Inspect a database
docker run --rm -v "$PWD:/data" ghcr.io/infraz/mmdb-cli:latest \
metadata -i GeoLite2-City.mmdb

# Generate a database from a JSON dataset (writes back to the host)
docker run --rm -v "$PWD:/data" --user "$(id -u):$(id -g)" \
ghcr.io/infraz/mmdb-cli:latest \
generate -i dataset.json -o result.mmdb
```

The container runs as a non-root user (UID 1000). When writing files to a
bind mount, add `--user "$(id -u):$(id -g)"` so the output is owned by you.

### Building the image locally

```bash
docker build -t mmdb-cli --build-arg VERSION=v0.0.0-dev .
docker run --rm mmdb-cli version
```

## Development

To get started, clone the repository and run the following commands to download the dependencies:
Expand Down
Loading