Posted on
Artificial Intelligence

Artificial Intelligence Docker Automation

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Artificial Intelligence Docker Automation with Bash: Reproducible, Portable, and Hands-Free

Ever shipped an AI model that worked on your laptop but crumbled elsewhere? Dependency hell, missing GPUs, stale Python environments—these show up when you least expect them. Docker automation turns fragile AI workflows into reproducible, portable, and schedulable jobs you can trust. In this post, you’ll learn how to containerize a small AI workload, automate it with Bash and Docker, and run it across distros with apt, dnf, or zypper.

What you’ll get:

  • Why Docker automation for AI is worth your time

  • Installation instructions for apt, dnf, and zypper

  • A working containerized AI batch job

  • Automation patterns with Make, docker compose, cron

  • Real-world tips for caching, resource control, and updates

Why AI + Docker + Bash is a winning combo

  • Reproducibility: A Docker image pins OS, Python, CUDA/CPU libs, and Python deps. The same bits run everywhere.

  • Portability: Develop on a laptop, run on a server, ship to CI, or scale on a cluster without changing your code.

  • Automation: Bash + docker compose + cron give you a simple, reliable pipeline without heavyweight orchestration.

  • Performance and control: Pin CPU/memory, cache model weights, and use volumes to avoid re-downloading models.

  • Safer changes: Versioned images let you roll forward/back instantly.

1) Prerequisites: Install Docker and tooling

Pick your distro’s package manager. After installing, enable Docker and add your user to the docker group so you can run it without sudo.

  • Debian/Ubuntu (apt)

    • sudo apt update
    • sudo apt install -y docker.io docker-compose-plugin git curl make python3 python3-venv python3-pip jq
    • sudo systemctl enable --now docker
    • sudo usermod -aG docker $USER then log out/in or run newgrp docker
  • Fedora/RHEL (dnf)

    • sudo dnf -y install moby-engine docker-compose-plugin git curl make python3 python3-pip jq
    • If docker-compose-plugin isn’t available, use: python3 -m pip install --user pipx && ~/.local/bin/pipx install docker-compose and call docker-compose instead of docker compose.
    • sudo systemctl enable --now docker
    • sudo usermod -aG docker $USER then log out/in or run newgrp docker
  • openSUSE (zypper)

    • sudo zypper refresh
    • sudo zypper install -y docker docker-compose git curl make python3 python3-pip jq
    • sudo systemctl enable --now docker
    • sudo usermod -aG docker $USER then log out/in or run newgrp docker

Optional (GPU): If you need NVIDIA GPUs, install the NVIDIA driver and NVIDIA Container Toolkit for your distro, then run with --gpus all. Check NVIDIA’s docs for exact steps.

Verify Docker:

  • docker --version

  • docker run --rm hello-world

2) Containerize a tiny AI batch job

We’ll create a CPU-only container that reads lines from a text file, runs a sentiment model, and writes JSONL results. It caches model weights so you don’t download every time.

Project layout:

  • Dockerfile

  • app.py

  • data/input.txt (your lines of text)

  • optional cache dir: hf-cache/

Dockerfile:

FROM python:3.11-slim

WORKDIR /app

# minimal build deps
RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*

# app code
COPY app.py .

# deps: install transformers from PyPI and PyTorch CPU wheels from PyTorch index
RUN pip install --no-cache-dir transformers==4.41.2 && \
    pip install --no-cache-dir --index-url https://download.pytorch.org/whl/cpu torch==2.3.0+cpu

# default command
CMD ["python", "app.py"]

app.py:

import json, os, sys
from transformers import pipeline

in_path = os.environ.get("INPUT", "/data/input.txt")
out_path = os.environ.get("OUTPUT", "/data/output.jsonl")
cache_dir = os.environ.get("HF_HOME", "/root/.cache/huggingface")

os.makedirs(os.path.dirname(out_path), exist_ok=True)

print(f"Loading model (cache: {cache_dir})...")
clf = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")

count = 0
with open(in_path, "r", encoding="utf-8") as fin, open(out_path, "w", encoding="utf-8") as fout:
    for line in fin:
        text = line.strip()
        if not text:
            continue
        res = clf(text)[0]
        fout.write(json.dumps({"text": text, "label": res["label"], "score": res["score"]}) + "\n")
        count += 1

