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
72 changes: 72 additions & 0 deletions hackathon-CoC2026/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Hackathon developer environment (Community over Code 2026, Glasgow).
#
# This is a JDK-based development container, not a slim runtime image:
# participants are expected to edit Wayang source and rebuild Wayang during
# the hackathon, so we keep Maven Wrapper + git + the full source tree
# available inside it.
#
# Build context is the REPO ROOT (see compose.yaml: `context: ..`), because
# the whole source tree needs to be present to build Wayang.

FROM eclipse-temurin:17-jdk

LABEL org.opencontainers.image.source="https://github.com/apache/wayang"

# git -> some mvnw/plugin steps and contributor workflows expect it
# bash -> mvnw and our entrypoint are bash scripts
# postgresql-client -> lets participants run `psql` from inside the
# container to poke at the hackathon Postgres service
RUN apt-get update \
&& apt-get install -y --no-install-recommends git bash postgresql-client \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /workspace/wayang

# The source tree is normally supplied at runtime via the bind mount in
# compose.yaml (so local edits show up immediately). We still COPY it here
# so `docker build` works standalone, without compose, e.g. in CI.
COPY . /workspace/wayang

# The repo's Maven Wrapper is frequently checked out with CRLF line endings
# on Windows, which breaks execution inside the Linux container.
RUN sed -i 's/\r$//' mvnw \
&& chmod +x mvnw

COPY hackathon-CoC2026/docker/entrypoint.sh /usr/local/bin/wayang-entrypoint
RUN chmod +x /usr/local/bin/wayang-entrypoint

# Pre-warm the Maven local repo (~/.m2) at image build time, so a PUSHED,
# PULLED image already has every dependency downloaded — this is what
# actually gets participants under the 10-15 minute target, vs. a
# from-source build which takes much longer on a cold cache (see
# README.md "Timing"). This step builds against whatever source was
# checked out when this image was built.
#
# ~/.m2 lives outside /workspace/wayang, so it is NOT overwritten by the
# bind mount in compose.yaml. The first time the wayang-maven-cache named
# volume is created, Docker seeds it from this image layer automatically
# (standard behavior for a volume mounted over a non-empty image
# directory), so the warm cache survives into the running container.
RUN ./mvnw -B -q clean package -pl :wayang-assembly -Pdistribution -DskipTests \
&& ./mvnw -B -q dependency:build-classpath -pl :wayang-assembly \
-Dmdep.outputFile=/tmp/wayang-classpath.txt \
&& rm -rf /workspace/wayang/wayang-assembly/target

ENTRYPOINT ["wayang-entrypoint"]
CMD ["bash"]
30 changes: 30 additions & 0 deletions hackathon-CoC2026/Dockerfile.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

.git
.gitignore
**/target/

.idea/
.vscode/
*.iml

*.log

.DS_Store
Thumbs.db

.m2/
204 changes: 204 additions & 0 deletions hackathon-CoC2026/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# Wayang Hackathon Development Environment — Community over Code 2026, Glasgow

This folder is a self-contained Docker development environment for the Wayang
hackathon. It gets a contributor from a fresh checkout to a working build of
Wayang with the **Java**, **Spark**, and **PostgreSQL** platforms all
runnable inside the container.

This is a *developer* environment, not just a runtime: the full source tree
is bind-mounted into the container, so you edit code on your host machine
with your usual editor/IDE, and build/run it inside the container. Nothing
beyond Git and Docker Desktop is required on the host.

**Timing**: building the Wayang distribution from source on a cold Maven
cache takes 30-50+ minutes depending on network speed and machine specs —
that's just how long compiling Wayang and its dependency tree (including
Spark) genuinely takes the first time. That is NOT what hackathon
participants are expected to do. Instead, a multi-architecture image
supporting both linux/amd64 and linux/arm64 is built and pushed to
GitHub Container Registry ahead of the event, with its Maven cache
already warmed at build time. Participants just pull the image:

```bash
docker compose pull
docker compose up -d
```

This is the intended 10-15 minute setup path — it's a Docker image pull
plus container startup, not a build. `docker compose up -d --build`
(building from source locally) is still available and is what this README
documents step by step below, for contributors actively working on the
Dockerfile/build itself — participants on hackathon day shouldn't need it.

