Back to Tutorials

Build a Docker Image

Build images from a Dockerfile, use build args, import Dockerfiles, and build for multiple architectures.

Prerequisites

  • Docker is running
  • A Dockerfile exists in your project directory
  • For multi-arch builds, Buildx must be available (included with Docker Desktop)
  • Multi-arch builds require a Pro subscription

Scenario 1: Build from a Dockerfile

  1. Click Image Library in the sidebar
  2. Click the Build button (hammer icon) in the toolbar
  3. The Image Build view opens with tabs:
    • Build — main build configuration
    • Dockerfile — edit/preview the Dockerfile
    • Output — build log output
  4. In the Build tab:
    • Context Path: click the folder icon and select your project directory
    • Dockerfile Path: auto-detected as Dockerfile in the context path, or browse to select a different file
    • Image Name: enter myapp
    • Tag: enter latest
  5. Click Build
  6. Switch to the Output tab to watch the build log in real-time
  7. When complete, the image appears in the Images list

Example Project Files

Create ~/Projects/myapp/package.json:

package.json
{
  "name": "myapp",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "express": "^4.18.2"
  }
}

Create ~/Projects/myapp/app.js:

app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello from Docker!'));
app.listen(3000, '0.0.0.0', () => console.log('Running on :3000'));

Generate ~/Projects/myapp/package-lock.json (required by npm ci):

bash
cd ~/Projects/myapp && npm install --package-lock-only

Create ~/Projects/myapp/Dockerfile:

Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

Create ~/Projects/myapp/.dockerignore:

.dockerignore
node_modules
.git

Scenario 2: Build with Build Arguments

  1. Open Image Build view (Image Library → Build)
  2. Set context path and image name as above
  3. Expand the Build Args section
  4. Add arguments:
    NameValue
    NODE_ENVproduction
    APP_VERSION1.2.3
  5. These are passed as --build-arg flags to the Docker build

Example Project Files (Python with Build Args)

Create ~/Projects/pyapp/requirements.txt:

requirements.txt
flask==3.0.0

Create ~/Projects/pyapp/app.py:

app.py
import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    version = os.environ.get('APP_VERSION', 'dev')
    return f'<h1>Python App v{version}</h1>'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

Create ~/Projects/pyapp/Dockerfile:

Dockerfile
FROM python:3.12-slim

ARG APP_VERSION=dev
ARG NODE_ENV=development

ENV APP_VERSION=${APP_VERSION}
ENV NODE_ENV=${NODE_ENV}

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

EXPOSE 8000
CMD ["python", "app.py"]

Scenario 3: Multi-Architecture Build (Pro)

  1. Open Image Build view
  2. Configure the build as in Scenario 1
  3. Toggle Multi-Architecture ON
  4. Select target platforms:
    • linux/amd64 (Intel/AMD)
    • linux/arm64 (Apple Silicon, ARM servers)
  5. Click Build
  6. Buildx creates a multi-arch manifest — the correct image is automatically selected when pulling on different architectures

Scenario 4: Import Dockerfile

  1. Open Image Build view
  2. Click Import Dockerfile (the import wizard)
  3. Browse to select a Dockerfile from your filesystem
  4. The Dockerfile content loads into the Dockerfile tab for preview and editing
  5. Proceed with the build configuration

What You'll See

  • Build output streams in real-time showing each step:
text
Step 1/8 : FROM node:20-alpine AS builder
---> a1b2c3d4e5f6
Step 2/8 : WORKDIR /app
...
Successfully built abc123def456
Successfully tagged myapp:latest
  • The segmented tab picker ensures responsive switching between Build, Dockerfile, and Output tabs
  • Multi-arch builds show progress for each platform separately

Tips

  • Use multi-stage builds (as in the Node.js example) to minimize final image size
  • The .dockerignore file in your context path is respected — add node_modules, .git, etc. to speed up builds
  • Build cache is used automatically — unchanged layers are reused from previous builds
  • Multi-arch builds are significantly slower than single-arch builds due to emulation

Related Tutorials