---
title: "Install"
url: "/docs/get-started/install/"
kind: "feature"
summary: "Build the arion binary from source, pick optional Cargo features, build the Docker image, or run it on Kubernetes."
---

> Arion site index: [/llms.txt](/llms.txt)

# Install

Build the arion binary from source, pick optional Cargo features, build the Docker image, or run it on Kubernetes.

Arion installs from source: one Cargo build produces a single binary named `arion`, and the repo's Dockerfile wraps the same build in a container image. Use this page to build either one; the [quickstart](@/docs/get-started/quickstart.md) then gets a first config running.

There are no published binaries, container images or Helm charts yet — every install starts from the source tree.

## Before you begin

- Rust 1.89 or newer (the workspace sets `rust-version = "1.89"`).
- `protoc`, the protobuf compiler — the build generates the configuration model from Envoy's protobuf definitions.
- `git`, with submodule support. Docker builds need Docker; nothing else does.

## Get the source

```bash
git clone https://github.com/arion-gateway/arion
cd arion
git submodule update --init --recursive
```

The submodules contain Envoy's data-plane API protos; the build fails without them.

## Build and run

{% <variant mode="standalone" label="Standalone"> %}
Build the release binary:

```bash
cargo build --release -p arion-proxy
```

The binary lands at `target/release/arion`. Point it at a config file with `--config` (short `-c`):

```bash
./target/release/arion --config arion-proxy/conf/arion-runtime.yaml
```

To run an unmodified Envoy bootstrap file instead of an Arion config, pass it with `--with-envoy-bootstrap <file>`.

Or build and run the Docker image, which bakes in that same sample config at `/etc/arion/arion-runtime.yaml`:

```bash
docker build -t arion-proxy -f docker/Dockerfile .
docker run -d -p 8000:8000 --name arion-proxy arion-proxy
```

Mount your own config over the baked-in one with `-v "$PWD/arion.yaml:/etc/arion/arion-runtime.yaml"`. In containers, set the `ARION_CPU_LIMIT` environment variable to tell Arion how many cores to size its worker threads for.
{% </variant> %}

{% <variant mode="kubernetes" label="Kubernetes"> %}
There is no published image, Helm chart or manifest yet: build the image locally and load it into your cluster, then run it with the config in a ConfigMap.

```bash
docker build -t arion-proxy:dev -f docker/Dockerfile .
kind load docker-image arion-proxy:dev   # or: minikube image load arion-proxy:dev
```

The image reads `/etc/arion/arion-runtime.yaml`, so mount the ConfigMap there:

```yaml,name=arion-k8s.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: arion-config
data:
  arion-runtime.yaml: |
    envoy_bootstrap:
      static_resources:
        listeners:
          - name: listener_http
            address:
              socket_address: { address: 0.0.0.0, port_value: 8080 }
            filter_chains:
              - name: http_chain
                filters:
                  - name: http_gateway
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                      http_filters:
                        - name: envoy.filters.http.router
                          typed_config:
                            "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
                      route_config:
                        name: placeholder
                        virtual_hosts:
                          - name: all_hosts
                            domains: ["*"]
                            routes:
                              - match: { prefix: "/" }
                                direct_response:
                                  status: 200
                                  body: { inline_string: "arion is up\n" }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: arion
spec:
  replicas: 1
  selector:
    matchLabels: { app: arion }
  template:
    metadata:
      labels: { app: arion }
    spec:
      containers:
        - name: arion
          image: arion-proxy:dev
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
          env:
            - name: ARION_CPU_LIMIT
              value: "2"
          volumeMounts:
            - name: config
              mountPath: /etc/arion
      volumes:
        - name: config
          configMap: { name: arion-config }
```

```bash
kubectl apply -f arion-k8s.yaml
```

Replace the placeholder route with your real configuration — the file from the [quickstart](@/docs/get-started/quickstart.md) works as the ConfigMap value, once its cluster endpoints point at Services instead of `127.0.0.1`. `ARION_CPU_LIMIT` sizes the worker thread pool where the container cannot read the host's CPU topology.
{% </variant> %}

## Cargo features

The default build enables none of the optional features. Add them at build time with `--features`:

```bash
cargo build --release -p arion-proxy --features wasm,prometheus,access-log
```

| Feature | What it enables |
| --- | --- |
| `wasm` | The Wasm HTTP filter host (Wasmtime). Required to load [Wasm filters](@/docs/extend/wasm-filters.md) at runtime. |
| `codemode` | The sandbox (Wasmtime and QuickJS) behind MCP [code mode](@/docs/mcp-gateway/code-mode.md). Required for an MCP gateway configured with `code_mode`. |
| `metrics` | Metrics collection. |
| `prometheus` | Prometheus metrics export. Implies `metrics`. |
| `access-log` | Access logging. |
| `tracing` | Distributed tracing. |
| `config-dump` | Config dump support on the [admin interface](@/docs/observe/admin-interface.md). |
| `jemalloc` | jemalloc as the global allocator. |
| `instrumentation` | Internal instrumentation. |
| `dhat-heap` | Heap profiling with dhat, for development. |

The Docker image builds with the default feature set; edit `docker/Dockerfile` if you need extras such as `wasm` or `codemode` in the image.

## Verify

{% <variant mode="standalone" label="Standalone"> %}
Start Arion with the sample config, then curl its direct-response route from a second terminal:

```bash
curl -i http://localhost:8000/direct-response
```

```text
HTTP/1.1 200 OK
...
meow! 🐱
```
{% </variant> %}

{% <variant mode="kubernetes" label="Kubernetes"> %}
```bash
kubectl port-forward deploy/arion 8080:8080
curl -i http://localhost:8080/
```

```text
HTTP/1.1 200 OK
...
arion is up
```
{% </variant> %}

## Limits

- No published binaries, images or Helm charts yet; builds are from source.
- Optional features are compile-time only. A binary built without `wasm` cannot load Wasm filters, and one built without `codemode` rejects an MCP gateway in code mode.
- `jemalloc` is unavailable on MSVC targets.

With a working binary or image, continue to the [quickstart](@/docs/get-started/quickstart.md), and see [deploying Arion](@/docs/operate/deploy.md) for production layouts.
