# Create Dockerfile

> Create general-purpose Dockerfiles for Node.js, Python, Go, Rust, and Java projects. Covers base image selection, dependency installation, user permissions, COPY patterns, ENTRYPOINT vs CMD, and .dockerignore. Use when containerizing an application for the first time, creating a consistent build/runtime environment, preparing an app for cloud deployment or Docker Compose, or when no existing Dockerfile is present in the project.

- Skill: `kunanonj/create-dockerfile` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kunanonj/create-dockerfile`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kunanonj/create-dockerfile/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: MIT
- Author: KunanonJ (https://skillmd.com/u/kunanonj)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kunanonj/create-dockerfile

---


# Create Dockerfile

Write production-ready Dockerfile for general-purpose application projects.

## When Use

- Containerizing Node.js, Python, Go, Rust, or Java app
- Making consistent build/runtime environment
- Preparing app for cloud deploy or Docker Compose
- No existing Dockerfile in project

## Inputs

- **Required**: Project language and entry point (e.g., `npm start`, `python app.py`)
- **Required**: Dependency manifest (package.json, requirements.txt, go.mod, Cargo.toml, pom.xml)
- **Optional**: Target environment (development or production)
- **Optional**: Exposed ports

## Steps

### Step 1: Choose Base Image

| Language | Dev Image | Prod Image | Size |
|---|---|---|---|
| Node.js | `node:22-bookworm` | `node:22-bookworm-slim` | ~200MB |
| Python | `python:3.12-bookworm` | `python:3.12-slim-bookworm` | ~150MB |
| Go | `golang:1.23-bookworm` | `gcr.io/distroless/static` | ~2MB |
| Rust | `rust:1.82-bookworm` | `debian:bookworm-slim` | ~80MB |
| Java | `eclipse-temurin:21-jdk` | `eclipse-temurin:21-jre` | ~200MB |

**Got:** Pick slim/distroless variant for production images.

### Step 2: Write Dockerfile (by language)

#### Node.js

```dockerfile
FROM node:22-bookworm-slim

RUN groupadd -r appuser && useradd -r -g appuser -m appuser

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --omit=dev

COPY . .

USER appuser
EXPOSE 3000
CMD ["node", "src/index.js"]
```

#### Python

```dockerfile
FROM python:3.12-slim-bookworm

RUN groupadd -r appuser && useradd -r -g appuser -m appuser

WORKDIR /app

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

COPY . .

USER appuser
EXPOSE 8000
CMD ["python", "app.py"]
```

#### Go

```dockerfile
FROM golang:1.23-bookworm AS builder

WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server ./cmd/server

FROM gcr.io/distroless/static
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
```

#### Rust

```dockerfile
FROM rust:1.82-bookworm AS builder

WORKDIR /src
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release && rm -rf src

COPY . .
RUN touch src/main.rs && cargo build --release

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /src/target/release/myapp /usr/local/bin/myapp
EXPOSE 8080
ENTRYPOINT ["myapp"]
```

#### Java (Maven)

```dockerfile
FROM eclipse-temurin:21-jdk AS builder

WORKDIR /src
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre
COPY --from=builder /src/target/*.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
```

**Got:** `docker build -t myapp .` finishes without errors.

**If fail:** Check base image availability and dependency install commands.

### Step 3: ENTRYPOINT vs CMD

| Directive | Purpose | Override |
|---|---|---|
| `ENTRYPOINT` | Fixed executable | Override with `--entrypoint` |
| `CMD` | Default arguments | Override with trailing args |
| Both | `ENTRYPOINT` + default args via `CMD` | Args override CMD only |

Use `ENTRYPOINT` for compiled binaries with single purpose. Use `CMD` for interpreted languages where might want `docker run myapp bash`.

### Step 4: Create .dockerignore

```text
.git
.gitignore
node_modules
__pycache__
*.pyc
target/
.env
.env.*
*.md
!README.md
.vscode
.idea
Dockerfile
docker-compose*.yml
```

**Got:** Build context drops dev artifacts.

### Step 5: Add Non-Root User

Always run as non-root in production:

```dockerfile
RUN groupadd -r appuser && useradd -r -g appuser -m appuser
USER appuser
```

For distroless images, use built-in nonroot user:

```dockerfile
FROM gcr.io/distroless/static:nonroot
USER nonroot
```

### Step 6: Build and Verify

```bash
docker build -t myapp:latest .
docker run --rm myapp:latest
docker image inspect myapp:latest --format '{{.Size}}'
```

**Got:** Container starts, responds on expected port, runs as non-root.

**If fail:** Check logs with `docker logs`. Verify WORKDIR, COPY paths, exposed ports.

## Checks

- [ ] `docker build` finishes without errors
- [ ] Container starts and app responds
- [ ] `.dockerignore` drops unneeded files
- [ ] App runs as non-root user
- [ ] Dependencies copied before source code (cache efficiency)
- [ ] No secrets or `.env` files baked into image

## Pitfalls

- **COPY before dependency install**: Invalidates dependency cache on every code change. Always copy manifest file first.
- **Running as root**: Default Docker user is root. Always add non-root user for production.
- **Missing .dockerignore**: Sending `node_modules` or `.git` into build context wastes time and disk.
- **Using `latest` tag for base images**: Pin to specific versions (e.g., `node:22.11.0`) for reproducibility.
- **Forgetting `--no-cache-dir`**: Python `pip` caches packages by default, bloating image.
- **ADD vs COPY**: Use `COPY` unless need URL download or tar extraction (`ADD` auto-extracts).

## See Also

- `create-r-dockerfile` - R-specific Dockerfile using rocker images
- `create-multistage-dockerfile` - multi-stage patterns for minimal production images
- `optimize-docker-build-cache` - advanced caching strategies
- `setup-compose-stack` - orchestrate containerized app with other services

