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
42 changes: 34 additions & 8 deletions cmd/ax/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Comprehensive AX image: the Go `ax` binary plus the Antigravity Python sidecar
# (SDK, localharness, agent), on a Debian-based image with shell tooling for
# skills/code execution. Used by both the ax-server (`ax serve`) and the harness
# actor (`ax harness`, which forks the Python sidecar).
# Multi-target AX image build:
# --target antigravity : python:3.13-slim + the Antigravity Python sidecar
# (SDK, localharness, agent). Used by the antigravity
# harness actor (`ax harness antigravity`).
# --target ax : debian:stable-slim + the Go `ax` binary. Used by
# the ax-server (`ax serve`) and the Go interactions
# harness actor (`ax harness antigravity-interactions`).
#
# Build context: repository root. The image targets the cluster's linux/amd64
# nodes, so it is built with `--platform linux/amd64`. For a standalone build:
# docker build --platform linux/amd64 -f cmd/ax/Dockerfile -t <ref> . && docker push <ref>
# Build context: repository root. Images target the cluster's linux/amd64 nodes,
# so build with `--platform linux/amd64`.
# For a standalone build:
# docker build --platform linux/amd64 --target antigravity -f cmd/ax/Dockerfile -t <ref> . && docker push <ref>
Comment thread
rakyll marked this conversation as resolved.
# docker build --platform linux/amd64 --target ax -f cmd/ax/Dockerfile -t <ref> . && docker push <ref>

# --- Stage 1: build the ax Go binary (with the harness build tag) -------------
FROM --platform=$BUILDPLATFORM golang:1.26 AS build
Expand All @@ -32,7 +37,8 @@ COPY . .
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -o /out/ax ./cmd/ax

FROM python:3.13-slim
# --- antigravity image -------
FROM python:3.13-slim AS antigravity
WORKDIR /workspace

RUN apt-get update \
Expand Down Expand Up @@ -73,3 +79,23 @@ EXPOSE 80
# which serves the HarnessService on :80.
CMD ["/ax-app/ax", "harness", \
"--host", "0.0.0.0", "--port", "80"]

