### Building Docker Images with DeployHQ

This guide outlines how to configure DeployHQ to build Docker images from your repository and optionally push them to a container registry. This feature requires a Dockerfile in your repository.

**Prerequisites:**

* **Dockerfile:** Your repository must contain a valid Dockerfile
* **Registry Account:** For pushing images, you need credentials for your chosen container registry

## Supported Container Registries

DeployHQ supports building and pushing Docker images to:

* **Docker Hub** - The default Docker container registry
* **Google Container Registry (GCR)** - Google Cloud's container registry
* **GitHub Container Registry (GHCR)** - GitHub's container registry
* **Azure Container Registry (ACR)** - Microsoft Azure's container registry

## Step-by-Step Configuration

1. **Select Protocol:** Navigate to your server settings within DeployHQ and select **Docker Build** as your server's protocol.

2. **Push to Registry:** Choose whether to push the built image to a registry after building. Disable this option if you only want to test that your Dockerfile builds successfully.

![Push to Registry](https://i.ibb.co/fYBKRgmd/docker-build-push-to-registry.png)

3. **Registry Configuration:** Select your target container registry and enter your credentials (see registry-specific instructions below).

   * **Registry Type:** Docker Hub, Google Container Registry (GCR), GitHub Container Registry (GHCR), or Azure Container Registry (ACR)
   * **Username:** Your registry username
   * **Password/Token:** Your registry password or access token
   * **Registry Namespace:** The namespace/project for your image path (see registry-specific details below)

![Registry Configuration](https://i.ibb.co/0y5vJVXZ/docker-build-registry-configuration.png)

4. **Image Configuration:** Set the image name and tag pattern.

   * **Image Name:** The name for your Docker image (without registry prefix or tag)
   * **Tag Pattern:** How to tag your images (e.g., `{revision}`, `latest`, `v1.0.{timestamp}`)

![Image Configuration](https://i.ibb.co/N2LXRzCG/docker-build-image-configuration.png)

5. **Build Configuration:** Configure the Dockerfile path and any build arguments.

   * **Dockerfile Path:** Path to your Dockerfile or directory containing it (default: `.`)
   * **Build Arguments:** Optional build-time variables in `KEY=value` format, one per line

![Build Configuration](https://i.ibb.co/PZ7JL2W1/docker-build-build-configuration.png)

## Registry Configuration

### Docker Hub

Docker Hub is the default public registry for Docker images.

**Credentials:**

* **Username:** Your Docker Hub username
* **Password/Token:** Your Docker Hub access token (recommended) or password
* **Registry Namespace:** (Optional) Your Docker Hub username or organization name. If not set, defaults to your username.

**Required Permissions:**

When creating an access token, select the following permissions:

* **Read** - Required to verify authentication
* **Write** - Required to push images

For organization repositories, ensure your Docker Hub account has "Editor" or "Owner" role on the repository.

**Creating an Access Token:**

1. Log in to [Docker Hub](https://hub.docker.com)
2. Go to **Account Settings** then **Security**
3. Click **New Access Token**
4. Give it a descriptive name (e.g., "DeployHQ")
5. Select **Read and Write** access permissions
6. Click **Generate** and copy the token for use in DeployHQ

**Important:** Access tokens are more secure than passwords and are recommended. If your Docker Hub account has 2FA enabled, you must use an access token.

**Image Reference Format:**

Your images will be pushed as: `username/image-name:tag`

### Google Container Registry (GCR)

GCR is Google Cloud's private container registry integrated with Google Cloud Platform.

**Credentials:**

* **Username:** `_json_key` (exactly as shown, this is a literal string)
* **Password/Token:** Your service account JSON key (the entire JSON content)
* **Registry Namespace:** Your Google Cloud project ID (required)

**Important:** The Registry Namespace field must be set to your GCP project ID (e.g., `my-project-123`). This is the project where your images will be stored. Do not confuse this with the username field, which is always `_json_key` for service account authentication.

**Required IAM Permissions:**

The service account needs the following IAM roles on your Google Cloud project:

| Role | Description |
|------|-------------|
| `roles/storage.objectAdmin` | Push and pull images (recommended minimum) |
| `roles/storage.admin` | Full control over GCR bucket (alternative) |

For more granular control, these individual permissions are required:

* `storage.buckets.get` - Access the GCR bucket
* `storage.objects.create` - Push new image layers
* `storage.objects.delete` - Overwrite existing tags
* `storage.objects.get` - Verify uploads
* `storage.objects.list` - List image layers

**Creating Service Account Credentials:**

1. Go to the [Google Cloud Console](https://console.cloud.google.com)
2. Navigate to **IAM and Admin** then **Service Accounts**
3. Click **Create Service Account**
4. Give it a name (e.g., "deployhq-gcr")
5. Grant the **Storage Object Admin** role (`roles/storage.objectAdmin`)
6. Click **Done** to create the service account
7. Click on the service account, go to **Keys** tab
8. Click **Add Key** then **Create new key**
9. Select **JSON** format and download the key file
10. Copy the **entire JSON content** as the password in DeployHQ

**Important:** The password field should contain the complete JSON object, starting with `{` and ending with `}`. Do not extract just the private key.

**GCR Endpoint:**

DeployHQ uses the `gcr.io` endpoint for pushes. Your images will be stored in the GCR repository for your project.

**Image Reference Format:**

Your images will be pushed as: `gcr.io/PROJECT_ID/image-name:tag`

### GitHub Container Registry (GHCR)

GHCR is GitHub's container registry, tightly integrated with GitHub repositories and packages.

**Credentials:**

* **Username:** Your GitHub username
* **Password/Token:** A GitHub Personal Access Token (PAT) with package permissions
* **Registry Namespace:** (Optional) Your GitHub username or organization name. If not set, defaults to your username. Set this to your organization name when pushing to organization packages.

**Required Token Scopes:**

| Scope | Description | Required |
|-------|-------------|----------|
| `write:packages` | Upload packages to GitHub Package Registry | Yes |
| `read:packages` | Download packages from GitHub Package Registry | Yes |
| `delete:packages` | Delete packages (optional, for cleanup) | No |

If your package is linked to a repository, you may also need:

* `repo` - Full control of private repositories (for private repo packages)

**Creating a Personal Access Token (Classic):**

1. Go to [GitHub Settings - Tokens](https://github.com/settings/tokens)
2. Click **Generate new token** then **Generate new token (classic)**
3. Give it a descriptive name (e.g., "DeployHQ Docker Build")
4. Set an expiration (or "No expiration" for persistent access)
5. Select the following scopes:

   * `write:packages`
   * `read:packages`
   * `repo` (if pushing to private repository packages)

6. Click **Generate token**
7. Copy the token immediately (it won't be shown again)

**Creating a Fine-grained Personal Access Token:**

1. Go to [GitHub Settings - Tokens](https://github.com/settings/tokens?type=beta)
2. Click **Generate new token**
3. Give it a descriptive name
4. Select the repository or organization
5. Under **Permissions**, set:

   * **Packages**: Read and write

6. Click **Generate token**

**Organization Packages:**

For organization-owned packages:

* Use the organization name as the username
* Ensure your GitHub account has "Write" or "Admin" access to the package
* The PAT must be authorized for the organization (SSO authorization if required)

**Package Visibility:**

* Public packages can be pulled without authentication
* Private packages require authentication for both push and pull
* Package visibility can be set in GitHub package settings

**Image Reference Format:**

Your images will be pushed as: `ghcr.io/OWNER/image-name:tag`

Where `OWNER` is your GitHub username or organization name.

### Azure Container Registry (ACR)

ACR is Azure's managed container registry service.

**Credentials:**

* **Username:** Your registry username (admin user) or service principal app ID
* **Password/Token:** Your registry password or service principal client secret
* **Registry Namespace:** Your registry name (e.g., `myregistry`) or full login server (e.g., `myregistry.azurecr.io`) **(required)**

**Image Reference Format:**

Your images will be pushed as: `myregistry.azurecr.io/image-name:tag`

## Tag Patterns

DeployHQ supports dynamic tag patterns using placeholders:

| Placeholder | Description | Example Output |
|-------------|-------------|----------------|
| `{revision}` | Short commit hash (8 characters) | `a1b2c3d4` |
| `{branch}` | Branch name (sanitized) | `main`, `feature-login` |
| `{timestamp}` | Build timestamp | `20240115143022` |

**Example Patterns:**

* `{revision}` - Tag with commit hash (default)
* `latest` - Always use the latest tag
* `{branch}-{revision}` - Include branch name: `main-a1b2c3d4`
* `v1.0.{timestamp}` - Version with timestamp: `v1.0.20240115143022`

## Build Arguments

Pass build-time variables to your Docker build using the Build Arguments field. Enter one argument per line in `KEY=value` format:

```text
NODE_ENV=production
API_URL=https://api.example.com
BUILD_NUMBER=123
```

These arguments are passed to `docker build` using the `--build-arg` flag and can be referenced in your Dockerfile using `ARG` instructions.

## Build-Only Mode

If you want to test your Dockerfile without pushing to a registry, uncheck the "Push image to registry after build" option. This is useful for:

* Validating Dockerfile syntax and build process
* Testing builds before configuring registry credentials
* CI/CD pipelines where pushing is handled separately

## Build Timeout Limits

Docker build durations are capped by plan:

* **Free / Free v2:** 15 minutes
* **Deprecated plans / Solo / Pro:** 1 hour
* **Business / Enterprise:** 3 hours

If a build exceeds the limit, it will be stopped automatically.

## Deployment Behavior

Unlike traditional file-based deployments, Docker Build:

* Does not transfer files to a destination server
* Builds the Docker image using DeployHQ's build infrastructure
* Optionally pushes the built image to your configured registry
* Records the built image reference in deployment metadata

## Troubleshooting

**Build Fails:**

* Verify your Dockerfile syntax is correct
* Check that all referenced files exist in your repository
* Review build logs for specific error messages

**Authentication Fails:**

* Verify your credentials are correct
* For GCR, ensure the entire JSON key is pasted (not just the private key)
* For GHCR, verify your PAT has the `write:packages` scope
* For Docker Hub, use an access token rather than your password
* For ACR, verify your registry username/password or service principal credentials

**Push Fails:**

* Verify you have push permissions to the registry
* Check that the image name is valid for your registry
* Ensure your registry quota has not been exceeded
* For GCR, ensure the Registry Namespace is set to your GCP project ID (not `_json_key`)