## What's here

```
hackathon-CoC2026/
├── Dockerfile # JDK 17 + git + Maven Wrapper + psql client
├── compose.yaml # the "wayang" dev container + a real "postgres" service
├── verify.sh # one-command build + cross-platform verification
├── docker/
│ ├── entrypoint.sh # normalizes mvnw line endings on every start
│ └── postgres/
│ └── init.sql # seeds a small table used by the Postgres smoke test
├── examples/
│ └── PostgresSmokeTest.java # a Wayang plan spanning Java, Spark, and Postgres
└── README.md # this file
```

## Prerequisites

Install on your host machine:

- [Git](https://git-scm.com/)
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) (includes
Docker Compose)

Verify:

```bash
docker --version
docker compose version
```

## 1. Get the source

```bash
git clone https://github.com/apache/wayang.git
cd wayang
```

(If you're working from a fork/branch, clone that instead.)

## 2. Start the environment

From this folder:

```bash
cd hackathon-CoC2026
docker compose pull # gets the pre-built, cache-warmed image (fast)
docker compose up -d
```

If you're actively changing the Dockerfile or want a from-source build
instead, use `docker compose up -d --build` (see Timing above — this is
slow on a cold cache).

Either way, this starts two services:

- `wayang` — the container you'll work in (Java 17 JDK, Maven Wrapper, git)
- `postgres` — a real PostgreSQL 16 instance, seeded with a small sample
table (`word_counts_seed`)

Check both containers are up:

```bash
docker compose ps
```

`postgres` should show as `healthy` before moving on (it has a healthcheck
that waits for it to accept connections).

## 3. Run the verification script

```bash
docker compose exec wayang bash hackathon-CoC2026/verify.sh
```
**Note:** `verify.sh` performs a full Wayang distribution build to validate
the development environment end-to-end. This build can take 30-50+ minutes
on a cold Maven cache. It is not required to start the pre-built hackathon
environment and is not part of the 10-15 minute participant setup target.

This single command: builds `wayang-assembly`, extracts the distribution,
runs the bundled WordCount app on the Java platform, resolves the full
Maven runtime classpath, and compiles + runs `PostgresSmokeTest.java` — a
Wayang plan that reads from Postgres, filters on Java, and maps on Spark.

The distribution's extracted layout is `bin/`, `conf/`, `jars/`, and
`libs/`. Both `jars/*` and `libs/*` are needed on the classpath to compile
and run against Wayang's own modules — `jars/` alone is not enough. Neither
directory contains Spark's own transitive runtime dependencies (e.g.
`spark-sql`), though — those are only resolved through Maven's local
repository, via `./mvnw -pl wayang-assembly dependency:build-classpath`,
which is why `verify.sh` builds the classpath from both sources combined.

You do not need to hand-edit `bin/wayang-submit` or add `--add-opens`/
`--add-exports` flags yourself — the script uses `wayang-submit` as-is for
the Java check, and pulls the same flags straight out of that script for its
own direct `java` invocation of the smoke test.

Confirmed working output looks like this:

```
Wayang plan executed across Postgres, Java, and Spark. Results:
WAYANG -> 42
SPARK -> 17
POSTGRES -> 9
Total rows: 3
```

If it fails, see Troubleshooting below.

You can also poke at the database directly from inside the container:

```bash
psql -h postgres -U wayang -d wayang_hackathon -c "select * from word_counts_seed;"
# password: wayang
```

## Troubleshooting