# --- ax image (Go-only) for the interactions harness and ax-server -----------
FROM debian:stable-slim AS ax
WORKDIR /workspace

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
less \
procps \
wget \
&& rm -rf /var/lib/apt/lists/*

COPY --from=build /out/ax /ax-app/ax

EXPOSE 80

CMD ["/ax-app/ax", "harness", "antigravity-interactions", \
"--host", "0.0.0.0", "--port", "80"]
33 changes: 25 additions & 8 deletions hack/install-ax.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,13 @@ detect_container_engine() {
fi
}

# build_ax_image builds and pushes the comprehensive ax image (the Go ax binary
# plus the Antigravity Python sidecar) and echoes its digest-pinned reference on
# stdout. Requires AX_IMAGE_REPO and a container engine.
build_ax_image() {
# _build_and_push_ax builds one target of cmd/ax/Dockerfile into ${repo}:<git-sha>,
# pushes it, and echoes the digest-pinned reference on stdout. Args:
# $1 repo - fully-qualified image repo (e.g. gcr.io/proj/ax)
# $2 target - Dockerfile target stage (ax | antigravity)
# Requires AX_IMAGE_REPO and a container engine.
_build_and_push_ax() {
local repo="$1" target="$2"
if [[ -z "${AX_IMAGE_REPO:-}" ]]; then
echo "Error: AX_IMAGE_REPO environment variable must be set" >&2
exit 1
Expand All @@ -120,14 +123,14 @@ build_ax_image() {
exit 1
fi

local repo tag image digest
repo="${AX_IMAGE_REPO}/ax"
local tag image digest
tag="$(git rev-parse --short HEAD)"
image="${repo}:${tag}"

log_step "build_ax_image -> ${image}" >&2
log_step "build ${target} -> ${image}" >&2
"${CONTAINER_ENGINE}" build \
--platform linux/amd64 \
--target "${target}" \
-f cmd/ax/Dockerfile \
-t "${image}" \
. 2>&1 \
Expand Down Expand Up @@ -156,6 +159,18 @@ build_ax_image() {
echo "${repo}@${digest}"
}

# build_ax_image builds and pushes the Go-only ax image used by the ax-server and the
# Go interactions harness.
build_ax_image() {
_build_and_push_ax "${AX_IMAGE_REPO}/ax" ax
}

# build_ax_antigravity_image builds and pushes the antigravity image used by the
# antigravity harness.
build_ax_antigravity_image() {
_build_and_push_ax "${AX_IMAGE_REPO}/ax-antigravity" antigravity
}

build_ateom_image() {
if [[ -n "${ATEOM_IMAGE:-}" ]]; then
echo "${ATEOM_IMAGE}"
Expand Down Expand Up @@ -206,8 +221,9 @@ deploy_ax_server() {
echo "Using GCS Bucket: ${AX_SNAPSHOTS_BUCKET}"

# Build and push the images, capturing their digest-pinned references.
local ax_image ateom_image
local ax_image ax_antigravity_image ateom_image
ax_image=$(build_ax_image)
ax_antigravity_image=$(build_ax_antigravity_image)
ateom_image=$(build_ateom_image)

# Resolve the event-log Postgres DSN. By default ax-server connects to an
Expand Down Expand Up @@ -241,6 +257,7 @@ deploy_ax_server() {
-e "s|\${GEMINI_API_KEY}|${GEMINI_API_KEY}|g"
-e "s|\${AX_SNAPSHOTS_BUCKET}|${AX_SNAPSHOTS_BUCKET}|g"
-e "s|\${AX_IMAGE}|${ax_image}|g"
-e "s|\${AX_ANTIGRAVITY_IMAGE}|${ax_antigravity_image}|g"
-e "s|\${ATEOM_IMAGE}|${ateom_image}|g"
-e "s|\${GOOGLE_CLOUD_PROJECT}|${GOOGLE_CLOUD_PROJECT:-}|g"
-e "s|\${AX_CONFIG_CONTENT}|${ax_config_content}|g"
Expand Down
24 changes: 15 additions & 9 deletions manifests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,27 @@ The target Kubernetes cluster is assumed to have
### 1. Build and Deploy

> [!NOTE]
> Do not manually edit `manifests/ax-deployment.yaml`. The installation script automatically injects your `${GEMINI_API_KEY}`, `${AX_SNAPSHOTS_BUCKET}`, and the built `${AX_IMAGE}` and `${ATEOM_IMAGE}` references during deployment.
> Do not manually edit `manifests/ax-deployment.yaml`. The installation script automatically injects your `${GEMINI_API_KEY}`, `${AX_SNAPSHOTS_BUCKET}`, and the built `${AX_IMAGE}`, `${AX_ANTIGRAVITY_IMAGE}`, and `${ATEOM_IMAGE}` references during deployment.

The installation script builds the required images and applies the resolved
manifests to your cluster:

- the comprehensive **ax** image, built from `cmd/ax/Dockerfile`,
- the **ax** image (the Go `ax` binary only), built from the `ax`
target of `cmd/ax/Dockerfile`; used by the ax-server and the Go interactions
harness,
- the **ax-antigravity** image (the Antigravity Python
sidecar: SDK, localharness, agent), built from the `antigravity` target of
`cmd/ax/Dockerfile`; used by the antigravity harness actor,
- the **ateom-gvisor** worker image, built with `ko` from the `go.mod` pinned
substrate module.

#### Build prerequisites

The ax image bundles the antigravity SDK, installed from PyPI at build time.
The image targets the cluster's **linux/amd64**
nodes and is built with `--platform linux/amd64`.
The ax-antigravity image bundles the antigravity SDK, installed from PyPI at
build time. Both images target the cluster's **linux/amd64**
nodes and are built with `--platform linux/amd64`.

You also need a container engine to build and push the ax image. The script
You also need a container engine to build and push the ax images. The script
auto-detects one (preferring a **running** docker, then podman); force a choice
with `CONTAINER_ENGINE=docker` or `CONTAINER_ENGINE=podman`:

Expand All @@ -45,9 +50,10 @@ with `CONTAINER_ENGINE=docker` or `CONTAINER_ENGINE=podman`:

#### Registry authentication

`GOOGLE_CLOUD_PROJECT` sets `AX_IMAGE_REPO=gcr.io/$GOOGLE_CLOUD_PROJECT`. The deploy pushes two
images — the **ax** image (via your container engine) and the **ateom** image
(via `ko`) — and both authenticate through the gcloud credential helper:
`GOOGLE_CLOUD_PROJECT` sets `AX_IMAGE_REPO=gcr.io/$GOOGLE_CLOUD_PROJECT`. The deploy pushes three
images — the **ax** and **ax-antigravity** images (via your container engine) and
the **ateom** image (via `ko`) — and all authenticate through the gcloud
credential helper:

```bash
gcloud auth login # authenticate gcloud
Expand Down
2 changes: 1 addition & 1 deletion manifests/ax-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ spec:
pauseImage: "gcr.io/gke-release/pause@sha256:bcbd57ba5653580ec647b16d8163cdd1112df3609129b01f912a8032e48265da"
containers:
- name: "axantigravity"
image: ${AX_IMAGE}
image: ${AX_ANTIGRAVITY_IMAGE}
# Substrate ignores the image CMD/ENV/WORKDIR, so the harness command and
# environment are specified here. `ax harness antigravity` forks the
# Antigravity Python sidecar, which serves on port 80 because substrate
Expand Down
Loading