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
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ COPY ./src /usr/local/src
# Extensions and libraries
COPY --from=composer /usr/local/src/vendor /usr/local/vendor

RUN \
apk update \
&& apk add --no-cache make automake autoconf gcc g++ git brotli-dev docker-cli curl

RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
&& chmod +x kubectl \
&& mv kubectl /usr/local/bin/kubectl

HEALTHCHECK --interval=30s --timeout=15s --start-period=60s --retries=3 CMD curl -s -H "Authorization: Bearer ${OPR_EXECUTOR_SECRET}" --fail http://127.0.0.1:80/v1/health

CMD [ "php", "app/http.php" ]
193 changes: 193 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
.PHONY: help start-docker test-docker helm-clean helm-install helm-install-local helm-upgrade helm-uninstall helm-test kind-create kind-delete kind-load kind-full docker-build docker-push deploy stop clean

# Configuration
IMAGE_NAME ?= openruntimes/executor
IMAGE_TAG ?= latest
HELM_RELEASE ?= executor
HELM_NAMESPACE ?= default
KIND_CLUSTER ?= executor-cluster

# Default target
help:
@echo "Open Runtimes Executor - Make Commands"
@echo ""
@echo "Docker Runner:"
@echo " make start-docker - Start executor with Docker runner"
@echo " make test-docker - Run tests against Docker executor"
@echo " make logs-docker - View Docker executor logs"
@echo ""
@echo "Helm Deployment:"
@echo " make helm-clean - Clean up conflicting resources"
@echo " make helm-install - Install executor with Helm"
@echo " make helm-upgrade - Upgrade executor Helm release"
@echo " make helm-uninstall - Uninstall executor Helm release"
@echo " make helm-test - Port-forward and test Helm deployment"
@echo ""
@echo "Kind (Local Kubernetes):"
@echo " make kind-create - Create Kind cluster"
@echo " make kind-delete - Delete Kind cluster"
@echo " make kind-load - Build and load image to Kind"
@echo " make kind-full - Full setup: create cluster, load image, install"
@echo ""
@echo "Docker Image:"
@echo " make docker-build - Build executor Docker image"
@echo " make docker-push - Push image to registry"
@echo ""
@echo "Combined:"
@echo " make deploy - Build, load to kind, and install with helm"
@echo ""
@echo "General:"
@echo " make stop - Stop Docker executor"
@echo " make clean - Clean up everything"

# Docker Runner targets
start-docker:
@echo "Starting Executor with Docker runner..."
docker-compose up -d
@echo "Executor is running on http://localhost:80"

logs-docker:
docker-compose logs -f

# Helm targets
helm-clean:
@echo "Cleaning up existing resources that conflict with Helm..."
-kubectl delete serviceaccount executor-sa -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete role executor-role -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete rolebinding executor-rolebinding -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete deployment executor-k8s -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete service executor-k8s -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete configmap executor-k8s-config -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete secret executor-k8s-secret -n $(HELM_NAMESPACE) 2>/dev/null || true
@echo "Cleanup complete!"

helm-install: helm-clean
@echo "Installing Executor with Helm..."
helm install $(HELM_RELEASE) ./deploy \
--namespace $(HELM_NAMESPACE) \
--create-namespace \
--wait
@echo ""
@echo "Executor installed successfully!"
@echo "To access the executor, run:"
@echo " make helm-test"

helm-install-local: helm-clean
@echo "Installing Executor with Helm (local Kind values)..."
helm install $(HELM_RELEASE) ./deploy \
-f ./deploy/values-local.yaml \
--namespace $(HELM_NAMESPACE) \
--create-namespace \
--wait
@echo ""
@echo "Executor installed successfully!"
@echo "To access the executor, run:"
@echo " make helm-test"

helm-upgrade:
@echo "Upgrading Executor..."
helm upgrade $(HELM_RELEASE) ./deploy \
--namespace $(HELM_NAMESPACE) \
--wait
@echo "Executor upgraded successfully!"

helm-uninstall:
@echo "Uninstalling Executor..."
helm uninstall $(HELM_RELEASE) --namespace $(HELM_NAMESPACE)
@echo "Executor uninstalled!"

helm-test:
@echo "Port-forwarding to executor service..."
@echo "Executor will be available at http://localhost:8080"
@echo "Press Ctrl+C to stop"
@kubectl port-forward -n $(HELM_NAMESPACE) svc/$(HELM_RELEASE)-openruntimes-executor 8080:80

# Kind targets
kind-create:
@echo "Creating Kind cluster..."
@if kind get clusters | grep -q $(KIND_CLUSTER); then \
echo "Cluster $(KIND_CLUSTER) already exists"; \
else \
kind create cluster --name $(KIND_CLUSTER); \
echo "Cluster created successfully!"; \
fi

kind-delete:
@echo "Deleting Kind cluster..."
kind delete cluster --name $(KIND_CLUSTER)
@echo "Cluster deleted!"

kind-load:
@echo "Building and loading image to Kind..."
docker build -t $(IMAGE_NAME):$(IMAGE_TAG) .
kind load docker-image $(IMAGE_NAME):$(IMAGE_TAG) --name $(KIND_CLUSTER)
@echo "Image loaded successfully!"

kind-full: kind-create kind-load helm-install-local
@echo ""
@echo "βœ… Full setup complete!"
@echo "Run 'make helm-test' to access the executor"

# Docker image targets
docker-build:
@echo "Building Docker image..."
docker build -t $(IMAGE_NAME):$(IMAGE_TAG) .
@echo "Image built successfully!"

docker-push: docker-build
@echo "Pushing Docker image..."
docker push $(IMAGE_NAME):$(IMAGE_TAG)
@echo "Image pushed successfully!"

