Posted on
Artificial Intelligence

Artificial Intelligence Enterprise Operations

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

AI Enterprise Operations: A Bash-first Playbook for Reliable, Reproducible AI

Your execs want “AI everywhere,” but your SREs worry about outages, snowflake servers, and ballooning GPU bills. The gap between a promising notebook and an auditable, supportable, cost-aware service is where AI Enterprise Operations (AIOps for AI) actually lives.

This guide shows how to bring discipline to AI with the Linux and Bash tooling you already know. You’ll standardize environments, containerize services, track model artifacts, automate pipelines, and instrument what matters—without overengineering. All commands are Linux-friendly and include apt, dnf, and zypper installation instructions where applicable.

Why this matters

  • AI workloads stress everything: CPUs/GPUs, networks, storage, and teams. Unmanaged, they’re brittle and expensive.

  • Enterprises need reproducibility, change control, and observability to meet policy and uptime.

  • Linux is the de facto substrate for AI. Bash remains the lingua franca for automation, glue code, and first-response debugging.

The payoff: fewer “works on my machine” failures, faster incident resolution, predictable releases, lower cost-to-serve.


Quick-start: Install foundational tools

Install Python, virtual environments, Git (with LFS for large models), cURL, jq, Make, and a container runtime (Podman recommended; Docker optional).

  • Ubuntu/Debian (apt)
sudo apt update
sudo apt install -y python3 python3-venv python3-pip git git-lfs curl jq make podman
# Optional: Docker (service-based)
sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"  # re-login or run `newgrp docker`
  • Fedora/RHEL/CentOS Stream (dnf)
sudo dnf install -y python3 python3-pip git git-lfs curl jq make podman
# Optional: Docker (Fedora provides moby-engine; on RHEL use Docker CE repo)
sudo dnf install -y moby-engine docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"
  • openSUSE/SLE (zypper)
sudo zypper refresh
sudo zypper install -y python3 python3-pip git git-lfs curl jq make podman
# Optional: Docker
sudo zypper install -y docker docker-compose
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"

Verify:

python3 --version
git --version
git lfs install
podman --version  # or: docker --version

1) Standardize your environment: repeatability beats heroics

Pin environments early. Use Python’s built-in venv for isolation and a minimal, explicit requirements.txt.

Create a project layout:

mkdir -p ~/aiops-demo/{app,models,data,ops}
cd ~/aiops-demo
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install fastapi uvicorn[standard] numpy prometheus-client
pip freeze > requirements.txt

A minimal inference service (save as app/service.py):

from fastapi import FastAPI
from prometheus_client import Counter, generate_latest, CONTENT_TYPE_LATEST
from fastapi.responses import Response
import os, numpy as np

app = FastAPI(title="AI Inference Service")
PREDICTIONS = Counter("predictions_total", "Number of predictions served")

MODEL_PATH = os.getenv("MODEL_PATH", "models/model.npy")
MODEL = np.load(MODEL_PATH) if os.path.exists(MODEL_PATH) else np.array([1.0])

@app.get("/predict")
def predict(x: float = 1.0):
    PREDICTIONS.inc()
    return {"y": float(np.dot(MODEL, np.array([x])))}

@app.get("/metrics")
def metrics():
    return Response(generate_latest(), media_type=CONTENT_TYPE_LATEST)

Run locally:

uvicorn app.service:app --host 0.0.0.0 --port 8000

Why this helps:

  • New teammates and CI get the same environment.

  • CVEs and rollbacks are manageable via version pins.

  • Security reviews are simpler with smaller, known stacks.


2) Containerize and run rootless by default

Containers give you a portable, testable unit. Prefer rootless Podman in enterprises for safer defaults. Docker is fine when managed appropriately.

Containerfile (works with Podman; also valid as Dockerfile):

# Containerfile
FROM python:3.11-slim
WORKDIR /srv/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY app ./app
EXPOSE 8000
ENV MODEL_PATH=/srv/app/models/model.npy
CMD ["uvicorn", "app.service:app", "--host", "0.0.0.0", "--port", "8000"]

Build and run with Podman:

podman build -t aiops-service:0.1 .
podman run --rm -p 8000:8000 -v "$(pwd)/models:/srv/app/models:ro" aiops-service:0.1

Or with Docker:

docker build -t aiops-service:0.1 .
docker run --rm -p 8000:8000 -v "$(pwd)/models:/srv/app/models:ro" aiops-service:0.1

Smoke test:

curl -s "http://localhost:8000/predict?x=2.5" | jq
curl -s http://localhost:8000/metrics | head

Why this helps:

  • Same artifact goes from laptop to CI to prod.

  • Rootless operation reduces blast radius.

  • Volume mounts keep models/data external and auditable.


3) Govern models and data: track, verify, and trust

Use Git LFS for large files, and add checksums for integrity verification. This adds “paper trails” auditors and incident reviews love.

Initialize LFS and track model files:

git init
git lfs install
echo "models/*.npy filter=lfs diff=lfs merge=lfs -text" >> .gitattributes
git add .gitattributes
git commit -m "Enable LFS for models"

Create and record a checksum when publishing a model:

python3 - <<'PY'
import numpy as np, os
os.makedirs("models", exist_ok=True)
np.save("models/model.npy", np.array([1.23]))
PY

sha256sum models/model.npy | tee models/model.sha256
git add models/model.npy models/model.sha256
git commit -m "Add model v1 with checksum"

