# Deploy

> Deploy Aerostack functions via CLI or the Admin Dashboard, with aerostack.toml configuration reference.

Two paths to deploy a function: the **Aerostack CLI** (recommended for development workflows) and the **Admin Dashboard** (for quick uploads and non-technical users).

Both paths produce the same result — a function running on Cloudflare's edge with all six platform bindings wired up automatically.

## Deploy via CLI

The CLI is the fastest path from code to production.

1. **Authenticate**

   If you have not already authenticated:

   ```bash
   aerostack login
   ```

2. **Select your project**

   ```bash
   aerostack project select
   ```

3. **Deploy**

   From your function directory (the one containing `aerostack.toml` and `src/index.ts`):

   ```bash
   aerostack deploy function
   ```

   The CLI will:
   1. Build your TypeScript source
   2. Upload the compiled bundle to your Aerostack project
   3. Wire up all platform bindings (DB, Cache, Queue, AI, Vector Search, Storage)
   4. Return the live URL

### CLI deploy output

```
Deploying function: my-bookmarks-api
  Building... done (1.2s)
  Uploading... done
  Bindings configured:
    DB        → aerostack-core (Database)
    CACHE     → project-cache (Cache)
    QUEUE     → project-queue (Queue)
    AI        → Workers AI
    VECTORIZE → project-vectors (Vector Search)
    STORAGE   → project-storage (Storage)

  Live at: https://my-bookmarks-api.your-project.aerostack.dev
```

### Redeploying

Run the same command again. Aerostack performs a zero-downtime deployment — requests in-flight complete on the old version, new requests go to the updated code.

```bash
aerostack deploy function
```

---

## Deploy via Admin Dashboard

1. **Open the Functions page**

   Go to [app.aerostack.dev](https://app.aerostack.dev) and navigate to **Functions** in the sidebar.

2. **Create a new function**

   Click **New Function**. Enter a name for your function (this becomes part of the URL).

3. **Upload your code**

   Upload your function bundle. The dashboard accepts:
   - A single `index.js` or `index.ts` file
   - A `.zip` archive containing your project (must include `src/index.ts` or `src/index.js`)

4. **Configure bindings**

   The dashboard auto-detects bindings from your `aerostack.toml` if included. Otherwise, toggle the bindings you need:

   - Database
   - Cache
   - Queue
   - AI
   - Vector Search
   - Storage

5. **Deploy**

   Click **Deploy**. The function goes live within seconds.

---

## `aerostack.toml` Reference

The `aerostack.toml` file configures your function's name, entry point, and bindings. Aerostack reads this during deployment to set up the correct infrastructure.

### Minimal configuration

```toml
name = "my-function"
main = "src/index.ts"
compatibility_date = "2024-12-01"
```

This is enough if you only need the `fetch()` handler and no specific bindings during local development. Aerostack provides all bindings automatically when deployed.

### Full configuration

```toml
name = "my-function"
main = "src/index.ts"
compatibility_date = "2024-12-01"

# Database
[[d1_databases]]
binding = "DB"
database_name = "aerostack-core"
database_id = "local"                # Only for local dev

# Cache
[[kv_namespaces]]
binding = "CACHE"
id = "local"                         # Only for local dev

# Queue
[[queues.producers]]
binding = "QUEUE"
queue = "my-function-queue"

[[queues.consumers]]
queue = "my-function-queue"
max_batch_size = 10
max_retries = 3

# AI
[ai]
binding = "AI"

# Vector Search
[[vectorize]]
binding = "VECTORIZE"
index_name = "my-index"

# Storage
[[r2_buckets]]
binding = "STORAGE"
bucket_name = "my-bucket"

# Cron triggers (optional)
[triggers]
crons = ["0 * * * *"]               # Every hour

# Environment variables (optional)
[vars]
ENVIRONMENT = "production"
API_VERSION = "v1"
```

  The `database_id` and cache `id` values marked "local" are **only used for local development** with `aerostack dev`. When deployed through Aerostack, the platform injects the real binding IDs for your project. Do not hardcode production IDs here.

### Queue configuration options

| Option | Default | Description |
|---|---|---|
| `max_batch_size` | 10 | Maximum messages per `queue()` invocation (1-100) |
| `max_retries` | 3 | Times a message is retried after `msg.retry()` before being dead-lettered |
| `max_batch_timeout` | 5 | Seconds to wait for a full batch before delivering a partial one |
| `max_concurrency` | 1 | Parallel `queue()` invocations (increase for high-throughput) |

### Cron syntax

Standard five-field cron expressions:

| Expression | Schedule |
|---|---|
| `* * * * *` | Every minute |
| `*/5 * * * *` | Every 5 minutes |
| `0 * * * *` | Every hour |
| `0 9 * * *` | Daily at 9:00 UTC |
| `0 9 * * 1` | Every Monday at 9:00 UTC |
| `0 0 1 * *` | First of every month at midnight |

---

## Environment Variables and Secrets

### Non-sensitive values

Add them to `aerostack.toml`:

```toml
[vars]
APP_NAME = "my-app"
LOG_LEVEL = "info"
```

Access them in your function:

```typescript

  async fetch(request: Request, env: Env): Promise {
    console.log(env.APP_NAME) // "my-app"
  }
}
```

### Secrets

Never put secrets in `aerostack.toml`. Use the Aerostack CLI:

```bash
aerostack secrets set MY_API_KEY
```

Secrets are encrypted at rest and injected into `env` at runtime, accessed the same way as variables:

```typescript
const apiKey = env.MY_API_KEY
```

  Never commit `.dev.vars` files. They contain local development secrets. Add `.dev.vars` to your `.gitignore`.

---

## Deployment Checklist

Before deploying to production:

- [ ] Function builds without errors (`aerostack deploy function --dry-run`)
- [ ] All database migrations are applied (if using schema changes)
- [ ] Secrets are set for the production environment
- [ ] Queue consumers are configured if you use `env.QUEUE`
- [ ] Cron triggers are correct in `aerostack.toml`
- [ ] Error handling covers all code paths (no unhandled exceptions)