# Combined deployment
deploy: kind-load helm-upgrade
@echo ""
@echo "βœ… Deployment complete!"
@echo "Run 'make helm-test' to access the executor"

# Testing targets
test-docker:
@echo "Running tests against Docker executor..."
composer test

# Cleanup targets
stop:
@echo "Stopping Docker executor..."
-docker-compose down

clean:
@echo "Cleaning up..."
@echo "Stopping Docker executor..."
-docker-compose down
@echo "Uninstalling Helm release..."
-helm uninstall $(HELM_RELEASE) --namespace $(HELM_NAMESPACE) 2>/dev/null || true
@echo "Cleaning up conflicting Kubernetes resources..."
-kubectl delete serviceaccount executor-sa -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete role executor-role -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete rolebinding executor-rolebinding -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete deployment executor-k8s -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete service executor-k8s -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete configmap executor-k8s-config -n $(HELM_NAMESPACE) 2>/dev/null || true
-kubectl delete secret executor-k8s-secret -n $(HELM_NAMESPACE) 2>/dev/null || true
@echo "Deleting Kind cluster..."
-kind delete cluster --name $(KIND_CLUSTER) 2>/dev/null || true
@echo "Cleaning Docker..."
-docker system prune -f
@echo "Cleanup complete!"

# Development targets
install:
composer install

lint:
composer lint

format:
composer format

check:
composer check

# Build target
build:
docker-compose build
62 changes: 60 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,60 @@ curl -H "authorization: Bearer executor-secret-key" -H "Content-Type: applicatio
docker compose down
```

## Kubernetes Deployment

For deploying to Kubernetes with Helm:

### Quick Start with Kind (Local)

```bash
# Create local Kubernetes cluster
make kind-create

# Build and deploy
make kind-full

# Test the executor
make helm-test
```

### Production Deployment

```bash
# Install with Helm
helm install executor ./deploy \
--set secret.executorSecret="your-secure-secret-key" \
--set ingress.enabled=true \
--set ingress.hosts[0].host="executor.example.com" \
--set sharedStorage.enabled=true \
--set sharedStorage.storageClass="nfs-storage"

# Or use production values
helm install executor ./deploy -f ./deploy/values-production.yaml
```

### Shared Storage (Required for Function Execution)

For full function execution in Kubernetes, you need shared storage between executor and runtime pods:

```bash
# Configure shared storage (ReadWriteMany required)
helm install executor ./deploy \
--set sharedStorage.enabled=true \
--set sharedStorage.storageClass="efs-sc" # AWS EFS
--set sharedStorage.size="100Gi"
```

Supported storage classes:
- **AWS**: EFS (`efs-sc`)
- **Azure**: Azure Files (`azurefile`)
- **GCP**: Filestore (`filestore-sc`)
- **On-Premises**: NFS, Ceph, GlusterFS

See the [shared storage documentation](./deploy/STORAGE.md) for detailed setup instructions.

See the [deployment documentation](./deploy/README.md) for more details.

## API Endpoints

| Method | Endpoint | Description | Params |
Expand Down Expand Up @@ -192,6 +246,7 @@ docker compose down
| Variable name | Description |
|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| OPR_EXECUTOR_ENV | Environment mode of the executor, ex. `development` |
| OPR_EXECUTOR_RUNNER | Runner type for the executor: `docker` (default) or `kubernetes` |
| OPR_EXECUTOR_RUNTIMES | Comma-separated list of supported runtimes `(ex: php-8.1,dart-2.18,deno-1.24,..)`. These runtimes should be available as container images. |
| OPR_EXECUTOR_CONNECTION_STORAGE | DSN string that represents a connection to your storage device, ex: `file://localhost` for local storage |
| OPR_EXECUTOR_INACTIVE_THRESHOLD | Threshold time (in seconds) for detecting inactive runtimes, ex: `60` |
Expand All @@ -200,8 +255,11 @@ docker compose down
| OPR_EXECUTOR_SECRET | Secret key used by the executor for authentication |
| OPR_EXECUTOR_LOGGING_PROVIDER | Deprecated: use `OPR_EXECUTOR_LOGGING_CONFIG` with DSN instead. External logging provider used by the executor, ex: `sentry` |
| OPR_EXECUTOR_LOGGING_CONFIG | External logging provider DSN used by the executor, ex: `sentry://PROJECT_ID:SENTRY_API_KEY@SENTRY_HOST/` |
| OPR_EXECUTOR_DOCKER_HUB_USERNAME | Username for Docker Hub authentication (if applicable) |
| OPR_EXECUTOR_DOCKER_HUB_PASSWORD | Password for Docker Hub authentication (if applicable) |
| OPR_EXECUTOR_DOCKER_HUB_USERNAME | Username for Docker Hub authentication (if applicable, used when runner is `docker`) |
| OPR_EXECUTOR_DOCKER_HUB_PASSWORD | Password for Docker Hub authentication (if applicable, used when runner is `docker`) |
| OPR_EXECUTOR_K8S_URL | Kubernetes API URL (if applicable, used when runner is `kubernetes`), ex: `https://kubernetes.default.svc` |
| OPR_EXECUTOR_K8S_NAMESPACE | Kubernetes namespace for runtime pods (if applicable, used when runner is `kubernetes`), ex: `default` |
| OPR_EXECUTOR_K8S_TOKEN | Kubernetes API token for external access (optional, auto-detected from ServiceAccount when running in-cluster) |
| OPR_EXECUTOR_RUNTIME_VERSIONS | Version tag for runtime environments, ex: `v5` |
| OPR_EXECUTOR_RETRY_ATTEMPTS | Number of retry attempts for failed executions, ex: `5` |
| OPR_EXECUTOR_RETRY_DELAY_MS | Delay (in milliseconds) between retry attempts, ex: `500` |
Expand Down
Loading
Loading