Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a6f0defd1 | |||
| 740382fca1 | |||
| 180acc92a0 | |||
| 689062fc87 | |||
| e6fd110073 | |||
| 5e1344af42 | |||
| d8acb126f5 | |||
| 87ac67a70e | |||
| e520ba98ca | |||
| 38c92e5fc7 | |||
| bbfc7cebf7 | |||
| f1b5e1bac8 | |||
| aa040d1412 | |||
| a1144605f3 | |||
| 06b46c2e8f | |||
| c8d1d3e1aa | |||
| b27aab20ee | |||
| 17e14a9fda | |||
| 954dc1d86e | |||
| 0abef440fa | |||
| 47163f690b |
@@ -190,18 +190,34 @@ jobs:
|
|||||||
-lcurl -lpthread -ldl -lm -lssl -lcrypto
|
-lcurl -lpthread -ldl -lm -lssl -lcrypto
|
||||||
echo "soul-demo compiled: $(ls -lh dist/soul-demo)"
|
echo "soul-demo compiled: $(ls -lh dist/soul-demo)"
|
||||||
# Package as minimal OCI image for k3s import
|
# Package as minimal OCI image for k3s import
|
||||||
docker build -f dist/Dockerfile.soul-demo -t soul-demo:local dist/
|
# --no-cache: prevents reuse of corrupted overlay2 layers from prior failed runs
|
||||||
|
docker build --no-cache -f dist/Dockerfile.soul-demo -t soul-demo:local dist/
|
||||||
docker save soul-demo:local -o dist/soul-demo-image.tar
|
docker save soul-demo:local -o dist/soul-demo-image.tar
|
||||||
echo "soul-demo-image.tar: $(du -sh dist/soul-demo-image.tar | cut -f1)"
|
echo "soul-demo-image.tar: $(du -sh dist/soul-demo-image.tar | cut -f1)"
|
||||||
docker rmi soul-demo:local 2>/dev/null || true
|
docker rmi soul-demo:local 2>/dev/null || true
|
||||||
|
|
||||||
|
- name: Download k3s binary
|
||||||
|
# Pre-download k3s on the host runner so Dockerfile.stage can COPY it
|
||||||
|
# directly. Previously k3s was downloaded inside the Docker builder stage,
|
||||||
|
# which combined with build-essential and C compilation caused RWLayer nil
|
||||||
|
# corruption on the runner's overlay2 driver. Host-runner download is safe.
|
||||||
|
if: steps.changetype.outputs.asset_only != 'true'
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
curl -fL --retry 3 --retry-delay 10 \
|
||||||
|
https://github.com/k3s-io/k3s/releases/download/v1.32.4%2Bk3s1/k3s \
|
||||||
|
-o dist/k3s
|
||||||
|
chmod +x dist/k3s
|
||||||
|
echo "k3s: $(ls -lh dist/k3s)"
|
||||||
|
|
||||||
- name: Build and tag image
|
- name: Build and tag image
|
||||||
if: steps.changetype.outputs.asset_only != 'true'
|
if: steps.changetype.outputs.asset_only != 'true'
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
# --no-cache: prevents reuse of corrupted overlay2 layers from prior failed runs.
|
||||||
|
# Dockerfile.stage is now single-stage (no builder) so build is fast even without cache.
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
--no-cache \
|
||||||
--cache-from us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:stage-latest \
|
|
||||||
-f Dockerfile.stage \
|
-f Dockerfile.stage \
|
||||||
-t "marketing:${{ steps.tag.outputs.tag }}" \
|
-t "marketing:${{ steps.tag.outputs.tag }}" \
|
||||||
.
|
.
|
||||||
|
|||||||
+19
-48
@@ -4,56 +4,24 @@
|
|||||||
# - neuron-web on port 8080 (landing page server)
|
# - neuron-web on port 8080 (landing page server)
|
||||||
# - soul-demo on port 7772 (demo chat, localhost only)
|
# - soul-demo on port 7772 (demo chat, localhost only)
|
||||||
#
|
#
|
||||||
# neuron-web is built by `elb build` in CI (not here). elb compiles each
|
# All binaries (neuron-web, soul-demo, k3s) are pre-built by CI on the host
|
||||||
# .el source independently and links the result — no combined mega-file,
|
# runner before this Dockerfile runs. This keeps the Docker build single-stage
|
||||||
# no exponential memory growth. The binary lands at dist/neuron-landing
|
# with no compilation and no network downloads, eliminating the multi-stage
|
||||||
# (linux/amd64) and is COPY'd directly into the runtime image.
|
# complexity that caused RWLayer corruption on the runner's overlay2 driver.
|
||||||
#
|
#
|
||||||
# soul-demo.c is pre-committed (small, no OOM risk) and compiled here.
|
# CI pre-build steps (in stage.yaml):
|
||||||
|
# - neuron-web: built by `elb build` → dist/neuron-landing
|
||||||
|
# - soul-demo: compiled by cc on host → dist/soul-demo
|
||||||
|
# - k3s: downloaded by curl on host → dist/k3s
|
||||||
|
|
||||||
# ── Stage 1: compile soul-demo ────────────────────────────────────────────────
|
FROM ubuntu:24.04
|
||||||
FROM debian:bookworm-slim AS builder
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
build-essential \
|
libcurl4t64 \
|
||||||
curl \
|
libssl3t64 \
|
||||||
libcurl4-openssl-dev \
|
|
||||||
libssl-dev \
|
|
||||||
ca-certificates \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
WORKDIR /build
|
|
||||||
|
|
||||||
COPY runtime/el_runtime.c runtime/el_runtime.h ./
|
|
||||||
|
|
||||||
# Pre-compile el_runtime as a separate cached layer.
|
|
||||||
# el_runtime.c changes rarely; main.c changes every run.
|
|
||||||
# Splitting this out means el_runtime.o is cached across builds when only main.c changes.
|
|
||||||
# -DHAVE_CURL: the staged el_runtime.c (from el.git) guards the OTLP observability
|
|
||||||
# section (emit_metric, emit_log, trace_span_*) behind #ifdef HAVE_CURL.
|
|
||||||
# libcurl IS installed above, so define HAVE_CURL to enable those functions.
|
|
||||||
RUN cc -O2 -DHAVE_CURL -c el_runtime.c -I. -o el_runtime.o
|
|
||||||
|
|
||||||
COPY dist/soul-demo.c dist/vessel_stubs.c ./
|
|
||||||
|
|
||||||
RUN cc -O2 -rdynamic \
|
|
||||||
-DEL_SOUL_DEMO_BUILD \
|
|
||||||
-o soul-demo \
|
|
||||||
soul-demo.c vessel_stubs.c el_runtime.o \
|
|
||||||
-lcurl -lpthread -ldl -lm -lssl -lcrypto
|
|
||||||
|
|
||||||
# ── Download k3s binary ───────────────────────────────────────────────────────
|
|
||||||
RUN curl -fL --retry 3 --retry-delay 10 https://github.com/k3s-io/k3s/releases/download/v1.32.4%2Bk3s1/k3s -o /usr/local/bin/k3s \
|
|
||||||
&& chmod +x /usr/local/bin/k3s
|
|
||||||
|
|
||||||
# ── Stage 2: runtime image ────────────────────────────────────────────────────
|
|
||||||
FROM debian:bookworm-slim
|
|
||||||
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get install -y --no-install-recommends \
|
|
||||||
libcurl4 \
|
|
||||||
libssl3 \
|
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& groupadd -r landing && useradd -r -g landing landing \
|
&& groupadd -r landing && useradd -r -g landing landing \
|
||||||
@@ -67,10 +35,13 @@ RUN apt-get update \
|
|||||||
COPY dist/neuron-landing /usr/local/bin/neuron-web
|
COPY dist/neuron-landing /usr/local/bin/neuron-web
|
||||||
RUN chmod +x /usr/local/bin/neuron-web
|
RUN chmod +x /usr/local/bin/neuron-web
|
||||||
|
|
||||||
COPY --from=builder /build/soul-demo /usr/local/bin/soul-demo
|
# soul-demo binary — compiled by cc on host runner in CI
|
||||||
|
COPY dist/soul-demo /usr/local/bin/soul-demo
|
||||||
|
RUN chmod +x /usr/local/bin/soul-demo
|
||||||
|
|
||||||
# k3s binary
|
# k3s binary — downloaded from GitHub releases by CI
|
||||||
COPY --from=builder /usr/local/bin/k3s /usr/local/bin/k3s
|
COPY dist/k3s /usr/local/bin/k3s
|
||||||
|
RUN chmod +x /usr/local/bin/k3s
|
||||||
|
|
||||||
# soul-demo OCI image tar — k3s imports this at startup (no registry needed)
|
# soul-demo OCI image tar — k3s imports this at startup (no registry needed)
|
||||||
RUN mkdir -p /var/lib/rancher/k3s/agent/images
|
RUN mkdir -p /var/lib/rancher/k3s/agent/images
|
||||||
|
|||||||
Vendored
+13
-15
@@ -16,28 +16,26 @@ echo "[entrypoint] Starting k3s server (embedded soul-demo orchestrator)..."
|
|||||||
# --disable metrics-server: saves ~50MB RAM
|
# --disable metrics-server: saves ~50MB RAM
|
||||||
# --write-kubeconfig-mode=644: allow non-root reads
|
# --write-kubeconfig-mode=644: allow non-root reads
|
||||||
# --data-dir: use the pre-chowned dir
|
# --data-dir: use the pre-chowned dir
|
||||||
|
# --flannel-iface=eth0: explicitly set the network interface.
|
||||||
|
# Cloud Run gen2 provides eth0 but k3s default IP detection walks the routing
|
||||||
|
# table looking for a default route, which fails in Cloud Run's network sandbox.
|
||||||
|
# Pinning to eth0 bypasses that detection and lets k3s bind correctly.
|
||||||
k3s server \
|
k3s server \
|
||||||
--disable traefik \
|
--disable traefik \
|
||||||
--disable servicelb \
|
--disable servicelb \
|
||||||
--disable metrics-server \
|
--disable metrics-server \
|
||||||
--write-kubeconfig-mode=644 \
|
--write-kubeconfig-mode=644 \
|
||||||
--data-dir /var/lib/rancher/k3s \
|
--data-dir /var/lib/rancher/k3s \
|
||||||
--node-name soul-node &
|
--node-name soul-node \
|
||||||
|
--flannel-iface=eth0 &
|
||||||
|
|
||||||
K3S_PID=$!
|
K3S_PID=$!
|
||||||
|
|
||||||
echo "[entrypoint] Waiting for k3s to become ready..."
|
# Start neuron-web immediately — do NOT block on k3s becoming ready.
|
||||||
until k3s kubectl get nodes --no-headers 2>/dev/null | grep -q "Ready"; do
|
# Cloud Run's startup probe requires port 8080 to be listening within the
|
||||||
sleep 2
|
# startup timeout. k3s may take 30-60s to initialise; blocking here causes
|
||||||
done
|
# probe failures and container termination before neuron-web ever starts.
|
||||||
echo "[entrypoint] k3s ready. soul-demo Deployment will be applied automatically from manifests."
|
# soul-demo becomes available asynchronously once k3s is ready. neuron-web
|
||||||
|
# handles soul-demo being temporarily unavailable gracefully.
|
||||||
# Wait for soul-demo pod to be Running before starting neuron-web
|
echo "[entrypoint] Starting neuron-web on port ${PORT:-8080} (k3s initialising in background)..."
|
||||||
echo "[entrypoint] Waiting for soul-demo pod..."
|
|
||||||
until k3s kubectl get pods -l app=soul-demo --no-headers 2>/dev/null | grep -q "Running"; do
|
|
||||||
sleep 3
|
|
||||||
done
|
|
||||||
echo "[entrypoint] soul-demo is running."
|
|
||||||
|
|
||||||
echo "[entrypoint] Starting neuron-web on port ${PORT:-8080}..."
|
|
||||||
exec /usr/local/bin/neuron-web
|
exec /usr/local/bin/neuron-web
|
||||||
|
|||||||
Vendored
+25
@@ -6,6 +6,31 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "el_runtime.h"
|
#include "el_runtime.h"
|
||||||
|
|
||||||
|
/* Pre-register the El HTTP handler so it is found by http_lookup_active()
|
||||||
|
* regardless of whether the binary was linked with -rdynamic.
|
||||||
|
*
|
||||||
|
* el_runtime's http_set_handler resolves handler names via:
|
||||||
|
* dlsym(RTLD_DEFAULT, "handle_request")
|
||||||
|
* but dlsym only searches the dynamic symbol table, which only contains
|
||||||
|
* user-defined symbols when the executable is linked with -rdynamic.
|
||||||
|
* elb does not add -rdynamic, so dlsym returns NULL and routes return
|
||||||
|
* "el-runtime: no http handler registered" even though http_serve is called.
|
||||||
|
*
|
||||||
|
* The fix: forward-declare handle_request here and register it directly
|
||||||
|
* via el_runtime_register_handler before main() runs. This populates the
|
||||||
|
* handler registry so http_lookup_active() finds it without needing dlsym.
|
||||||
|
*/
|
||||||
|
extern el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body);
|
||||||
|
/* el_runtime_register_handler is intentionally not declared in el_runtime.h
|
||||||
|
* ("extern lookup works since C symbols are global" — runtime comment). */
|
||||||
|
extern void el_runtime_register_handler(const char* name,
|
||||||
|
el_val_t (*fn)(el_val_t, el_val_t, el_val_t));
|
||||||
|
|
||||||
|
__attribute__((constructor))
|
||||||
|
static void pre_register_http_handlers(void) {
|
||||||
|
el_runtime_register_handler("handle_request", handle_request);
|
||||||
|
}
|
||||||
|
|
||||||
el_val_t http_get_auth(el_val_t url, el_val_t tok) {
|
el_val_t http_get_auth(el_val_t url, el_val_t tok) {
|
||||||
char bearer[2048]; snprintf(bearer, sizeof(bearer), "Bearer %s", EL_CSTR(tok));
|
char bearer[2048]; snprintf(bearer, sizeof(bearer), "Bearer %s", EL_CSTR(tok));
|
||||||
el_val_t hdr_val = EL_STR(bearer);
|
el_val_t hdr_val = EL_STR(bearer);
|
||||||
|
|||||||
Reference in New Issue
Block a user