# Buildah Essential Commands Guide

Buildah is a command-line tool for building OCI-compatible container images. Unlike other container build tools, Buildah doesn't require a daemon to be running and allows for granular control over the container building process.

## Creating Containers = BUILD STEP

### buildah from

Creates a new working container, either from scratch or using a specified image.

```bash
# Create a container from an image
buildah from [options] <image-name>

# Create a container from scratch
buildah from scratch

# Examples
buildah from fedora:latest
buildah from docker://ubuntu:22.04
buildah from --name my-container alpine:latest
```

Important options:
- `--name <name>`: Set a name for the container
- `--pull`: Pull image policy (missing, always, never, newer)
- `--authfile <path>`: Path to authentication file
- `--creds <username:password>`: Registry credentials

## Working with Containers

### buildah run

Runs a command inside of the container.

```bash
# Basic syntax
buildah run [options] <container-id> <command>

# Examples
buildah run my-container yum install -y httpd
buildah run my-container -- sh -c "echo 'Hello World' > /etc/motd"
buildah run --hostname myhost my-container ps -auxw
```

Important options:
- `--tty`, `-t`: Allocate a pseudo-TTY
- `--env`, `-e <env=value>`: Set environment variables
- `--volume`, `-v <host-dir:container-dir:opts>`: Mount a volume
- `--workingdir <directory>`: Set the working directory

### buildah copy

Copy files from the host into the container.

```bash
# Basic syntax
buildah copy [options] <container-id> <source> <destination>

# Examples
buildah copy my-container ./app /app
buildah copy my-container config.json /etc/myapp/
```

### buildah add

Add content from a file, URL, or directory to the container.

```bash
# Basic syntax
buildah add [options] <container-id> <source> <destination>

# Examples
buildah add my-container https://example.com/archive.tar.gz /tmp/
buildah add my-container ./local/dir /app/
```

## Configuring Containers

### buildah config

Updates container configuration settings.

```bash
# Basic syntax
buildah config [options] <container-id>

# Examples
buildah config --author="John Doe" my-container
buildah config --port 8080 my-container
buildah config --env PATH=$PATH my-container
buildah config --label version=1.0 my-container
buildah config --entrypoint "/entrypoint.sh" my-container
```

Important options:
- `--author <author>`: Set the author
- `--cmd <command>`: Set the default command
- `--entrypoint <command>`: Set the entry point
- `--env`, `-e <env=value>`: Set environment variables
- `--label`, `-l <label=value>`: Add image labels
- `--port`, `-p <port>`: Expose ports
- `--user`, `-u <user[:group]>`: Set the default user
- `--workingdir <directory>`: Set the working directory
- `--volume`, `-v <volume>`: Add a volume

## Building Images

### buildah commit

Create an image from a working container.

```bash
# Basic syntax
buildah commit [options] <container-id> [<image-name>]

# Examples
buildah commit my-container new-image:latest
buildah commit --format docker my-container docker.io/username/image:tag
buildah commit --rm my-container localhost/myimage:v1.0
```

Important options:
- `--format`, `-f`: Output format (oci or docker)
- `--rm`: Remove the container after committing
- `--quiet`, `-q`: Suppress output
- `--squash`: Squash all layers into a single layer

### buildah build

Build an image using instructions from Containerfiles or Dockerfiles.

```bash
# Basic syntax
buildah build [options] <context>

# Examples
buildah build .
buildah build -t myimage:latest .
buildah build -f Containerfile.custom .
buildah build --layers --format docker -t username/myapp:1.0 .
```

Important options:
- `--file`, `-f <Containerfile>`: Path to Containerfile/Dockerfile
- `--tag`, `-t <name:tag>`: Tag to apply to the built image
- `--layers`: Cache intermediate layers during build
- `--pull`: Force pull of newer base images
- `--no-cache`: Do not use cache during build
- `--build-arg <key=value>`: Set build-time variables
- `--format`: Output format (oci or docker)

## Managing Images

### buildah images

List images in local storage.

```bash
buildah images [options]
```

### buildah rmi

Remove one or more images.

```bash
buildah rmi [options] <image>
```

### buildah push

Push an image to a registry.

```bash
# Basic syntax
buildah push [options] <image> [destination]

# Examples
buildah push myimage:latest docker://registry.example.com/myimage:latest
buildah push --tls-verify=false localhost/myimage docker://localhost:5000/myimage
```

Important options:
- `--authfile <path>`: Path to authentication file
- `--creds <username:password>`: Registry credentials
- `--tls-verify <bool>`: Require HTTPS and verify certificates

### buildah tag

Add an additional name to a local image.

```bash
# Basic syntax
buildah tag <image> <new-name>

# Example
buildah tag localhost/myimage:latest myimage:v1.0
```

### buildah pull

Pull an image from a registry.

```bash
# Basic syntax
buildah pull [options] <image-name>

# Examples
buildah pull docker.io/library/ubuntu:latest
buildah pull --tls-verify=false registry.example.com/myimage:latest
```

Important options:
- `--authfile <path>`: Path to authentication file
- `--creds <username:password>`: Registry credentials
- `--tls-verify <bool>`: Require HTTPS and verify certificates

## Typical Workflow Example

```bash
# Create a container from an existing image
container=$(buildah from fedora:latest)

# Run a command to install software
buildah run $container dnf install -y nginx

# Copy local configuration files to the container
buildah copy $container ./nginx.conf /etc/nginx/nginx.conf

# Configure container metadata
buildah config --port 80 $container
buildah config --label maintainer="example@example.com" $container
buildah config --entrypoint "/usr/sbin/nginx" $container

# Commit the container to create a new image
buildah commit --rm $container my-nginx:latest

# Or build using a Containerfile
buildah build -t my-nginx:latest .

# Push the image to a registry
buildah push my-nginx:latest docker://docker.io/username/my-nginx:latest
```
