Skip to main content

Manual Build

Want to configure and run builds directly without using Auto CI? Manual build gives you complete control over the build process. It's useful for building specific branches or commits, or creating test images before deployment.

When to use manual build?
  • When you want to test builds before setting up Auto CI
  • When you need temporary builds for specific branches or commits.
  • When you want to build urgent hotfixes immediately.
  • When you want to verify after changing build settings.

Build Tab

Build Overview

KIWI uses Kaniko to build container images. Kaniko is a tool that can safely build images inside a container without requiring a Docker daemon.

Kaniko Benefits
  • Security: No Docker daemon needed, reducing privilege escalation risks.
  • K8s Friendly: Can build directly inside Kubernetes Pods.
  • Caching Support: Layer cache reduces build time

Supported Registries:

  • Harbor (recommended)
  • Docker Hub
  • Private Docker Registry

Configuring a Build

Step 1: Navigate to Service Detail Page

  1. Go to the [Service Management] page
  2. Click on the service card you want to build to open the detail page

Step 2: Click the Build Stage

  1. Click the Build stage in the pipeline
  2. The build settings modal opens.

Step 3: Configure Dockerfile

There are three ways to specify the Dockerfile:

  • Auto-detect: Automatically finds Dockerfile in the repository. Recommended for standard project structures.
  • Specify path: Directly enter the Dockerfile path. Use when you have multiple Dockerfiles or non-standard locations.
  • Build Wizard: Auto-generates a Dockerfile if one doesn't exist. Recommended for projects without a Dockerfile.

Dockerfile path examples:

./Dockerfile                    # Default Dockerfile at root (most common)
./docker/Dockerfile.prod # Environment-specific Dockerfile
./services/api/Dockerfile # Service-specific Dockerfile in monorepo
Best Practice

Placing the Dockerfile at the project root is the most common and recommended approach. Use auto-detect unless you have a specific reason not to.

Step 4: Configure Build Arguments (Optional)

Additional settings for advanced users. Most projects will build with default values.

  • Build Context: Directory where build starts (default: .)
  • Build Arguments (ARG): Pass values to Dockerfile ARG (e.g., NODE_ENV=production)
  • Target Stage: Build only a specific stage in multi-stage builds (e.g., production)
What are build arguments?

Build arguments pass values to variables defined with the ARG command in Dockerfile. For example, passing NODE_ENV=production to a Dockerfile with ARG NODE_ENV will build in production mode.

Step 5: Configure Image Registry

Enter registry information where the built image will be stored:

  • Registry URL: Image repository address. (e.g., harbor.company.com)
  • Project: Image storage location (project name). (e.g., library, my-team)
  • Image Name: Name of the image. (e.g., my-web-app)
  • Tag Rule: Version tagging method. (e.g., ${BRANCH}-${SHORT_SHA})
Understanding Tag Rules
  • ${BRANCH}: Build branch name. (e.g., main, develop)
  • ${SHORT_SHA}: First 7 chars of commit hash. (e.g., a1b2c3d)
  • ${TIMESTAMP}: Build time. (e.g., 20240115-123456)

Example: ${BRANCH}-${SHORT_SHA}main-a1b2c3d

Step 6: Save Settings

  1. Click the Save button.
  2. Verify the "Build settings saved" message

Running a Build

Once configuration is complete, let's actually run a build.

Step 1: Select Build Branch

  1. Click the Build stage on the service detail page
  2. Select the branch to build from the branch dropdown
Verify Branch

Building the wrong branch could deploy unintended code. Double-check the branch before building.

Step 2: Start Build

  1. Click the Start Build button.
  2. The build is queued and runs in order.

Step 3: Review Build Log

You can monitor build progress in real-time:

[1/5] Cloning repository...
[2/5] Parsing Dockerfile...
[3/5] Building layers...
→ Building layer 1: FROM node:20-alpine
→ Building layer 2: COPY package*.json
→ Building layer 3: RUN npm ci
→ Building layer 4: COPY . .
→ Building layer 5: RUN npm run build
[4/5] Pushing to registry...
[5/5] Build completed successfully!
Using Build Logs

When a build fails, check the log to see which step caused the error. Most errors occur during the Building layers step, usually due to dependency installation failures or build script errors.

Step 4: Verify Build Completion

When the build completes, you can check the following information:

  • Build Status: Success (green) or Failure (red).
  • Image Tag: Full path of the generated image.
  • Image Size: Size of the built image.
  • Build Duration: Time from start to completion.

Build Optimization

Learn how to reduce build time and image size.

Improving Build Speed with Caching

KIWI optimizes build speed using two types of cache:

  • Layer Cache: Reuses unchanged Docker layers. Dramatically reduces dependency installation time.
  • Registry Cache: Utilizes existing image layers. Reduces network transfer volume.
First Build vs Subsequent Builds

The first build takes longer as all layers must be created fresh. From the second build onwards, cache is utilized for faster completion. If only source code changed, dependency installation steps are pulled from cache.

Dockerfile Optimization Tips

The order of Dockerfile instructions is important for effective cache utilization.

1. Place infrequently changing layers first

# Good example - dependencies first, source code later
COPY package*.json ./
RUN npm ci
COPY . .

# Bad example - changing source code reinstalls dependencies
COPY . .
RUN npm ci

2. Minimize image size with multi-stage builds

# Build stage: includes build tools (large image)
FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

# Production stage: only what's needed to run (small image)
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/main.js"]

3. Exclude unnecessary files with .dockerignore

node_modules
.git
.env
*.log
.DS_Store
Without .dockerignore

node_modules or .git folders get included in the image, increasing build time and image size. Always create a .dockerignore file.


Build History

You can view and manage past build records.

How to View History

  1. Click the Build stage on the service detail page
  2. Select the Build History tab

Information Available in History

  • Build Number: Sequentially assigned build identifier.
  • Branch: Git branch used for the build.
  • Commit: Commit hash at build time (click to go to GitLab).
  • Status: Success / Failure / In Progress / Cancelled.
  • Duration: Time taken for the build.
  • Image Tag: Full tag of the generated image.
Using Build History

Check failed build logs to identify issues, or copy successful build image tags for deployment.


Troubleshooting

Common problems during builds and their solutions.

Dockerfile Not Found

  • Path error: Verify the Dockerfile path is correct in build settings.
  • Filename case: Check that Dockerfile has exact capitalization (dockerfile won't be recognized)
  • Insufficient Git permissions: Verify the GitLab token has read_repository permission.

Build Failure

  • npm ERR!: Dependency installation failed. Check package.json and package-lock.json.
  • COPY failed: File path error. Check paths and review .dockerignore.
  • Permission denied: File permission issue. Fix file permissions or add RUN chmod.
  • Out of memory: Insufficient memory. Request build Pod resource increase from administrator.

Image Push Failure

  • Authentication failed: Re-verify Registry credentials (username/password) in service settings.
  • Insufficient permissions: Check write permissions for the Registry project
  • Size exceeded: Optimize image size with multi-stage builds.
Unresolved Issues

If the above solutions don't work, review the complete build log and contact an administrator if needed.