# Deploy an app

A **deployment** is one attempt to ship a new version of your app. The `dina deploy` command starts a deployment. Every deployment belongs to an app you've already created.

If you haven't created an app yet, see [Manage apps](/docs/apps).

## Two ways to deploy

You can hand Dina either source code or a pre-built container image. Pick the one that matches your workflow.

### From source

Run this from the folder containing your app:

```sh
dina deploy --app my-app
```

The CLI zips the current directory, uploads it, builds a container from the `Dockerfile`, and rolls it out. Good fit if:

- Your codebase already has a `Dockerfile`.
- You want one tool for "push to production" without a separate image registry.
- You're iterating fast and don't want to rebuild images yourself.

### From a pre-built image

```sh
dina deploy --app my-app --tag ghcr.io/acme/web:2024-03-14
```

The CLI skips the upload and tells Dina to run that image directly. Good fit if:

- Your CI pipeline already builds and publishes images.
- You want reproducible builds pinned to a specific tag or digest.
- The image is in a registry Dina can reach.

## Waiting for the deployment to finish

By default, `dina deploy` returns as soon as the deployment has been accepted — the build itself keeps running in the background.

Add `--wait` to stay attached until it's live:

```sh
dina deploy --app my-app --wait
```

The CLI polls the platform and exits when the deployment reaches `running` (success) or one of the failure states. If the deployment fails, the command exits with a non-zero status, which is useful in CI.

## Controlling the runtime

When you deploy, you can tell Dina:

- **Which port your app listens on** with `--port`. Defaults to `8080`.
- **How many replicas to run** with `--replicas`. Defaults to `1`.

```sh
dina deploy --app my-app --port 3000 --replicas 3 --wait
```

These values are only sent when you pass them explicitly. Leaving them off keeps whatever the previous deployment was using.

## Build arguments

For source deployments, you can pass build arguments into your `Dockerfile`:

```sh
dina deploy --app my-app \
  --build-arg NODE_ENV=production \
  --build-arg COMMIT_SHA=$(git rev-parse HEAD)
```

Each `--build-arg` is a `KEY=VALUE` pair. They're visible during the build but don't become environment variables at runtime — for that, see [environment variables](/docs/environment-variables).

## CI-friendly deployments

When running in CI, you'll want:

- `--no-input` — the CLI errors out instead of waiting on a prompt.
- `--wait` — the command exits non-zero if the deployment fails, so your pipeline fails loudly.
- `--quiet` — suppresses progress chatter on stderr.

Putting it together:

```sh
dina deploy --app my-app --tag $IMAGE --wait --no-input --quiet
```

## What just happened?

After any deployment, `dina apps info --app my-app` will show you:

- The **active deployment ID** (useful if you need to roll back or inspect build logs).
- The **image** that's running.
- The **port** and **replicas** in effect.

To see the full history of deployments for an app:

```sh
dina apps deployments --app my-app
```

See [Logs and deployments](/docs/logs-and-deployments) for more on inspecting a specific deployment or its build output.

## Common problems

**"App not found".** The `--app` name must match an app you've already created. Run `dina apps list` to see your apps.

**Build fails.** Check the build logs:

```sh
dina apps deployments --app my-app
dina apps deployments logs --app my-app --id <deployment-id>
```

The deployment ID is the first column of `dina apps deployments`.

**Upload is slow.** Add a `.dockerignore` so you don't ship `node_modules`, build artefacts, or large test fixtures. Smaller uploads also mean faster builds.