- **`mvnw: command not found` / permission denied** — the entrypoint fixes
line endings and permissions on `mvnw` on every container start, but if
you edited/replaced it from the host afterward, re-run
`sed -i 's/\r$//' mvnw && chmod +x mvnw` inside the container.
- **Postgres connection refused** — wait for `docker compose ps` to show
`postgres` as `healthy`; the `wayang` service is configured to start after
that, but a manual `docker compose exec` shell you opened earlier may have
started before it. Just retry.
- **Slow first build** — this is the Maven dependency download, not a bug
(see Timing above). It's cached in the `wayang-maven-cache` volume;
`docker compose down` (without `-v`) keeps it, `docker compose down -v`
deletes it.
- **Out of memory during the build** — increase Docker Desktop's memory
limit (Settings → Resources).
- **`ClassNotFoundException`/`NoClassDefFoundError` for a Spark class** —
confirm `/tmp/wayang-classpath.txt` from `verify.sh` actually contains
`spark-sql` and `spark-sql-api` jars; if not, re-run the `dependency:
build-classpath` step and check for Maven resolution errors above it.
- **`no matching manifest for linux/arm64/v8`** — the published image may
not include an ARM64 variant. Ensure the image supports both
`linux/amd64` and `linux/arm64` platforms, then run
`docker compose pull` again.
- **`tar: ... Function not implemented` on Apple Silicon** — this can occur
when an AMD64-only image is forced to run on an ARM64 host through
emulation. Do not force `linux/amd64`; use the multi-architecture image
so Docker pulls the native ARM64 variant.

## Resetting everything

```bash
docker compose down -v
```

This removes both containers and both named volumes (Maven cache and
Postgres data), so the next `docker compose up -d --build` starts completely
fresh.

## For maintainers: publishing the image

The hackathon image is published to GitHub Container Registry (GHCR).
To publish an updated image, build and push images for both `linux/amd64`
and `linux/arm64`, then create a multi-architecture manifest for the shared
tag. Ensure the published package is public so participants can pull it
without authenticating.

After publishing an update, verify that both architectures are present and
that the image passes the end-to-end smoke test.

## Later platforms

This environment currently exercises Java, Spark, and PostgreSQL, per the
initial hackathon scope. Adding another platform (e.g. SQLite, GraphChi)
only requires seeding/service changes here in `hackathon-CoC2026/` — the
`Dockerfile` and `compose.yaml` at the repository root are untouched.
82 changes: 82 additions & 0 deletions hackathon-CoC2026/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Run from this folder with: docker compose up -d --build
#
# Paths below (context, volumes) are relative to THIS file, so `..` means
# the repository root.

services:
wayang:
# `docker compose up -d` (no --build) pulls this pre-built image, which
# already has its Maven cache warmed — this is what gets participants
# to a working setup in minutes on hackathon day. `docker compose up -d
# --build` ignores this and builds locally from the Dockerfile instead,
# which is slower (see README.md "Timing") but always matches your
# exact checkout — useful for contributors actively changing the
# Dockerfile/build itself, not needed for hackathon participants.
image: ghcr.io/mohit-devlogs/wayang-hackathon:latest
build:
context: ..
dockerfile: hackathon-CoC2026/Dockerfile
container_name: wayang-hackathon
security_opt:
- seccomp=unconfined
working_dir: /workspace/wayang
volumes:
# Full repo, read-write, so edits made on the host (or inside the
# container) are shared both ways.
- ..:/workspace/wayang
# Named volume for the Maven local repo: keeps ~/.m2 between
# `docker compose down` / `up` cycles so dependencies aren't
# re-downloaded every time.
- wayang-maven-cache:/root/.m2
environment:
# Picked up by hackathon-CoC2026/examples/PostgresSmokeTest.java and
# can be used from any app via System.getenv(...) or by writing them
# into a wayang.properties file (see README.md).
WAYANG_POSTGRES_JDBC_URL: jdbc:postgresql://postgres:5432/wayang_hackathon
WAYANG_POSTGRES_USER: wayang
WAYANG_POSTGRES_PASSWORD: wayang
depends_on:
postgres:
condition: service_healthy
stdin_open: true
tty: true

postgres:
image: postgres:16-alpine
container_name: wayang-hackathon-postgres
environment:
POSTGRES_DB: wayang_hackathon
POSTGRES_USER: wayang
POSTGRES_PASSWORD: wayang
volumes:
- ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
- wayang-postgres-data:/var/lib/postgresql/data
ports:
# Exposed on the host too, so participants can point a local SQL
# client at it if they want (e.g. `psql -h localhost -p 55432`).
- "55432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U wayang -d wayang_hackathon"]
interval: 5s
timeout: 5s
retries: 20

volumes:
wayang-maven-cache:
wayang-postgres-data:
Loading
Loading