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

# Docker Image Builds

> Deploy game servers from your own Docker images.

# Docker Image Builds

PlayFlow supports two ways to deploy your game server: uploading a ZIP of your server build, or importing a pre-built Docker image. This guide covers the Docker image approach, which gives you full control over your server environment and enables tighter CI/CD integration.

## How It Works

When you import a Docker image, PlayFlow pulls it from your container registry and makes it available for server launches. Servers started from a Docker image build skip the ZIP download and extraction step entirely -- the image is ready to run immediately.

<Info>
  Docker image builds are ideal for teams that already have a containerized build pipeline. If you are new to containers or prefer a simpler workflow, the [ZIP upload method](/unity/game-servers) handles containerization for you automatically.
</Info>

## Prerequisites

Before you begin, make sure you have:

* A PlayFlow project with an API key (find it in **Project Settings** on the dashboard)
* A Docker image pushed to an accessible container registry (Docker Hub, GitHub Container Registry, AWS ECR, etc.)
* If your registry is private, the credentials to pull the image

## Importing a Docker Image

<Steps>
  <Step title="Push your image to a container registry">
    Build and push your game server image to any Docker-compatible registry. Make sure the image contains everything your server needs to run.

    ```bash theme={null}
    docker build -t registry.example.com/my-game-server:v1.0 .
    docker push registry.example.com/my-game-server:v1.0
    ```
  </Step>

  <Step title="Import the image into PlayFlow">
    Call the Docker image import endpoint with your image URL and, optionally, registry credentials and an executable path.

    <CodeGroup>
      ```bash curl (public registry) theme={null}
      curl -X POST https://app.playflowcloud.com/api/v3/builds/docker-image \
        -H "api-key: YOUR_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "my-server-build",
          "image_url": "registry.example.com/my-game-server:v1.0"
        }'
      ```

      ```bash curl (private registry) theme={null}
      curl -X POST https://app.playflowcloud.com/api/v3/builds/docker-image \
        -H "api-key: YOUR_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "my-server-build",
          "image_url": "registry.example.com/my-game-server:v1.0",
          "executable_path": "/app/server",
          "registry_credentials": {
            "username": "your-username",
            "password": "your-access-token"
          }
        }'
      ```
    </CodeGroup>
  </Step>

  <Step title="Wait for processing to complete">
    The build is created with status `processing`. PlayFlow pulls the image and prepares it for server launches. You can poll the build status endpoint or watch for updates on the dashboard.

    ```bash theme={null}
    curl https://app.playflowcloud.com/api/v3/builds/BUILD_ID \
      -H "api-key: YOUR_API_KEY"
    ```

    When processing finishes, the status changes to `ready`.
  </Step>

  <Step title="Launch a server from the build">
    Once the build is ready, start a server using it just like any other build. PlayFlow uses the Docker image directly -- no ZIP download or extraction required.

    ```bash theme={null}
    curl -X POST https://app.playflowcloud.com/api/v3/servers/start \
      -H "api-key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "build_id": "BUILD_ID",
        "region": "us-east"
      }'
    ```
  </Step>
</Steps>

## Request Body Reference

| Field                           | Type   | Required                      | Description                                                                                                 |
| :------------------------------ | :----- | :---------------------------- | :---------------------------------------------------------------------------------------------------------- |
| `name`                          | string | Yes                           | A name for this build. Builds with the same name auto-increment their version number.                       |
| `image_url`                     | string | Yes                           | The full image URL including tag (e.g., `registry.example.com/my-server:v1.0`).                             |
| `executable_path`               | string | No                            | The path to the server executable inside the container. Only needed if it cannot be inferred automatically. |
| `registry_credentials`          | object | No                            | Credentials for pulling from a private registry.                                                            |
| `registry_credentials.username` | string | Yes (if credentials provided) | Registry username or service account name.                                                                  |
| `registry_credentials.password` | string | Yes (if credentials provided) | Registry password, access token, or personal access token.                                                  |

## Docker Image vs. ZIP Upload

<Tabs>
  <Tab title="Docker Image">
    **Best for:** advanced users, custom runtimes, CI/CD pipelines, non-standard server setups.

    * You build and manage the Docker image yourself
    * Full control over the base image, dependencies, and runtime environment
    * Faster server startup since the image is pre-built
    * Integrates naturally with CI/CD -- push to your registry, then import to PlayFlow
    * Supports any language, framework, or game engine
  </Tab>

  <Tab title="ZIP Upload">
    **Best for:** simple deployments, Unity/Godot builds, getting started quickly.

    * Upload a ZIP of your server binary and PlayFlow handles containerization
    * No Docker knowledge required
    * Great for standard Unity or Godot dedicated server builds
    * PlayFlow manages the image build and optimization
  </Tab>
</Tabs>

## CI/CD Integration

Docker image builds fit naturally into automated pipelines. Here is an example GitHub Actions workflow that builds your server image, pushes it to a registry, and imports it into PlayFlow:

```yaml github-actions.yml theme={null}
name: Deploy Game Server
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build and push Docker image
        run: |
          docker build -t ghcr.io/${{ github.repository }}/server:${{ github.sha }} .
          echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
          docker push ghcr.io/${{ github.repository }}/server:${{ github.sha }}

      - name: Import to PlayFlow
        run: |
          curl -X POST https://app.playflowcloud.com/api/v3/builds/docker-image \
            -H "api-key: ${{ secrets.PLAYFLOW_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{
              "name": "production-server",
              "image_url": "ghcr.io/${{ github.repository }}/server:${{ github.sha }}",
              "registry_credentials": {
                "username": "${{ github.actor }}",
                "password": "${{ secrets.GHCR_TOKEN }}"
              }
            }'
```

## Tips

<Warning>
  Always use a specific image tag (e.g., `:v1.0` or a commit SHA) rather than `:latest`. This ensures that your servers run the exact version you tested, and makes rollbacks straightforward.
</Warning>

* **Keep images small.** Smaller images pull faster, which reduces build processing time. Use multi-stage builds and minimal base images (e.g., `debian-slim`, `alpine`) where possible.
* **Include health checks.** If your server exposes a health endpoint, PlayFlow can use it to verify the server started correctly.
* **Test locally first.** Run your image with `docker run` before importing to PlayFlow to catch configuration issues early.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Server Regions" icon="globe" href="/fundamentals/regions">
    Choose the best deployment region for your players.
  </Card>

  <Card title="Pricing & Instance Types" icon="credit-card" href="/fundamentals/plan-instance-types">
    Review available compute sizes and pricing.
  </Card>
</CardGroup>
