Skip to content
Closed
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
1 change: 1 addition & 0 deletions .github/workflows/43-railway-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ jobs:
SENDGRID_API_KEY: ${{ secrets.AGENTA_TEST_OSS_SENDGRID_API_KEY }}
COMPOSIO_API_KEY: ${{ secrets.AGENTA_TEST_OSS_COMPOSIO_API_KEY }}
DAYTONA_API_KEY: ${{ secrets.AGENTA_TEST_OSS_DAYTONA_API_KEY }}
SANDBOX_AGENT_DAYTONA_API_KEY: ${{ secrets.AGENTA_TEST_OSS_DAYTONA_API_KEY }}
RAILWAY_POST_BOOTSTRAP_SLEEP: "2"
RAILWAY_INFRA_SETTLE_SECONDS: "20"
RAILWAY_APP_SETTLE_SECONDS: "0"
Expand Down
12 changes: 12 additions & 0 deletions docs/docs/self-host/guides/04-deploy-on-railway.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The scripts create the following services inside one Railway project:
- **Web** frontend (Next.js)
- **API** backend (FastAPI + Gunicorn)
- **Services** backend (FastAPI + Gunicorn)
- **sandbox-agent** runner for agent workflows
- **Postgres** with a persistent volume
- **Redis** with a persistent volume
- **SuperTokens** for authentication
Expand Down Expand Up @@ -85,6 +86,7 @@ Set the image tags you want to deploy. Use `latest` for the most recent stable r
export AGENTA_API_IMAGE="ghcr.io/agenta-ai/agenta-api:latest"
export AGENTA_WEB_IMAGE="ghcr.io/agenta-ai/agenta-web:latest"
export AGENTA_SERVICES_IMAGE="ghcr.io/agenta-ai/agenta-services:latest"
export AGENTA_SANDBOX_AGENT_IMAGE="ghcr.io/agenta-ai/agenta-sandbox-agent:latest"
```

Then run the deploy script:
Expand All @@ -101,6 +103,7 @@ You can also pin to a specific version instead of `latest`:
export AGENTA_API_IMAGE="ghcr.io/agenta-ai/agenta-api:v0.30.0"
export AGENTA_WEB_IMAGE="ghcr.io/agenta-ai/agenta-web:v0.30.0"
export AGENTA_SERVICES_IMAGE="ghcr.io/agenta-ai/agenta-services:v0.30.0"
export AGENTA_SANDBOX_AGENT_IMAGE="ghcr.io/agenta-ai/agenta-sandbox-agent:v0.30.0"
```

## Step 5: Verify
Expand All @@ -126,6 +129,7 @@ export RAILWAY_ENVIRONMENT_NAME="production"
export AGENTA_API_IMAGE="ghcr.io/agenta-ai/agenta-api:latest"
export AGENTA_WEB_IMAGE="ghcr.io/agenta-ai/agenta-web:latest"
export AGENTA_SERVICES_IMAGE="ghcr.io/agenta-ai/agenta-services:latest"
export AGENTA_SANDBOX_AGENT_IMAGE="ghcr.io/agenta-ai/agenta-sandbox-agent:latest"

