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
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
name: Test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.16.0

- name: Run tests
run: zig build test:all
39 changes: 39 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Docker

on:
push:
tags:
- '*.*.*'

jobs:
docker:
name: Build and push
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6

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

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

- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Extract version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT

- name: Build and push all variants
uses: docker/bake-action@v7
env:
VERSION: ${{ steps.version.outputs.VERSION }}
REGISTRY: ${{ secrets.DOCKERHUB_USERNAME }}/zedis
with:
push: true
98 changes: 71 additions & 27 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,58 @@ permissions:
contents: write

jobs:
test:
name: Test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.16.0

- name: Run tests
run: zig build test:all

build:
name: Build ${{ matrix.platform }}
needs: test
runs-on: ubuntu-latest
strategy:
matrix:
include:
- platform: linux-x86_64
target: x86_64-linux
binary: zedis
ext: ""
- platform: linux-aarch64
target: aarch64-linux
binary: zedis
ext: ""
- platform: macos-x86_64
target: x86_64-macos
binary: zedis
ext: ""
- platform: macos-arm64
target: aarch64-macos
binary: zedis
# - platform: windows-x86_64
# target: x86_64-windows
# binary: zedis.exe
ext: ""
- platform: windows-x86_64
target: x86_64-windows
binary: zedis.exe
ext: ".exe"

steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: master
version: 0.16.0

- name: Extract version from tag
id: version
Expand All @@ -44,13 +69,13 @@ jobs:
- name: Build
run: |
zig build -Doptimize=ReleaseFast -Dtarget=${{ matrix.target }}
cp zig-out/bin/${{ matrix.binary }} zedis-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}${{ matrix.platform == 'windows-x86_64' && '.exe' || '' }}
cp zig-out/bin/${{ matrix.binary }} zedis-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}${{ matrix.ext }}

- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: zedis-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}
path: zedis-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}${{ matrix.platform == 'windows-x86_64' && '.exe' || '' }}
path: zedis-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}${{ matrix.ext }}

release:
name: Create Release
Expand All @@ -59,7 +84,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: Extract version from tag
id: version
Expand All @@ -83,48 +108,67 @@ jobs:
sha256sum zedis-${{ steps.version.outputs.VERSION }}-* > SHA256SUMS

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
files: |
zedis-${{ steps.version.outputs.VERSION }}-linux-x86_64
zedis-${{ steps.version.outputs.VERSION }}-linux-aarch64
zedis-${{ steps.version.outputs.VERSION }}-macos-x86_64
zedis-${{ steps.version.outputs.VERSION }}-macos-arm64
# zedis-${{ steps.version.outputs.VERSION }}-windows-x86_64.exe
zedis-${{ steps.version.outputs.VERSION }}-windows-x86_64.exe
SHA256SUMS
body: |
${{ steps.changelog.outputs.changes }}

---

## Installation
## Install

### Download Binaries
**Linux (x86_64)**
```bash
curl -Lo zedis https://github.com/charlesfonseca/zedis/releases/download/${{ steps.version.outputs.VERSION }}/zedis-${{ steps.version.outputs.VERSION }}-linux-x86_64
chmod +x zedis && sudo mv zedis /usr/local/bin/
```

**Linux (ARM64)**
```bash
curl -Lo zedis https://github.com/charlesfonseca/zedis/releases/download/${{ steps.version.outputs.VERSION }}/zedis-${{ steps.version.outputs.VERSION }}-linux-aarch64
chmod +x zedis && sudo mv zedis /usr/local/bin/
```

Pre-built binaries are available for Linux, macOS, and Windows.
**macOS (Apple Silicon)**
```bash
curl -Lo zedis https://github.com/charlesfonseca/zedis/releases/download/${{ steps.version.outputs.VERSION }}/zedis-${{ steps.version.outputs.VERSION }}-macos-arm64
chmod +x zedis && sudo mv zedis /usr/local/bin/
```

**macOS (Intel)**
```bash
curl -Lo zedis https://github.com/charlesfonseca/zedis/releases/download/${{ steps.version.outputs.VERSION }}/zedis-${{ steps.version.outputs.VERSION }}-macos-x86_64
chmod +x zedis && sudo mv zedis /usr/local/bin/
```

1. Download the appropriate binary for your platform
2. Verify the checksum against SHA256SUMS
3. Make the binary executable (Linux/macOS): `chmod +x zedis-*`
4. Run the server: `./zedis-${{ steps.version.outputs.VERSION }}-<platform>`
**Windows** — download `zedis-${{ steps.version.outputs.VERSION }}-windows-x86_64.exe` from the assets above.

### Verify Checksums
### Verify checksums

