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
36 changes: 36 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Git
.git
.gitignore
.github

# Build artifacts
dist/
*.tar.gz
*.zip

# Documentation
*.md
CLAUDE.md
LICENSE

# IDE and editors
.vscode/
.idea/
*.swp
*.swo
*~

# OS files
.DS_Store
Thumbs.db

# Go test cache
*.test
*.out
coverage.txt

# Dependencies (will be downloaded during build)
vendor/

# CI/CD
.github/
101 changes: 98 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ permissions:
jobs:
build-all-platforms:
runs-on: mac-mini-org-heart

outputs:
version: ${{ steps.buildvars.outputs.version }}
commit: ${{ steps.buildvars.outputs.commit }}
build_time: ${{ steps.buildvars.outputs.time }}

steps:
- name: Checkout tag
Expand Down Expand Up @@ -66,7 +67,7 @@ jobs:
anytype-cli-*.tar.gz
anytype-cli-*.zip

create-release:
create_release:
needs: build-all-platforms
runs-on: ubuntu-latest

Expand All @@ -81,11 +82,105 @@ jobs:
run: ls -la artifacts/

- name: Create Release & Upload Assets
id: create_release
uses: softprops/action-gh-release@v2
with:
name: ${{ github.ref_name }}
files: artifacts/anytype-cli-*
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref, '-rc') }}
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}

push-docker-image:
name: Build Docker image and push to registry
needs:
- build-all-platforms
- create_release
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.ref }}

- name: Set deploy-platforms
run: |
echo "DEPLOY_PLATFORMS=linux/amd64,linux/arm64" >> $GITHUB_ENV

- name: Normalization of the release version
id: release-version
shell: bash
run: |
tag="${{ github.ref_name }}"
ver="${tag#v}"
echo "RELEASE_VERSION=${ver}" >> "$GITHUB_OUTPUT"

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push to GitHub Container Registry
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: ${{ env.DEPLOY_PLATFORMS }}
push: true
build-args: |
VERSION=${{ needs.build-all-platforms.outputs.version }}
COMMIT=${{ needs.build-all-platforms.outputs.commit }}
BUILD_TIME=${{ needs.build-all-platforms.outputs.build_time }}
GIT_STATE=clean
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.ref_name }}
ghcr.io/${{ github.repository }}:v${{ steps.release-version.outputs.RELEASE_VERSION }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.description=Anytype CLI - Command-line interface for Anytype with embedded gRPC server
org.opencontainers.image.licenses=MIT
org.opencontainers.image.version=${{ steps.release-version.outputs.RELEASE_VERSION }}
org.opencontainers.image.revision=${{ github.sha }}

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push to Docker Hub
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: ${{ env.DEPLOY_PLATFORMS }}
push: true
build-args: |
VERSION=${{ needs.build-all-platforms.outputs.version }}
COMMIT=${{ needs.build-all-platforms.outputs.commit }}
BUILD_TIME=${{ needs.build-all-platforms.outputs.build_time }}
GIT_STATE=clean
tags: |
docker.io/${{ github.repository }}:latest
docker.io/${{ github.repository }}:${{ github.ref_name }}
docker.io/${{ github.repository }}:v${{ steps.release-version.outputs.RELEASE_VERSION }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.description=Anytype CLI - Command-line interface for Anytype with embedded gRPC server
org.opencontainers.image.licenses=MIT
org.opencontainers.image.version=${{ steps.release-version.outputs.RELEASE_VERSION }}
org.opencontainers.image.revision=${{ github.sha }}

70 changes: 70 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# syntax=docker/dockerfile:1

# =============================================================================
# Build stage
# =============================================================================
FROM golang:1.24-alpine AS builder

WORKDIR /app

# Install build dependencies
# - build-base: gcc, musl-dev (required for CGO/tantivy linking)
# - curl: for downloading the tantivy library
# - make: to use Makefile build
RUN apk add --no-cache build-base curl make

# Copy dependency files first for better layer caching
COPY go.mod go.sum ./
RUN go mod download && go mod verify

# Copy source code
COPY . .

# Build arguments for version info (pass via --build-arg)
ARG VERSION=unknown
ARG COMMIT=unknown
ARG BUILD_TIME=unknown
ARG GIT_STATE=unknown
ARG TARGETARCH

# Build a statically-linked binary via Makefile
RUN CGO_ENABLED=1 \
GOOS=linux \
GOARCH="${TARGETARCH}" \
BUILD_TAGS="noheic" \
EXTRA_LDFLAGS="-linkmode external -extldflags '-static'" \
OUTPUT=/app/anytype \
VERSION="${VERSION}" \
COMMIT="${COMMIT}" \
BUILD_TIME="${BUILD_TIME}" \
GIT_STATE="${GIT_STATE}" \
make build

# =============================================================================
# Production stage
# =============================================================================
FROM alpine:3.23 AS production

WORKDIR /app

# Install ca-certificates for TLS and netcat for health checks
RUN apk add --no-cache ca-certificates netcat-openbsd

# Copy binary from builder
COPY --from=builder /app/anytype /app/anytype

# Note: Running as root to avoid volume permission issues in docker-compose

# gRPC (31010), gRPC-Web (31011), API (31012)
EXPOSE 31010 31011 31012

# Persistent data volumes
VOLUME ["/root/.anytype", "/root/.config/anytype"]

# Health check: verify gRPC port is accepting connections
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD nc -z 127.0.0.1 31010 || exit 1

# Run the embedded server in foreground
ENTRYPOINT ["/app/anytype"]
CMD ["serve"]