# Development and production

> Run your app against the local Dev Server, then deploy it to Inngest Cloud.

The Go SDK runs in one of two modes:

- **Dev mode** connects to the local [Dev Server](/docs-markdown/local-development). Use it on your machine and in CI.
- **Cloud mode** connects to Inngest Cloud. This is the default, so a deployed app never trusts unsigned requests by accident.

## Turn on dev mode

Set the `INNGEST_DEV` environment variable, then start the Dev Server:

```shell
INNGEST_DEV=1 go run .
```

```shell
npx --ignore-scripts=false inngest-cli@latest dev -u http://localhost:8080/api/inngest
```

`INNGEST_DEV=1` uses the Dev Server at `http://127.0.0.1:8288`. To use a Dev Server at another address, set `INNGEST_DEV` to its URL, for example `INNGEST_DEV=http://192.168.1.254:8288`.

> **Callout:** Any value turns on dev mode, including 0 and false. To use cloud mode, leave INNGEST\_DEV unset.

To choose the mode in code instead, set `ClientOpts.Dev`. It overrides `INNGEST_DEV`:

```go
client, err := inngestgo.NewClient(inngestgo.ClientOpts{
	AppID: "billing",
	// Use the Dev Server everywhere except production.  This overrides INNGEST_DEV.
	Dev: inngestgo.BoolPtr(os.Getenv("APP_ENV") != "production"),
})
```

[Durable Endpoints](/docs-markdown/reference/go/durable-endpoints) read only `INNGEST_DEV`, because `stephttp.Setup` doesn't use the client. To point a provider at another Inngest API, set `stephttp.SetupOpts.Optional.BaseURL`.

## What changes between modes

|                           | Dev mode                                           | Cloud mode                                                              |
| ------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------- |
| Inngest API and event API | The Dev Server, `http://127.0.0.1:8288` by default | `https://api.inngest.com` and `https://inn.gs`                          |
| Requests from Inngest     | Not verified                                       | Must have a valid signature from your signing key                       |
| Signing key               | Not needed                                         | Required to serve functions, connect workers, and run Durable Endpoints |
| Event key                 | Not needed to send events                          | Required to send events                                                 |
| Unauthenticated syncs     | Allowed                                            | Rejected unless `ServeOpts.EnableUnauthedSync` is set                   |

## Deploy to production

Before you deploy, set these environment variables, and make sure that `INNGEST_DEV` isn't set:

| Variable                       | Description                                                                                                                                                                                   |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `INNGEST_SIGNING_KEY`          | Verifies requests from Inngest and authenticates syncs. Find it in your environment's [signing key settings](https://app.inngest.com/env/production/manage/signing-key).                      |
| `INNGEST_SIGNING_KEY_FALLBACK` | Optional. The previous signing key, so that requests keep working while you [rotate keys](/docs-markdown/platform-and-operations/rotate-event-and-signing-keys).                              |
| `INNGEST_EVENT_KEY`            | Sends events with `client.Send` and `step.Send`. Create one in your environment's [event keys](https://app.inngest.com/env/production/manage/keys).                                           |
| `INNGEST_ENV`                  | Optional. The [branch environment](/docs-markdown/platform-and-operations/environments-and-branch-deploys#use-branch-deploys-for-preview-deployments) to use, for example in preview deploys. |

You can also set each value in `inngestgo.ClientOpts`, such as `SigningKey` and `EventKey`. A value set in code takes the place of its environment variable.

Then make your functions available to Inngest:

- **Serve:** deploy the app and [sync it](/docs-markdown/platform-and-operations/apps-and-syncs) with the URL of your `client.Serve()` endpoint.
- **Connect:** start your workers. Each worker syncs itself when it connects.

See [serve or connect your functions](/docs-markdown/reference/go/durable-workflows#serve-or-connect-your-functions) for both setups, and [environment variables](/docs-markdown/sdk/environment-variables) for every variable the SDK reads.

## Self-hosting

To use a [self-hosted Inngest server](/docs-markdown/self-hosting), run in cloud mode and set `INNGEST_BASE_URL` to the server's URL. To use separate hosts for the API and events, set `INNGEST_API_BASE_URL` and `INNGEST_EVENT_API_BASE_URL`, or `ClientOpts.APIBaseURL` and `ClientOpts.EventAPIBaseURL`.