# Deployment

The **Deployment flow** is pretty straightforward:

**Queued -> Build (if needed) -> Deployment -> DNS Records -> Running Environment**

Once a deployment is triggered, the Environment gets Queued, then, if needed, the images are built.

{% hint style="info" %}
The build may not be needed if:

* The image was already built (there are no code changes since the last deployment)
* The **Component** (Application / Service) is using a public image
  {% endhint %}

The actual Deployment phase is started once all images are available. Bunnyshell creates the Kubernetes manifests for the Environment, and applies them into a dedicated Kubernetes Namespace, isolated from other Namespaces for security purposes.

Bunnyshell will create:

* the Ingress
* a Kubernetes Service for each Component that has a port exposed
* a Kubernetes Deployment, which has the default replica number set at 1
* the actual Pod(s)
* Persistent Volumes, if needed

The replica count can be set from `docker-compose.yaml` by setting the property `deploy.replicas` for each service.

```
services:
  ...
  backend:
    build:
      context: ./backend
      target: ${FRONTEND_BUILD_TARGET:-dev}
    ...
    deploy:
      replicas: 3
```

{% hint style="info" %}
In the situation above, the `backend` will have 3 Pods created within the Kubernetes Deployment.
{% endhint %}

Once the Kubernetes manifests are applied, the flow enters a pending state, in which it waits for the resources to be up and running.

After all is done, Bunnyshell creates the DNS records for the publicly exposed endpoints.

Finally, the Environment enters the **Running** state and you can use it.

{% hint style="warning" %}
Keep in mind that Bunnyshell provides additional (advanced) mechanisms to handle deployments, by declaring the `pod` property, which allows the use of [Init- and Sidecar- containers](https://documentation.bunnyshell.com/reference-guide/environment-definition-file-env.yaml#components.n.pod-definition).
{% endhint %}
