Category: Без рубрики

  • Agentic AI News: What DevOps Teams Need to Track

    Agentic AI News: A DevOps Guide to the Autonomous Agent Shift

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you’ve been half-following agentic AI news over the last few months, you’ve probably noticed the pattern: every week brings a new framework, a new “autonomous agent” demo, and a new set of claims about agents that can plan, execute, and self-correct without a human in the loop. For developers and sysadmins, the more useful question isn’t “is this hype?” — it’s “what do I actually need to change in my infrastructure to run this stuff safely?”

    This guide breaks down what’s actually new in agentic AI, why it matters operationally, and how to containerize, deploy, and monitor agent workloads on your own infrastructure without getting burned.

    What Counts as “Agentic AI” Right Now

    Agentic AI refers to systems that don’t just respond to a single prompt — they plan a sequence of steps, call tools or APIs, evaluate the results, and decide what to do next, often looping until a goal is met or a budget runs out. That’s a meaningful shift from the request/response chatbot pattern most teams are used to.

    From Chatbots to Autonomous Loops

    The practical difference shows up in three places:

  • State: agents maintain a working memory of what they’ve tried and what happened, not just the last message.
  • Tool use: agents call shell commands, APIs, databases, or other services as part of execution, not just to fetch context.
  • Control flow: agents decide their own next action, which means your infrastructure has to assume unpredictable, repeated calls rather than a single fixed request.
  • Frameworks like LangGraph and various open-source agent orchestrators have leaned into this pattern, and it’s why agentic AI news keeps circling back to the same operational concerns: cost control, sandboxing, and observability.

    Why This Matters for Infrastructure Teams

    The news cycle around agentic AI tends to focus on capability — what the agent can now do. The part that gets less coverage, and that actually matters for your job, is that agents run longer, call out more often, and fail in less predictable ways than a typical microservice. If you’re the one who gets paged when something misbehaves, you need guardrails before you need more capability.

    Recent Agentic AI News Themes Worth Tracking

    A few threads keep showing up across agentic AI news coverage:

    Open-Source Agent Frameworks Maturing

    Open-source agent orchestration tooling has moved from research demos to production-adjacent releases with retry logic, checkpointing, and human-in-the-loop approval steps. That maturity is good news operationally — it means fewer bespoke wrappers and more standard patterns you can containerize and monitor like any other service.

    Tool-Use Standardization

    There’s growing convergence around structured tool-calling interfaces (function calling, schema-based tool definitions) instead of agents parsing raw text to decide what to do. This matters because it makes agent actions auditable — you can log exactly which tool was called with which arguments, rather than trying to reverse-engineer intent from free text.

    Cost and Rate-Limit Pressure

    Because agents loop and re-call models multiple times per task, teams are reporting real cost surprises. This is pushing more agentic AI news toward practical topics: budget caps per task, step limits, and circuit breakers — the same patterns you’d already use for any retrying background job.

    Deploying Agentic AI Workloads with Docker

    Whether you’re running an open-source agent framework or a custom Python loop calling a model API, the deployment shape is similar: a long-running or on-demand worker process, a queue or trigger, and outbound calls to a model provider and whatever tools the agent is allowed to use.

    A Minimal Containerized Agent Worker

    Here’s a simple example of containerizing a Python-based agent worker that reads tasks off a queue and executes them with a bounded step count:

    # agent_worker.py
    import os
    import time
    
    MAX_STEPS = int(os.getenv("AGENT_MAX_STEPS", "6"))
    
    def run_agent_task(task: dict) -> dict:
        steps_taken = 0
        result = None
    
        while steps_taken < MAX_STEPS:
            action = decide_next_action(task, result)
            if action["type"] == "finish":
                return {"status": "done", "output": action["output"]}
            result = execute_tool(action)
            steps_taken += 1
    
        return {"status": "step_limit_reached", "last_result": result}
    
    def decide_next_action(task, last_result):
        # Call your model provider here with task + last_result as context
        raise NotImplementedError
    
    def execute_tool(action):
        # Dispatch to whitelisted tools only
        raise NotImplementedError
    
    if __name__ == "__main__":
        while True:
            task = poll_queue()
            if task:
                run_agent_task(task)
            else:
                time.sleep(2)

    FROM python:3.12-slim
    
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    COPY agent_worker.py .
    
    ENV AGENT_MAX_STEPS=6
    USER 1000
    CMD ["python", "agent_worker.py"]

    The AGENT_MAX_STEPS cap is the single most important line in this example. Without a hard ceiling, a misbehaving agent loop will happily keep calling your model provider — and your bill — indefinitely.

    Compose Stack: Agent Worker + Queue + Monitoring

    version: "3.9"
    services:
      agent-worker:
        build: .
        restart: unless-stopped
        environment:
          - AGENT_MAX_STEPS=6
          - QUEUE_URL=redis://queue:6379/0
        depends_on:
          - queue
        deploy:
          resources:
            limits:
              cpus: "1.0"
              memory: 512M
    
      queue:
        image: redis:7-alpine
        restart: unless-stopped
        volumes:
          - queue-data:/data
    
      prometheus:
        image: prom/prometheus:latest
        restart: unless-stopped
        ports:
          - "9090:9090"
        volumes:
          - ./prometheus.yml:/etc/prometheus/prometheus.yml
    
    volumes:
      queue-data:

    Running this stack is not much different from any other worker/queue deployment you’ve already built — which is exactly the point. Treat agentic workloads as you would any bursty background job system, not as a special snowflake.

    For a broader look at running containerized services reliably, our Docker Compose monitoring stack guide walks through wiring Prometheus and Grafana into a stack like this one.

    Resource Limits Are Non-Negotiable

    Set CPU and memory limits on every agent container. Agents that call subprocesses, spawn browser automation, or shell out to CLI tools can consume resources far more aggressively than a typical API service, especially if a loop condition doesn’t terminate the way you expect.

    Monitoring and Observability for Agents

    Standard application metrics (latency, error rate, request count) aren’t enough for agentic workloads. You also need:

  • Step count per task — flags runaway loops before they become cost incidents.
  • Tool call logs — every tool invocation with its arguments, for auditability.
  • Token/cost per task — model API usage tends to be the real cost driver, not compute.
  • Timeout and abort rate — how often tasks hit your step or time limits instead of completing cleanly.
  • If you’re already running a BetterStack uptime and log monitoring setup, extending it to capture structured logs from your agent worker (one log line per tool call, with task ID and step number) gives you a searchable audit trail without much extra work. Alternatively, ship structured logs to your existing observability stack the same way you would for any other service — the format matters more than the destination.

    Setting Alerts Before You Need Them

    Don’t wait for an agentic AI news headline about a runaway agent bill to be your motivation. Set alerts on:

  • Step-limit-reached rate exceeding a threshold (signals prompt or tool-definition problems)
  • Hourly model API spend crossing a budget line
  • Tool call failure rate spiking (often the first sign of an upstream API change)
  • Security Considerations for Autonomous Agents

    Agentic AI news coverage often glosses over the security implications of giving a model the ability to call tools autonomously. A few practical rules:

  • Whitelist tools explicitly. Never let an agent construct arbitrary shell commands from model output; expose a fixed set of narrow, parameterized functions instead.
  • Run agents in isolated containers, not on hosts with broad filesystem or network access.
  • Scope credentials tightly. An agent’s API keys should have the minimum permissions needed for its specific tools — not your full admin credentials.
  • Log everything. If an agent takes an unexpected action, you need a full trace of what it decided and why.
  • If you’re evaluating where to run these workloads, a VPS with predictable CPU/memory limits makes it much easier to enforce container-level resource caps than a shared or bursty environment. Providers like DigitalOcean and Hetzner both offer straightforward Docker-friendly droplets/VMs where you can size instances precisely for agent worker workloads and scale horizontally as task volume grows.

    Testing Agent Behavior Before Production

    Before deploying any agent framework update, run it against a fixed set of test tasks with tool calls mocked out. This catches regressions in decision-making (an agent suddenly looping more, or choosing the wrong tool) before it hits production traffic and your budget.

    Keeping Up With Agentic AI News Without Drowning in It

    Given how fast this space moves, it’s not realistic to read every announcement. A more sustainable approach:

  • Follow release notes for the specific framework(s) you’ve adopted, not the entire ecosystem.
  • Skim agentic AI news weekly for security disclosures or breaking API changes — treat those as must-read.
  • Ignore benchmark-of-the-week posts unless they affect a model you’re actually running in production.
  • Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    What is agentic AI in simple terms?
    Agentic AI describes AI systems that plan multi-step actions, call tools or APIs, evaluate results, and decide their next step on their own, rather than just answering a single prompt.

    Is agentic AI the same as an AI agent framework like LangGraph?
    Not exactly — “agentic AI” describes the behavior pattern, while frameworks like LangGraph are specific tools for building and orchestrating that behavior. You can build an agentic system without using any particular framework.

    How do I stop an AI agent from running up my API bill?
    Set a hard step limit per task, a token/cost budget per task, and alerting on hourly spend. Treat these the same way you’d treat rate limits on any retrying background job.

    Do agentic AI workloads need special infrastructure?
    Not special, but they do need infrastructure that assumes bursty, repeated outbound calls and enforces per-container resource limits. A standard Docker worker/queue setup on a properly sized VPS handles this well.

    What’s the biggest security risk with autonomous agents?
    Letting an agent construct and execute arbitrary commands or API calls without a whitelist. Always scope tool access explicitly and log every tool invocation.

    Where should I host agent worker containers?
    Any Docker-friendly VPS with clear CPU/memory limits works. Predictable, non-shared resources make it far easier to reason about how an agent workload will behave under load.

    Agentic AI news will keep moving fast, but the infrastructure fundamentals don’t change much: containerize the workload, cap its steps and budget, log every action, and monitor it like you would any other background job system — just with tighter guardrails.

  • Docker Compose Up Build: Full Guide & Best Practices

    Docker Compose Up Build: The Complete Guide to Rebuilding and Running Containers

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you’ve spent any time working with multi-container applications, you’ve almost certainly typed docker compose up build into your terminal, only to get a syntax error or unexpected behavior. The correct command is docker compose up --build, and understanding exactly what it does — and when to use it — will save you hours of debugging “why isn’t my code change showing up” mysteries.

    This guide covers the full mechanics of docker compose up --build, how it differs from running docker compose build separately, common pitfalls with caching, and practical workflows for local development, CI pipelines, and production-adjacent staging environments.

    What Does docker compose up –build Actually Do

    The docker compose up --build command tells Compose to rebuild any service images before starting the containers. Without the --build flag, Compose only builds an image if it doesn’t already exist locally — if you’ve made changes to your Dockerfile or the files it copies in, those changes will be silently ignored and you’ll keep running the old image.

    Here’s the basic syntax:

    docker compose up --build

    This single command does three things in sequence:

  • Rebuilds every service in your docker-compose.yml that has a build: directive
  • Recreates containers that depend on those rebuilt images
  • Starts (or restarts) all services defined in the compose file
  • If you only want to rebuild and start a single service, you can scope it:

    docker compose up --build web

    This rebuilds and starts only the web service, along with any services it depends on via depends_on.

    Why the Plain docker compose up Command Isn’t Enough

    A lot of confusion comes from assuming Compose always rebuilds on up. It doesn’t. Compose checks whether an image already exists for the service; if it does, up reuses it, even if your source code or Dockerfile has changed since the image was built.

    This is a common source of “phantom bugs” where a developer fixes an issue, runs docker compose up, and the bug is still there — because the container is running stale code baked into an old image layer. Running docker compose up --build forces Compose to re-evaluate the build context and rebuild as needed.

    The Difference Between docker compose build and docker compose up –build

    These two approaches look similar but serve different purposes:

    # Build images without starting containers
    docker compose build
    
    # Build images and immediately start containers
    docker compose up --build

    docker compose build is useful in CI/CD pipelines where you want to build and push an image without running it locally. docker compose up --build is better suited for local development loops where you’re iterating quickly and want your changes reflected immediately.

    If you’re setting up a CI pipeline, it’s worth reading the official Docker Compose CLI reference for the full list of flags and how they interact with build caching.

    Common Flags and Options You’ll Actually Use

    Beyond the basic --build flag, there are several options that make the command far more useful in day-to-day work.

    Forcing a Full Rebuild with –no-cache

    Docker’s build cache is usually your friend — it speeds up rebuilds by reusing unchanged layers. But sometimes the cache causes problems, especially when a base image has been updated upstream or a RUN apt-get install step needs fresh package lists.

    docker compose build --no-cache
    docker compose up --build --no-cache

    Note that --no-cache isn’t actually a flag on up directly in older Compose versions — if you hit an error, run the no-cache build separately first, then bring the stack up:

    docker compose build --no-cache && docker compose up

    Running in Detached Mode

    For background services, especially on a VPS or remote server, combine --build with -d:

    docker compose up --build -d

    This rebuilds images and runs containers in detached mode so your terminal session stays free. This is the pattern most people use when deploying to a DigitalOcean droplet or similar cloud VM — SSH in, pull the latest code, and run this one command to redeploy.

    Forcing Container Recreation

    Sometimes Compose decides a container doesn’t need to be recreated even after a rebuild, particularly if only environment variables changed. Force it with:

    docker compose up --build --force-recreate

    This guarantees old containers are torn down and replaced, not just restarted.

    Practical Workflow Examples

    Let’s walk through a realistic scenario. Say you have a simple Node.js API with the following docker-compose.yml:

    version: "3.9"
    services:
      api:
        build:
          context: .
          dockerfile: Dockerfile
        ports:
          - "3000:3000"
        environment:
          - NODE_ENV=development
        volumes:
          - ./src:/app/src
      db:
        image: postgres:16
        environment:
          - POSTGRES_PASSWORD=devpassword
        volumes:
          - pgdata:/var/lib/postgresql/data
    
    volumes:
      pgdata:

    And a Dockerfile like this:

    FROM node:20-alpine
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    EXPOSE 3000
    CMD ["node", "src/index.js"]

    If you add a new npm dependency to package.json, running plain docker compose up won’t install it — the existing image already has node_modules baked in from the last build. You need:

    docker compose up --build

    This re-runs npm install inside the image build step, picking up the new dependency, then starts both the api and db services.

    Handling Multi-Service Rebuilds Efficiently

    In larger projects with multiple services (API, worker, frontend, reverse proxy), rebuilding everything every time is wasteful. Scope your builds:

    docker compose up --build api worker

    This rebuilds only api and worker, leaving db and any unchanged services untouched, which speeds up your iteration loop considerably.

    If you’re managing a growing compose file, it’s worth reviewing our guide to organizing multi-container Docker projects for patterns on splitting services across multiple compose files with docker compose -f.

    Troubleshooting Common docker compose up –build Issues

    A few issues come up repeatedly with this command, and most have simple fixes.

  • Changes not appearing after rebuild: Check whether you have a bind-mounted volume overwriting the container’s code directory with an outdated local copy. Volumes mounted in docker-compose.yml take precedence over what’s baked into the image.
  • Build succeeds but container immediately exits: Check your CMD or ENTRYPOINT — the container will exit if the foreground process crashes or completes. Run docker compose logs <service> to see the actual error.
  • “no space left on device” during build: Docker’s build cache and dangling images accumulate over time. Run docker system prune -a (carefully — this removes unused images) to reclaim space.
  • Environment variable changes not taking effect: Environment variables set in .env files or environment: blocks don’t always force a rebuild. Combine with --force-recreate to be safe.
  • Build context is too large and slow: Add a .dockerignore file to exclude node_modules, .git, and other large directories from being sent to the Docker daemon during build.
  • Speeding Up Builds with BuildKit

    Modern Docker installations use BuildKit by default, which parallelizes build steps and caches more intelligently. If you’re on an older setup, enable it explicitly:

    DOCKER_BUILDKIT=1 docker compose up --build

    BuildKit also supports cache mounts for package managers, which can dramatically speed up repeated npm install or pip install steps. See Docker’s own documentation on BuildKit for configuration details.

    Deploying with docker compose up –build on a Remote Server

    When deploying to a VPS, the workflow typically looks like this: SSH into the server, pull the latest code, and rebuild.

    ssh user@your-server-ip
    cd /opt/myapp
    git pull origin main
    docker compose up --build -d

    For production deployments, consider adding a health check to your compose file so Compose (and any orchestration layer) knows when a service is actually ready:

    services:
      api:
        build: .
        healthcheck:
          test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
          interval: 30s
          timeout: 5s
          retries: 3

    If you’re running this on a budget VPS provider, Hetzner offers solid price-to-performance ratios for small Docker Compose deployments, and their cloud consoles make it easy to spin up a fresh instance to test a deployment before pushing to your main server.

    For teams that need uptime monitoring on these deployed services, pairing your compose stack with BetterStack gives you alerting when a container-based service goes down, which is especially useful right after a --build deploy where a bad image can silently break a health check.

    If your compose-based app sits behind a public domain, routing DNS and basic DDoS protection through Cloudflare is a near-zero-cost way to harden a VPS-hosted deployment before you invest in a full load balancer setup.

    Automating Rebuilds in CI/CD

    Many teams wire docker compose up --build into a deployment script triggered by a git push. A minimal GitHub Actions step might look like:

    - name: Deploy via SSH
      run: |
        ssh -o StrictHostKeyChecking=no user@${{ secrets.SERVER_IP }} 
          "cd /opt/myapp && git pull && docker compose up --build -d"

    This pattern works well for small to medium projects. For anything with higher uptime requirements, you’ll want a proper CI pipeline that builds and tests images before they ever touch your production compose file — check out our beginner’s guide to Docker fundamentals if you’re still solidifying the basics before automating deployments.

    Best Practices Checklist

    Before you wire docker compose up --build into your regular workflow, keep these practices in mind:

  • Always add a .dockerignore file to keep build contexts small and fast
  • Use --build only when source files or Dockerfiles have changed — otherwise plain up is faster
  • Combine with -d for background services on remote servers
  • Use --force-recreate when environment variables or configs change without a corresponding image rebuild
  • Periodically run docker system prune to clean up unused build cache and dangling images
  • Pin base image versions (e.g., node:20-alpine instead of node:latest) to avoid unexpected behavior from upstream updates
  • Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Is “docker compose up build” a valid command?
    No. The correct syntax requires two dashes: docker compose up --build. Without the dashes, Docker will interpret build as a service name and likely return an error saying no such service exists.

    Does docker compose up –build always rebuild every service?
    Yes, by default it rebuilds all services in the compose file that have a build: directive. To limit the rebuild to specific services, list them after the command, like docker compose up --build api.

    What’s the difference between docker compose up –build and docker-compose up –build?
    Functionally they’re the same. docker compose (no hyphen) is the newer Compose V2 syntax integrated into the Docker CLI, while docker-compose is the older standalone Python-based tool. Compose V2 is faster and actively maintained, so it’s the recommended syntax going forward.

    Why isn’t my code change showing up even after running docker compose up –build?
    The most common cause is a bind-mounted volume overriding the container’s working directory with a stale local copy, or the build cache reusing a layer that should have been invalidated. Try docker compose build --no-cache followed by docker compose up --force-recreate.

    Does docker compose up –build slow down my workflow?
    It adds build time on every run, so it’s slower than plain up when nothing has changed. Use it selectively — only when you’ve modified your Dockerfile, dependencies, or files copied during the build step.

    Can I use docker compose up –build in production?
    It’s more common in development and simple deployment scripts. For production, most teams prefer building images in CI, pushing them to a registry, and having the production compose file reference a specific image tag rather than rebuilding on the server itself.

    Wrapping Up

    docker compose up --build is one of the most-used commands in a containerized development workflow, but its behavior around caching and image reuse trips up even experienced developers. The core rule to remember: if you’ve changed anything that affects the image (Dockerfile, dependencies, copied files), you need --build to see those changes reflected. Combine it with -d for background services, --force-recreate when configs change, and --no-cache when you suspect stale cache layers are the culprit, and you’ll avoid most of the common headaches associated with this command.

  • AI Agent vs Agentic AI: Key Differences Explained

    AI Agent vs Agentic AI: What Developers Actually Need to Know

    Every vendor pitch deck in 2026 uses “agent” and “agentic” interchangeably, and it’s making architecture decisions harder than they need to be. If you’re a developer or sysadmin trying to figure out what to actually deploy on your infrastructure, the distinction matters — it changes your compute footprint, your orchestration layer, and your monitoring strategy.

    This article breaks down the ai agent vs agentic ai debate in concrete technical terms, with real deployment patterns you can run on your own servers.

    Quick Definitions Before We Go Deeper

  • AI agent: A single autonomous unit that perceives input, reasons over it, and takes an action — usually calling one or more tools or APIs to complete a bounded task.
  • Agentic AI: A system-level architecture where multiple agents (or agent instances) coordinate, delegate, and iterate toward a goal with minimal human intervention, often involving planning, memory, and self-correction loops.
  • In other words: an AI agent is a component. Agentic AI is the system built from those components, plus the orchestration logic that makes them work together.

    What Is an AI Agent?

    An AI agent is typically a single LLM-backed process wired to a fixed set of tools. Think of a Slack bot that reads a support ticket, queries a knowledge base, and drafts a reply. It has:

  • A defined input/output contract
  • A limited toolset (search, database query, API call)
  • No persistent long-term planning — it reacts, it doesn’t strategize across sessions
  • Usually a single LLM call or a short chain of calls per request
  • This is the pattern most teams are already running in production. It’s the same shape as a traditional microservice, just with an LLM doing the reasoning step instead of hardcoded business logic.

    What Is Agentic AI?

    Agentic AI describes a system where multiple agents — or a single agent operating across many iterative steps — collaborate to solve a multi-stage problem without a human approving each step. A DevOps example: an agentic pipeline that receives a vague ticket like “deploy is failing on staging,” then:

    1. Spins up a diagnostic agent to pull logs
    2. Spins up a root-cause agent to correlate logs against recent commits
    3. Spins up a remediation agent to propose (or apply) a fix
    4. Reports back with a summary and a rollback plan if the fix fails

    Each of those steps could itself be an AI agent. The agentic system is the orchestration layer that sequences them, maintains shared state, and decides when to loop back versus escalate to a human.

    Key Differences at a Glance

    | Dimension | AI Agent | Agentic AI |
    |—|—|—|
    | Scope | Single task | Multi-step goal |
    | State | Mostly stateless per request | Persistent memory across steps |
    | Autonomy | Reacts to input | Plans and self-corrects |
    | Failure mode | Returns an error | Retries, replans, or escalates |
    | Infra footprint | One process/container | Orchestrator + N worker agents |
    | Typical trigger | API call or webhook | Goal statement or ticket |

    If you’re deciding what to build first, start with the AI agent pattern. It’s cheaper to run, easier to debug, and easier to put behind rate limits. Only move to agentic AI once you have a workflow that genuinely needs multi-step planning — most “agentic” use cases people pitch you don’t actually need it.

    Architecture: How This Looks in Practice

    A single AI agent is straightforward to containerize. Here’s a minimal Python agent using a tool-calling pattern, wrapped for Docker deployment:

    # agent.py
    import os
    import requests
    from openai import OpenAI
    
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    
    def check_service_status(url: str) -> str:
        resp = requests.get(url, timeout=5)
        return f"{url} returned {resp.status_code}"
    
    tools = [{
        "type": "function",
        "function": {
            "name": "check_service_status",
            "description": "Check HTTP status of a service URL",
            "parameters": {
                "type": "object",
                "properties": {"url": {"type": "string"}},
                "required": ["url"]
            }
        }
    }]
    
    def run_agent(prompt: str):
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": prompt}],
            tools=tools
        )
        return response.choices[0].message

    FROM python:3.12-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    COPY agent.py .
    CMD ["python", "agent.py"]

    That’s a full AI agent: one container, one job, one tool. Run it with:

    docker build -t status-check-agent .
    docker run --env OPENAI_API_KEY=$OPENAI_API_KEY status-check-agent

    Deploying an Agentic AI System with Docker Compose

    Agentic AI needs an orchestrator plus multiple agent workers, usually with a shared message queue or state store between them. A minimal version:

    # docker-compose.yml
    version: "3.9"
    services:
      orchestrator:
        build: ./orchestrator
        environment:
          - REDIS_URL=redis://redis:6379
        depends_on:
          - redis
    
      diagnostic-agent:
        build: ./agents/diagnostic
        environment:
          - REDIS_URL=redis://redis:6379
        depends_on:
          - redis
    
      remediation-agent:
        build: ./agents/remediation
        environment:
          - REDIS_URL=redis://redis:6379
        depends_on:
          - redis
    
      redis:
        image: redis:7-alpine
        ports:
          - "6379:6379"

    The orchestrator publishes tasks to Redis, each worker agent subscribes to its channel, and results flow back for the orchestrator to sequence the next step. This is roughly the same pattern used by frameworks like LangGraph and CrewAI, just stripped down to raw containers so you can see what’s actually happening under the hood.

    If you’re already running container workloads, this maps cleanly onto skills you have. Our Docker container monitoring guide covers how to keep tabs on multi-container stacks like this one, and if you haven’t settled on hosting yet, check our VPS hosting comparison for DevOps teams before committing infrastructure spend.

    Choosing the Right Pattern for Your Use Case

    Here’s a practical decision framework:

  • Use a single AI agent when the task is well-defined, has a clear input/output shape, and doesn’t require the system to decide what to do next — only how to answer this one thing.
  • Use agentic AI when the task involves ambiguity, multiple dependent steps, or requires the system to adapt its plan based on intermediate results.
  • Avoid agentic AI for anything latency-sensitive or cost-sensitive at scale — every planning loop adds LLM calls, and LLM calls add both latency and token cost.
  • Always add a human checkpoint before agentic systems take destructive or irreversible actions (deleting resources, pushing to production, sending customer-facing messages).
  • One operational reality worth flagging: agentic systems fail in messier ways than single agents. A single agent either returns a good answer or an error. An agentic system can get stuck in a planning loop, burn through your API budget, or take a plausible-but-wrong action three steps deep before anyone notices. Set hard iteration limits and cost ceilings from day one — don’t wait for a runaway loop to teach you the lesson.

    Monitoring and Guardrails

    Whatever you deploy, observability is non-negotiable. At minimum, track:

  • Token usage per agent, per task type
  • Tool call success/failure rates
  • Loop iteration counts for agentic workflows
  • Wall-clock time per completed task
  • Tools like Prometheus paired with Grafana work fine for this if you’re already running that stack — you’re just treating each agent container like any other service, with custom metrics exported for token spend and loop depth.

    If you’re deploying agentic pipelines that run continuously (not just on-demand), it’s worth putting real uptime and cost alerting in front of them rather than checking dashboards manually. A managed monitoring service saves you from finding out about a runaway agent loop from your cloud bill instead of an alert.

    Cost and Infrastructure Considerations

    Agentic AI systems are meaningfully more expensive to run than single agents, for two reasons: multiple LLM calls per task, and the standing infrastructure (queue, orchestrator, state store) needed to coordinate them. Before you commit to an agentic architecture, estimate:

  • Average number of LLM calls per completed workflow
  • Peak concurrent workflows your infra needs to support
  • Storage/retention requirements for agent memory and logs
  • For most small-to-mid-size deployments, a single mid-tier VPS running Docker Compose is enough to prototype an agentic system before you need Kubernetes. Scale the orchestration layer only once you’ve validated the workflow actually needs multiple coordinating agents — plenty of teams build a five-agent system for a job a single well-prompted agent could have handled.

    FAQ

    Is agentic AI just marketing for AI agents?
    Not entirely. There’s a real technical distinction: an AI agent handles one bounded task, while agentic AI coordinates multiple steps or multiple agents toward a broader goal with less human oversight. But yes, a lot of vendor marketing blurs the line to make simple agent wrappers sound more sophisticated than they are.

    Do I need a multi-agent framework to build agentic AI?
    No. You can build agentic behavior with a single agent that loops and re-plans based on its own intermediate outputs. Frameworks like LangGraph or CrewAI make multi-agent coordination easier, but they’re not required to get agentic behavior.

    Which is cheaper to run in production, an AI agent or agentic AI?
    A single AI agent is almost always cheaper — fewer LLM calls per task and a simpler infrastructure footprint. Agentic AI systems multiply both cost and complexity because of iterative planning and inter-agent coordination overhead.

    Can I containerize an agentic AI system the same way I containerize microservices?
    Yes. Each agent can run as its own container, coordinated through a message queue like Redis or RabbitMQ, similar to standard microservice patterns. The main addition is shared state/memory management between agents.

    What’s the biggest risk with agentic AI in production?
    Uncontrolled iteration loops and cost overruns. Without hard limits on planning steps and token budgets, an agentic system can spiral into repeated LLM calls without a human noticing until the bill or the logs show it.

    Should I start with an AI agent or jump straight to agentic AI?
    Start with a single AI agent. Validate that the task genuinely requires multi-step planning before adding orchestration complexity — most production use cases are solved by a well-scoped single agent.

    Bottom Line

    The ai agent vs agentic ai distinction isn’t academic — it directly determines your deployment shape, your monitoring needs, and your cost profile. Start narrow with a single agent wired to a fixed toolset, containerize it, and only reach for a full agentic architecture once you’ve proven the workflow actually needs multi-step, multi-agent coordination. Most teams over-build here; don’t be one of them.

  • AI Phone Agents: Self-Hosting Guide with Docker

    AI Phone Agents: A Developer’s Guide to Self-Hosting Voice Automation

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    AI phone agents — automated systems that answer calls, hold natural conversations, and route or resolve requests without a human on the line — have moved from novelty to production infrastructure. If you run servers for a living, you’ve probably already been asked to “just wire up an AI agent to the support line.” This guide walks through what that actually takes: the architecture, the Docker-based deployment, the telephony integration, and the operational tradeoffs of running AI phone agents on infrastructure you control instead of a black-box SaaS.

    What Are AI Phone Agents?

    An AI phone agent is a pipeline that converts an inbound or outbound phone call into a real-time conversation with a language model. Under the hood, it’s a chain of four systems working in near real time:

  • Telephony layer — receives/places the call and streams audio (Twilio, Telnyx, or SIP trunking)
  • Speech-to-text (STT) — transcribes caller audio to text as it arrives
  • LLM orchestration — generates a response, calls tools/APIs, manages conversation state
  • Text-to-speech (TTS) — converts the LLM’s reply back into audio streamed to the caller
  • Commercial platforms like Vapi or Retell bundle all of this behind an API key. That’s fine for a prototype, but once you’re handling real call volume, you hit the same wall every SaaS-wrapped-open-source product eventually hits: per-minute pricing that scales linearly with usage, vendor lock-in on voice models, and no control over where audio and transcripts are stored — a real problem if you’re in a regulated industry.

    Why Self-Host AI Phone Agents

    Running your own stack makes sense once you clear a few hundred call-minutes a day, or once data residency actually matters. The tradeoffs are concrete:

  • Cost at scale — self-hosted STT/TTS on a GPU box is often 5-10x cheaper per minute than metered API pricing once utilization is decent
  • Latency control — colocating your LLM inference and telephony bridge in the same region cuts round-trip latency, which matters a lot for conversational feel
  • Data ownership — call transcripts and audio never leave infrastructure you control, which simplifies compliance
  • Model flexibility — swap in any open-weight LLM or fine-tune on your own call logs
  • The cost is operational complexity. You’re now responsible for uptime, GPU capacity, and a real-time audio pipeline instead of a REST call.

    Core Architecture

    A minimal self-hosted stack looks like this:

    Caller --> Twilio Media Streams (WebSocket) --> Orchestrator (Python/Node)
                                                           |
                        +----------------------------------+----------------------------------+
                        |                                  |                                  |
                  Whisper (STT)                     LLM (vLLM/Ollama)                  Piper/Coqui (TTS)

    Twilio (or an equivalent provider) opens a bidirectional WebSocket media stream for the call. Your orchestrator service buffers incoming audio chunks, feeds them to a streaming STT model, passes the resulting text to an LLM, and streams the LLM’s response through TTS back over the same socket. All of this needs to happen with well under a second of round-trip latency to feel like a real conversation.

    Docker Compose Setup

    Here’s a working docker-compose.yml for the core services. It assumes a GPU-enabled host for the STT and LLM containers.

    version: "3.9"
    
    services:
      orchestrator:
        build: ./orchestrator
        ports:
          - "8080:8080"
        environment:
          - TWILIO_ACCOUNT_SID=${TWILIO_ACCOUNT_SID}
          - TWILIO_AUTH_TOKEN=${TWILIO_AUTH_TOKEN}
          - STT_URL=http://whisper:9000
          - LLM_URL=http://llm:11434
          - TTS_URL=http://tts:5002
        depends_on:
          - whisper
          - llm
          - tts
    
      whisper:
        image: onerahmet/openai-whisper-asr-webservice:latest
        environment:
          - ASR_MODEL=medium
          - ASR_ENGINE=faster_whisper
        deploy:
          resources:
            reservations:
              devices:
                - capabilities: [gpu]
    
      llm:
        image: ollama/ollama:latest
        volumes:
          - ollama_data:/root/.ollama
        deploy:
          resources:
            reservations:
              devices:
                - capabilities: [gpu]
    
      tts:
        image: ghcr.io/coqui-ai/tts:latest
        command: ["--model_name", "tts_models/en/vctk/vits"]
    
    volumes:
      ollama_data:

    Bring it up with:

    docker compose up -d
    docker compose logs -f orchestrator

    If you haven’t tuned a Docker Compose stack for GPU workloads before, our Docker Compose GPU deployment guide covers the NVIDIA Container Toolkit setup you’ll need before these containers will actually see the GPU.

    Setting Up Speech-to-Text and Text-to-Speech

    For STT, OpenAI’s Whisper run through faster-whisper gives near real-time transcription on a single consumer GPU. The medium model is a good balance of accuracy and latency for phone-quality (8kHz) audio; large-v3 is more accurate but adds 200-400ms of latency per chunk, which is often not worth it for a live call.

    For TTS, Coqui TTS and Piper are the two open-source options worth evaluating. Piper is CPU-friendly and extremely fast, which matters if you’re not running TTS on a GPU box — it can hit sub-200ms synthesis on modest hardware. Coqui’s VITS models sound more natural but need a GPU to stay fast enough for live conversation.

    A minimal orchestrator loop (Python, using websockets and httpx) looks like this:

    import asyncio
    import httpx
    import websockets
    
    async def handle_call(websocket):
        async for message in websocket:
            audio_chunk = decode_media_stream(message)
            transcript = await transcribe(audio_chunk)
            if transcript:
                reply = await query_llm(transcript)
                audio_reply = await synthesize(reply)
                await websocket.send(encode_media_stream(audio_reply))
    
    async def transcribe(chunk: bytes) -> str:
        async with httpx.AsyncClient() as client:
            resp = await client.post("http://whisper:9000/asr", content=chunk)
            return resp.json().get("text", "")
    
    async def query_llm(text: str) -> str:
        async with httpx.AsyncClient() as client:
            resp = await client.post(
                "http://llm:11434/api/generate",
                json={"model": "llama3.1:8b", "prompt": text, "stream": False},
            )
            return resp.json()["response"]
    
    async def synthesize(text: str) -> bytes:
        async with httpx.AsyncClient() as client:
            resp = await client.post("http://tts:5002/api/tts", json={"text": text})
            return resp.content

    This is intentionally bare — production versions need interrupt handling (so the caller can talk over the agent), silence detection to know when the caller has finished speaking, and streaming responses from the LLM rather than waiting for the full completion.

    Connecting to a Telephony Provider

    Twilio’s Media Streams API is the easiest on-ramp: you point a TwiML <Connect><Stream> verb at your orchestrator’s WebSocket URL and Twilio handles the PSTN side entirely. For higher call volume or lower per-minute cost, a SIP trunk into Asterisk or FreeSWITCH gives you more control but adds real telephony ops work — NAT traversal, codec negotiation, and carrier peering are not trivial.

    A basic TwiML response to bridge an inbound call into your stream:

    <Response>
      <Connect>
        <Stream url="wss://agents.example.com/media" />
      </Connect>
    </Response>

    Scaling and Monitoring Your AI Phone Agent Infrastructure

    Once you’re past a handful of concurrent calls, a single Docker host won’t cut it. Each active call pins an STT stream, an LLM context, and a TTS session simultaneously, so concurrency scales GPU memory usage fast. Plan for:

  • Horizontal scaling of the orchestrator behind a load balancer, with sticky WebSocket routing per call
  • GPU pooling — batch multiple Whisper/TTS requests where the model server supports it (faster-whisper and vLLM both do)
  • Call queuing — a Redis-backed queue to hold calls when GPU capacity is saturated, rather than dropping them
  • Monitoring matters more here than in most services because failures are invisible until a caller hangs up frustrated. We run BetterStack for uptime checks on the orchestrator’s health endpoint and log-based alerting on STT/TTS error rates — worth setting up before you put a phone number in front of real customers. If you haven’t built out alerting for a service like this before, see our guide to self-hosted monitoring stacks for the Prometheus/Grafana side of things.

    For the hosting layer itself, GPU-backed instances are the main cost driver. DigitalOcean’s GPU droplets are a reasonable starting point if you want simple provisioning without committing to reserved capacity, and they scale down cleanly if call volume doesn’t materialize. If you’re running steady, predictable volume instead, Hetzner’s dedicated GPU servers come in significantly cheaper per hour for always-on workloads.

    Security Considerations

    Phone calls carry PII by default — names, account numbers, sometimes payment details read aloud. A few non-negotiables:

  • Encrypt call recordings and transcripts at rest, and set a retention policy instead of keeping everything indefinitely
  • Put the orchestrator’s public WebSocket endpoint behind TLS termination and IP allowlisting for your telephony provider’s signaling ranges
  • Never let the LLM’s tool-calling layer execute arbitrary actions (refunds, account changes) without a secondary confirmation step — prompt injection via a caller’s spoken input is a real attack surface, not a theoretical one
  • Front the public endpoints with Cloudflare for DDoS protection and WAF rules, since a public-facing voice endpoint is an easy target for automated abuse
  • If you’re exposing any of this stack to the public internet, our Linux server hardening checklist is a reasonable baseline before you take a first production call.

    Cost Comparison: Self-Hosted vs SaaS

    Rough numbers based on a single GPU instance handling moderate concurrent call volume:

    | Approach | Cost per minute | Setup effort | Data control |
    |—|—|—|—|
    | SaaS (Vapi/Retell) | $0.05-$0.15 | Low | None |
    | Self-hosted (cloud GPU) | $0.01-$0.03 | High | Full |
    | Self-hosted (dedicated GPU) | $0.005-$0.015 | High | Full |

    The breakeven point is usually somewhere around 5,000-10,000 call-minutes a month, depending on which models you’re running and how efficiently you batch inference. Below that volume, the engineering time to build and maintain the pipeline usually costs more than the SaaS markup.

    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do AI phone agents need a GPU to run?
    STT and TTS models can run on CPU, but latency suffers enough that conversations feel sluggish. For anything beyond a low-volume prototype, a GPU for Whisper and your LLM is effectively required to keep round-trip latency under a second.

    Can I use GPT-4 or Claude instead of a self-hosted LLM?
    Yes — nothing about this architecture requires an open-weight model. Swapping the query_llm function to call an API instead of Ollama works fine; you just give up the cost and data-residency benefits of full self-hosting for that piece of the pipeline.

    How do I handle interruptions when the caller talks over the agent?
    You need voice activity detection (VAD) running continuously on the incoming stream, and the orchestrator must be able to cancel an in-flight TTS response the moment new caller speech is detected. Libraries like webrtcvad or Silero VAD handle the detection; the cancellation logic is on you.

    What’s the biggest latency bottleneck in this stack?
    Usually the LLM generation step, especially if you wait for a full completion before starting TTS. Streaming tokens from the LLM into TTS as they arrive, rather than waiting for the full response, is the single biggest latency win available.

    Is this legal for handling customer calls?
    Generally yes, but call recording consent laws vary by state and country — some require two-party consent before recording. Check local requirements and play a disclosure message before recording begins.

    How many concurrent calls can one GPU handle?
    Depends heavily on model size and GPU memory, but a single mid-range GPU (e.g., an RTX 4090 or A10) running faster-whisper medium plus a small quantized LLM can typically handle 8-15 concurrent calls before latency degrades noticeably.

    Wrapping Up

    Self-hosting AI phone agents is a legitimate infrastructure project, not just a wrapper around an API key — you’re building a real-time audio pipeline with the same latency and reliability demands as VoIP itself. Start with the Docker Compose stack above on a single GPU box, get the conversation loop working end to end, and only invest in horizontal scaling once you have actual call volume to justify it.

  • Build an AI Agent: Python, Docker & Deployment Guide

    How to Build an AI Agent: A Practical Developer’s Guide

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you’ve spent any time on developer Twitter or Hacker News in the last year, you’ve seen the term “AI agent” thrown around constantly. Most of the explanations are either too abstract (“it’s software that thinks!”) or too shallow (a single API call wrapped in a for-loop). This guide skips the hype and shows you how to build an AI agent that actually does something useful, then run it in production like any other service in your stack — containerized, monitored, and secured.

    We’ll build a real agent in Python, containerize it with Docker, and deploy it to a VPS. By the end, you’ll understand the architecture well enough to build your own agents for DevOps automation, log triage, or customer support.

    What Is an AI Agent, Really?

    An AI agent is a program that uses a large language model (LLM) as its reasoning engine, but unlike a chatbot, it doesn’t just generate text — it takes actions. It calls functions, hits APIs, reads files, queries databases, and uses the results to decide what to do next. The defining trait is the loop: observe, reason, act, repeat — until the task is done or a stopping condition is hit.

    Agents vs. Simple Chatbots

    A chatbot answers one prompt and stops. An agent:

  • Breaks a goal into sub-tasks
  • Chooses which tool to call for each sub-task (a shell command, an API, a search query)
  • Evaluates the tool’s output and decides the next step
  • Keeps state across multiple steps until the goal is satisfied
  • If you’ve used GitHub’s Copilot Workspace or any coding assistant that can run commands and fix its own errors, you’ve already used an agent. The same pattern applies to server automation, incident response, and content pipelines — which is exactly the kind of workload this site’s readers deal with daily.

    Core Components of an AI Agent

    Every agent, regardless of framework, is built from the same four pieces:

  • A model — the LLM that does the reasoning (GPT-4, Claude, Llama, etc.)
  • A tool set — functions the agent is allowed to call (shell exec, HTTP requests, DB queries)
  • Memory — short-term context for the current task, and optionally long-term storage for prior runs
  • A control loop — the code that ties it all together and decides when to stop
  • The Reasoning Loop

    The control loop is the part most tutorials gloss over. In practice it’s a simple while loop: send the model the current state, parse its response for a tool call, execute that tool, feed the result back in, repeat. The loop terminates when the model returns a final answer instead of a tool call, or when you hit a max-iteration safety limit (always set one — an ungoverned loop can burn through API credits fast).

    Tools and Function Calling

    Modern LLM APIs support structured “function calling,” where you describe available functions in JSON Schema and the model returns a structured call instead of free text. This is far more reliable than parsing natural language for commands.

    Memory and State

    For short tasks, an in-memory list of messages is enough. For anything long-running — like an agent that monitors your infrastructure over days — you’ll want persistent storage. Redis works well for this: fast, simple key-value storage for conversation state and tool results.

    Building Your First AI Agent in Python

    Here’s a minimal but functional agent that can execute shell commands and read files — useful as a base for a DevOps automation bot. It uses OpenAI’s function-calling API, but the same pattern works with Anthropic’s Claude API or any local model server.

    import json
    import subprocess
    from openai import OpenAI
    
    client = OpenAI()
    
    tools = [
        {
            "type": "function",
            "function": {
                "name": "run_shell_command",
                "description": "Run a read-only shell command and return its output",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "command": {"type": "string"}
                    },
                    "required": ["command"]
                }
            }
        }
    ]
    
    ALLOWED_COMMANDS = ("df", "uptime", "free", "docker ps", "systemctl status")
    
    def run_shell_command(command: str) -> str:
        if not command.startswith(ALLOWED_COMMANDS):
            return "Error: command not permitted by allowlist"
        result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=10)
        return result.stdout or result.stderr
    
    def run_agent(user_goal: str, max_steps: int = 6):
        messages = [{"role": "user", "content": user_goal}]
    
        for _ in range(max_steps):
            response = client.chat.completions.create(
                model="gpt-4o",
                messages=messages,
                tools=tools,
            )
            message = response.choices[0].message
            messages.append(message)
    
            if not message.tool_calls:
                return message.content  # final answer
    
            for call in message.tool_calls:
                args = json.loads(call.function.arguments)
                output = run_shell_command(args["command"])
                messages.append({
                    "role": "tool",
                    "tool_call_id": call.id,
                    "content": output,
                })
    
        return "Max steps reached without a final answer."
    
    if __name__ == "__main__":
        print(run_agent("Check disk usage and container status, summarize any issues"))

    Note the ALLOWED_COMMANDS allowlist. This is not optional — an agent with unrestricted shell access is a remote code execution vulnerability wearing a trench coat. Always constrain what tools your agent can actually invoke.

    If you’d rather not hand-roll the loop, frameworks like LangChain or LlamaIndex handle tool orchestration, retries, and memory for you, at the cost of extra abstraction layers you’ll eventually need to peel back to debug anything.

    Deploying Your AI Agent with Docker

    Once the agent works locally, containerize it so it runs identically in staging and production — the same reasoning we cover in our Docker Compose guide for multi-container apps applies here.

    Containerizing the Agent

    FROM python:3.12-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY agent.py .
    
    # Never bake API keys into the image — inject at runtime
    ENV OPENAI_API_KEY=""
    
    USER nobody
    CMD ["python", "agent.py"]

    Build and run it with the key injected as an environment variable, not hardcoded:

    docker build -t my-ai-agent .
    docker run --rm 
      -e OPENAI_API_KEY="$OPENAI_API_KEY" 
      --memory=512m 
      --cpus=1 
      my-ai-agent

    The --memory and --cpus flags matter more for agents than for typical web services — a runaway reasoning loop can spike CPU usage if your max-step guard fails, so hard resource limits are cheap insurance.

    Running as a Persistent Service

    For an agent that needs to stay alive and respond to triggers (webhooks, cron, a message queue), wrap it in a small FastAPI service instead of a one-shot script, and run it under docker-compose alongside Redis for state:

    services:
      agent:
        build: .
        restart: unless-stopped
        environment:
          - OPENAI_API_KEY=${OPENAI_API_KEY}
          - REDIS_URL=redis://redis:6379
        depends_on:
          - redis
    
      redis:
        image: redis:7-alpine
        volumes:
          - redis-data:/data
    
    volumes:
      redis-data:

    Hosting Your AI Agent in Production

    An agent that calls external tools and possibly touches production infrastructure deserves a properly isolated VPS, not a shared dev box. A basic 2-vCPU / 4GB droplet from DigitalOcean is enough for most single-agent workloads, and their managed Redis add-on saves you from running your own. If you’re optimizing for cost-per-vCPU on long-running background workers, Hetzner cloud instances are consistently cheaper for the same specs — a detail we go into in our VPS cost comparison guide.

    Once deployed, you need visibility into whether the agent is actually alive and completing tasks, not silently stuck in a retry loop. BetterStack uptime and log monitoring can alert you the moment your agent’s health-check endpoint stops responding, which matters a lot more for autonomous services than for a static website — nobody’s refreshing a page to notice an agent has hung.

    Securing Your AI Agent

    Agents with tool access are a bigger attack surface than a typical CRUD app, because a cleverly crafted input (prompt injection) can trick the model into calling a tool it shouldn’t. Bake these controls in from day one:

  • Allowlist tools and commands explicitly — never let the model construct arbitrary shell strings
  • Run the container as a non-root user with no unnecessary filesystem access
  • Set hard timeouts and max-iteration limits on the reasoning loop
  • Log every tool call and its output so you can audit what the agent actually did
  • Keep API keys in environment variables or a secrets manager, never in the image or source control
  • Rate-limit external API calls the agent can trigger to avoid runaway cost or abuse
  • If your agent is public-facing (say, behind a webhook), put it behind Cloudflare for DDoS protection and WAF rules before traffic reaches your container — this is standard practice for any exposed endpoint, agent or not.

    Wrapping Up

    Building an AI agent isn’t fundamentally different from building any other backend service: you still need containerization, resource limits, monitoring, and a security model. The LLM is just the decision-making component in the middle. Start small — a single-tool agent solving one narrow problem — before reaching for multi-agent frameworks or long-running autonomous systems. Get the loop, the tool allowlist, and the deployment pipeline right first; complexity can come later once you trust the foundation.

    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do I need a framework like LangChain to build an AI agent?
    No. For a single-purpose agent with a handful of tools, a plain function-calling loop (as shown above) is easier to debug and has fewer moving parts. Frameworks earn their keep once you’re managing many agents, complex memory, or multi-step planning across sessions.

    Which LLM should I use for an agent?
    GPT-4o and Claude models both support reliable function calling and handle multi-step reasoning well. For cost-sensitive, high-volume agents, smaller or open-source models (Llama 3, Mistral) can work if the tool set is narrow and well-defined — test accuracy on your specific tasks before committing.

    How do I stop an agent from running forever or looping?
    Always cap iterations with a max_steps counter and enforce per-call timeouts on any tool the agent invokes. Combine this with container-level CPU and memory limits so a stuck loop can’t consume unbounded resources.

    Is it safe to let an agent run shell commands on my server?
    Only with a strict allowlist of specific commands, run as a non-root, non-privileged user, ideally inside an isolated container with no access to secrets it doesn’t need. Never give an agent unrestricted shell=True execution against production.

    Can I run an AI agent without paying for a cloud LLM API?
    Yes — self-hosted models via Ollama or a GPU VPS can replace the OpenAI/Anthropic API for many agent workloads, at the cost of managing your own inference infrastructure and generally lower reasoning quality on complex tool-use tasks.

    How much does it cost to run an AI agent in production?
    Costs split into two buckets: LLM API usage (billed per token, scales with loop iterations) and hosting (a small VPS is usually $10-40/month). Set hard iteration limits and log token usage per run so costs stay predictable as usage grows.

  • Building AI Agents: A Practical DevOps Guide

    Building AI Agents: A Developer’s Guide to Autonomous Workflows

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Every few years a new abstraction shows up in software engineering that changes how we ship products. Containers did it for deployment. Kubernetes did it for orchestration. Now agentic AI is doing it for automation. If you’ve spent any time on engineering Twitter or Hacker News in the last year, you’ve seen the term thrown around constantly, but most of the content out there is either hand-wavy product marketing or academic papers you need a PhD to parse.

    This guide skips both. We’re going to treat building AI agents like any other DevOps problem: define the architecture, write the code, containerize it, deploy it, and monitor it in production. By the end you’ll have a working agent running in Docker, with a clear path to scaling it on real infrastructure.

    What Is an AI Agent, Actually?

    An AI agent is a program that uses a large language model (LLM) not just to generate text, but to make decisions in a loop: observe the current state, decide on an action, execute that action (often by calling a tool or API), and then observe the result before deciding again. The key difference from a simple chatbot is autonomy — an agent can chain multiple steps together without a human clicking “send” after every message.

    Agents vs. Simple LLM API Calls

    A lot of people confuse “calling GPT-4 in a script” with “building an agent.” They’re not the same thing. A single API call is stateless: you send a prompt, you get a completion, done. An agent wraps that call in a loop with memory, tool access, and a stopping condition. Concretely, an agent architecture usually includes:

  • A planner that breaks a goal into steps
  • A tool layer that lets the model call functions (search the web, query a database, hit an API)
  • A memory store that persists context across steps (often a vector database)
  • An executor loop that keeps iterating until the goal is met or a max-step limit is hit
  • If your script doesn’t have at least a loop and a tool layer, you’ve built a prompt wrapper, not an agent. That distinction matters when you’re scoping infrastructure — agents are stateful, long-running processes, which changes how you deploy and monitor them compared to a stateless API endpoint.

    Why Self-Hosting Matters for Agent Workloads

    Most tutorials assume you’ll run your agent on a managed platform or a laptop. Neither works well in production. Managed agent platforms lock you into their pricing and rate limits, and a laptop obviously can’t run 24/7. If your agent needs to poll a queue, watch a filesystem, or run scheduled tasks, you need a real server.

    This is also where cost control becomes a real concern. LLM API calls aren’t free, and a poorly bounded agent loop can burn through your token budget in minutes if it gets stuck retrying a failed tool call. Self-hosting the orchestration layer — while still calling out to an LLM API — gives you full control over rate limiting, retry logic, and logging, none of which you get with a black-box SaaS agent builder.

    Building a Simple AI Agent in Python

    Let’s build something real. We’ll use the OpenAI API for the model calls and keep the orchestration logic in plain Python so you can see exactly what’s happening at each step — no heavy framework required to start.

    First, set up your environment:

    mkdir agent-demo && cd agent-demo
    python3 -m venv venv
    source venv/bin/activate
    pip install openai requests python-dotenv

    Now create agent.py:

    import os
    import json
    import requests
    from openai import OpenAI
    from dotenv import load_dotenv
    
    load_dotenv()
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    
    def get_weather(city: str) -> str:
        """Tool: fetch current weather for a city."""
        resp = requests.get(f"https://wttr.in/{city}?format=3", timeout=5)
        return resp.text.strip()
    
    TOOLS = [
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "Get current weather for a given city",
                "parameters": {
                    "type": "object",
                    "properties": {"city": {"type": "string"}},
                    "required": ["city"],
                },
            },
        }
    ]
    
    def run_agent(user_goal: str, max_steps: int = 5):
        messages = [{"role": "user", "content": user_goal}]
    
        for step in range(max_steps):
            response = client.chat.completions.create(
                model="gpt-4o-mini",
                messages=messages,
                tools=TOOLS,
            )
            message = response.choices[0].message
            messages.append(message)
    
            if not message.tool_calls:
                return message.content
    
            for call in message.tool_calls:
                args = json.loads(call.function.arguments)
                if call.function.name == "get_weather":
                    result = get_weather(args["city"])
                else:
                    result = "Unknown tool"
    
                messages.append({
                    "role": "tool",
                    "tool_call_id": call.id,
                    "content": result,
                })
    
        return "Max steps reached without a final answer."
    
    if __name__ == "__main__":
        print(run_agent("What's the weather like in Lisbon right now?"))

    This is the entire skeleton of an agent: a loop, a tool the model can call, and a hard stop at max_steps so a broken loop can’t run forever and rack up API charges. Every production agent framework — LangChain, CrewAI, AutoGen — is a more elaborate version of this same pattern. Understanding this loop first will save you hours of debugging once you move to a framework, because you’ll actually know what’s happening under the abstraction.

    Adding Memory with a Vector Store

    Once your agent needs to recall information across sessions, a plain message list isn’t enough. Most production agents pair the loop above with a vector database like Chroma or Pinecone to store and retrieve embeddings of past interactions or documents. The pattern is straightforward: embed incoming text, store it with metadata, and query the store for relevant context before each LLM call. We won’t build the full retrieval pipeline here, but keep in mind that memory is a separate concern from the agent loop — don’t couple them tightly, or you’ll struggle to swap vector stores later.

    Containerizing Your Agent with Docker

    Once the logic works locally, package it so it runs identically anywhere. If you’re new to multi-service setups, our guide to Docker Compose fundamentals covers the basics this section builds on.

    FROM python:3.12-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY agent.py .
    
    ENV PYTHONUNBUFFERED=1
    
    CMD ["python", "agent.py"]

    Running a Multi-Agent Stack with Docker Compose

    Real-world setups rarely involve a single agent. You’ll typically have an agent process, a vector database for memory, and maybe a Redis instance for task queuing. Here’s a docker-compose.yml that ties them together:

    version: "3.9"
    services:
      agent:
        build: .
        env_file: .env
        depends_on:
          - redis
          - chroma
        restart: unless-stopped
    
      redis:
        image: redis:7-alpine
        restart: unless-stopped
    
      chroma:
        image: chromadb/chroma:latest
        ports:
          - "8000:8000"
        volumes:
          - chroma-data:/chroma/chroma
        restart: unless-stopped
    
    volumes:
      chroma-data:

    Bring it up with docker compose up -d --build, and you have an isolated, reproducible agent stack that behaves the same on your laptop as it does on a production VPS. This matters more than it sounds — LLM agent behavior can be subtly sensitive to Python and library versions, and Docker eliminates the “works on my machine” class of bugs entirely.

    Monitoring and Scaling Agents in Production

    Agents fail differently than typical web services. Instead of a clean 500 error, an agent might silently loop, hallucinate a tool call that doesn’t exist, or quietly burn through your API budget over a weekend while nobody’s watching. Standard uptime monitoring isn’t enough here — you need to track step counts, token usage, and tool-call failure rates.

    Logging Every Step for Debuggability

    At minimum, log the full message history for every agent run, not just the final output. When an agent misbehaves, the failure is almost always buried three or four steps back in the transcript, not in the final response. Structure your logs as JSON so they’re easy to query later:

    import logging
    import json
    
    logger = logging.getLogger("agent")
    
    def log_step(step: int, message: dict):
        logger.info(json.dumps({"step": step, "message": message}))

    Ship those logs somewhere durable rather than relying on docker logs, which rotates and disappears. For teams that don’t want to run their own ELK stack, a hosted option like BetterStack gives you centralized log aggregation and uptime alerting without the operational overhead — genuinely useful once you have more than one agent running unattended. If you’re comparing observability options more broadly, see our breakdown of self-hosted monitoring stacks for the tradeoffs.

    Setting Hard Limits to Control Cost

    Beyond max_steps, add a token budget check before every LLM call and kill the run if it’s exceeded. This single guardrail has saved more than a few teams from a surprise five-figure API bill after an agent got stuck in a retry loop over a long weekend.

    Choosing Infrastructure for Your Agent Workloads

    Agents that run continuously — polling queues, watching webhooks, executing scheduled jobs — need a server, not a laptop or a serverless function with a 15-minute timeout. A small VPS is more than enough to start. DigitalOcean droplets are a solid default if you want a simple, well-documented control panel and predictable pricing while you’re iterating on the architecture. If you’re optimizing for cost once your agent stack stabilizes, Hetzner cloud instances offer significantly cheaper compute per dollar for the same workload, which adds up once you’re running multiple agents around the clock.

    Whichever provider you pick, harden the box before you deploy anything — our Linux server hardening checklist is a good starting point, since an agent with API keys and tool access on a poorly secured server is a bigger liability than a typical web app.

    Security Considerations for Autonomous Agents

    An agent that can execute code, hit arbitrary URLs, or write to a filesystem is functionally similar to giving a script root-ish access to your infrastructure. A few non-negotiables:

  • Never let an agent execute raw shell commands from model output without a strict allowlist of permitted operations
  • Scope API keys narrowly — a tool that only needs read access shouldn’t hold a key with write permissions
  • Sandbox any code-execution tools in a disposable container, not the host running your agent process
  • Rate-limit and log every outbound HTTP call the agent makes, since a compromised or confused agent can be tricked into exfiltrating data through a tool call
  • Treat all tool outputs as untrusted input — a malicious webpage or API response can attempt prompt injection against your own agent
  • That last point deserves emphasis: prompt injection through tool results is one of the most common real-world agent vulnerabilities, and it’s easy to overlook because it doesn’t look like a traditional security bug.

    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    What’s the difference between building AI agents and using a chatbot API?
    A chatbot API call is a single stateless request-response exchange. Building AI agents involves wrapping model calls in a loop with memory, tool access, and a decision-making process that can span multiple steps without human input at each stage.

    Do I need a framework like LangChain to build an agent?
    No. As shown in the Python example above, you can build a working agent loop with plain code and the OpenAI SDK. Frameworks add convenience for complex multi-agent orchestration, but understanding the raw loop first makes debugging framework-based agents much easier.

    How much does it cost to run an AI agent in production?
    Costs depend on token usage per step and how many steps your loop runs before stopping. A well-bounded agent with a hard max_steps limit and token budget checks typically costs a few cents to a few dollars per run, depending on the model. Unbounded loops are the main cause of runaway bills.

    Can I run AI agents entirely on my own hardware without cloud APIs?
    Yes, using local models served through tools like Ollama or vLLM instead of a hosted API. This removes per-token costs but requires GPU hardware and generally produces weaker reasoning than frontier hosted models, so it’s a tradeoff between cost and capability.

    Is Docker required to deploy an AI agent?
    Not strictly, but it’s strongly recommended. Agent behavior can be sensitive to Python and dependency versions, and Docker guarantees your local testing environment matches production exactly, which matters more for agents than for typical stateless services.

    How do I prevent an agent from getting stuck in an infinite loop?
    Always enforce a hard max_steps limit in your executor loop, plus a token budget check before each LLM call. Log every step so you can diagnose why a loop got stuck rather than just killing and restarting it blindly.

    Wrapping Up

    Building AI agents isn’t magic — it’s a loop, a tool layer, some memory, and a lot of the same DevOps discipline you’d apply to any other production service: containerize it, monitor it, log everything, and put hard limits on anything that costs money per call. Start with the plain Python loop above, containerize it with Docker once it works, and deploy it on a small VPS you actually control. That gets you further, faster, than reaching for a heavyweight framework before you understand what it’s abstracting away.

  • AI Agent Companies: A 2026 DevOps Buyer’s Guide

    AI Agent Companies: A DevOps Guide to Evaluating and Self-Hosting Agent Platforms

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Every week another one of the AI agent companies announces a new framework, SDK, or “autonomous” platform. For developers and sysadmins who actually have to run this stuff in production, the marketing noise is less useful than a straight answer to two questions: who is actually building the infrastructure layer, and what does it take to self-host an agent stack without setting your cloud bill on fire?

    This post breaks down the landscape of AI agent companies from an infrastructure perspective — model providers, hyperscaler platforms, and open-source frameworks — and walks through a real Docker-based deployment you can run on your own VPS.

    The Three Types of AI Agent Companies (and Why That Matters for Infra)

    Not all AI agent companies solve the same problem. Before you pick a vendor, it helps to understand which category they fall into, because that determines how much infrastructure work lands on your plate.

    1. Model Providers Bolting On Agent Tooling

    Companies like OpenAI and Anthropic sell the underlying language model and layer agent primitives — tool calling, memory, planning loops — on top of their APIs. You don’t manage compute for inference, but you’re locked into their rate limits, pricing, and uptime. This is the fastest path to a working prototype and the worst path if you need predictable costs at scale.

    2. Cloud Hyperscaler Agent Platforms

    AWS Bedrock Agents, Google’s Vertex AI Agent Builder, and Azure AI Studio wrap orchestration, retrieval, and observability around foundation models inside their existing cloud ecosystems. These make sense if you’re already deep in one cloud’s IAM and networking stack, but they add a layer of proprietary configuration that doesn’t travel well if you ever want to migrate.

    3. Open-Source Agent Frameworks You Self-Host

    Projects like LangGraph and CrewAI give you the orchestration logic — state machines, agent-to-agent handoffs, tool routing — as code you run yourself, typically against whichever model API or local inference server you choose. This is the category most relevant to a DevOps-focused audience, because the entire deployment, scaling, and monitoring burden is yours. It’s also the only option that lets you swap the underlying model without rewriting your agent logic.

    For teams that already run their own container infrastructure, this third category is usually the right call — you keep control of cost, data residency, and uptime instead of inheriting someone else’s SLA.

    Evaluating AI Agent Companies: A DevOps Checklist

    Before signing up for any platform or pulling in a framework, run through this checklist:

  • Deployment model — Is it a hosted SaaS, a managed cloud service, or a self-hostable open-source project?
  • State and memory storage — Where does conversation and task state live, and can you point it at your own Postgres or Redis instance?
  • Rate limits and quotas — Are limits per-API-key, per-org, or negotiable at scale?
  • Observability hooks — Does it expose OpenTelemetry traces, structured logs, or webhooks you can pipe into your existing monitoring stack?
  • Model portability — Can you swap GPT-4-class models for a self-hosted Llama or Mistral deployment without rewriting the agent graph?
  • Data egress and compliance — Where is data processed, and does that satisfy your regulatory requirements?
  • If a vendor can’t give you clear answers on the first three, treat it as a prototype tool, not a production dependency.

    Deploying an Open-Source Agent Stack with Docker

    Here’s a minimal, realistic setup: a self-hosted agent orchestrator, a vector store for retrieval, and a Postgres instance for state, all wired together with Docker Compose. This mirrors the kind of stack you’d run for an internal support-ticket agent or a documentation Q&A bot.

    # docker-compose.yml
    version: "3.9"
    
    services:
      agent-orchestrator:
        image: python:3.11-slim
        working_dir: /app
        volumes:
          - ./agent:/app
        command: bash -c "pip install -r requirements.txt && python agent_server.py"
        environment:
          - OPENAI_API_KEY=${OPENAI_API_KEY}
          - DATABASE_URL=postgresql://agent:agent@postgres:5432/agentdb
          - VECTOR_DB_URL=http://qdrant:6333
        ports:
          - "8080:8080"
        depends_on:
          - postgres
          - qdrant
        restart: unless-stopped
    
      postgres:
        image: postgres:16-alpine
        environment:
          - POSTGRES_USER=agent
          - POSTGRES_PASSWORD=agent
          - POSTGRES_DB=agentdb
        volumes:
          - pgdata:/var/lib/postgresql/data
        restart: unless-stopped
    
      qdrant:
        image: qdrant/qdrant:latest
        volumes:
          - qdrantdata:/qdrant/storage
        restart: unless-stopped
    
    volumes:
      pgdata:
      qdrantdata:

    Bring it up with:

    export OPENAI_API_KEY=sk-your-key-here
    docker compose up -d
    docker compose logs -f agent-orchestrator

    This gives you a working orchestrator with persistent state and a vector store, all running on a single VPS. If you haven’t set up a production-grade Compose file before, our Docker Compose production guide covers health checks, restart policies, and secrets handling in more depth.

    Once you outgrow a single host — multiple agent workers, GPU nodes for local inference, autoscaling based on queue depth — you’ll want to move this onto an orchestrator. Our comparison of Kubernetes vs Docker Swarm walks through which one makes sense for a small ops team versus a larger platform engineering group.

    Monitoring Your Agent Infrastructure

    Agent workloads fail differently than typical web services — a stuck reasoning loop, a runaway tool call, or a silent API timeout can burn through budget without ever throwing a 500 error. At minimum, track:

  • Token usage per agent run, broken out by model
  • Tool call latency and error rate
  • Queue depth if you’re running async agent workers
  • Cost per completed task, not just per API call
  • A lightweight way to get alerting on these metrics without building a custom dashboard from scratch is to pipe structured logs into an uptime and monitoring service. BetterStack handles log aggregation and incident alerting well for this kind of workload and integrates cleanly with a Docker-based stack — worth checking out if you don’t already have something in place.

    Securing Agent Workloads

    Agents that can call tools — hitting internal APIs, writing to a database, executing shell commands — are a meaningfully larger attack surface than a plain chat interface. A few non-negotiables:

  • Run tool-execution sandboxes in isolated containers, never in the same process as the orchestrator
  • Scope API keys and database credentials per-agent, not shared across your whole fleet
  • Log every tool invocation with full arguments for post-incident review
  • Treat any user-supplied text that reaches a tool call as untrusted input, the same way you’d treat a raw SQL query
  • This isn’t optional hardening — prompt injection attacks that trick an agent into calling a destructive tool are a documented and increasingly common attack pattern, and the fix is standard application security discipline, not a special AI-specific tool.

    Cost Comparison: Managed vs Self-Hosted

    Managed AI agent platforms bill per-token and per-API-call, and those costs compound fast once an agent starts looping through multi-step reasoning chains. Self-hosting the orchestration layer doesn’t eliminate model costs if you’re still calling a hosted LLM API, but it does let you cap infrastructure spend to a predictable VPS bill. A mid-tier server from a provider like Hetzner or DigitalOcean running the Compose stack above typically costs less per month than a moderate volume of managed-platform API calls, especially once you add caching and rate-limiting in front of the model calls yourself. If you’re still comparing hosts, our VPS hosting comparison for 2026 has current pricing and benchmark numbers.

    Choosing the Right Approach for Your Team

    If you’re a solo developer or small team prototyping an idea, start with a hosted API and an open-source framework like LangGraph or CrewAI — you get to production faster and can always migrate the orchestration layer later since it’s just code you control. If you’re running this at company scale with compliance requirements, the hyperscaler agent platforms buy you integration with existing IAM and audit tooling at the cost of portability. Either way, keep the orchestration logic decoupled from the specific model provider — that’s the one decision that’s expensive to reverse later.

    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    What’s the difference between an AI agent company and a plain LLM API provider?
    An LLM API provider (like a raw OpenAI or Anthropic completions endpoint) just returns text. AI agent companies add orchestration on top — tool calling, multi-step planning, memory, and often a hosted runtime to execute agent loops, so the model can take actions rather than just respond to a single prompt.

    Can I self-host an AI agent framework without paying for a managed platform?
    Yes. Frameworks like LangGraph, CrewAI, and AutoGen are open source and run as regular Python processes — you only pay for the underlying model API calls (or your own inference hardware) and whatever compute hosts the orchestrator itself.

    Do I need a GPU to run an AI agent stack?
    Only if you’re running the language model itself locally. If you’re calling a hosted model API for inference and just self-hosting the orchestration and state layer, a standard CPU-based VPS is sufficient.

    How do I stop an AI agent from getting stuck in an infinite reasoning loop?
    Set a hard maximum step count and a wall-clock timeout at the orchestrator level, and log every intermediate step so you can debug loops after the fact rather than relying on the model to self-terminate.

    Are AI agent companies a security risk if agents can execute code or call APIs?
    Yes, if tool execution isn’t sandboxed. Treat every tool call as you would an untrusted API request — isolate execution, scope credentials tightly, and log all inputs and outputs for auditing.

    Which AI agent company should I pick for a production deployment?
    There’s no single right answer — it depends on whether you need vendor-managed infrastructure (hyperscaler platforms), fast prototyping (hosted APIs with agent SDKs), or full control over cost and data (self-hosted open-source frameworks). Most teams that already run their own Docker infrastructure get the best cost-to-control ratio from the self-hosted route.

    The AI agent space is moving fast, but the infrastructure fundamentals haven’t changed: containerize your services, monitor token and tool-call costs like you’d monitor any other metered resource, and keep your orchestration logic portable across model providers. Do that, and it won’t matter much which of the current crop of AI agent companies wins the marketing war next quarter.

  • Docker Compose Log Command: A Complete Debugging Guide

    Docker Compose Log Command: A Complete Debugging Guide

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If your containers are misbehaving, the first place to look is the log output — and the docker compose logs command is how you get it. This guide covers everything from basic syntax to advanced filtering, log driver configuration, and shipping logs to a centralized platform for production monitoring.

    Whether you’re running a single Compose stack on your laptop or a multi-service application in production, mastering the docker compose log workflow will save you hours of guesswork when something breaks.

    This article assumes you already have Docker and Docker Compose installed and a working docker-compose.yml — if you’re setting up a stack from scratch, get the containers running first with docker compose up -d, then come back here once you need to actually read what they’re doing. Everything below works identically whether your compose file defines two services or twenty, and the same flags apply whether you’re debugging on a local dev machine or SSH’d into a remote host.

    What Is the docker compose logs Command?

    docker compose logs is a subcommand of the Docker Compose CLI that aggregates and displays the stdout/stderr output from every container defined in your docker-compose.yml file (or a specific service, if you name one). Unlike docker logs, which only works against a single container, docker compose logs understands your entire stack — it knows which containers belong to which project and can interleave their output with service-name prefixes so you can tell at a glance which container printed what.

    This matters because most real applications aren’t a single container. A typical stack might include a web server, a database, a cache, and a background worker — four separate log streams that you’d otherwise have to tail individually with four terminal windows.

    Basic Syntax and Options

    The command follows this pattern:

    docker compose logs [OPTIONS] [SERVICE...]

    Run it with no arguments from the directory containing your docker-compose.yml and you’ll get the full log history for every service in the project:

    docker compose logs

    To scope it to one or more services, just name them:

    docker compose logs web db

    Following Logs in Real Time

    Static output is useful for a quick check, but during active debugging you want a live stream. Use -f or --follow:

    docker compose logs -f web

    This behaves like tail -f — new log lines appear as they’re written, and the command keeps running until you press Ctrl+C. This is the single most-used flag in the docker compose logs toolkit, and it’s usually the first thing you run after docker compose up -d.

    Filtering Logs by Service

    When you’re running several services and only care about one, always scope by service name rather than grepping through the combined output:

    docker compose logs -f --tail=100 api

    You can also pass multiple service names at once to watch related containers together, which is handy when debugging an interaction between, say, a frontend proxy and its backend API.

    Limiting Log Output with –tail

    By default, docker compose logs prints the entire buffered history, which can be enormous for long-running containers. The --tail flag limits output to the last N lines:

    docker compose logs --tail=50 web

    Combine it with -f to see recent context and then continue following:

    docker compose logs -f --tail=50 web

    Advanced Log Filtering Techniques

    Timestamps and Time Ranges

    Add -t (or --timestamps) to prefix every line with an ISO 8601 timestamp — essential when correlating log events with an incident timeline:

    docker compose logs -t web

    To narrow output to a specific window, use --since and --until:

    docker compose logs --since 2026-07-08T10:00:00 --until 2026-07-08T10:15:00 web

    You can also use relative durations like --since 30m or --since 2h, which is often faster than typing out a full timestamp when you’re chasing something that just happened.

    Combining Logs with grep

    docker compose logs doesn’t have a built-in search flag, but because it writes to stdout, you can pipe it straight into standard Unix tools:

    docker compose logs --no-color web | grep -i "error"

    The --no-color flag strips ANSI color codes so your grep matches aren’t broken up by escape sequences. This pattern — Compose logs piped into grep, awk, or jq (for JSON-formatted app logs) — covers the vast majority of manual debugging you’ll ever need to do.

    Handling Logs for Scaled Services

    If you’re running multiple replicas of a service with docker compose up --scale worker=3, docker compose logs worker interleaves output from all three containers, each prefixed with its own container name so you can tell them apart. This is useful for spotting whether a bug affects every replica or just one — a single misbehaving replica often points to a stuck connection or a stale cache entry rather than a code bug. If you need to isolate a single replica’s output, use docker ps to find its container ID and switch to plain docker logs <container_id> instead.

    Configuring Log Drivers in Docker Compose

    By default, Docker uses the json-file logging driver, which writes each container’s output to a JSON file on disk. That’s fine for development, but it has two problems in production: unbounded log files can fill your disk, and json-file logs disappear if the host is replaced.

    You can configure log rotation and an alternate driver per service directly in your docker-compose.yml:

    services:
      web:
        image: myapp:latest
        logging:
          driver: json-file
          options:
            max-size: "10m"
            max-file: "3"

    This caps each container’s log file at 10 MB and keeps a maximum of 3 rotated files, which prevents runaway disk usage — a surprisingly common cause of production outages that has nothing to do with your application code.

    For teams that need durable, searchable logs, switching to a shipping-friendly driver like journald or syslog, or running a sidecar log forwarder, is the next step. That’s a bigger topic than this article can fully cover, but if you’re already tuning Docker networking for multi-container apps, log driver configuration belongs in the same pass.

    Centralizing Logs for Production

    docker compose logs is a local debugging tool — it reads whatever the log driver has retained on that specific host. That’s a real limitation once you’re running more than one server, since logs vanish when a container is removed or a host is rebuilt. For production stacks, you want logs shipped somewhere durable and searchable.

    A few practical options:

  • Log shipping agents like Filebeat, Fluentd, or Vector can tail the Docker log directory and forward entries to a central store.
  • Managed log platforms such as BetterStack give you searchable, alertable log aggregation without running your own Elasticsearch cluster — worth evaluating if you’re outgrowing docker compose logs -f as your primary debugging tool.
  • Cloud-native logging — if you’re hosting on a VPS, pairing your Compose stack with a provider like DigitalOcean makes it straightforward to attach block storage for log retention or spin up a dedicated logging droplet.
  • Structured logging — configure your application to emit JSON logs so downstream tools can parse fields instead of regex-matching plain text.
  • If you’re just getting started with Compose in general, our Docker Compose restart policies guide is a good companion piece — restart behavior and logging are usually the first two things you tune once a stack graduates from “works on my machine” to “runs in production.”

    For the official reference on every driver and option, the Docker documentation on logging drivers covers configuration syntax that’s easy to get subtly wrong, particularly around driver-specific options that Compose passes through without validation.

    Rotating Logs Automatically

    Log rotation deserves its own callout because it’s the most commonly skipped step. Without max-size and max-file set, json-file logs grow forever. On a busy service, that can mean gigabytes of logs eating disk space within days. Add rotation to every service in your Compose file, not just the noisy ones — the quiet services are the ones nobody remembers to check until the disk is full.

    Using docker compose logs in CI/CD Pipelines

    CI runners are another place docker compose logs earns its keep. When an integration test fails inside a containerized service, the test runner has usually already exited before you can attach a terminal. The fix is to dump logs as a post-failure step in your pipeline configuration, for example in a GitHub Actions job:

    - name: Dump logs on failure
      if: failure()
      run: docker compose logs --no-color > compose-output.log

    Running this on failure means you get the full container output attached to the CI job log, instead of a bare “test failed” message with no context. This one habit saves more debugging time than almost any other logging practice on this list.

    Common Issues and Troubleshooting

    A few problems come up often enough to call out specifically:

  • “No such service” error — you named a service that doesn’t exist in docker-compose.yml, or you’re running the command from the wrong directory. docker compose logs only sees services defined in the compose file in your current working directory (or the one passed via -f).
  • Logs appear empty or truncated — check the container’s log driver. If it’s set to none or a non-default driver like syslog without local buffering, docker compose logs won’t have anything to show, since it reads from the driver’s local output, not the application directly.
  • Color codes cluttering piped output — always add --no-color when piping into grep, awk, or a file.
  • Logs missing after container restart — by default, Docker keeps logs from the current container instance. If a container was recreated (not just restarted), previous logs may be gone unless you’re shipping them elsewhere.
  • Interleaved output is hard to read — when following multiple services at once, each line is prefixed with the service name and color-coded in an interactive terminal, but this can still get noisy with high-throughput services. Narrow to one service when you need to focus.
  • Comparing docker logs vs docker compose logs

    It’s worth being explicit about the difference, since the two commands look similar but aren’t interchangeable:

    docker logs my_container_1
    docker compose logs my_service

    docker logs operates on a single container by name or ID and knows nothing about Compose projects. docker compose logs operates on services defined in your compose file and can span multiple containers per service if you’re running replicas. If you only remember one rule, remember this: use docker compose logs when you’re thinking in terms of your application’s services, and docker logs when you’re debugging one specific container instance.

    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Q: How do I see logs for only one service in a multi-service Compose stack?
    A: Pass the service name as an argument: docker compose logs web. You can list multiple service names separated by spaces to watch several at once.

    Q: How do I follow logs in real time?
    A: Add the -f or --follow flag: docker compose logs -f. Press Ctrl+C to stop following.

    Q: Why does docker compose logs show no output at all?
    A: Usually because the container isn’t running, the log driver is set to something that doesn’t retain local output (like none), or you’re running the command outside the directory containing your docker-compose.yml.

    Q: Can I export docker compose logs to a file?
    A: Yes — redirect stdout: docker compose logs --no-color > app.log. Use --no-color first so the file doesn’t contain ANSI escape codes.

    Q: How do I limit how much log history is shown?
    A: Use --tail=N to show only the last N lines per service, or --since to restrict output to a time window.

    Q: Does docker compose logs work after a container has stopped?
    A: Yes, as long as the container hasn’t been removed. Docker retains the log file for stopped containers until they’re deleted with docker compose down or docker rm.

    Wrapping Up

    The docker compose logs command is the fastest path from “something’s wrong” to “here’s why.” Start with -f and --tail for everyday debugging, add --since and -t when you need to correlate events with a timeline, and don’t skip log rotation once you’re running anything in production. When local log files stop being enough, that’s your signal to invest in centralized, searchable logging rather than scrolling through terminal history.

  • AI Agent Platforms: Self-Hosting Guide for DevOps Teams

    AI Agent Platforms: A Practical Self-Hosting Guide for Developers

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    AI agent platforms have moved from research demos to production infrastructure. If you run a homelab, manage a small SaaS, or just want an LLM-powered agent that isn’t locked behind a third-party API with rate limits and unpredictable pricing, self-hosting is now a realistic option. This guide walks through what AI agent platforms actually are, how the major open-source options compare, and how to deploy one with Docker on a Linux VPS.

    What Is an AI Agent Platform?

    An AI agent platform is software that wraps a large language model (LLM) with tools, memory, and orchestration logic so it can complete multi-step tasks autonomously — calling APIs, running code, querying databases, or chaining multiple agents together. Unlike a simple chatbot, an agent platform typically provides:

  • A task/planning loop (the agent decides what to do next based on prior results)
  • Tool/function calling (web search, shell execution, API calls)
  • Memory persistence (vector databases or key-value stores)
  • Multi-agent orchestration (agents delegating subtasks to other agents)
  • An API or UI for triggering and monitoring runs
  • Popular options developers are self-hosting right now include AutoGen, CrewAI, LangGraph, and n8n (which added agent nodes on top of its existing workflow engine). Each has a different philosophy, and the right choice depends on whether you need strict orchestration control, rapid prototyping, or a low-code interface for non-developers on your team.

    Why Self-Host Instead of Using a SaaS Agent Platform

    Managed agent platforms (hosted versions of the tools above, or newer commercial offerings) are convenient, but they come with tradeoffs that matter for production DevOps work:

  • Data residency — agent runs often touch sensitive internal data (logs, customer records, infra credentials). Keeping that on infrastructure you control matters for compliance.
  • Cost predictability — SaaS agent platforms typically bill per-run or per-token on top of your LLM API costs, which compounds fast at scale.
  • Latency and reliability — self-hosted agents on your own network reduce round trips to third-party orchestration layers.
  • Customization — you can swap models, add custom tools, and modify the planning loop without waiting on a vendor’s roadmap.
  • If you’re already running services on a VPS provisioning workflow for other Dockerized apps, adding an agent platform is a natural extension rather than a new operational burden.

    Comparing the Major Self-Hostable Agent Frameworks

    Here’s a quick breakdown for developers evaluating options:

    | Platform | Best for | Orchestration model | Language |
    |—|—|—|—|
    | AutoGen | Multi-agent research, complex reasoning chains | Conversational agents talking to each other | Python |
    | CrewAI | Role-based agent teams (e.g., researcher + writer + reviewer) | Sequential/hierarchical crews | Python |
    | LangGraph | Fine-grained control over agent state machines | Graph-based state transitions | Python/TS |
    | n8n | Ops teams wanting a visual builder with agent nodes bolted onto existing automations | Workflow + agent hybrid | Node.js |

    For most DevOps teams already comfortable with Docker Compose, n8n or CrewAI are the fastest path to something running in production because both ship official container images and don’t require you to hand-roll a serving layer.

    Deploying an AI Agent Platform with Docker

    Below is a working example using CrewAI wrapped in a minimal FastAPI service, containerized and run behind Nginx on a Linux VPS. This pattern generalizes to any of the frameworks above — swap the Python service logic and keep the same container/reverse-proxy structure.

    Step 1: Project Structure and Dependencies

    mkdir agent-platform && cd agent-platform
    mkdir app
    touch app/main.py app/requirements.txt Dockerfile docker-compose.yml

    # app/requirements.txt
    fastapi==0.111.0
    uvicorn[standard]==0.30.1
    crewai==0.41.1
    openai==1.35.10
    python-dotenv==1.0.1

    Step 2: A Minimal Agent Service

    # app/main.py
    import os
    from fastapi import FastAPI
    from pydantic import BaseModel
    from crewai import Agent, Task, Crew
    
    app = FastAPI()
    
    researcher = Agent(
        role="Researcher",
        goal="Find accurate, current information on a given topic",
        backstory="An analyst who verifies facts before summarizing.",
        verbose=False,
    )
    
    class AgentRequest(BaseModel):
        topic: str
    
    @app.post("/run")
    def run_agent(req: AgentRequest):
        task = Task(
            description=f"Research the topic: {req.topic}. Return a concise summary.",
            agent=researcher,
            expected_output="A 3-paragraph summary with cited sources.",
        )
        crew = Crew(agents=[researcher], tasks=[task])
        result = crew.kickoff()
        return {"topic": req.topic, "result": str(result)}
    
    @app.get("/health")
    def health():
        return {"status": "ok"}

    Step 3: Dockerfile

    FROM python:3.11-slim
    
    WORKDIR /app
    COPY app/requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY app/ .
    
    EXPOSE 8000
    CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

    Step 4: docker-compose.yml with Environment Isolation

    version: "3.9"
    services:
      agent-api:
        build: .
        container_name: agent-platform
        restart: unless-stopped
        env_file:
          - .env
        ports:
          - "127.0.0.1:8000:8000"
        networks:
          - agent-net
    
    networks:
      agent-net:
        driver: bridge

    Note the API is bound to 127.0.0.1 only — you should never expose an agent’s raw API port directly to the internet. Put it behind a reverse proxy with TLS and authentication, which we cover next.

    # .env (never commit this file)
    OPENAI_API_KEY=sk-your-key-here

    Bring it up:

    docker compose build
    docker compose up -d
    curl -X POST http://127.0.0.1:8000/run -H "Content-Type: application/json" 
      -d '{"topic": "latest trends in container orchestration"}'

    Step 5: Reverse Proxy and Access Control

    Agent platforms execute arbitrary tool calls, which makes them a higher-value target than a typical CRUD API. At minimum, put Nginx in front with basic auth or an API key check, and restrict rate limits:

    server {
        listen 443 ssl;
        server_name agent.yourdomain.com;
    
        ssl_certificate /etc/letsencrypt/live/agent.yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/agent.yourdomain.com/privkey.pem;
    
        location / {
            auth_basic "Restricted";
            auth_basic_user_file /etc/nginx/.htpasswd;
            limit_req zone=agentlimit burst=10 nodelay;
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
        }
    }

    For production monitoring of the container’s health and resource usage, pair this with an uptime checker — we’ve covered lightweight monitoring stacks in our Docker container monitoring guide, which applies directly to agent workloads since they can spike CPU/memory unpredictably during long reasoning chains.

    Handling Secrets and Tool Permissions Safely

    Agent platforms frequently need credentials for the tools they call — a database connection string, a cloud API key, or shell access. Treat every credential passed to an agent as if it could be exfiltrated, because a sufficiently manipulated prompt can trick an agent into leaking data it has access to. Practical mitigations:

  • Run agent containers with a non-root user and a read-only filesystem where possible
  • Scope API keys to the minimum permissions the agent’s tools actually need
  • Never give an agent direct shell access to a container that also holds production secrets
  • Log every tool call the agent makes for auditability
  • Use short-lived tokens instead of long-lived API keys when the underlying service supports it
  • # Hardened Dockerfile additions
    RUN useradd -m -u 1001 agentuser
    USER agentuser

    If your agent platform needs to persist memory between runs, avoid storing it in plaintext on the container filesystem. A managed Postgres instance with pgvector, or a dedicated vector database, is a safer and more scalable choice than local disk.

    Scaling Beyond a Single VPS

    Once a single agent instance proves out, teams typically hit two walls: concurrent request handling and cost of LLM calls at scale. For the former, horizontal scaling behind a load balancer works the same way it does for any stateless API — just make sure agent memory/state lives in shared storage (Redis or Postgres), not in-process. For the latter, review your provider’s token pricing carefully; agentic workflows can call the LLM 5-20x per task depending on how many reasoning steps and tool calls are involved.

    If you’re evaluating where to host this stack, a VPS with dedicated vCPUs handles agent workloads noticeably better than burstable/shared instances, since reasoning loops are CPU and memory intensive during tool execution. Providers like DigitalOcean offer straightforward Docker-ready droplets that work well for this, and Hetzner is a solid budget option if you’re running this as a side project rather than a funded product.

    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Q: Do I need a GPU to self-host an AI agent platform?
    A: No, in most cases. The orchestration layer (CrewAI, AutoGen, LangGraph) runs fine on a standard CPU VPS since the actual LLM inference happens via API call to OpenAI, Anthropic, or another provider. You only need local GPU compute if you’re also self-hosting the underlying model.

    Q: Which AI agent platform is easiest for a first deployment?
    A: CrewAI or n8n. Both have official Docker images and require less boilerplate than AutoGen or LangGraph, which expose more low-level control but demand more setup.

    Q: Is it safe to give an agent shell access on my server?
    A: Only in an isolated, disposable container with no access to production secrets or networks. Treat shell-enabled agents the same way you’d treat an untrusted CI job.

    Q: How much does it cost to run an AI agent platform in production?
    A: Infrastructure cost is usually small (a $10-40/month VPS is plenty). The real cost driver is LLM API usage, since agentic tasks can trigger many model calls per run — monitor token usage closely in the first few weeks.

    Q: Can I run multiple agent platforms on the same VPS?
    A: Yes, as long as each runs in its own container with isolated networks and resource limits set via Docker Compose or docker run --memory/--cpus flags, to prevent one agent’s workload from starving the others.

    Q: Do these frameworks support open-source/local LLMs instead of OpenAI?
    A: Yes — AutoGen, CrewAI, and LangGraph all support local models via Ollama or any OpenAI-compatible endpoint, which is worth exploring if API costs or data residency are a concern.

    Wrapping Up

    Self-hosting an AI agent platform is no longer an experimental weekend project — it’s a viable production pattern for teams that want control over cost, data, and customization. Start small with a single containerized agent behind a reverse proxy, harden the credential handling early, and scale the orchestration layer only once you’ve validated the workload pattern. The Docker fundamentals here are identical to any other service you’ve already deployed; the main difference is treating the agent’s tool permissions with the same care you’d give a CI pipeline with production access.

    If you’re setting this up alongside other self-hosted services, our self-hosted Docker stack guide covers the broader reverse-proxy and TLS patterns referenced above in more depth.

  • No Code AI Agent Builder: Self-Host Guide 2026

    No Code AI Agent Builder: A Self-Hosted, Docker-First Guide for Developers

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Every week another SaaS company ships a “no code AI agent builder” with a slick drag-and-drop canvas and a pricing page that scales badly the moment you have real usage. If you’re a developer or sysadmin, you don’t need the SaaS wrapper — you need the underlying workflow engine, running on infrastructure you control, with logs you can actually read at 2 AM when something breaks.

    This guide covers what a no code AI agent builder actually is under the hood, which self-hostable platforms are worth your time in 2026, and how to deploy one on a VPS with Docker, connect it to an LLM API, and keep it monitored and secure. No proprietary black boxes, no per-execution billing surprises.

    What Is a No Code AI Agent Builder?

    A no code AI agent builder is a visual workflow platform that lets you chain together triggers, LLM calls, tool integrations, and conditional logic without writing custom application code. Under the hood, most of these tools are just orchestration engines — they take a JSON or YAML definition of nodes and edges, execute them in sequence or parallel, and expose the whole thing through a web UI so non-engineers (and busy engineers) can wire up automations quickly.

    The “agent” part means the workflow can reason, call tools, and make decisions using a large language model rather than following a purely static script. A support ticket triage bot, a research assistant that pulls from your internal wiki, or an on-call summarizer that pings Slack — these are all agents, and most of them don’t need custom Python to build.

    Why Developers Are Adopting No Code AI Agent Builders

    It’s tempting to assume “no code” is only for non-technical teams, but that’s not why this category has exploded. The real reasons developers reach for a no code AI agent builder:

  • Faster iteration — testing a prompt chain change takes seconds in a visual canvas versus a redeploy cycle.
  • Lower maintenance surface — the orchestration logic lives in a database record, not a repo you have to keep patched forever.
  • Easier handoff — ops and support teams can adjust workflows without opening a pull request.
  • Built-in observability — most platforms log every node execution, which beats grepping through custom logging you’d have to write yourself.
  • The tradeoff is control. If you use a hosted SaaS version, you’re renting someone else’s infrastructure and someone else’s uptime guarantees. That’s exactly why self-hosting the open-source versions of these tools is the better move for anyone comfortable with Docker.

    The Best Self-Hostable No Code AI Agent Builder Platforms

    A few platforms dominate the self-hosted space right now:

  • n8n — the most mature open-source workflow automation tool, with native AI agent nodes, LangChain integration, and a huge library of pre-built connectors.
  • Flowise — purpose-built for LLM chains and agents, with a canvas modeled closely on LangChain concepts.
  • Dify — combines a no-code agent builder with a hosted prompt IDE and built-in vector database support.
  • Langflow — another LangChain-native visual builder, popular for RAG pipeline prototyping.
  • All four ship official Docker images, which means you can run any of them on a single VPS in under ten minutes. For most teams building their first internal automation, n8n is the safest starting point because of its connector ecosystem and active community — but if you’re building LLM-specific agents exclusively, Flowise or Dify will feel more purpose-fit.

    If you’re also running Docker-based media or streaming services on the same host, it’s worth reviewing our Docker Compose guide for beginners first so your networking and volume conventions stay consistent across stacks.

    Self-Hosting Your No Code AI Agent Builder with Docker

    Here’s a minimal docker-compose.yml to get n8n running with persistent storage and a Postgres backend, which you’ll want once you go beyond a handful of workflows:

    version: "3.8"
    
    services:
      postgres:
        image: postgres:16
        restart: unless-stopped
        environment:
          POSTGRES_USER: n8n
          POSTGRES_PASSWORD: ${DB_PASSWORD}
          POSTGRES_DB: n8n
        volumes:
          - postgres_data:/var/lib/postgresql/data
    
      n8n:
        image: n8nio/n8n:latest
        restart: unless-stopped
        ports:
          - "5678:5678"
        environment:
          DB_TYPE: postgresdb
          DB_POSTGRESDB_HOST: postgres
          DB_POSTGRESDB_DATABASE: n8n
          DB_POSTGRESDB_USER: n8n
          DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD}
          N8N_HOST: agents.yourdomain.com
          N8N_PROTOCOL: https
          WEBHOOK_URL: https://agents.yourdomain.com/
          GENERIC_TIMEZONE: UTC
        volumes:
          - n8n_data:/home/node/.n8n
        depends_on:
          - postgres
    
    volumes:
      postgres_data:
      n8n_data:

    Store your database password in a .env file next to the compose file rather than hardcoding it:

    echo "DB_PASSWORD=$(openssl rand -base64 24)" > .env
    docker compose up -d

    That’s the entire backend. No code was written — just infrastructure declared.

    Step-by-Step: Deploying a No Code AI Agent Builder on a VPS

    Once Docker and Compose are installed on your VPS, the deployment flow looks like this:

    1. Provision a VPS with at least 2 vCPUs and 4GB RAM — LLM-backed workflows are memory-hungry once you add vector store nodes.
    2. Point a DNS A record at the server and put a reverse proxy (Caddy or Traefik) in front of it for automatic TLS.
    3. Copy the docker-compose.yml above onto the server and run docker compose up -d.
    4. Log in to the n8n UI, create your owner account, and generate an API credential for your LLM provider (OpenAI, Anthropic, or a self-hosted model via Ollama).
    5. Build your first agent workflow: a trigger node, an AI Agent node with your chosen model, and an output action (Slack message, database write, or webhook response).

    A basic Caddy config for TLS termination is just three lines:

    agents.yourdomain.com {
        reverse_proxy localhost:5678
    }

    Caddy handles Let’s Encrypt certificate issuance and renewal automatically — no cron job, no certbot script to maintain.

    Connecting Your Agent to External APIs and LLMs

    The real power of a no code AI agent builder shows up once you start chaining tool calls. A typical support-triage agent might:

  • Receive a webhook from your helpdesk when a new ticket is created.
  • Call an LLM node to classify urgency and topic.
  • Query an internal API or database for related documentation.
  • Post a summarized response back to Slack or the ticketing system.
  • Each of these is a drag-and-drop node with credentials stored centrally, encrypted at rest. If you’re already running a home theater or streaming review pipeline, the same pattern applies — for example, an agent that watches an RSS feed for new device firmware releases and drafts a summary for your editorial team, similar to the automation we describe in our self-hosted VPS setup walkthrough.

    Monitoring and Securing Your AI Agent Stack

    A no code AI agent builder is still a production service the moment it’s handling real workflows, and it deserves the same rigor as any other app on your VPS.

    Monitoring Your AI Agent Builder in Production

    At minimum, track:

  • Uptime of the web UI and webhook endpoints.
  • Execution failures — most platforms expose a REST API or webhook you can pipe into an alerting tool.
  • Resource usage — LLM nodes can spike memory when processing large context windows.
  • API rate limits on whatever model provider you’re calling.
  • A lightweight uptime and status-page tool like BetterStack plugs in well here — point it at your n8n health check endpoint and you’ll get paged the moment the container crashes or the reverse proxy drops.

    For infrastructure, don’t run this on a cheap shared host you’re also using for anything customer-facing. A dedicated small VPS from DigitalOcean or a cost-efficient dedicated box from Hetzner gives you enough headroom to run Postgres, the agent builder, and a reverse proxy without contention. If your agents are publicly reachable via webhook, put Cloudflare in front for DDoS protection and to hide your origin IP.

    Security basics that are easy to skip but shouldn’t be:

  • Put the agent builder’s admin UI behind basic auth or a VPN, not just the app’s own login.
  • Rotate API keys stored as credentials inside the platform on a schedule.
  • Restrict outbound webhook destinations with an allowlist if your platform supports it.
  • Back up the workflow database — losing years of built agents to a disk failure is avoidable with a nightly pg_dump cron job.
  • 0 3 * * * docker exec postgres pg_dump -U n8n n8n | gzip > /backups/n8n-$(date +%F).sql.gz

    If you’re also optimizing content around this stack for organic traffic, a rank-tracking tool like SE Ranking can help you validate which agent-builder comparison keywords are actually worth targeting before you invest more writing time.

    Choosing the Right No Code AI Agent Builder for Your Team

    There’s no single best answer — it depends on what you’re automating:

  • If you need broad connector coverage (CRMs, Slack, databases, email), go with n8n.
  • If you’re building strictly LLM/RAG-heavy agents, Flowise or Dify will save setup time.
  • If your team already lives in LangChain code and just wants a visual layer on top, Langflow is the closest match.
  • Whichever you pick, self-hosting via Docker means you can migrate between them later without re-architecting your infrastructure — the compose file and reverse proxy pattern stays nearly identical.

    Recommended: Ready to put this into practice? SE Ranking is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Is a no code AI agent builder the same as a chatbot builder?
    No. Chatbot builders are typically limited to conversational front-ends, while an agent builder can trigger on any event (webhook, schedule, database change) and take autonomous multi-step actions, not just reply to messages.

    Do I need to know how to code to use one?
    Not for basic workflows. But knowing Docker, basic networking, and reading JSON payloads will get you much further when debugging failed executions or writing custom expressions inside nodes.

    Can I self-host a no code AI agent builder for free?
    Yes — n8n, Flowise, Dify, and Langflow are all open source and free to self-host. You only pay for your VPS and whatever LLM API calls the agents make.

    How much does the LLM API cost add up to?
    It depends entirely on model choice and volume. Using a cheaper model for classification steps and reserving expensive models for final generation steps typically cuts costs by more than half.

    Is it safe to expose these tools to the public internet?
    Only the webhook endpoints should be public, and even then behind a CDN/WAF like Cloudflare. Keep the admin dashboard restricted to a VPN or IP allowlist.

    What’s the biggest mistake teams make with these platforms?
    Treating them as toys instead of production services — skipping backups, monitoring, and credential rotation until after an incident forces the issue.

    Final Thoughts

    A no code AI agent builder gives you the speed of visual workflow design without giving up the control you get from running your own infrastructure. Start with n8n or Flowise on a small VPS, put Docker Compose and a reverse proxy in front of it, and treat the stack with the same monitoring and backup discipline you’d apply to any other production service. The visual canvas is the easy part — the operational discipline around it is what actually keeps your agents reliable.