```bash
sha256sum -c SHA256SUMS
```

### Quick Start
## Quick start

```bash
# Start the server (default: 127.0.0.1:6379)
./zedis-<platform>
# Start server (listens on 127.0.0.1:6379 by default)
zedis

# Connect using redis-cli
redis-cli -h 127.0.0.1 -p 6379
# Connect
redis-cli ping
# PONG

# Try some commands
SET mykey "Hello, Zedis!"
GET mykey
SET hello world
GET hello
# "world"
```
draft: false
prerelease: false
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

## [0.1.1] - 2026-04-24

### Added

- Add CI workflow running tests on push to main and pull requests.
- Add multi-variant Docker images: alpine, debian-slim, and distroless.
- Add Docker Bake configuration for parallel multi-platform builds (linux/amd64, linux/arm64).
- Add Docker Hub publishing workflow on tag push.
- Add release binaries for linux-aarch64 and windows-x86_64.

### Fixed

- Fix config file loading hanging on async file reader EOF by switching to `readPositionalAll`.
- Fix Dockerfile: drop unnecessary build dependencies, fix symlink trailing slash, use nologin shell for service user, fix healthcheck.

### Changed

- Gate release binary builds on passing tests.
- Update all GitHub Actions to latest versions.

## [0.1.0] - 2026-04-23

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

##############################################################################
# Stage: install Zig and build a static musl binary (works in all variants)
##############################################################################
FROM alpine:3.20 AS builder

ARG ZIG_VERSION=0.16.0

RUN apk add --no-cache curl xz

RUN case "$(uname -m)" in \
x86_64) ZIG_ARCH=x86_64 ;; \
aarch64) ZIG_ARCH=aarch64 ;; \
*) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;; \
esac && \
curl -fsSL "https://ziglang.org/download/${ZIG_VERSION}/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}.tar.xz" | \
tar -xJ -C /opt && \
ln -s /opt/zig-${ZIG_ARCH}-linux-${ZIG_VERSION} /opt/zig && \
ln -s /opt/zig/zig /usr/local/bin/zig

WORKDIR /build
COPY build.zig build.zig.zon ./
COPY src src/

RUN zig build -Doptimize=ReleaseSafe -Dtarget="$(uname -m)-linux-musl"

##############################################################################
# Stage: create data dir with correct ownership for distroless
##############################################################################
FROM busybox:musl AS dirs

RUN mkdir -p /home/nonroot/data && \
chown -R 65532:65532 /home/nonroot && \
touch /home/nonroot/data/.keep

##############################################################################
# alpine — default variant, smallest with shell access
##############################################################################
FROM alpine:3.20 AS alpine

RUN apk add --no-cache ca-certificates tzdata && \
adduser -D -s /sbin/nologin zedis

COPY --from=builder /build/zig-out/bin/zedis /usr/local/bin/zedis
COPY docker/zedis.conf /etc/zedis/zedis.conf

RUN mkdir -p /var/lib/zedis/data && \
chown -R zedis:zedis /var/lib/zedis /etc/zedis

USER zedis
WORKDIR /var/lib/zedis
EXPOSE 6379
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD sh -c 'printf "PING\r\n" | nc localhost 6379 -w1 | grep -q PONG'
ENTRYPOINT ["zedis", "/etc/zedis/zedis.conf"]

##############################################################################
# debian — glibc base, wider ecosystem compatibility
##############################################################################
FROM debian:bookworm-slim AS debian

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
tzdata \
netcat-openbsd \
&& rm -rf /var/lib/apt/lists/* \
&& useradd -r -s /usr/sbin/nologin zedis

COPY --from=builder /build/zig-out/bin/zedis /usr/local/bin/zedis
COPY docker/zedis.conf /etc/zedis/zedis.conf

RUN mkdir -p /var/lib/zedis/data && \
chown -R zedis:zedis /var/lib/zedis /etc/zedis

USER zedis
WORKDIR /var/lib/zedis
EXPOSE 6379
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD nc -z localhost 6379
ENTRYPOINT ["zedis", "/etc/zedis/zedis.conf"]

##############################################################################
# distroless — no shell, smallest attack surface
##############################################################################
FROM gcr.io/distroless/static-debian12 AS distroless

COPY --from=builder /build/zig-out/bin/zedis /usr/local/bin/zedis
COPY docker/zedis-distroless.conf /etc/zedis/zedis.conf
COPY --from=dirs /home/nonroot/data /home/nonroot/data

USER nonroot
WORKDIR /home/nonroot
EXPOSE 6379
ENTRYPOINT ["zedis", "/etc/zedis/zedis.conf"]
Loading
Loading