> ## Documentation Index
> Fetch the complete documentation index at: https://developers.liara.ir/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a release

> Starts a new release of the app, from an uploaded `sourceID` or, for `docker` apps, from an `image`. Send exactly one of them. Releases that are still building or deploying are cancelled. Source releases are built first; image releases are deployed directly.

**Limit:** the number of deployments per day depends on your bundle plan. Team permission: `deploy`, `operate` or `manage`.



## OpenAPI

````yaml /spec/paas.yaml post /v2/projects/{project_id}/releases
openapi: 3.0.1
info:
  title: Apps & Deployments
  version: 1.0.0
  description: >
    Create apps, deploy them, change their plans and settings, and read

    their logs, metrics and events.


    ## Identifying an app


    Most endpoints identify an app by its **name** (`project_id`, for

    example `my-app`). Some use its **ID** instead (`projectID`, the
    24-character

    `_id` returned when you create or list apps). Each endpoint says which one

    it expects.


    ## Deploying


    1. Upload your source code as a `.tar.gz` or `.zip` archive with
       `POST /v2/projects/{project_id}/sources`. You get a `sourceID`.
    2. Create a release with `POST /v2/projects/{project_id}/releases`, passing
       the `sourceID`. For `docker` apps you can pass a ready-made `image`
       instead.
    3. Follow the build with `GET /v2/releases/{releaseID}/build-logs` and
       check the release `state` with `GET /v1/releases/{releaseID}` until it's
       `READY` (or `FAILED`, `CANCELED`, `TIMEDOUT` or `UNHEALTHY`).

    ## Interactive shell (WebSocket)


    Open a shell in a running app over WebSocket:


    ```text

    wss://api.liara.ir/v1/exec?token=<api-token>&project_id=<app-name>&cmd=<command>

    ```


    - `token`: your API token.

    - `project_id`: the app's name.

    - `cmd`: the command to run, for example `/bin/bash`. URL-encode it.

    - `teamID` (optional): the team that owns the app. You need the `operate`
      or `manage` permission on the app.

    Everything you send is passed to the command's input, and its output is

    sent back to you. If the app has never been deployed successfully, you get

    the message `Service does not exist yet. You should have at least one

    successful release.` and the connection closes. The handshake fails with

    `401` for a missing or invalid token, `400` if `project_id` or `cmd` is

    missing or `teamID` is invalid, `403` without access to the team or app,

    and `404` if the app doesn't exist.


    ## Team permissions


    With `teamID`, each endpoint needs one of the project permissions it lists

    (`view`, `deploy`, `operate` or `manage`). A permission from your role or

    a resource permission on that app both count.
servers:
  - url: https://api.liara.ir
security:
  - bearerAuth: []
tags:
  - name: Apps
    description: Create, list, inspect and delete apps.
  - name: Configuration
    description: Environment variables, port, DNS servers, plans and scaling.
  - name: Settings
    description: >-
      Read-only filesystem, default subdomain, zero-downtime deployment and
      fixed outbound IP.
  - name: Deployments
    description: Upload source code, create releases, follow builds and roll back.
  - name: Logs, Metrics & Events
    description: Runtime logs, resource usage and lifecycle events.
  - name: Networks
    description: Private networks that apps and databases are created in.