print(f"Processed {count} lines. Wrote {out_path}")

Build the image:

  • docker build -t ai-batch:0.1 .

Prepare input:

  • mkdir -p data hf-cache

  • printf "I love containers!\nAutomation saves time.\nThis is slow and frustrating.\n" > data/input.txt

Run once, with persistent cache and data:

  • docker run --rm -v $(pwd)/data:/data -v $(pwd)/hf-cache:/root/.cache/huggingface ai-batch:0.1

Inspect results:

  • head -n 3 data/output.jsonl

  • jq -r '.label + " " + (.score|tostring) + " | " + .text' data/output.jsonl

Tip: The first run downloads the model and can take longer. Subsequent runs are fast thanks to the cache volume.

3) Automate with docker compose and Make

Compose file (compose.yaml) to standardize the run:

services:
  batch:
    image: ai-batch:0.1
    build: .
    environment:
      - INPUT=/data/input.txt
      - OUTPUT=/data/output.jsonl
      - HF_HOME=/root/.cache/huggingface
    volumes:
      - ./data:/data
      - ./hf-cache:/root/.cache/huggingface
    # Uncomment if you have GPUs set up
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - capabilities: [gpu]

Makefile to keep commands short:

IMAGE?=ai-batch:0.1

build:
    docker build -t $(IMAGE) .

run:
    docker compose run --rm batch

up:
    docker compose up --build --no-deps --detach batch

logs:
    docker compose logs -f --tail=100 batch

clean:
    docker compose down --remove-orphans || true
    docker image rm -f $(IMAGE) || true

Usage:

  • make build

  • make run (one-off)

  • make up then make logs

4) Schedule it: cron or systemd timers

Run the batch job hourly via cron:

  • crontab -e then add:
0 * * * * cd /opt/ai-batch && /usr/bin/docker compose run --rm batch >> /var/log/ai-batch.log 2>&1
  • Confirm:
    • grep ai-batch /var/log/ai-batch.log
    • docker system prune -f occasionally to keep things tidy (careful—removes unused objects)

Prefer systemd? Create a service and timer that run the same compose command on a schedule for better logging and retry controls.

5) Production-minded tips you can use today

  • Pin versions:

    • In Dockerfile, lock package versions (you saw that above).
    • Tag images per release: docker build -t ai-batch:0.1 . then also docker tag ai-batch:0.1 ai-batch:latest.
  • Cache model weights:

    • Mount ./hf-cache to /root/.cache/huggingface so you don’t redownload each run.
  • Resource limits:

    • For one-off runs: docker run --rm --cpus=2 --memory=2g ... to prevent noisy neighbors.
  • Configuration via env:

    • Swap inputs/outputs without editing code: docker run -e INPUT=/data/new.txt -e OUTPUT=/data/out.jsonl ....
  • Rollbacks:

    • Keep ai-batch:0.1, 0.2, etc. If a release misbehaves: docker run ai-batch:0.1 and you’re back.

Real-world example: sentiment-scan the last hour of support tickets every hour, append results to a warehouse, alert if negative rates spike. Swap the model or destination path with environment variables—no code changes.

Troubleshooting

  • Permission denied on Docker: ensure you ran sudo usermod -aG docker $USER and re-logged in.

  • docker compose not found:

    • Use the plugin syntax: docker compose version.
    • If missing, install via your package manager as above, or pipx install docker-compose and run docker-compose.
  • Slow first run: it’s downloading model weights. Persist the cache volume to speed subsequent runs.

  • PyTorch wheels: if your environment blocks PyTorch’s index, remove the CPU wheel line and use plain PyPI (may be larger/slower).

Conclusion and next steps (CTA)

Docker automation turns AI workloads into dependable, repeatable building blocks. You now have:

  • A containerized AI batch job

  • Compose + Make for one-liners

  • Cron scheduling

  • Caching, versioning, and resource control patterns

Next steps:

  • Add GPUs with NVIDIA Container Toolkit and run with --gpus all.

  • Wire CI/CD (GitHub Actions) to build and push your images on every commit.

  • Parameterize jobs with env files and secrets.

  • Extend to multiple services (preprocess → infer → postprocess) in one compose stack.

Grab this template, adapt it to your model, and ship your first automated AI job today.