./hosting/railway/oss/scripts/deploy-from-images.sh
```
Expand Down Expand Up @@ -183,6 +187,14 @@ These environment variables control the deployment scripts. All have sensible de
| `SENDGRID_API_KEY` | (none) | SendGrid email key |
| `COMPOSIO_API_KEY` | (none) | Composio API key |

### Agent Runner

| Variable | Default | Description |
|---|---|---|
| `AGENTA_SANDBOX_AGENT_IMAGE` | `ghcr.io/agenta-ai/agenta-sandbox-agent:latest` | Image used by the `sandbox-agent` runner service |
| `SANDBOX_AGENT_PROVIDER` | `local` | Default sandbox provider for agent runs |
| `SANDBOX_AGENT_DAYTONA_API_KEY` | (none) | Daytona key for agent-runner sandboxes |

### Smoke Test Tuning

| Variable | Default | Description |
Expand Down
6 changes: 4 additions & 2 deletions hosting/railway/oss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ baseline.
- `web/` - web wrapper image and runtime config
- `api/` - api wrapper image with explicit gunicorn command
- `services/` - services wrapper image with explicit gunicorn command
- `sandbox-agent/` - agent runner image
- `redis/` - redis wrapper to ensure volume permissions are writable
- `worker-evaluations/` - Taskiq worker image for evaluations
- `worker-tracing/` - tracing ingestion worker image
Expand All @@ -35,7 +36,7 @@ baseline.
- `scripts/deploy-gateway.sh` - deploy gateway image from local Dockerfile
- `scripts/smoke.sh` - quick health checks
- `scripts/upgrade.sh` - run full in-place upgrade flow
- `scripts/build-and-push-images.sh` - build local `api/web/services` images and push tags
- `scripts/build-and-push-images.sh` - build local `api/web/services/sandbox-agent` images and push tags
- `scripts/deploy-from-images.sh` - deploy Railway services from explicit image tags
- `scripts/preview-create-or-update.sh` - create or update a PR-scoped preview project
- `scripts/preview-destroy.sh` - delete a PR-scoped preview project
Expand Down Expand Up @@ -119,6 +120,7 @@ Optional reliability knobs for fresh projects:
- `RAILWAY_ALEMBIC_MAX_ATTEMPTS` (default `3`)

`deploy-from-images.sh` redeploys Postgres and Redis before running Alembic, then retries Alembic on failure to reduce first-deploy race conditions.
It also deploys `sandbox-agent` before `services` and configures `AGENTA_AGENT_RUNNER_URL` to the runner's private Railway URL.

## Preview Lifecycle Scripts

Expand Down Expand Up @@ -209,7 +211,7 @@ The API image defaults to docker-compose hostnames for Redis (`redis-durable:638

First deploys on Railway take longer because Docker layer caches are cold. Deploy now relies mostly on readiness polling in smoke checks instead of fixed sleeps, so slower starts are less likely to fail prematurely.

For GitHub preview builds, CI now uses shared BuildKit registry cache tags (`buildcache-shared`) plus PR-scoped tags (`buildcache-pr-<number>`). It also builds API, web, and services images in parallel matrix jobs. This keeps repeated PR builds fast and also improves first builds on new PRs by reusing layers from previous runs. Manual workflow dispatches without a PR number use `manual-<sha>` image tags and skip deploy.
For GitHub preview builds, CI now uses shared BuildKit registry cache tags (`buildcache-shared`) plus PR-scoped tags (`buildcache-pr-<number>`). It also builds API, web, services, and sandbox-agent images in parallel matrix jobs. This keeps repeated PR builds fast and also improves first builds on new PRs by reusing layers from previous runs. Manual workflow dispatches without a PR number use `manual-<sha>` image tags and skip deploy.

### SDK source in preview builds

Expand Down
8 changes: 8 additions & 0 deletions hosting/railway/oss/sandbox-agent/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Wrapper Dockerfile for Railway deployment.
# Adds the runtime port to the GHCR image and keeps the runner service image-backed.

FROM ghcr.io/agenta-ai/agenta-sandbox-agent:latest

ENV PORT=8765