paths:
  /v2/projects/{project_id}/releases:
    post:
      tags:
        - Deployments
      summary: Deploy a release
      description: >-
        Starts a new release of the app, from an uploaded `sourceID` or, for
        `docker` apps, from an `image`. Send exactly one of them. Releases that
        are still building or deploying are cancelled. Source releases are built
        first; image releases are deployed directly.


        **Limit:** the number of deployments per day depends on your bundle
        plan. Team permission: `deploy`, `operate` or `manage`.
      operationId: createRelease
      parameters:
        - $ref: '#/components/parameters/TeamID'
        - $ref: '#/components/parameters/AppName'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRelease'
            examples:
              source:
                summary: Deploy uploaded source code
                value:
                  type: node
                  port: 3000
                  sourceID: 00000000-0000-0000-0000-000000000000.tar.gz
                  message: Fix login page
                  platformConfig:
                    version: '22'
                  disks:
                    - name: uploads
                      mountTo: uploads
              image:
                summary: Deploy a Docker image
                value:
                  type: docker
                  port: 80
                  image: nginx:1.27
      responses:
        '201':
          description: The release was created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  releaseID:
                    type: string
              example:
                releaseID: '000000000000000000000170'
        '400':
          description: >-
            The body or `teamID` is invalid. For example: both or neither of
            `sourceID` and `image` were sent, a disk doesn't exist, a disk is
            mounted on `/`, a `docker` app uses a relative mount path, the app
            is frozen (`frozen_project`), or the image couldn't be found or
            declares volumes that have no disk mounted on them.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                statusCode: 400
                error: Bad Request
                message: Please only use one of the sourceID or image fields. Not both.
                data: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/TeamForbidden'
        '404':
          description: The app doesn't exist.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                statusCode: 404
                error: Not Found
                message: project_not_found
                data: null
        '428':
          description: >-
            You've reached today's deployment limit
            (`max_deployment_count_in_day`), or your bundle plan doesn't allow
            the `germany` build location (`germany_builder_not_allowed`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                statusCode: 428
                error: Precondition Required
                message: Max deployment count in day.
                data:
                  code: max_deployment_count_in_day
components:
  parameters:
    TeamID:
      name: teamID
      in: query
      required: false
      description: >-
        Run the request in the context of a team you belong to, instead of your
        personal account.
      schema:
        $ref: '#/components/schemas/ObjectID'
      example: '000000000000000000000002'
    AppName:
      name: project_id
      in: path
      required: true
      description: The app's name.
      schema:
        type: string
      example: my-app
  schemas:
    CreateRelease:
      type: object
      required:
        - type
        - port
      properties:
        type:
          $ref: '#/components/schemas/Platform'
        port:
          type: integer
          minimum: 1
          description: >-
            The port your app listens on. For `static`, `react`, `vue`,
            `angular`, `laravel`, `php`, `django` and `flask` it's always `80`,
            and for `next` always `3000`, whatever you send.
        sourceID:
          type: string
          description: From `POST /v2/projects/{project_id}/sources`.
        image:
          type: string
          description: >-
            Only for `docker` apps. A container image to deploy instead of
            source code.
        envs:
          type: object
          additionalProperties:
            type: string
          description: If not empty, replaces all of the app's environment variables.
        args:
          type: array
          description: Arguments to start the app with.
          items:
            type: string
        cron:
          type: array
          description: >-
            Scheduled jobs, each a cron schedule followed by a command. Only for
            `next`, `laravel`, `php`, `python`, `django`, `flask` and `go`.
          items:
            type: string
        disks:
          type: array
          maxItems: 8
          items:
            $ref: '#/components/schemas/DiskMount'
        healthCheck:
          type: object
          description: >-
            Command that checks whether the app is healthy. Times are in
            milliseconds.
          properties:
            command:
              type: array
              items:
                type: string
            interval:
              type: integer
              minimum: 30
              default: 1000
            timeout:
              type: integer
              minimum: 1
              maximum: 10000
              default: 1000
            retries:
              type: integer
              minimum: 0
              maximum: 10
              default: 3
            startPeriod:
              type: integer
              minimum: 0
              maximum: 3000
              default: 500
        message:
          type: string
          maxLength: 50
          description: A note about the release. Longer text is cut off.
        gitInfo:
          type: object
          description: Information about the commit being deployed, shown with the release.
          properties:
            branch:
              type: string
            commit:
              type: string
            message:
              type: string
            committedAt:
              type: string
            remote:
              type: string
            tags:
              type: array
              items:
                type: string
            author:
              type: object
              properties:
                name:
                  type: string
                email:
                  type: string
        platformConfig:
          type: object
          description: >
            Platform-specific build settings. The allowed fields depend on
            `type`:


            | Platform | Fields |

            |----------|--------|

            | `node` | `version` (`8`, `10`, `11`, `12`, `14`, `16`, `18`, `20`,
            `22`, `24` or `latest`), `npmAudit`, `npmCiFallback`, `timezone`,
            `mirror` |

            | `next` | `nodeVersion` (`20`, `22`, `24`), `modifyConfig`,
            `npmCiFallback`, `mirror` |

            | `react`, `angular` | `mirror`, `sourceMap` |

            | `vue` | `mirror` |

            | `laravel` | `phpVersion` (`7.2`–`8.4`, `legacy` or `old-release
            8.2`), `timezone`, `npmMirror`, `composerMirror`, `routeCache`,
            `configCache`, `buildAssets`, `ssr`, `modifyImagickPolicy`,
            `installDevDependencies`, `reverb`, `reverbPath`, `modifyHtaccess` |

            | `php` | `version` (`7.2`–`8.4`), `timezone`, `composerMirror` |

            | `django` | `pythonVersion` (`3.7`–`3.13`), `nodeVersion` (`14`,
            `16`, `18`, `20`), `timezone`, `settingsFile`, `modifySettings`,
            `collectStatic`, `compileMessages`, `geospatial`, `pipTimeout`,
            `mirror` |

            | `flask` | `pythonVersion` (`3.7`–`3.13`), `nodeVersion` (`14`,
            `16`, `18`, `20`), `appModule`, `timezone`, `mirror` |

            | `python` | `version` (`3.8`–`3.13`), `timezone`, `mirror` |

            | `netcore`, `dotnet` | `version` (`2.1`, `2.2`, `3.0`, `3.1`,
            `5.0`, `6.0`, `7.0`, `8.0`, `9.0` or `10.0`), `timezone`,
            `finalDllName`, `csprojectFile` |

            | `go` | `version` (`1.21`–`1.25`), `cgoEnabled`, `mainFile`,
            `timezone` |


            `mirror` (and `npmMirror` / `composerMirror`) download packages

            through Liara's package mirrors.
        build:
          type: object
          properties:
            args:
              type: object
              description: Build arguments.
              additionalProperties:
                type: string
            cache:
              type: boolean
              default: true
              description: Reuse cached layers from earlier builds.
            location:
              type: string
              description: >-
                Where to build. If omitted, a default is chosen for the app's
                platform. Your bundle plan must allow `germany`.
              enum:
                - iran
                - germany
            dockerfile:
              type: string
              default: Dockerfile
              description: Path of the Dockerfile, for `docker` apps.
    Error:
      type: object
      description: Standard error body.
      properties:
        statusCode:
          type: integer
        error:
          type: string
          description: HTTP status text.
        message:
          type: string
          description: What went wrong.
        data:
          type: object
          nullable: true
          description: >-
            Extra details. When present, `code` is a stable, machine-readable
            error code.
          properties:
            code:
              type: string
    ObjectID:
      type: string
      pattern: ^[0-9a-fA-F]{24}$
      description: 24-character hexadecimal ID.
    Platform:
      type: string
      description: The app's platform.
      enum:
        - node
        - next
        - react
        - vue
        - angular
        - static
        - laravel
        - php
        - django
        - flask
        - python
        - netcore
        - dotnet
        - go
        - docker
    DiskMount:
      type: object
      required:
        - name
        - mountTo
      properties:
        name:
          type: string
          description: Name of one of the app's disks.
        mountTo:
          type: string
          description: >-
            Where to mount it. Relative paths are relative to your app's root
            directory; `docker` apps must use absolute paths. Can't be `/`.
    AuthError:
      type: object
      description: Error body returned when the API token is rejected.
      properties:
        error:
          type: string
  responses:
    Unauthorized:
      description: The API token is missing, invalid or expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthError'
          example:
            error: Unauthorized.
    TeamForbidden:
      description: >-
        With `teamID`: you aren't a member of the team (`team_not_found`), or
        you don't have the required permission on this app (`no_permission`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            teamNotFound:
              summary: Not a team member
              value:
                statusCode: 403
                error: Forbidden
                message: Team not found
                data:
                  code: team_not_found
            noPermission:
              summary: Missing permission
              value:
                statusCode: 403
                error: Forbidden
                message: You do not have permission to access this resource.
                data:
                  code: no_permission
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Send your API token as `Authorization: Bearer <api-token>`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.