# How to Build Production Docker Images for Akash Console Services: Complete Guide

> Build production Docker images for Akash Console services using the provided build script. Optimize builds with Node.js, Next.js, and optional Docker BuildKit for faster, cache-efficient images.

- Repository: [Akash Network/console](https://github.com/akash-network/console)
- Tags: how-to-guide
- Published: 2026-02-24

---

**Use the [`build.sh`](https://github.com/akash-network/console/blob/main/build.sh) helper script in `packages/docker/script/` to orchestrate multi-stage Docker builds for Node.js and Next.js services, with optional Docker BuildKit support for accelerated, cache-optimized image creation.**

Akash Console is a monorepo containing multiple backend APIs and frontend applications that are packaged as independent Docker images for production deployment. To **build production Docker images for Akash Console services**, you use a centralized build pipeline located in `packages/docker/` that supports both automated helper scripts and manual Docker Compose workflows. This guide walks through the exact commands, Dockerfile structures, and optimization techniques used in the `akash-network/console` repository.

## Multi-Stage Dockerfile Architecture

The repository maintains two optimized Dockerfile templates in `packages/docker/` that handle different service types.

### Node-Only Services

Backend services like the **API**, **tx-signer**, **notifications**, **indexer**, and **provider-proxy** use [`packages/docker/Dockerfile.node`](https://github.com/akash-network/console/blob/main/packages/docker/Dockerfile.node). This multi-stage Dockerfile uses `node:24.13.0-alpine` as the base image, installs dependencies in a `development` stage, compiles the application in a `builder` stage, and copies the artifacts into a minimal `production` stage that runs under a non-root user.

### Next.js Frontend Services

Frontend applications including **deploy-web**, **stats-web**, and **provider-console** use [`packages/docker/Dockerfile.nextjs`](https://github.com/akash-network/console/blob/main/packages/docker/Dockerfile.nextjs). This file extends the Node multi-stage pattern with an additional `production-nginx` stage that adds an Nginx front-end with a self-signed TLS certificate, serving the static Next.js export.

## Building Images with the Helper Script

The recommended workflow uses [`packages/docker/script/build.sh`](https://github.com/akash-network/console/blob/main/packages/docker/script/build.sh), which automates git SHA detection, caching logic, and registry pushing.

### Build a Single Service

To build a specific service such as the API with a custom version tag:

```bash
./packages/docker/script/build.sh \
  -r gcr.io/cloudmos-explorer/console-api \
  -t v2.5.0 \
  -a api

```

The script extracts the latest commit SHA that touched the service (lines 68-78 in [`build.sh`](https://github.com/akash-network/console/blob/main/build.sh)) and checks whether an image for that SHA already exists in the registry using `docker manifest inspect`. If found, it pulls and retags the existing image rather than rebuilding.

### Build All Services

While the script processes one service per invocation, you can sequence builds for all services by running the command for each application:

```bash
REPO=gcr.io/cloudmos-explorer/console
TAG=v2.5.0

for app in api tx-signer notifications indexer provider-proxy deploy-web stats-web provider-console; do
  ./packages/docker/script/build.sh -r "$REPO-$app" -t "$TAG" -a "$app"
done

```

### Force Rebuilds and BuildKit Optimization

To ignore cached SHA images and force a fresh build, add the `-f` flag:

```bash
./packages/docker/script/build.sh -r $REPO -t $TAG -a api -f

```

For faster builds with shared cache scopes, enable Docker BuildKit:

```bash
USE_DOCKER_BUILDKIT=1 \
  ./packages/docker/script/build.sh -r $REPO -t $TAG -a api

```

When `USE_DOCKER_BUILDKIT=1` is set, the script invokes the `ensure_builder` and `docker_buildx_bake` functions in [[`packages/docker/script/dc.sh`](https://github.com/akash-network/console/blob/main/packages/docker/script/dc.sh)](https://github.com/akash-network/console/blob/main/packages/docker/script/dc.sh), switching from standard `docker compose build` to `docker buildx bake` with configurable `BUILDKIT_CACHE_SCOPE` parameters.

## Direct Docker Compose Builds

For debugging or custom build arguments, bypass the helper script and invoke Docker Compose directly using [`packages/docker/docker-compose.build.yml`](https://github.com/akash-network/console/blob/main/packages/docker/docker-compose.build.yml):

```bash
WORKSPACE=apps/api \
DEPLOYMENT_ENV=prod \
docker compose -f packages/docker/docker-compose.build.yml build api

```

For Next.js services requiring custom build-time secrets like Sentry tokens:

```bash
WORKSPACE=apps/deploy-web \
DEPLOYMENT_ENV=prod \
docker compose -f packages/docker/docker-compose.build.yml \
  build --build-arg SENTRY_AUTH_TOKEN=xxxx deploy-web

```

The `WORKSPACE` argument maps to the monorepo path (e.g., `apps/api`, `apps/deploy-web`), which the Dockerfile uses to locate the correct [`package.json`](https://github.com/akash-network/console/blob/main/package.json) and source files.

## Production Image Internals

Both Dockerfiles produce minimal production images by copying only compiled artifacts from the builder stage. The Node Dockerfile creates a non-root user for security, while the Next.js Dockerfile includes an Nginx configuration for TLS termination. The final images are tagged with the user-supplied version and optionally `latest`, then pushed to the configured registry (lines 122-133 in [`build.sh`](https://github.com/akash-network/console/blob/main/build.sh)).

## Summary

- **Two Dockerfile patterns** handle the monorepo: `Dockerfile.node` for backend services and `Dockerfile.nextjs` for frontend applications, both located in `packages/docker/`.
- **Use [`build.sh`](https://github.com/akash-network/console/blob/main/build.sh)** as the primary entry point for production builds; it handles SHA detection, caching, tagging, and pushing to registries like GCR.
- **Enable BuildKit** with `USE_DOCKER_BUILDKIT=1` to leverage `docker buildx bake` and cache scopes defined in [`dc.sh`](https://github.com/akash-network/console/blob/main/dc.sh) for faster CI/CD pipelines.
- **Specify the `WORKSPACE`** environment variable when building manually to point Docker to the correct application within the monorepo structure.
- **Force rebuilds** with the `-f` flag when you need to bypass the SHA-based cache and regenerate images from source.

## Frequently Asked Questions

### How does the build script avoid redundant rebuilds?

The script calculates the latest git SHA that modified the specific service directory and queries the registry via `docker manifest inspect` to check if an image tagged with that SHA already exists. If found, the script pulls that image and applies the new version tag rather than recompiling, significantly reducing build times for unchanged code.

### Can I build images for local testing without pushing to a registry?

Yes. Omit the registry push by using the direct Docker Compose method with the [`docker-compose.build.yml`](https://github.com/akash-network/console/blob/main/docker-compose.build.yml) file. Set your `WORKSPACE` and run `docker compose -f packages/docker/docker-compose.build.yml build <service-name>` to create images locally without executing the push logic contained in [`build.sh`](https://github.com/akash-network/console/blob/main/build.sh).

### What is the difference between [`docker-compose.build.yml`](https://github.com/akash-network/console/blob/main/docker-compose.build.yml) and [`docker-compose.prod.yml`](https://github.com/akash-network/console/blob/main/docker-compose.prod.yml)?

The [`docker-compose.build.yml`](https://github.com/akash-network/console/blob/main/docker-compose.build.yml) file defines the build context, Dockerfile paths, and `WORKSPACE` arguments necessary to compile images. The [`docker-compose.prod.yml`](https://github.com/akash-network/console/blob/main/docker-compose.prod.yml) and [`docker-compose.prod-with-db.yml`](https://github.com/akash-network/console/blob/main/docker-compose.prod-with-db.yml) files are runtime configurations used for deploying pre-built images; they specify container orchestration, environment variables, and networking for production workloads.

### How do I add custom build arguments like Sentry integration?

Pass additional build arguments through the direct Docker Compose invocation using the `--build-arg` flag. For example, `docker compose -f packages/docker/docker-compose.build.yml build --build-arg SENTRY_AUTH_TOKEN=your_token deploy-web`. The helper script ([`build.sh`](https://github.com/akash-network/console/blob/main/build.sh)) does not currently expose arbitrary build arguments, making direct Compose the preferred method for custom tokens or flags.