Verify at service start (add to entrypoint or CI/CD preflight):

set -euo pipefail
cd /srv/app
sha256sum -c models/model.sha256

Why this helps:

  • Detects silent corruption or partial syncs.

  • Tightens change control: every new model has a hash and commit.

  • Easier rollbacks to a known-good version.


4) Automate pipelines with Make and systemd timers

You don’t need a heavy orchestrator to be reliable. Make plus systemd timers handle a lot of daily batch and refresh work.

Install Make if missing:

  • apt: sudo apt install -y make

  • dnf: sudo dnf install -y make

  • zypper: sudo zypper install -y make

A tiny Makefile (save as Makefile):

.PHONY: prepare train package serve clean

prepare:
    python3 -m venv .venv && . .venv/bin/activate && pip install -r requirements.txt

train:
    . .venv/bin/activate && python3 - <<'PY'
import numpy as np, os
os.makedirs("models", exist_ok=True)
np.save("models/model.npy", np.array([4.56]))
PY
    sha256sum models/model.npy | tee models/model.sha256

package:
    podman build -t aiops-service:$(shell date +%Y%m%d%H%M) .

serve:
    podman run --rm -p 8000:8000 -v "$(PWD)/models:/srv/app/models:ro" aiops-service:latest

clean:
    rm -rf .venv __pycache__

Schedule nightly retraining with a user service and timer:

~/.config/systemd/user/ai-train.service

[Unit]
Description=Nightly AI Retraining

[Service]
Type=oneshot
WorkingDirectory=%h/aiops-demo
ExecStart=/usr/bin/make train

~/.config/systemd/user/ai-train.timer

[Unit]
Description=Run AI Retraining nightly

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

Enable and check:

systemctl --user daemon-reload
systemctl --user enable --now ai-train.timer
systemctl --user list-timers | grep ai-train
journalctl --user -u ai-train.service -n 50 --no-pager

Why this helps:

  • Simple, inspectable automation reduces operational surprises.

  • systemd’s logs and retries beat ad-hoc cron scripts.

  • Make encodes dependencies and order in plain text.


5) Observe what matters: metrics, logs, and cost guards

Expose metrics in the app (we already did with /metrics) and add a lightweight Bash wrapper to track runtime, exits, and (optionally) GPU usage.

A generic telemetry wrapper (ops/run_with_telemetry.sh):

#!/usr/bin/env bash
set -euo pipefail

log_file="${LOG_FILE:-ops/run.log}"
cmd=("$@")
start_ts="$(date --iso-8601=seconds)"
start_ns="$(date +%s%N)"

gpu_mem_mb=""
if command -v nvidia-smi >/dev/null 2>&1; then
  gpu_mem_mb="$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits 2>/dev/null | paste -sd+ - | bc || echo "")"
fi

status="ok"
"${cmd[@]}" || status="error"

end_ns="$(date +%s%N)"
duration_ms="$(( (end_ns - start_ns)/1000000 ))"
end_ts="$(date --iso-8601=seconds)"

printf '{"ts_start":"%s","ts_end":"%s","duration_ms":%d,"status":"%s","gpu_mem_mb":"%s","cmd":"%s"}\n' \
  "$start_ts" "$end_ts" "$duration_ms" "$status" "${gpu_mem_mb:-}" "$(printf '%q ' "${cmd[@]}")" | tee -a "$log_file"

Run any job through it:

chmod +x ops/run_with_telemetry.sh
LOG_FILE=ops/jobs.jsonl ./ops/run_with_telemetry.sh bash -lc "sleep 2 && curl -s http://localhost:8000/predict?x=3 | jq -c"

Summarize failures and durations with jq:

jq -r 'select(.status!="ok")' ops/jobs.jsonl
jq -s 'map(.duration_ms) | {p50:(sort|.[length/2|floor]),p95:(sort|.[(length*0.95)|floor])}' ops/jobs.jsonl

Why this helps:

  • You get immediate SLO-ish visibility with near-zero overhead.

  • GPU usage hints prevent idle-expensive jobs.

  • JSON Lines + jq is grep-friendly, ops-friendly, and pipeline-friendly.


Real-world example: from notebook to service in a sprint

  • A data science team moved a fraud model from a Jupyter notebook to the FastAPI container above, pinned with requirements.txt.

  • They shipped a small Makefile and systemd timer to retrain nightly on new labeled data.

  • Git LFS stored model binaries; model.sha256 prevented bad deploys.

  • Result: 30% fewer “it works locally” incidents, one-command rollback via image tags, and clear cost signals (job durations, GPU mem).


Conclusion and Call to Action

Enterprise AI doesn’t need to be fragile or mysterious. With a few disciplined, Bash-friendly practices, you can make AI services reliable, reproducible, and auditable:

  • Standardize environments with venv and pinned requirements.

  • Containerize and prefer rootless Podman for safer defaults.

  • Govern model artifacts with Git LFS and checksums.

  • Automate pipelines using Make and systemd timers.

  • Instrument your services and jobs with simple metrics and JSON logs.

Next steps: 1) Bootstrap a repo with the structure above and commit your first MODEL_PATH-based service. 2) Build and run it in a container on your dev machine. 3) Add the checksum gate and a nightly retrain timer. 4) Wire logs and metrics into your existing monitoring.

If you want a ready-to-fork template (Containerfile, Makefile, systemd units, telemetry script), say the word and I’ll generate a repo scaffold you can drop into your org today.