CMD ["node_modules/.bin/tsx", "src/server.ts"]
2 changes: 2 additions & 0 deletions hosting/railway/oss/scripts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SOURCE_COMPOSE_FILE="${RAILWAY_SOURCE_COMPOSE_FILE:-$(railway_source_compose_fil
WEB_IMAGE="${AGENTA_WEB_IMAGE:-ghcr.io/agenta-ai/agenta-web:latest}"
API_IMAGE="${AGENTA_API_IMAGE:-ghcr.io/agenta-ai/agenta-api:latest}"
SERVICES_IMAGE="${AGENTA_SERVICES_IMAGE:-ghcr.io/agenta-ai/agenta-services:latest}"
SANDBOX_AGENT_IMAGE="${AGENTA_SANDBOX_AGENT_IMAGE:-ghcr.io/agenta-ai/agenta-sandbox-agent:latest}"
SUPERTOKENS_IMAGE="${SUPERTOKENS_IMAGE:-$(require_compose_service_image "$SOURCE_COMPOSE_FILE" "supertokens")}"
REDIS_IMAGE="${REDIS_IMAGE:-$(require_compose_redis_image "$SOURCE_COMPOSE_FILE")}"
POSTGRES_IMAGE="${POSTGRES_IMAGE:-$(require_compose_service_image "$SOURCE_COMPOSE_FILE" "postgres")}"
Expand Down Expand Up @@ -146,6 +147,7 @@ main() {
add_service_image web "$WEB_IMAGE"
add_service_image api "$API_IMAGE"
add_service_image services "$SERVICES_IMAGE"
add_service_image sandbox-agent "$SANDBOX_AGENT_IMAGE"
add_service_image worker-evaluations "$API_IMAGE"
add_service_image worker-tracing "$API_IMAGE"
add_service_image worker-webhooks "$API_IMAGE"
Expand Down
5 changes: 5 additions & 0 deletions hosting/railway/oss/scripts/build-and-push-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,21 @@ fi
API_IMAGE="${REGISTRY}/${NAMESPACE}/agenta-api:${TAG}"
WEB_IMAGE="${REGISTRY}/${NAMESPACE}/agenta-web:${TAG}"
SERVICES_IMAGE="${REGISTRY}/${NAMESPACE}/agenta-services:${TAG}"
SANDBOX_AGENT_IMAGE="${REGISTRY}/${NAMESPACE}/agenta-sandbox-agent:${TAG}"

printf "Building local images with tag '%s'\n" "$TAG"

docker build -t "$API_IMAGE" -f "$ROOT_DIR/api/oss/docker/Dockerfile.gh" "$ROOT_DIR"
docker build -t "$WEB_IMAGE" -f "$ROOT_DIR/web/oss/docker/Dockerfile.gh" "$ROOT_DIR/web"
docker build -t "$SERVICES_IMAGE" -f "$ROOT_DIR/services/oss/docker/Dockerfile.gh" "$ROOT_DIR"
docker build -t "$SANDBOX_AGENT_IMAGE" -f "$ROOT_DIR/services/agent/docker/Dockerfile" "$ROOT_DIR/services/agent"

if [ "$PUSH_IMAGES" = "true" ]; then
printf "Pushing images to %s/%s\n" "$REGISTRY" "$NAMESPACE"
docker push "$API_IMAGE"
docker push "$WEB_IMAGE"
docker push "$SERVICES_IMAGE"
docker push "$SANDBOX_AGENT_IMAGE"
else
printf "Skipping push because PUSH_IMAGES=%s\n" "$PUSH_IMAGES"
fi
Expand All @@ -43,9 +46,11 @@ cat > "$OUTPUT_FILE" <<EOF
export AGENTA_API_IMAGE="$API_IMAGE"
export AGENTA_WEB_IMAGE="$WEB_IMAGE"
export AGENTA_SERVICES_IMAGE="$SERVICES_IMAGE"
export AGENTA_SANDBOX_AGENT_IMAGE="$SANDBOX_AGENT_IMAGE"
EOF

printf "Wrote image exports to %s\n" "$OUTPUT_FILE"
printf "AGENTA_API_IMAGE=%s\n" "$API_IMAGE"
printf "AGENTA_WEB_IMAGE=%s\n" "$WEB_IMAGE"
printf "AGENTA_SERVICES_IMAGE=%s\n" "$SERVICES_IMAGE"
printf "AGENTA_SANDBOX_AGENT_IMAGE=%s\n" "$SANDBOX_AGENT_IMAGE"
25 changes: 24 additions & 1 deletion hosting/railway/oss/scripts/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ main() {
pg_host_ref="\${{${POSTGRES_REF_NS}.RAILWAY_PRIVATE_DOMAIN}}"
local pg_port_ref
pg_port_ref="\${{${POSTGRES_REF_NS}.PGPORT}}"
local agent_runner_host_ref
agent_runner_host_ref='${{sandbox-agent.RAILWAY_PRIVATE_DOMAIN}}'
local agent_runner_url
agent_runner_url="http://${agent_runner_host_ref}:8765"

local pg_async_core
pg_async_core="postgresql+asyncpg://${pg_user_ref}:${pg_password_ref}@${pg_host_ref}:${pg_port_ref}/agenta_oss_core"
Expand Down Expand Up @@ -247,13 +251,31 @@ main() {
AGENTA_CRYPT_KEY="$AGENTA_CRYPT_KEY" \
POSTGRES_URI_CORE="$pg_async_core" \
POSTGRES_URI_TRACING="$pg_async_tracing" \
POSTGRES_URI_SUPERTOKENS="$pg_sync_supertokens"
POSTGRES_URI_SUPERTOKENS="$pg_sync_supertokens" \
AGENTA_AGENT_RUNNER_URL="$agent_runner_url" \
AGENTA_AGENT_ENABLE_MCP="${AGENTA_AGENT_ENABLE_MCP:-false}"

unset_vars services AGENTA_LICENSE PORT SCRIPT_NAME REDIS_URI REDIS_URI_VOLATILE REDIS_URI_DURABLE SUPERTOKENS_CONNECTION_URI ALEMBIC_CFG_PATH_CORE ALEMBIC_CFG_PATH_TRACING AGENTA_API_INTERNAL_URL

set_optional_vars services \
"DAYTONA_API_KEY=${DAYTONA_API_KEY:-}"

set_vars sandbox-agent \
PORT=8765 \
SANDBOX_AGENT_PROVIDER="${SANDBOX_AGENT_PROVIDER:-local}"

set_optional_vars sandbox-agent \
"AGENTA_HOST=${AGENTA_HOST:-}" \
"AGENTA_API_KEY=${AGENTA_API_KEY:-}" \
"SANDBOX_AGENT_DAYTONA_API_KEY=${SANDBOX_AGENT_DAYTONA_API_KEY:-}" \
"SANDBOX_AGENT_DAYTONA_API_URL=${SANDBOX_AGENT_DAYTONA_API_URL:-}" \
"SANDBOX_AGENT_DAYTONA_TARGET=${SANDBOX_AGENT_DAYTONA_TARGET:-}" \
"SANDBOX_AGENT_DAYTONA_SNAPSHOT=${SANDBOX_AGENT_DAYTONA_SNAPSHOT:-}" \
"SANDBOX_AGENT_DAYTONA_IMAGE=${SANDBOX_AGENT_DAYTONA_IMAGE:-}" \
"SANDBOX_AGENT_DAYTONA_INSTALL_PI=${SANDBOX_AGENT_DAYTONA_INSTALL_PI:-}"

unset_vars sandbox-agent AGENTA_LICENSE SCRIPT_NAME REDIS_URI REDIS_URI_VOLATILE REDIS_URI_DURABLE SUPERTOKENS_CONNECTION_URI POSTGRES_URI_CORE POSTGRES_URI_TRACING POSTGRES_URI_SUPERTOKENS DAYTONA_API_KEY DAYTONA_API_URL DAYTONA_SNAPSHOT DAYTONA_TARGET

set_vars worker-evaluations \
AGENTA_WEB_URL="https://${public_domain_ref}" \
AGENTA_SERVICES_URL="https://${public_domain_ref}/services" \
Expand Down Expand Up @@ -351,6 +373,7 @@ main() {
set_healthcheck gateway "/"
set_healthcheck api "/health"
set_healthcheck services "/health"
set_healthcheck sandbox-agent "/health"

printf "Configuration completed for project '%s' environment '%s'\n" "$PROJECT_NAME" "$ENV_NAME"
}
Expand Down
19 changes: 17 additions & 2 deletions hosting/railway/oss/scripts/deploy-from-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ REDIS_IMAGE="${REDIS_IMAGE:-$(require_compose_redis_image "$SOURCE_COMPOSE_FILE"
AGENTA_API_IMAGE="${AGENTA_API_IMAGE:-}"
AGENTA_WEB_IMAGE="${AGENTA_WEB_IMAGE:-}"
AGENTA_SERVICES_IMAGE="${AGENTA_SERVICES_IMAGE:-}"
AGENTA_SANDBOX_AGENT_IMAGE="${AGENTA_SANDBOX_AGENT_IMAGE:-}"

if [ -z "$AGENTA_API_IMAGE" ] || [ -z "$AGENTA_WEB_IMAGE" ] || [ -z "$AGENTA_SERVICES_IMAGE" ]; then
printf "AGENTA_API_IMAGE, AGENTA_WEB_IMAGE, and AGENTA_SERVICES_IMAGE are required\n" >&2
if [ -z "$AGENTA_API_IMAGE" ] || [ -z "$AGENTA_WEB_IMAGE" ] || [ -z "$AGENTA_SERVICES_IMAGE" ] || [ -z "$AGENTA_SANDBOX_AGENT_IMAGE" ]; then
printf "AGENTA_API_IMAGE, AGENTA_WEB_IMAGE, AGENTA_SERVICES_IMAGE, and AGENTA_SANDBOX_AGENT_IMAGE are required\n" >&2
exit 1
fi

Expand Down Expand Up @@ -126,6 +127,18 @@ CMD ["gunicorn", "entrypoints.main:app", "--bind", "0.0.0.0:8080", "--worker-cla
EOF
}

render_sandbox_agent_wrapper() {
local dir="$TMP_DIR/sandbox-agent"
mkdir -p "$dir"
cat > "$dir/Dockerfile" <<EOF
FROM ${AGENTA_SANDBOX_AGENT_IMAGE}

ENV PORT=8765

CMD ["node_modules/.bin/tsx", "src/server.ts"]
EOF
}

render_web_wrapper() {
local dir="$TMP_DIR/web"
mkdir -p "$dir"
Expand Down Expand Up @@ -174,6 +187,7 @@ EOF

render_api_wrapper
render_services_wrapper
render_sandbox_agent_wrapper
render_web_wrapper
render_alembic_wrapper
render_redis_wrapper
Expand Down Expand Up @@ -208,6 +222,7 @@ railway_call up "$TMP_DIR/worker-tracing" --path-as-root --service worker-tracin
railway_call up "$TMP_DIR/worker-evaluations" --path-as-root --service worker-evaluations --detach
railway_call up "$TMP_DIR/worker-webhooks" --path-as-root --service worker-webhooks --detach
railway_call up "$TMP_DIR/worker-events" --path-as-root --service worker-events --detach
railway_call up "$TMP_DIR/sandbox-agent" --path-as-root --service sandbox-agent --detach
railway_call up "$TMP_DIR/services" --path-as-root --service services --detach
railway_call up "$TMP_DIR/cron" --path-as-root --service cron --detach
railway_call up "$TMP_DIR/web" --path-as-root --service web --detach
Expand Down
1 change: 1 addition & 0 deletions hosting/railway/oss/scripts/deploy-services.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ railway up hosting/railway/oss/worker-tracing --path-as-root --service worker-tr
railway up hosting/railway/oss/worker-evaluations --path-as-root --service worker-evaluations --detach
railway up hosting/railway/oss/worker-webhooks --path-as-root --service worker-webhooks --detach
railway up hosting/railway/oss/worker-events --path-as-root --service worker-events --detach
railway up hosting/railway/oss/sandbox-agent --path-as-root --service sandbox-agent --detach
railway up hosting/railway/oss/services --path-as-root --service services --detach
railway up hosting/railway/oss/cron --path-as-root --service cron --detach
railway up hosting/railway/oss/web --path-as-root --service web --detach
Expand Down
6 changes: 6 additions & 0 deletions hosting/railway/oss/scripts/preview-resolve-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ if [ -z "${AGENTA_SERVICES_IMAGE:-}" ] && [ -n "$IMAGE_TAG" ]; then
export AGENTA_SERVICES_IMAGE="ghcr.io/${GHCR_NAMESPACE}/agenta-services:${IMAGE_TAG}"
fi

if [ -z "${AGENTA_SANDBOX_AGENT_IMAGE:-}" ] && [ -n "$IMAGE_TAG" ]; then
export AGENTA_SANDBOX_AGENT_IMAGE="ghcr.io/${GHCR_NAMESPACE}/agenta-sandbox-agent:${IMAGE_TAG}"
fi

export AGENTA_API_IMAGE="${AGENTA_API_IMAGE:-ghcr.io/${GHCR_NAMESPACE}/agenta-api:latest}"
export AGENTA_WEB_IMAGE="${AGENTA_WEB_IMAGE:-ghcr.io/${GHCR_NAMESPACE}/agenta-web:latest}"
export AGENTA_SERVICES_IMAGE="${AGENTA_SERVICES_IMAGE:-ghcr.io/${GHCR_NAMESPACE}/agenta-services:latest}"
export AGENTA_SANDBOX_AGENT_IMAGE="${AGENTA_SANDBOX_AGENT_IMAGE:-ghcr.io/${GHCR_NAMESPACE}/agenta-sandbox-agent:latest}"

export RAILWAY_PROJECT_NAME="$PROJECT_NAME"
export RAILWAY_ENVIRONMENT_NAME="$ENV_NAME"
Expand All @@ -60,4 +65,5 @@ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
printf "AGENTA_API_IMAGE=%s\n" "$AGENTA_API_IMAGE"
printf "AGENTA_WEB_IMAGE=%s\n" "$AGENTA_WEB_IMAGE"
printf "AGENTA_SERVICES_IMAGE=%s\n" "$AGENTA_SERVICES_IMAGE"
printf "AGENTA_SANDBOX_AGENT_IMAGE=%s\n" "$AGENTA_SANDBOX_AGENT_IMAGE"
fi
Loading