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
22 changes: 22 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Rust build artifacts (these are rebuilt inside the container)
**/target/

# Git
.git/

# Local dev artifacts that aren't needed in build context
local-dev/secrets/
local-dev/scripts/

# Editor / OS junk
.vscode/
.idea/
*.swp
*.swo
.DS_Store

# Compiled modules (rebuilt in container)
compiled_modules/

# Testing artifacts
testing/
67 changes: 67 additions & 0 deletions .github/workflows/LocalDevCheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Local Dev Check

on:
push:
branches: [main, develop]
pull_request:
branches: "**"

permissions:
contents: read

jobs:
local-dev-smoke-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Build local-dev docker-compose
run: docker compose -f local-dev/docker-compose.yml build

- name: Create empty secrets file
run: touch local-dev/secrets/secrets.toml

- name: Start services
run: docker compose -f local-dev/docker-compose.yml up -d

- name: Wait for healthy
run: |
timeout=120
elapsed=0
while [ $elapsed -lt $timeout ]; do
status=$(docker inspect --format='{{.State.Health.Status}}' $(docker compose -f local-dev/docker-compose.yml ps -q plaid) 2>/dev/null || echo "unknown")
if [ "$status" = "healthy" ]; then
echo "Service is healthy after ${elapsed}s"
exit 0
fi
echo "Waiting for healthy... (${elapsed}s, status: $status)"
sleep 5
elapsed=$((elapsed + 5))
done
echo "Timed out waiting for healthy status after ${timeout}s"
exit 1

- name: Validate health endpoint
run: |
response=$(curl -sf http://localhost:8080/webhook/health)
if [ "$response" != "ok" ]; then
echo "Expected 'ok', got: $response"
exit 1
fi
echo "Health check returned: $response"

- name: Validate hello webhook
run: |
curl -sf -X POST \
-H "Content-Type: application/json" \
-d '{"test": true}' \
http://localhost:8080/webhook/hello

- name: Dump logs on failure
if: failure()
run: docker compose -f local-dev/docker-compose.yml logs

- name: Tear down
if: always()
run: docker compose -f local-dev/docker-compose.yml down -v
9 changes: 9 additions & 0 deletions local-dev/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Build artifacts
rules/target/
compiled_modules/

# Secrets (real secrets, not the example template)
secrets/secrets.toml

# Local overrides (per-developer customizations)
docker-compose.override.yml
73 changes: 73 additions & 0 deletions local-dev/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Multi-stage Dockerfile for local Plaid development.
#
# Stage 1: Build the plaid runtime (cranelift only — no LLVM needed)
# Stage 2: Build WASM rule modules
# Stage 3: Minimal runtime image

# ── Stage 1: Build plaid runtime ─────────────────────────────────────────────
ARG RUST_VERSION=1.88.0
FROM rust:${RUST_VERSION}-slim-bookworm AS runtime-builder

RUN apt-get update && apt-get install -y \
build-essential \
libsodium-dev \
libssl-dev \
libzstd-dev \
libz-dev \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /build
COPY runtime/ runtime/

RUN cargo build \
--manifest-path runtime/Cargo.toml \
--release \
--bin=plaid \
--no-default-features \
--features=cranelift,sled

# ── Stage 2: Build WASM modules ─────────────────────────────────────────────
ARG RUST_VERSION=1.88.0
FROM rust:${RUST_VERSION}-slim-bookworm AS module-builder

RUN rustup target add wasm32-unknown-unknown

WORKDIR /build
COPY runtime/plaid-stl/ runtime/plaid-stl/
COPY local-dev/rules/ local-dev/rules/

RUN cargo build \
--manifest-path local-dev/rules/Cargo.toml \
--release \
--target wasm32-unknown-unknown

# ── Stage 3: Runtime ─────────────────────────────────────────────────────────
FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y \
libsodium23 \
libssl3 \
libzstd1 \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*

RUN useradd -m plaiduser

# Copy runtime binary
COPY --from=runtime-builder /build/runtime/target/release/plaid /usr/local/bin/plaid

# Copy compiled WASM modules
COPY --from=module-builder \
/build/local-dev/rules/target/wasm32-unknown-unknown/release/*.wasm \
/modules/

# Default config + secrets paths (overridable via docker-compose volumes)
RUN mkdir -p /config /secrets /data && chown -R plaiduser:plaiduser /data

USER plaiduser

EXPOSE 8080

CMD ["plaid", "--config", "/config", "--secrets", "/secrets/secrets.toml"]
Loading