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

  • AI Agents Software: Self-Hosting Guide for DevOps Teams

    AI Agents Software: A DevOps Guide to Self-Hosting in Production

    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 agents software has moved from research demos to production workloads fast. Teams are wiring up autonomous agents to trigger deployments, monitor logs, answer support tickets, and orchestrate multi-step workflows without a human clicking through every step. The problem is that most tutorials assume you’ll just point at a hosted API and call it a day. That’s fine until you need predictable latency, data residency, cost control, or the ability to run agents against your own internal systems without shipping credentials to a third party.

    What Counts as AI Agents Software

    An AI agent, in the DevOps sense, is a process that combines a language model with tool-calling capability and a loop: observe state, decide an action, execute it, observe the result, repeat. Unlike a chatbot that answers one prompt and stops, an agent can call shell commands, query APIs, read and write files, or trigger CI/CD pipelines on its own.

    Common frameworks you’ll run into:

  • LangChain / LangGraph — Python-based orchestration for chaining tools and models
  • AutoGen — Microsoft’s multi-agent conversation framework
  • CrewAI — role-based agent orchestration for task delegation
  • Custom agents built directly against the OpenAI API or Anthropic API
  • All of these need a runtime, a place to store state (vector DB, Redis, Postgres), and network access to whatever tools the agent is allowed to call. That’s infrastructure work, not just prompt engineering.

    Why Self-Host Instead of Using a SaaS Agent Platform

    Hosted agent platforms are convenient, but they come with tradeoffs that matter once you’re running anything beyond a demo:

  • Cost at scale — token-metered SaaS pricing gets expensive fast when agents run long reasoning loops
  • Data control — agents that touch internal databases or proprietary code shouldn’t be routing that context through a third-party orchestration layer you don’t control
  • Latency — co-locating your agent runtime with the services it calls (your own APIs, your own database) cuts round-trip time significantly
  • Customization — self-hosted agents let you swap models, add custom tool integrations, and control retry/timeout behavior at the infrastructure level
  • If you already run Docker workloads and manage your own VPS fleet, self-hosting agent software is a natural extension of your existing stack rather than a new discipline.

    Building the Agent Runtime

    Containerizing an AI Agent with Docker

    Treat your agent the same way you’d treat any long-running service — package it as a container with a clear entrypoint, health check, and restart policy. Here’s a minimal example using a Python agent built on LangChain:

    FROM python:3.11-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . .
    
    ENV PYTHONUNBUFFERED=1
    
    HEALTHCHECK --interval=30s --timeout=5s 
      CMD python healthcheck.py || exit 1
    
    CMD ["python", "agent_runner.py"]

    A basic requirements.txt:

    langchain==0.3.7
    langchain-openai==0.2.9
    redis==5.2.0
    fastapi==0.115.5
    uvicorn==0.32.1

    And a stripped-down runner that exposes the agent behind an HTTP endpoint so it fits cleanly into a reverse-proxy setup:

    # agent_runner.py
    from fastapi import FastAPI, Request
    from langchain_openai import ChatOpenAI
    from langchain.agents import AgentExecutor, create_tool_calling_agent
    import uvicorn
    
    app = FastAPI()
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
    
    @app.post("/run")
    async def run_agent(request: Request):
        payload = await request.json()
        task = payload.get("task")
        result = llm.invoke(task)
        return {"output": result.content}
    
    if __name__ == "__main__":
        uvicorn.run(app, host="0.0.0.0", port=8000)

    Wrap it in docker-compose.yml alongside Redis for state and a Postgres instance for persistent logs:

    version: "3.9"
    services:
      agent:
        build: .
        restart: unless-stopped
        ports:
          - "8000:8000"
        env_file: .env
        depends_on:
          - redis
          - db
    
      redis:
        image: redis:7-alpine
        restart: unless-stopped
    
      db:
        image: postgres:16-alpine
        restart: unless-stopped
        environment:
          POSTGRES_USER: agent
          POSTGRES_PASSWORD: ${DB_PASSWORD}
          POSTGRES_DB: agent_logs
        volumes:
          - pgdata:/var/lib/postgresql/data
    
    volumes:
      pgdata:

    This pattern — one container per concern, restart policies set, secrets pulled from .env rather than hardcoded — is the same discipline covered in our Docker Compose production guide, and it applies directly to agent workloads.

    Choosing Infrastructure: VPS vs Managed Kubernetes

    For most teams running one to a handful of agents, a single well-sized VPS is enough — you don’t need Kubernetes to run a container with a health check and a restart policy. A 4 vCPU / 8GB droplet handles a moderate agent workload comfortably, especially since the heavy compute (the LLM inference itself) usually happens on a hosted model API rather than locally.

    If you’re evaluating providers, DigitalOcean droplets are a solid starting point for agent workloads that need predictable pricing and fast provisioning, while Hetzner is worth comparing if you’re optimizing hard for cost-per-core on longer-running background agents. Both work fine with the Docker Compose setup above — no orchestration platform required until you’re running dozens of agent instances concurrently.

    Once you outgrow a single box, look at our scaling Docker workloads across multiple hosts writeup before jumping straight to Kubernetes — a lot of agent workloads scale fine horizontally with a load balancer and a shared Redis/Postgres backend.

    Securing and Monitoring Your AI Agent Stack

    Agents that can execute shell commands or hit internal APIs are a bigger attack surface than a typical web app. Treat the agent’s tool-calling permissions the same way you’d treat a service account: narrow scope, explicit allowlists, no blanket sudo.

    A few concrete steps:

  • Run the agent container as a non-root user
  • Put the HTTP endpoint behind a reverse proxy with TLS — Cloudflare tunnels are an easy way to expose the agent’s API without opening inbound ports on the VPS directly
  • Rate-limit the /run endpoint so a runaway agent loop can’t hammer your own infrastructure or burn through API credits
  • Log every tool call the agent makes, not just the final output — this is what actually lets you debug a bad decision after the fact
  • For uptime and alerting, hook the health check endpoint into BetterStack so you get paged if the agent process dies or starts returning errors — the same way you’d monitor any other production API.

    # quick manual check before wiring up automated monitoring
    curl -sf http://localhost:8000/run 
      -X POST -H "Content-Type: application/json" 
      -d '{"task": "ping"}' | jq .

    Cost and Scaling Considerations

    Token costs dominate agent operating expense, not compute. A well-optimized agent loop that limits unnecessary reasoning steps and caches repeated tool calls in Redis can cut API spend by 30-50% compared to a naive implementation that re-queries the model on every iteration. Before scaling out infrastructure, profile where your token spend is actually going — it’s usually cheaper to fix a chatty prompt loop than to add more servers.

    When you do need to scale horizontally, put a load balancer in front of multiple agent container replicas and share state through Redis rather than in-memory — this keeps any single container disposable, which matters when you’re doing rolling deploys of new agent logic.

    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 and a simple chatbot API call?
    A chatbot responds to one prompt and stops. An agent runs a loop — it can call tools, evaluate the result, and decide on a follow-up action without a human in between each step. That loop is what needs the extra infrastructure (state storage, tool permissions, monitoring).

    Do I need a GPU to self-host AI agents software?
    Usually not. Most production agent setups call a hosted model API (OpenAI, Anthropic, etc.) for inference and only self-host the orchestration layer — the container that manages the loop, tool calls, and state. You only need local GPU compute if you’re also self-hosting the language model itself, which is a separate and much heavier undertaking.

    Is Docker Compose enough, or do I need Kubernetes?
    For a handful of agents, Docker Compose on a single VPS is enough and far simpler to operate. Move to Kubernetes only once you’re running many agent replicas that need automated scheduling, scaling, and failover — most teams overestimate how soon they’ll need it.

    How do I stop an agent from running away and burning API credits?
    Set hard iteration limits in your agent loop, add request timeouts, and rate-limit the endpoint that triggers agent runs. Also log token usage per run so you can spot runaway loops in monitoring before they show up on a bill.

    Can I run open-source models instead of a hosted API?
    Yes — tools like Ollama let you run open-weight models locally, but expect a real hit to reasoning quality on complex multi-step tasks compared to frontier hosted models. It’s a reasonable tradeoff for cost-sensitive or data-sensitive workloads, less so if you need reliable complex tool-use chains.

    Where should agent logs and state live?
    Use Postgres or a similar durable store for conversation/run history you need to audit later, and Redis for short-lived state like in-progress task context. Don’t rely on container-local disk — it disappears on redeploy.

    Wrapping Up

    Running AI agents software in production isn’t fundamentally different from running any other containerized service — it just adds a few new failure modes around tool permissions, runaway loops, and token cost. Start with a single Docker container behind a reverse proxy, wire up basic health checks and logging, and only add complexity (multi-host scaling, Kubernetes, custom model hosting) once you actually hit the limits of the simple setup. The teams that get burned are the ones that skip monitoring and rate limits because “it’s just a demo” — and then it isn’t.

  • AI Agent Dev: A Practical DevOps Guide for 2026

    AI Agent Dev: A Practical DevOps Guide to Building and Deploying AI Agents

    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 dev has moved past the demo-in-a-notebook phase. Teams are now shipping autonomous and semi-autonomous agents into production, wiring them into ticketing systems, CI pipelines, monitoring stacks, and customer-facing chat. That shift means AI agent dev is no longer just a machine learning problem — it’s a DevOps problem. You need reproducible environments, container isolation, secrets management, observability, and a rollback plan, exactly like any other service you run.

    This guide walks through the practical side of AI agent dev: setting up a sane local environment, containerizing agents with Docker, orchestrating multi-agent systems, monitoring them once they’re live, and deploying them securely to a VPS or cloud provider. Code examples are runnable, not pseudocode.

    Why AI Agent Dev Needs a DevOps Mindset

    An AI agent is, at its core, a long-running process that calls an LLM API, executes tools (shell commands, database queries, HTTP requests), and maintains state between steps. That combination — long-running, stateful, executing arbitrary tool calls — is exactly the kind of workload that breaks when you don’t apply standard ops discipline.

    Common failure patterns in unmanaged AI agent dev setups:

  • API keys hardcoded in notebooks or committed to git history
  • Agents with unrestricted shell access running directly on the host
  • No logging of tool calls, so a bad decision by the agent is undebuggable after the fact
  • Dependency drift between a developer’s laptop and the server, causing “works on my machine” failures
  • No resource limits, so a runaway agent loop can spike CPU or API spend
  • Every one of these is solved by patterns DevOps engineers already know: containerization, secrets managers, centralized logging, and resource quotas. If you’ve done any Docker Compose work before, you already have most of the muscle memory needed for solid AI agent dev.

    Setting Up Your AI Agent Development Environment

    Start with a clean, isolated Python environment rather than installing agent frameworks globally. A pyproject.toml-based setup with venv or uv keeps dependency conflicts contained:

    python3 -m venv .venv
    source .venv/bin/activate
    pip install --upgrade pip
    pip install langchain langchain-openai python-dotenv requests

    Keep secrets out of source control from day one. Use a .env file locally and a real secrets manager in production:

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

    Add .env to .gitignore immediately:

    echo ".env" >> .gitignore

    A minimal single-tool agent looks like this — enough to prove the loop works before you add complexity:

    # agent.py
    import os
    from dotenv import load_dotenv
    from langchain_openai import ChatOpenAI
    from langchain.agents import create_react_agent, AgentExecutor
    from langchain_core.tools import tool
    from langchain import hub
    
    load_dotenv()
    
    @tool
    def get_server_uptime(host: str) -> str:
        """Return a placeholder uptime string for a given host."""
        return f"{host} has been up for 14 days, 3 hours."
    
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
    prompt = hub.pull("hwchase17/react")
    tools = [get_server_uptime]
    
    agent = create_react_agent(llm, tools, prompt)
    executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
    
    if __name__ == "__main__":
        result = executor.invoke({"input": "How long has web01 been up?"})
        print(result["output"])

    For the underlying LLM APIs and tool-calling conventions, the LangChain documentation and the Docker documentation are the two references you’ll return to most during AI agent dev.

    Containerizing AI Agents with Docker

    Once the agent loop works locally, containerize it immediately — don’t wait until “it’s ready.” A Dockerfile forces you to be explicit about dependencies, and it’s the only way to guarantee the agent behaves the same on your laptop and on a production VPS.

    FROM python:3.12-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY agent.py .
    
    # Run as a non-root user — never run agent tool-calls as root
    RUN useradd -m agentuser
    USER agentuser
    
    ENV AGENT_LOG_LEVEL=INFO
    
    CMD ["python", "agent.py"]

    Build and run it with an explicit memory ceiling — agents that loop unexpectedly should never be able to take down the host:

    docker build -t ai-agent-dev:latest .
    docker run --rm 
      --memory=512m 
      --cpus=1 
      --env-file .env 
      ai-agent-dev:latest

    Running as a non-root user and capping resources are the two changes that stop a misbehaving agent from becoming a host-level incident instead of a contained one.

    Orchestrating Multi-Agent Systems with Docker Compose

    Real AI agent dev projects rarely stay single-agent for long. You’ll typically end up with a router agent, one or more specialist agents, a vector database, and a message queue between them. Docker Compose keeps this manageable without jumping straight to Kubernetes.

    # docker-compose.yml
    services:
      router-agent:
        build: ./router
        env_file: .env
        depends_on:
          - redis
          - vectordb
        restart: unless-stopped
        deploy:
          resources:
            limits:
              memory: 512M
    
      worker-agent:
        build: ./worker
        env_file: .env
        depends_on:
          - redis
        restart: unless-stopped
        deploy:
          replicas: 3
    
      redis:
        image: redis:7-alpine
        restart: unless-stopped
    
      vectordb:
        image: qdrant/qdrant:latest
        volumes:
          - vectordata:/qdrant/storage
        restart: unless-stopped
    
    volumes:
      vectordata:

    The worker-agent service scales to three replicas so the router can distribute tasks under load without any single agent process becoming a bottleneck. This is the same pattern you’d use scaling any stateless worker fleet — nothing agent-specific about it, which is the point.

    Monitoring and Observability for Production Agents

    Unlike a typical web service, an AI agent’s failures are often silent: it doesn’t crash, it just makes a bad tool call or hallucinates an answer. Standard uptime monitoring won’t catch that, so you need to log at the decision level, not just the process level.

    Minimum viable observability for AI agent dev:

  • Structured JSON logs for every tool call, including inputs and outputs
  • A dashboard tracking token spend per agent, per day
  • Alerting on abnormal loop counts (an agent calling the same tool 20 times in a row usually means it’s stuck)
  • Centralized log shipping so you’re not SSH-ing into containers to docker logs during an incident
  • A lightweight structured logger addition to the agent:

    import json
    import logging
    import time
    
    logger = logging.getLogger("ai_agent")
    
    def log_tool_call(tool_name: str, tool_input: str, tool_output: str) -> None:
        logger.info(json.dumps({
            "timestamp": time.time(),
            "tool": tool_name,
            "input": tool_input,
            "output": tool_output,
        }))

    For the infrastructure side of monitoring — uptime checks, incident alerting, and status pages for agent-backed endpoints — BetterStack is worth evaluating; it’s built specifically for exactly this kind of always-on service monitoring and integrates cleanly with container-based deployments. If you’re already tracking traditional Linux server monitoring metrics, extend the same dashboards to cover your agent containers rather than standing up a second system.

    Deploying to the Cloud

    For most AI agent dev workloads, a single well-sized VPS handles surprisingly heavy traffic since the LLM API call, not your container, is the bottleneck. Two solid, budget-friendly options:

  • DigitalOcean — droplets with one-click Docker images, simple to wire into an existing CI/CD pipeline, good documentation for container deployments
  • Hetzner — significantly cheaper per-core pricing for CPU-bound orchestration layers (routing, queueing) where you don’t need GPU access
  • A minimal deployment flow once you’ve provisioned a droplet or server:

    # on the remote server
    git clone https://github.com/yourorg/ai-agent-dev-project.git
    cd ai-agent-dev-project
    docker compose pull
    docker compose up -d
    docker compose logs -f router-agent

    Put a reverse proxy in front of any agent that exposes an HTTP endpoint, and terminate TLS there rather than in the agent container itself — that keeps certificate rotation out of your application code entirely.

    Security Considerations for AI Agent Dev

    Agents that execute tools are effectively remote code execution surfaces if you’re not careful. Treat every tool definition as an attack surface, not a convenience function.

  • Never give an agent a raw shell-execution tool without an allowlist of permitted commands
  • Sandbox filesystem access to a dedicated directory, never the host root
  • Rotate API keys on a schedule and store them in a secrets manager, not environment files on disk long-term
  • Rate-limit tool calls per agent session to prevent runaway API spend from a prompt-injection loop
  • Log every tool call with enough context to reconstruct what happened during a post-incident review
  • If your agents are internet-facing, put them behind a WAF and DDoS-mitigation layer. Cloudflare is a common choice here since it handles both in front of a small VPS deployment without needing a dedicated security team.

    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 AI agent dev and regular LLM app development?
    Regular LLM apps typically make a single prompt-response call. AI agent dev involves a loop where the model decides which tools to call, executes them, and reasons over the results — closer to building an autonomous worker process than a single API integration.

    Do I need Kubernetes for AI agent dev?
    Not at the start. Docker Compose handles single-server multi-agent setups fine for most teams. Move to Kubernetes only once you need multi-node scaling or have SLAs that demand automatic failover across hosts.

    How do I stop an agent from making expensive API calls in a loop?
    Set a hard max-iteration count in your agent executor, log every tool call, and alert when the same tool is called repeatedly within a short window. Most frameworks, including LangChain’s AgentExecutor, support a max_iterations parameter directly.

    Is Python the only realistic option for AI agent dev?
    No — TypeScript (via LangChain.js or the Vercel AI SDK) and Go are both viable, especially if your existing infrastructure is already in those languages. Python currently has the deepest ecosystem of agent frameworks, which is why most tutorials default to it.

    How much does it cost to run a production AI agent?
    Costs are dominated by LLM API token spend, not infrastructure. A modestly sized VPS from DigitalOcean or Hetzner running the container orchestration layer typically costs less per month than a single day of unmonitored token spend from a runaway agent loop — which is exactly why the monitoring section above matters.

    Can I run open-source models instead of paid APIs for AI agent dev?
    Yes, tools like Ollama let you run models like Llama or Mistral locally or on a GPU-equipped server, which removes per-token API costs entirely at the expense of needing more powerful hardware and generally weaker tool-calling reliability than top-tier hosted models.

    Wrapping Up

    AI agent dev succeeds or fails on the same fundamentals as any other production service: isolation, observability, and a clear security boundary around what the code is allowed to touch. Docker gives you the isolation, structured logging gives you the observability, and tool allowlisting gives you the security boundary. Get those three right before you worry about which agent framework has the trendiest API — the framework matters far less than the operational discipline around it.

  • Example of Agentic AI: 7 Real DevOps Use Cases

    Example of Agentic AI: Real-World Use Cases for DevOps Teams

    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 engineering Twitter or LinkedIn lately, you’ve seen the term “agentic AI” thrown around next to buzzwords like “autonomous” and “self-healing.” It’s easy to dismiss as marketing noise, but the underlying pattern is real and it’s already running in production systems. This article breaks down what agentic AI actually is, walks through a concrete example of agentic ai applied to a CI/CD pipeline, and shows several more use cases you can build or evaluate today.

    Disclosure: This post contains affiliate links. If you sign up through one of the links below, we may earn a commission at no extra cost to you. We only recommend infrastructure providers we’ve actually used in production.

    What Is Agentic AI, Actually?

    Agentic AI refers to systems built around a large language model (LLM) that can plan a sequence of actions, execute tools (scripts, API calls, database queries), observe the results, and decide what to do next — without a human manually approving each step. This is different from a traditional chatbot, which just answers a question and stops.

    Think of the difference this way: a standard AI assistant tells you how to restart a crashed container. An agentic AI system checks the container’s exit code, pulls the last 200 lines of logs, correlates them against a known error pattern, restarts the container, verifies the health check passes, and only pings you if it can’t resolve the issue on its own.

    Key Characteristics of Agentic AI

  • Autonomy — it takes multi-step action without a human in the loop for every decision
  • Tool use — it calls real functions: shell commands, REST APIs, database queries, Kubernetes controllers
  • Memory/state — it tracks what it has already tried so it doesn’t loop forever
  • Goal-directed planning — it breaks a high-level objective (“keep the API under 200ms p95”) into concrete steps
  • Feedback loops — it observes the outcome of each action and adjusts the next step accordingly
  • If a system is missing most of these traits, it’s probably just an LLM wrapper, not a true agent.

    Example of Agentic AI #1: Autonomous CI/CD Remediation

    Here’s a concrete example of agentic ai wired into a GitHub Actions pipeline. When a deployment fails, instead of just notifying a human, the agent investigates and attempts a fix first.

    # .github/workflows/deploy.yml
    name: deploy-with-agent-remediation
    on:
      push:
        branches: [main]
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: Deploy to production
            id: deploy
            run: ./scripts/deploy.sh
            continue-on-error: true
          - name: Trigger remediation agent
            if: steps.deploy.outcome == 'failure'
            run: python3 agents/remediation_agent.py --job-id ${{ github.run_id }}

    The remediation_agent.py script is where the actual agentic loop lives. Below is a simplified version showing the plan-act-observe pattern:

    import subprocess
    import json
    
    def run_tool(cmd: str) -> str:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        return result.stdout + result.stderr
    
    def remediation_agent(job_id: str, max_steps: int = 5):
        context = [f"Deployment {job_id} failed. Diagnose and attempt a fix."]
    
        for step in range(max_steps):
            # In production this call goes to an LLM API (e.g. Claude) with
            # the current context and a list of available tools.
            action = decide_next_action(context)
    
            if action["type"] == "done":
                print(f"Resolved in {step + 1} steps: {action['summary']}")
                return True
    
            output = run_tool(action["command"])
            context.append(f"Ran: {action['command']}nResult: {output[:500]}")
    
        print("Agent could not resolve the issue automatically. Paging on-call.")
        page_oncall(job_id, context)
        return False

    In practice, decide_next_action sends the accumulated context to an LLM with tool-calling enabled, and the model returns a structured action like {"type": "tool", "command": "kubectl rollout status deploy/api -n prod"}. The loop keeps going until the model reports success or the step budget runs out, at which point a human takes over.

    Why This Beats a Static Runbook

    A static runbook is a fixed script: if X fails, run Y. Agentic systems instead reason about which diagnostic to run next based on what the previous command returned. That flexibility matters because production failures rarely match the exact scenario a runbook author anticipated.

    Example of Agentic AI #2: Self-Healing Infrastructure Monitoring

    Monitoring tools like BetterStack already do a good job of alerting you when something breaks. The agentic layer sits on top: instead of just firing a Slack alert, an agent receives the alert, pulls metrics and logs, forms a hypothesis, and takes a corrective action such as scaling a deployment or restarting a stuck worker pool.

    A simple version of this pattern for a Dockerized service:

    #!/bin/bash
    # health_agent.sh - called by a monitoring webhook on alert
    
    SERVICE=$1
    EXIT_CODE=$(docker inspect --format='{{.State.ExitCode}}' "$SERVICE")
    
    if [ "$EXIT_CODE" -eq 137 ]; then
      echo "OOMKilled detected for $SERVICE — raising memory limit and restarting"
      docker update --memory=1g --memory-swap=1g "$SERVICE"
      docker start "$SERVICE"
    elif [ "$EXIT_CODE" -eq 1 ]; then
      echo "Generic failure — pulling logs for LLM triage"
      docker logs --tail 100 "$SERVICE" > /tmp/last_failure.log
      python3 agents/triage.py --log /tmp/last_failure.log --service "$SERVICE"
    fi

    We cover the broader monitoring stack this pairs with in our Docker container monitoring guide, which walks through setting up the metrics pipeline an agent like this depends on.

    Cloud Cost Optimization Agents

    Another increasingly common example of agentic ai lives in FinOps tooling. These agents monitor cloud spend across providers, identify idle resources (unattached volumes, oversized instances, forgotten load balancers), and either flag them or terminate them automatically based on policy rules you define. If you’re running infrastructure on DigitalOcean or Hetzner, pairing their APIs with a lightweight agent script is often cheaper than buying a full FinOps platform — you can query usage via their REST APIs, feed the results to an LLM for anomaly detection, and auto-tag or resize resources that look wasteful.

    Security Triage Agents

    Security operations centers use agentic AI to pre-triage alerts from tools like intrusion detection systems and cloud security posture managers. The agent correlates a new alert against historical incidents, checks whether the source IP has prior flags, and either auto-closes false positives or escalates genuine threats with a written summary — cutting analyst workload significantly. This only works safely with tight guardrails, which we discuss more in our Linux server hardening checklist.

    Building Your Own Agentic AI Workflow

    If you want to experiment with this pattern yourself, here’s a minimal stack that works well for infrastructure use cases:

  • An LLM with reliable tool/function calling — Anthropic’s Claude models or OpenAI’s GPT-4 class models both support this
  • A sandboxed execution environment (a container, not your host shell) so the agent can’t run destructive commands unchecked
  • A hard step limit and cost budget per run, so a bad loop doesn’t rack up API bills or spin forever
  • Structured logging of every action the agent takes, for audit and debugging
  • A human-approval gate for any action that’s destructive or hard to reverse (deleting resources, force-pushing, dropping databases)
  • That last point is the one teams skip most often, and it’s the one that causes incidents. An agent that can restart a container autonomously is low risk. An agent that can delete a database volume autonomously needs a human in the loop, full stop.

    Guardrails That Actually Matter in Production

    When you move an agentic workflow from a demo to production, the failure modes change. A few guardrails worth building in from day one:

  • Allowlist the tools the agent can call — never let it construct arbitrary shell commands from raw model output
  • Rate-limit destructive actions so a hallucinating agent can’t, say, restart the same service 50 times in a minute
  • Log every decision with the reasoning attached, not just the action, so you can audit why it did what it did
  • Set a maximum blast radius — scope credentials so the agent can only touch the specific resources it’s meant to manage
  • Teams that skip these steps tend to have a rough first incident. Teams that build them in up front get most of the benefit of autonomy with a fraction of the risk.

    Wrapping Up

    Agentic AI isn’t a single product you buy — it’s a design pattern: give a model tools, let it observe outcomes, and let it iterate toward a goal within defined limits. The CI/CD remediation example above is a good starting project because failures are frequent, low-stakes to experiment with, and easy to roll back. Once that’s stable, extending the same pattern to monitoring, cost optimization, or security triage is a natural next step.

    If you’re setting up the underlying infrastructure these agents run on, a reliable VPS with predictable performance and an API you can script against matters more than people expect — check out DigitalOcean or Hetzner if you’re evaluating providers, and pair it with BetterStack for the observability layer your agent will read from.

    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: What’s a simple example of agentic ai that doesn’t involve infrastructure?
    A: A common non-infra example is an AI travel-booking agent that searches flights, compares prices across sites, checks your calendar for conflicts, and books the ticket — taking multiple sequential actions toward one goal without you approving each search individually.

    Q: How is agentic AI different from RPA (robotic process automation)?
    A: RPA follows a fixed, pre-scripted sequence of steps with no reasoning involved. Agentic AI decides its next step dynamically based on the outcome of the previous one, which lets it handle situations the original script author never anticipated.

    Q: Is agentic AI safe to run against production systems?
    A: It can be, but only with guardrails: sandboxed execution, an allowlist of permitted tools, step/cost limits, and a human-approval gate for destructive actions. Without those, an agent can amplify a small bug into a large outage.

    Q: Do I need a custom LLM to build an agentic workflow?
    A: No. General-purpose models with function-calling support, like Claude or GPT-4-class models, work fine for most DevOps use cases. The engineering effort goes into the tool integrations and guardrails, not the model itself.

    Q: What’s the easiest first agentic AI project for a DevOps team?
    A: Automated log triage on failed CI/CD jobs. It’s low-risk, the failure modes are well understood, and it gives immediate, measurable time savings for the on-call rotation.

    Q: Can agentic AI replace on-call engineers entirely?
    A: Not currently, and probably not for a long while. It reduces the volume of alerts that need a human, but genuinely novel failures still require human judgment, especially for anything with real business or safety impact.

  • Anthropic AI Agent Guide: Automating DevOps with Claude

    Anthropic AI Agent: A Practical DevOps Guide to Claude 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.

    If you manage servers, containers, or CI/CD pipelines, you’ve probably heard the term “AI agent” thrown around a lot in the last year. Anthropic’s Claude models now support agentic workflows that can read logs, run shell commands, edit config files, and even manage Docker containers with minimal human intervention. This guide walks through what an Anthropic AI agent actually is, how to stand one up on your own infrastructure, and where it realistically fits into a DevOps toolchain.

    What Is an Anthropic AI Agent?

    An Anthropic AI agent is an instance of a Claude model (Sonnet, Opus, or Haiku) given tool access — shell execution, file I/O, web search, or custom API calls — plus a loop that lets it plan, act, observe results, and iterate. Unlike a single prompt-response chatbot interaction, an agent can chain dozens of tool calls together to complete a multi-step task: SSH into a box, check disk usage, rotate logs, restart a service, and confirm the fix worked.

    Anthropic ships this capability through the Claude Agent SDK and the Claude Code CLI, both of which expose a permission model so you control exactly what the agent can touch — read-only file access, sandboxed bash, or full write access to production systems.

    Claude vs Traditional Automation Scripts

    Traditional automation (cron jobs, Ansible playbooks, bash scripts) is deterministic: it does exactly what you wrote, every time. An Anthropic AI agent is probabilistic and context-aware — it can interpret ambiguous instructions like “figure out why the container keeps restarting” and adapt its investigation based on what it finds. That flexibility is powerful for triage and one-off diagnostics, but it’s not a drop-in replacement for idempotent infrastructure-as-code. The right mental model is: use Ansible or Terraform for repeatable, auditable changes, and use an agent for exploratory debugging, log analysis, and tasks too varied to script in advance.

    This distinction matters when you’re deciding what to automate. We cover the broader tradeoffs in our guide to Docker Compose automation, which is a good companion read if you’re mixing traditional tooling with agent-driven workflows.

    Setting Up Your First Anthropic AI Agent

    The fastest path to a working agent is Anthropic’s own SDK, which runs on Node.js or Python and talks to the Claude API. Here’s a minimal setup for a Linux server.

    Installing the Claude Agent SDK

    First, get Node.js 18+ installed and pull the SDK:

    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
    sudo apt-get install -y nodejs
    npm install -g @anthropic-ai/claude-agent-sdk

    Set your API key as an environment variable rather than hardcoding it anywhere:

    export ANTHROPIC_API_KEY="sk-ant-your-key-here"
    echo 'export ANTHROPIC_API_KEY="sk-ant-your-key-here"' >> ~/.bashrc

    Then create a small agent script that reads system logs and flags anomalies:

    import { query } from "@anthropic-ai/claude-agent-sdk";
    
    async function runAgent() {
      const result = await query({
        prompt: "Check /var/log/syslog for the last hour. Summarize any errors and suggest fixes.",
        options: {
          allowedTools: ["bash"],
          permissionMode: "acceptEdits",
          cwd: "/var/log"
        }
      });
    
      for await (const message of result) {
        if (message.type === "text") {
          console.log(message.text);
        }
      }
    }
    
    runAgent();

    Run it with node agent.js. The SDK handles the tool-call loop internally — you don’t have to write the retry or parsing logic yourself.

    Connecting Claude to Your Infrastructure

    For most DevOps use cases, you’ll want the agent running inside a container rather than directly on the host, so a bad tool call can’t take out your whole server. A basic Dockerfile:

    FROM node:20-slim
    
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    
    ENV ANTHROPIC_API_KEY=""
    CMD ["node", "agent.js"]

    Build and run it with a scoped-down set of permissions:

    docker build -t claude-agent .
    docker run --rm 
      -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY 
      -v /var/log:/var/log:ro 
      claude-agent

    Notice the :ro flag — mounting logs as read-only means the agent can diagnose issues without being able to modify or delete anything on the host. That’s the pattern you want for any agent you’re not 100% ready to trust with write access. If you’re new to container permission boundaries, our Docker security hardening checklist covers this in more depth.

    Real-World Use Cases for DevOps Teams

    Once the plumbing is in place, an Anthropic AI agent is genuinely useful for a specific set of DevOps tasks — not everything, but a meaningful slice of daily work:

  • Log triage: pointing an agent at a noisy log stream and asking it to summarize root causes instead of grepping manually.
  • Incident first response: having an agent gather diagnostics (disk, memory, recent deploys, error rates) before a human engineer even opens a laptop.
  • Dockerfile and Compose review: catching missing .dockerignore entries, insecure USER root defaults, or bloated layers.
  • Config drift detection: comparing a running container’s environment against what’s declared in version control.
  • Documentation generation: turning a messy shell history or runbook into clean Markdown for the team wiki.
  • CI pipeline debugging: parsing failed build logs and proposing the specific line that broke.
  • What it’s not great at yet: anything requiring precise, repeatable state changes across a fleet of machines, or tasks where a wrong guess is expensive (production database migrations, for example). Keep humans in the loop for those, and use the agent’s permissionMode settings to require approval before any destructive command runs.

    Deploying Your Agent on a VPS

    Most small teams don’t need a Kubernetes cluster to run an agent — a single VPS with Docker is enough to get real value. A typical setup looks like this:

    # On a fresh Ubuntu 22.04 VPS
    sudo apt update && sudo apt install -y docker.io docker-compose-plugin
    sudo systemctl enable --now docker
    
    # Clone your agent project
    git clone https://github.com/yourorg/claude-agent-worker.git
    cd claude-agent-worker
    
    # Run it as a background service
    docker compose up -d

    A docker-compose.yml for a persistent agent worker might look like:

    version: "3.9"
    services:
      agent:
        build: .
        restart: unless-stopped
        environment:
          - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
        volumes:
          - ./logs:/var/log:ro
        deploy:
          resources:
            limits:
              memory: 512M

    If you’re choosing where to host this, both DigitalOcean and Hetzner offer cheap, fast VPS options that handle a lightweight agent worker without issue — you don’t need a large instance since most of the compute happens on Anthropic’s side, not your box.

    Choosing the Right VPS for an Agent Worker

    Because the model inference happens via API call rather than locally, your server’s job is mostly orchestration: making HTTP requests, running shell tools, and writing logs. A 2 vCPU / 4GB RAM droplet is plenty for a single agent handling periodic tasks. If you’re running multiple agents in parallel — say, one per microservice — scale RAM before CPU, since concurrent Node processes are usually memory-bound before they’re compute-bound. We break down sizing recommendations further in our VPS sizing guide for containerized apps.

    Monitoring and Securing Your AI Agent

    An agent with shell access is, functionally, a new privileged user on your system — treat it like one. A few non-negotiables:

  • Least privilege first. Start every agent with allowedTools restricted to read-only operations, and only widen scope once you trust the specific workflow.
  • Log every tool call. The SDK emits structured events for each action the agent takes; ship these to a centralized log so you have an audit trail. BetterStack is a solid option if you want uptime monitoring and log aggregation in one place without standing up your own ELK stack.
  • Put it behind a firewall. If your agent exposes any webhook or API endpoint (for example, to trigger it from CI), put Cloudflare in front of it for DDoS protection and to restrict access by IP range.
  • Rotate API keys regularly, and never commit them to version control — use a secrets manager or at minimum a .env file excluded via .gitignore.
  • Set spend limits in the Anthropic console so a runaway loop can’t rack up an unexpected bill.
  • Security here isn’t optional flavor text — an agent that can run arbitrary shell commands is a real attack surface if its API key or prompts are exposed. Scope permissions tightly, and expand only after you’ve watched it behave correctly in a staging environment.

    Wrapping Up

    An Anthropic AI agent isn’t magic — it’s a capable, context-aware assistant that’s genuinely good at the messy, ambiguous parts of DevOps work that scripts handle poorly: triage, summarization, and first-pass diagnosis. Pair it with your existing infrastructure-as-code for the deterministic stuff, run it in a sandboxed container, log everything, and you’ve got a legitimately useful addition to a small ops team’s toolkit.

    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 Anthropic AI agent and a regular Claude chat session?
    A chat session is a single request-response exchange. An agent runs in a loop with tool access — it can execute commands, read the output, and decide on its next action autonomously until the task is done or it hits a stopping condition you define.

    Do I need Claude Opus for agent workflows, or will Sonnet work?
    Sonnet handles most DevOps agent tasks fine — log parsing, config review, straightforward diagnostics — at a lower cost and faster latency. Reserve Opus for genuinely complex, multi-file reasoning tasks where accuracy matters more than speed.

    Can an Anthropic AI agent run entirely on-premises without calling Anthropic’s API?
    No. The model inference itself happens on Anthropic’s infrastructure via API call. Your local agent process only handles orchestration — running tools, reading files, and passing results back and forth. Nothing about the model weights runs on your hardware.

    Is it safe to give an agent write access to production servers?
    Not by default. Start with read-only access and a sandboxed container, review its behavior in staging, and only grant write permissions for narrowly scoped, well-tested workflows. Treat permission scoping the same way you’d treat any new service account.

    How much does running an Anthropic AI agent cost for a small team?
    Costs scale with API token usage, not server resources. A lightweight agent doing periodic log checks might cost a few dollars a month in API calls; heavier, continuous monitoring workflows cost more. Set spend limits in the Anthropic console to avoid surprises.

    What happens if the agent makes a mistake, like deleting the wrong file?
    This is exactly why permission scoping and read-only mounts matter. If you’ve restricted the agent’s tools appropriately, the blast radius of a mistake is limited to what it can actually touch. Always test new agent workflows in a non-production environment first.

  • Anthropic AI Agents: A DevOps Deployment Guide

    Anthropic AI Agents: A Practical DevOps Guide to Building and Deploying Them

    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.

    Anthropic AI agents — autonomous, tool-using programs built on Claude models — are quickly becoming part of the standard DevOps toolkit, sitting alongside cron jobs, CI runners, and monitoring bots. If you’re a developer or sysadmin trying to figure out how to actually run these agents in production rather than just poke at them in a notebook, this guide covers the infrastructure side: environment setup, containerization, orchestration, hosting, and security.

    What Are Anthropic AI Agents?

    An Anthropic AI agent is a program that uses a Claude model as its reasoning engine, combined with a loop that lets it call external tools (functions, APIs, shell commands) and use the results to decide what to do next. Unlike a single-shot chatbot response, an agent runs a multi-step loop: it reads a goal, plans an action, executes a tool, observes the result, and repeats until the task is done.

    Common production use cases include:

  • Automated incident triage that queries logs, correlates metrics, and drafts a summary for on-call engineers
  • Infrastructure-as-code assistants that generate and validate Terraform or Docker configs
  • Customer support agents that look up account data via internal APIs before responding
  • Data pipeline agents that clean, transform, and validate datasets against a schema
  • How Anthropic Agents Differ from Simple Chatbots

    The key architectural difference is the tool-use loop. A chatbot takes a prompt and returns text. An agent takes a prompt, decides it needs information it doesn’t have, calls a tool (e.g., a get_server_status function), receives structured output, and folds that back into its context before producing a final answer or taking another action. This means agents need infrastructure that a plain chatbot doesn’t: a place to run tool code safely, state management across multi-step tasks, and logging that captures the full decision trail, not just the final output.

    Setting Up Your Environment

    Start with a clean Python environment and the official Anthropic SDK. You’ll need an API key from the Anthropic Console, which you should store as an environment variable, never hardcoded.

    python3 -m venv venv
    source venv/bin/activate
    pip install anthropic python-dotenv

    Create a .env file for local development:

    echo "ANTHROPIC_API_KEY=sk-ant-your-key-here" > .env
    echo ".env" >> .gitignore

    Building a Minimal Tool-Using Agent

    Here’s a minimal agent that can check disk usage on a server — a realistic sysadmin task. The agent decides when to call the tool based on the user’s request.

    import os
    import subprocess
    import anthropic
    from dotenv import load_dotenv
    
    load_dotenv()
    client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
    
    def get_disk_usage(path="/"):
        result = subprocess.run(["df", "-h", path], capture_output=True, text=True)
        return result.stdout
    
    tools = [
        {
            "name": "get_disk_usage",
            "description": "Return disk usage stats for a given filesystem path.",
            "input_schema": {
                "type": "object",
                "properties": {"path": {"type": "string"}},
                "required": ["path"],
            },
        }
    ]
    
    def run_agent(user_prompt):
        messages = [{"role": "user", "content": user_prompt}]
        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=1024,
            tools=tools,
            messages=messages,
        )
    
        if response.stop_reason == "tool_use":
            tool_call = next(b for b in response.content if b.type == "tool_use")
            result = get_disk_usage(tool_call.input.get("path", "/"))
            messages.append({"role": "assistant", "content": response.content})
            messages.append({
                "role": "user",
                "content": [{
                    "type": "tool_result",
                    "tool_use_id": tool_call.id,
                    "content": result,
                }],
            })
            final = client.messages.create(
                model="claude-sonnet-4-5",
                max_tokens=1024,
                tools=tools,
                messages=messages,
            )
            return final.content[0].text
        return response.content[0].text
    
    if __name__ == "__main__":
        print(run_agent("Is my root partition running low on space?"))

    This is intentionally simple, but it’s the core pattern every production agent extends: model call, tool dispatch, tool result fed back, final response. Anthropic’s own agent SDK documentation covers more advanced patterns like parallel tool calls and multi-turn planning if you need to go further.

    Deploying Anthropic Agents with Docker

    Once your agent works locally, containerize it. This gives you reproducible deployments and lets you isolate the shell/tool execution environment from your host system — important when the agent can run arbitrary commands.

    FROM python:3.12-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . .
    
    # Run as non-root user
    RUN useradd -m agentuser
    USER agentuser
    
    CMD ["python", "agent.py"]

    If you’re new to writing production Dockerfiles, our Docker Compose guide for beginners covers the fundamentals of multi-container setups you’ll want before scaling this further.

    Orchestrating Agents with Docker Compose

    Most real agent deployments need more than one container — the agent itself, a task queue, and often a small database for conversation state.

    version: "3.9"
    services:
      agent:
        build: .
        env_file: .env
        depends_on:
          - redis
        restart: unless-stopped
        deploy:
          resources:
            limits:
              memory: 512M
    
      redis:
        image: redis:7-alpine
        volumes:
          - redis-data:/data
    
    volumes:
      redis-data:

    Redis here acts as a lightweight queue and state store for multi-step agent tasks, so the agent can pick up where it left off if the container restarts. Bring it up with:

    docker compose up -d --build
    docker compose logs -f agent

    Hosting Considerations: Where to Run Your Agents

    Agent workloads are bursty — mostly idle, then a spike of API calls and tool execution during a task. A few things matter more than raw CPU count:

  • Predictable network egress — agents making frequent outbound API calls to Anthropic and other services benefit from a provider with generous, clearly-priced bandwidth.
  • Fast provisioning — you’ll want to spin up isolated sandboxes for testing new tool integrations without touching production.
  • Snapshotting — the ability to snapshot a VM before letting an agent run with elevated permissions is a cheap insurance policy.
  • For most small-to-mid agent deployments, a $12–24/month VPS is plenty. DigitalOcean droplets are a solid default if you want managed simplicity and one-click Docker images. If you’re optimizing for cost at scale, Hetzner offers comparable specs at a lower price point, which matters once you’re running several agent containers around the clock. Either works well with the Compose setup above — just make sure to size the instance to your peak tool-execution load, not your average.

    Monitoring and Observability for Agent Workloads

    Agents fail differently than typical web services — a hung tool call, a runaway loop, or a silent API error can burn through your token budget without an obvious crash. Wire up uptime and log monitoring from day one. BetterStack is a good fit here: it can alert you on container health, log anomalies, and API error rate spikes without needing to build your own observability stack. Pair that with structured logging in your agent code — log every tool call, its input, and its result, not just the final response — so you can reconstruct what the agent actually did when something goes wrong. Our guide to self-hosted log monitoring has more detail on setting up log aggregation for containerized workloads like this.

    Security Best Practices for Production Agents

    Giving an LLM the ability to execute code or call APIs is a real attack surface, not a theoretical one. Treat agent permissions the way you’d treat any service account:

  • Scope API keys and tool permissions to the minimum the agent actually needs — don’t hand a triage agent write access to production databases.
  • Run tool execution in a sandboxed container or VM, never directly on a host with sensitive data.
  • Validate and sanitize any input the agent passes to shell commands or SQL queries — prompt injection can trick an agent into misusing a legitimate tool.
  • Set hard limits on iteration count and token spend per task to prevent runaway loops.
  • Log every tool call for auditability, and review logs periodically, not just when something breaks.
  • Cost and Rate Limit Management

    Agent loops can consume tokens fast, especially multi-step tasks with large tool outputs. Set a max_tokens ceiling per call, cap the number of tool-use iterations per task (5–10 is reasonable for most workflows), and monitor your Anthropic Console usage dashboard weekly during early rollout. If you’re running agents for multiple internal teams, consider a lightweight cost-tracking wrapper that tags each request with a project ID so you can attribute spend accurately before it becomes a surprise line item.

    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 Docker to run Anthropic AI agents in production?
    A: Not strictly, but it’s strongly recommended. Containerizing isolates tool execution from your host system, which matters a lot once the agent can run shell commands or hit internal APIs.

    Q: How much does it cost to run an agent in production?
    A: Costs are dominated by API token usage, not hosting. A small VPS (4GB RAM) is usually sufficient for the agent process itself; token costs scale with task complexity and iteration count, so cap both.

    Q: Can Anthropic agents run fully offline?
    A: No — the reasoning step requires a call to Claude’s API, so you need reliable outbound internet access. Tool execution (the part that touches your infrastructure) can be entirely local.

    Q: What’s the biggest security risk with tool-using agents?
    A: Prompt injection leading to tool misuse — untrusted input tricking the agent into calling a tool with dangerous parameters. Sandbox tool execution and validate inputs to mitigate this.

    Q: How do I prevent an agent from looping forever?
    A: Set a hard cap on tool-use iterations per task in your agent loop code, and enforce a max_tokens limit on every model call.

    Q: Which Claude model should I use for agent workloads?
    A: Sonnet-tier models are generally the best balance of cost and capability for most agent tasks; reserve Opus-tier models for tasks requiring deeper multi-step reasoning.

    Anthropic AI agents are still a young category, but the deployment pattern is already familiar to anyone who’s shipped containerized services before: build small, containerize early, monitor aggressively, and scope permissions tightly. Start with the minimal agent above, get it running reliably in Docker, then layer on orchestration and monitoring as your task complexity grows.

  • Bot Telegram List: Best DevOps Telegram Bots (2026)

    The Best Bot Telegram List for DevOps and Server Monitoring in 2026

    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 run production servers, ship code daily, or manage a small homelab, you’ve probably typed journalctl -f or refreshed a dashboard one too many times. A good bot telegram list solves that problem by pushing the information to you instead of making you go looking for it. Telegram’s Bot API is free, has no rate-limit surprises for small teams, and works on every platform you already have open — which is why it has quietly become one of the most popular notification channels for sysadmins and DevOps engineers.

    This guide is a practical, curated bot telegram list organized by use case — monitoring, CI/CD, server management, and cost tracking — plus a walkthrough for self-hosting your own bot with Docker if none of the public options fit your workflow.

    Why Telegram Bots Belong in Your Ops Toolkit

    Telegram bots are lightweight HTTPS webhooks or long-polling clients that talk to the official Telegram Bot API. Unlike Slack apps, they don’t require workspace admin approval, OAuth scopes, or a paid tier to get real-time push notifications. Unlike email, they arrive instantly and don’t get buried in a inbox full of noreply@ noise.

    Why Sysadmins Prefer Telegram Over Email and Slack for Alerts

    Three reasons come up constantly when engineers explain why they switched:

  • Delivery speed. Telegram pushes messages in under a second in most regions, versus email which can be delayed by spam filtering or greylisting.
  • No vendor lock-in. A Telegram bot token works the same whether you’re sending alerts from a bash script, a Python daemon, or a Grafana webhook — no proprietary SDK required.
  • Group and channel support. You can broadcast to an entire on-call team via a group chat, or keep a private channel as an audit log of every deploy and alert, searchable later.
  • These properties make Telegram bots a natural fit for anyone already running a self-hosted monitoring stack and looking for a cheap, reliable notification transport.

    Building Your Own Bot Telegram List

    Before relying on third-party bots, it’s worth understanding how easy it is to run your own. Self-hosting gives you full control over what data leaves your infrastructure — an important consideration if your alerts contain hostnames, IPs, or customer data.

    How to Self-Host a Telegram Bot with Docker

    Creating a bot takes two minutes: message @BotFather on Telegram, run /newbot, and save the token it gives you. From there, you can containerize a simple alert-forwarding bot in Python using the python-telegram-bot library.

    # bot.py
    import os
    import logging
    from telegram import Bot
    from flask import Flask, request
    
    logging.basicConfig(level=logging.INFO)
    app = Flask(__name__)
    bot = Bot(token=os.environ["TELEGRAM_BOT_TOKEN"])
    CHAT_ID = os.environ["TELEGRAM_CHAT_ID"]
    
    @app.route("/alert", methods=["POST"])
    def receive_alert():
        payload = request.get_json(force=True)
        message = payload.get("message", "Unnamed alert triggered")
        bot.send_message(chat_id=CHAT_ID, text=f"U0001F6A8 {message}")
        return {"status": "sent"}, 200
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=5000)

    Package it with a minimal Dockerfile:

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

    And wire it up with docker-compose.yml so it restarts on boot and reads secrets from environment variables instead of hardcoding them:

    services:
      telegram-alert-bot:
        build: .
        container_name: telegram-alert-bot
        restart: unless-stopped
        environment:
          TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN}
          TELEGRAM_CHAT_ID: ${TELEGRAM_CHAT_ID}
        ports:
          - "5000:5000"

    Once deployed, any monitoring tool that can send a webhook — Prometheus Alertmanager, Uptime Kuma, a cron job, a curl call from a deploy script — can now push straight into your bot telegram list. For a deeper dive into container orchestration patterns like this one, see our Docker Compose guide.

    Categories to Include in Your Bot Telegram List

    A well-rounded bot telegram list for a DevOps workflow usually covers these categories:

  • Monitoring and uptime bots — forward alerts from Prometheus Alertmanager, Grafana, or Uptime Kuma the moment a threshold is breached.
  • CI/CD notification bots — post build status, deploy success/failure, and rollback events from GitHub Actions, GitLab CI, or Jenkins.
  • Server management bots — accept authenticated commands like /restart nginx or /disk to check disk usage without opening an SSH session.
  • Log-tail bots — stream filtered journalctl or Docker log output for a specific service when something looks off.
  • Cost and billing bots — ping you when cloud spend crosses a budget threshold, useful if you run infrastructure across multiple providers.
  • Streaming and media bots — for teams running self-hosted media servers, bots that report transcode failures or new library additions.
  • Most teams don’t need every category on day one. Start with monitoring and CI/CD notifications — they catch the incidents that actually wake people up — then expand from there.

    Securing Your Telegram Bot Deployment

    A bot with a leaked token is a bot anyone can send messages through, and a bot with an open webhook endpoint is a bot anyone can flood with fake alerts. A few non-negotiable practices:

  • Never commit your bot token to a public repository — use .env files excluded via .gitignore, or a secrets manager.
  • Restrict who can trigger command-style bots by checking the sender’s chat_id against an allowlist before executing anything.
  • Put your webhook endpoint behind a reverse proxy with TLS, and consider tunneling it through Cloudflare instead of exposing a raw port on your VPS. See our Cloudflare Tunnel setup guide for a walkthrough.
  • Rotate the bot token immediately via BotFather if you suspect it has leaked — Telegram makes this a one-command action (/revoke).
  • Rate-limit inbound webhook calls so a misconfigured monitoring rule can’t spam your chat (or your bot’s IP) into a temporary Telegram API ban.
  • Recommended VPS and Monitoring Stack for Running Your Bots

    Self-hosted bots need somewhere reliable to run. A small VPS is plenty — these bots are lightweight and rarely need more than 512MB of RAM. DigitalOcean and Hetzner both offer cheap, predictable-pricing droplets that are a good fit for a bot telegram list running alongside your existing monitoring containers.

    If you’d rather not build the monitoring layer that feeds your bots from scratch, BetterStack provides hosted uptime and log monitoring with native webhook support you can point straight at your Telegram bot’s /alert endpoint. And if you’re exposing that endpoint to the internet, routing it through Cloudflare adds DDoS protection and TLS termination without extra config on your end.

    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 paid Telegram account to run a bot?
    No. Bot creation via BotFather is completely free, and there’s no tier system — the same API is available whether you’re sending ten messages a day or ten thousand.

    Can one bot serve multiple chat groups or channels?
    Yes. A single bot token can send messages to any chat_id it has been added to, so you can run one bot that posts to a monitoring channel, a deploys channel, and a personal DM for critical alerts.

    Is it safe to send server hostnames and IPs through Telegram?
    Telegram messages are encrypted in transit, but the platform itself isn’t end-to-end encrypted by default (only Secret Chats are). For sensitive data, use a private group restricted to your team and avoid pasting credentials directly into messages.

    What’s the difference between polling and webhook mode for a bot?
    Polling mode has your bot repeatedly ask Telegram’s servers for new messages, which is simpler to set up but slightly less efficient. Webhook mode has Telegram push updates to your server instantly, but requires a public HTTPS endpoint — which is why a reverse proxy or tunnel setup matters.

    How many messages can a Telegram bot send per second?
    Telegram’s official limit is roughly 30 messages per second to different chats, and about one message per second to the same chat. For alerting use cases this is far more than you’ll ever need.

    Can I trigger actions on my server by messaging my bot, not just receive alerts?
    Yes — that’s the server management bot pattern. Your bot’s message handler can parse commands like /restart nginx and execute a whitelisted shell command, though this should always be paired with strict sender verification as described in the security section above.

    A good bot telegram list isn’t about collecting as many bots as possible — it’s about routing the right signal to the right channel at the right time. Start with one monitoring bot and one CI/CD bot, self-host them with Docker for full control over your data, and expand the list only when a real workflow gap shows up.

  • Free Hosting Vps

    Free Hosting VPS: What It Actually Means and When to Use One

    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.

    Looking for a free hosting VPS can feel like searching for a unicorn — most “free VPS” offers are either trial credits with an expiration date, severely limited resource tiers, or bait for a paid upgrade. This guide explains what a free hosting VPS realistically looks like in 2026, where the real free tiers exist, what their limits are, and how to set one up properly so you don’t waste time on a dead end. If your workloads are serious — a production API, a customer-facing site, or anything with real traffic — you’ll also learn when it’s time to move past a free hosting vps and pay for real resources.

    What “Free Hosting VPS” Really Means

    A VPS (Virtual Private Server) is a slice of a physical machine, virtualized so you get your own OS, root access, and dedicated CPU/RAM/disk allocation — unlike shared hosting, where you’re one of many tenants on a single web server stack with no shell access. When people search for a free hosting vps, they’re usually looking for one of three things:

  • A permanent free tier with genuinely no cost, just small resource caps
  • A free trial with credit that expires after a set period
  • A “free” VPS bundled with another paid service (registrar, CDN, etc.)
  • Only the first category is a true free hosting vps in the sense most developers want — something you can run indefinitely without a card on file. The second is common and useful for testing, but it’s a trial, not a permanent plan. The third is rare and usually not worth the trade-offs.

    Why Providers Offer Free VPS Tiers at All

    Free tiers exist because providers want developers to build on their platform early, get comfortable with the tooling, and upgrade organically once a project grows. It’s a acquisition funnel, not charity. That’s worth remembering: a free hosting vps tier is designed to be outgrown, and the provider’s onboarding, documentation, and support quality on the free tier is usually a preview of what you’d get as a paying customer.

    Common Limits You’ll Run Into

    Every free hosting vps option comes with constraints, and they’re not arbitrary — they exist to keep the free tier sustainable for the provider. Expect some combination of:

  • Capped RAM (often 512MB–1GB)
  • Shared or throttled CPU cores
  • Limited outbound bandwidth per month
  • Small disk allocations (10–25GB is typical)
  • Time-boxed credit (e.g., $100–200 expiring in 60 days) rather than a truly indefinite plan
  • Restrictions on what you can run (no crypto mining, no mass email sending, no high-traffic proxying)
  • Where to Actually Find a Free Hosting VPS

    There isn’t one single “best” free hosting vps — the right option depends on what you’re building. A few realistic paths:

    Cloud Provider Trial Credits

    Major providers like DigitalOcean, Vultr, and Linode periodically offer signup credit that functions as a free hosting vps for a limited window — often enough to run a small droplet for one to two months while you learn the platform, test a deployment pipeline, or prototype a side project. The key is understanding these are trial credits, not permanent free plans: set a calendar reminder before the credit expires so you’re not surprised by a charge.

    Always-Free Cloud Compute Tiers

    A smaller number of providers maintain an always-free compute instance (small, ARM-based, or burstable) rather than a time-limited credit. These tend to have the tightest resource ceilings of any free hosting vps option, but they don’t expire as long as your account stays active and compliant with usage terms. They’re a reasonable home for a lightweight monitoring agent, a personal DNS resolver, or a small Telegram/Discord bot — not for anything with meaningful traffic.

    University and Open-Source Program Credits

    If you’re a student or maintain an active open-source project, some providers run credit programs specifically for that audience. These aren’t a free hosting vps in the strict “forever free” sense either, but the credit amounts and durations are often more generous than standard trials.

    Setting Up Your First Free VPS

    Once you’ve picked a provider, the setup steps are largely the same regardless of whether you’re on a free hosting vps trial or a paid instance — that consistency is actually one of the best reasons to start on a free tier: everything you learn transfers directly.

    Initial Server Hardening

    Before deploying anything, lock down SSH access and create a non-root user:

    # Create a new user and add to sudo group
    adduser deploy
    usermod -aG sudo deploy
    
    # Disable root SSH login and password auth
    sed -i 's/^PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
    sed -i 's/^PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
    systemctl restart sshd
    
    # Enable a basic firewall
    ufw allow OpenSSH
    ufw allow 80,443/tcp
    ufw enable

    This step matters more on a free hosting vps than a paid one, because free-tier IP ranges are frequently scanned by bots looking for default credentials.

    Installing Docker for Portable Deployments

    Running services in containers keeps your setup portable if you later migrate from a free hosting vps to a paid plan or a different provider entirely:

    # docker-compose.yml — minimal example
    version: "3.9"
    services:
      app:
        image: nginx:alpine
        ports:
          - "80:80"
        restart: unless-stopped

    For official installation steps, follow the current instructions at Docker’s documentation. If you’re new to the compose workflow, it’s worth reading up on Dockerfile vs Docker Compose differences before deciding how to structure your services, and once things are running you’ll want to know how to tear a stack down cleanly — see Docker Compose Down: Full Guide to Stopping Stacks.

    Monitoring Resource Usage

    Free hosting vps instances have tight ceilings, so keep an eye on memory and disk before you hit a hard limit:

    # Quick resource check
    free -h
    df -h
    docker stats --no-stream

    Setting up basic alerting early — even a simple cron job that pings you when disk usage crosses 80% — saves you from a surprise outage on a resource-constrained instance.

    Free Hosting VPS vs Shared Hosting

    It’s worth being clear about what a free hosting vps gets you that shared hosting doesn’t, since the two are often confused by newcomers:

  • Root access — you control the OS, install any package, and configure services directly
  • Isolated resources — your RAM and CPU allocation isn’t silently shared with noisy neighbors the way it can be on shared hosting
  • Full networking control — you can open arbitrary ports, run your own reverse proxy, and configure firewall rules
  • No platform lock-in — anything that runs in a standard Linux container or VM will run the same way on your next host
  • The trade-off is that you’re responsible for security patching, backups, and uptime — shared hosting abstracts all of that away, at the cost of flexibility.

    When to Move Beyond a Free VPS

    A free hosting vps is a good starting point for learning, prototyping, and low-traffic personal projects, but there are clear signals it’s time to upgrade:

  • You’re consistently hitting RAM or CPU limits under normal load, not just spikes
  • Your project has real users depending on uptime
  • You need consistent, non-expiring billing rather than credit that runs out
  • You’re running anything that handles customer data, which usually requires stronger backup and compliance guarantees than free tiers offer
  • If you’re automating deployments or workflows on your VPS, it’s also worth reading about self-hosting n8n on Docker once you’ve outgrown the free tier — automation platforms tend to need more consistent resources than a free hosting vps can reliably provide.


    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 a free hosting vps actually free forever, or does it expire?
    It depends on the type. Trial credits (the most common form of free hosting vps) expire after a fixed period, typically 30–90 days. Always-free compute tiers don’t expire on a timer, but they come with the smallest resource allocations and usage restrictions.

    Can I run a production website on a free hosting vps?
    You can, but it’s not advisable for anything with meaningful traffic or uptime requirements. Free tiers are throttled and often lack SLAs, so unexpected downtime is more likely than on a paid plan.

    Do I need a credit card to sign up for a free hosting vps?
    Most providers require a card on file even for free trial credit, primarily to prevent abuse. Always-free tiers sometimes waive this, but requirements vary by provider and change over time, so check the current signup flow directly.

    What’s the difference between a free hosting vps and free static site hosting?
    A VPS gives you a full virtual machine with root access and the ability to run any server software. Free static hosting (for example on platforms like Cloudflare Pages) only serves pre-built static files — no backend processes, databases, or custom server configuration. If your project needs a database, background jobs, or a custom API, you need a VPS, not static hosting.

    Conclusion

    A free hosting vps is genuinely useful for learning server administration, testing a deployment pipeline, or running a small personal project — but it’s rarely a permanent home for anything serious. Understand which category of “free” you’re actually signing up for, harden the server properly from day one, and treat it as a stepping stone rather than a destination. When your project outgrows the resource ceiling — and most useful projects eventually do — moving to a small paid instance from a provider like Hetzner is a straightforward next step, since the Linux fundamentals you learned on the free tier carry over directly. For deeper background on server virtualization concepts, the Kubernetes documentation is also a useful reference once you’re managing more than a single instance.

  • Docker Compose Environment Variables: Complete Guide

    Docker Compose Environment Variables: A Complete 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 ever hardcoded a database password directly into a docker-compose.yml file and then panicked when you realized it got pushed to a public GitHub repo, you already understand why managing a docker compose environment correctly matters. Environment variables are the standard way to inject configuration into containers without baking secrets or environment-specific values into your images. Get this wrong and you end up with leaked credentials, brittle deployments, or containers that behave differently in staging than in production.

    This guide walks through every practical way to set, override, and debug environment variables in Docker Compose, plus the precedence rules that trip up almost everyone the first time.

    Why Environment Variables Matter in a Docker Compose Setup

    Environment variables let you decouple your application’s configuration from its code. Instead of rebuilding an image every time a database URL or API key changes, you pass that value in at runtime. This is the core idea behind the 12-Factor App methodology, and Docker Compose was built with it in mind.

    A well-structured docker compose environment gives you:

  • Portable images that work identically across dev, staging, and production
  • A single source of truth for configuration per environment
  • The ability to keep secrets out of version control
  • Easier debugging, since you can inspect exactly what values a container received
  • If you’re new to Compose in general, it’s worth reading our Docker Compose networking guide first, since environment variables and networking often intersect (service discovery, hostnames, ports).

    Setting Variables with the environment Key

    The most direct way to pass environment variables into a service is the environment key inside your docker-compose.yml. You can write it as a list or a mapping:

    services:
      web:
        image: node:20-alpine
        environment:
          - NODE_ENV=production
          - API_PORT=3000
          - DEBUG=false

    or the map form:

    services:
      web:
        image: node:20-alpine
        environment:
          NODE_ENV: production
          API_PORT: "3000"
          DEBUG: "false"

    Both are functionally identical. The map form is easier to read and merge in overlay files, so most teams standardize on it. Numeric and boolean-looking values should be quoted, because YAML will otherwise try to parse 3000 or false as their native types instead of strings, which can cause subtle bugs in some applications.

    You can also pull values from your shell into the compose file:

    services:
      web:
        environment:
          - API_KEY=${API_KEY}

    Running API_KEY=abc123 docker compose up will inject abc123 into the container. This is useful for CI pipelines where secrets are already exported as shell variables.

    Using env_file for Larger Configuration Sets

    Once you have more than a handful of variables, listing them inline gets unwieldy. The env_file directive lets you point to a plain text file instead:

    services:
      web:
        image: node:20-alpine
        env_file:
          - .env.production

    The file itself is just KEY=VALUE pairs, one per line:

    NODE_ENV=production
    API_PORT=3000
    DATABASE_URL=postgres://user:pass@db:5432/appdb

    A few rules to know:

  • Lines starting with # are treated as comments
  • Blank lines are ignored
  • Values are not shell-expanded inside the file (no $HOME substitution)
  • You can list multiple env_file entries; later files override earlier ones
  • This is the cleanest option when you’re managing dozens of variables across multiple services, and it keeps your docker-compose.yml readable. Just make sure any file containing real secrets is listed in .gitignore — a mistake we cover in more depth in our container secrets management guide.

    The Special .env File and Variable Substitution

    Docker Compose treats a file literally named .env in the same directory as your docker-compose.yml differently from other env files. It isn’t injected into containers automatically — instead, Compose reads it to substitute ${VARIABLE} placeholders inside the compose file itself, before the file is even parsed.

    # .env
    POSTGRES_VERSION=16
    POSTGRES_PASSWORD=supersecret
    COMPOSE_PROJECT_NAME=myapp

    services:
      db:
        image: postgres:${POSTGRES_VERSION}
        environment:
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

    This distinction confuses a lot of people: .env drives compose-file templating, while env_file: drives container environment injection. You can use both together — a .env file for values referenced in the YAML structure (image tags, project name, ports) and env_file: entries for values that need to land inside the running container.

    You can verify what Compose actually resolved with:

    docker compose config

    This prints the fully rendered configuration with all variables substituted, which is the fastest way to catch a typo before it reaches production.

    Using Multiple Compose Files to Override Environment Values

    Docker Compose supports merging multiple compose files together, which is handy for maintaining a base environment configuration and layering environment-specific overrides on top:

    docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

    # docker-compose.prod.yml
    services:
      web:
        environment:
          NODE_ENV: production
          LOG_LEVEL: warn

    Values in the later file override matching keys in the base file, following the same merge rules as top-level list-vs-map behavior in the compose spec. This pattern is especially useful for keeping a shared docker-compose.yml for local development and a slim docker-compose.prod.yml that only overrides the handful of variables that actually differ — log level, replica counts, or a production database URL. Compose also automatically loads a file named docker-compose.override.yml if it exists in the same directory, without needing the -f flag at all, which is convenient for keeping personal local overrides out of version control.

    Precedence: Which Value Actually Wins

    When the same variable is set in multiple places, Compose applies a strict precedence order, from highest to lowest priority:

    1. Variables set with docker compose run -e VAR=value
    2. Variables defined under the environment key in the compose file
    3. Variables from files listed under env_file
    4. Variables set in the shell environment before running docker compose up
    5. Variables defined in a .env file (used only for compose-file substitution, not container injection)

    In practice, this means an environment: entry will always override a matching key from env_file:, even if env_file is listed. If your container isn’t picking up the value you expect, check every one of these layers — this is the single most common source of “why isn’t my environment variable working” issues reported on the official Docker Compose documentation and forums.

    Managing Secrets Safely

    Environment variables are convenient, but they aren’t a secure secrets store by themselves — anything passed via environment: or .env is visible to anyone who can run docker inspect or docker compose config against the running stack. For sensitive values in production, consider:

  • Using Docker Compose’s native secrets: block, which mounts values as files rather than environment variables
  • Pulling secrets at runtime from a vault (HashiCorp Vault, AWS Secrets Manager, Doppler)
  • Restricting file permissions on .env files (chmod 600 .env)
  • Never committing .env or env_file targets to git — add them to .gitignore immediately after creating them
  • Using separate .env files per environment (.env.dev, .env.staging, .env.production) and loading the correct one explicitly
  • If you’re deploying these stacks on your own infrastructure, make sure the host itself is locked down too — a misconfigured environment variable is a much smaller risk than an exposed Docker socket on a public-facing VPS. Providers like DigitalOcean make it straightforward to spin up a hardened droplet specifically for container workloads, with private networking so your secrets never traverse the public internet.

    Once your environment variables are correctly configured, the next challenge is observability — knowing when a misconfigured variable causes a service to silently fail. Tools like BetterStack can monitor container logs and alert you the moment a service crashes from a missing environment variable, which saves hours of manual debugging in production.

    Debugging a Broken Environment

    When a container isn’t seeing the variable you expect, work through this checklist:

    # See what Compose resolved before starting anything
    docker compose config
    
    # Check the environment inside a running container
    docker compose exec web env
    
    # Check a stopped/crashed container's environment
    docker inspect <container_id> --format '{{.Config.Env}}'

    Common causes of mismatched values:

  • A typo in the variable name (DATABSE_URL vs DATABASE_URL)
  • Quoting issues in the .env file (Compose does not strip surrounding quotes consistently across versions)
  • An environment: entry silently overriding an env_file: value
  • Forgetting to restart the container after changing .env — Compose doesn’t hot-reload environment changes; you need docker compose up -d --force-recreate
  • A Real-World Multi-Service Example

    Here’s how these pieces fit together in a typical stack with a web app, a database, and Redis cache. Assume the following directory structure:

    myapp/
    ├── docker-compose.yml
    ├── docker-compose.prod.yml
    ├── .env
    ├── .env.production
    └── app/

    The base docker-compose.yml stays generic:

    services:
      web:
        build: ./app
        env_file:
          - .env.production
        environment:
          REDIS_URL: redis://cache:6379
        depends_on:
          - db
          - cache
      db:
        image: postgres:${POSTGRES_VERSION}
        environment:
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
        volumes:
          - db-data:/var/lib/postgresql/data
      cache:
        image: redis:7-alpine
    
    volumes:
      db-data:

    Notice the layering: ${POSTGRES_VERSION} and ${POSTGRES_PASSWORD} come from the auto-loaded .env file and get substituted into the YAML structure itself, while REDIS_URL is hardcoded because it never changes between environments, and the application’s own secrets live in .env.production, loaded via env_file:. This split keeps infrastructure-level values (image versions, resource names) separate from application-level configuration (API keys, connection strings), which makes the compose file easier to audit at a glance.

    Common Mistakes to Avoid

  • Committing .env files with real secrets to version control instead of using .env.example as a template
  • Assuming docker compose up automatically picks up changes to .env — you need to recreate containers
  • Mixing up .env (compose-file substitution) with env_file: (container injection) and expecting them to behave the same way
  • Quoting numeric or boolean values inconsistently, which causes type mismatches inside the application
  • Hardcoding environment-specific values like database hostnames directly into the image instead of injecting them at runtime
  • 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: What’s the difference between .env and env_file in Docker Compose?
    A: .env is read by Compose itself to substitute ${VAR} placeholders inside the docker-compose.yml file before parsing. env_file injects variables directly into a container’s runtime environment. They serve different purposes and can be used together.

    Q: Can I use multiple .env files with different names?
    A: Compose only auto-loads a file literally named .env. To use a differently named file for substitution, pass it explicitly with docker compose --env-file .env.staging up.

    Q: Does environment: override env_file: if both set the same variable?
    A: Yes. Values under the environment: key always take precedence over matching keys loaded from env_file:.

    Q: Are environment variables secure enough for passwords and API keys?
    A: For low-stakes local development, generally fine. For production secrets, use Docker’s secrets: block, a vault service, or your cloud provider’s secrets manager instead, since environment variables are visible via docker inspect.

    Q: Why isn’t my .env file being picked up?
    A: The most common cause is the file not being in the same directory as docker-compose.yml, or a typo in the filename (it must be exactly .env, not env or .env.txt).

    Q: How do I pass a variable from the shell into a container at runtime?
    A: Export it in your shell and reference it in the compose file, e.g. environment: - API_KEY=${API_KEY}, then run API_KEY=abc123 docker compose up.

    Wrapping Up

    A clean docker compose environment setup comes down to picking the right mechanism for the job: environment: for a handful of values, env_file: for larger sets, and .env for compose-file-level substitution. Once you understand the precedence order and keep secrets out of version control, most of the “why isn’t this variable working” headaches disappear. For a deeper look at structuring multi-service stacks around these variables, check out our complete Docker Compose guide. Test your setup locally with docker compose config before every deploy, and you’ll catch most environment-related surprises long before they reach production.

  • Free Ai Agent

    Free AI Agent Options for Self-Hosted DevOps Teams

    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.

    Teams evaluating automation often start with the same question: is there a genuinely usable free AI agent option before committing budget to a paid platform? The short answer is yes — open-source frameworks, self-hosted runtimes, and generous free tiers from API providers make it possible to run a capable free ai agent stack today, provided you’re comfortable managing the infrastructure yourself. This guide walks through the practical building blocks, deployment patterns, and tradeoffs involved.

    Most “free” agent platforms are free in the sense that the software itself has no license cost, not in the sense that running it costs nothing. You still pay for compute, storage, and any LLM API calls the agent makes. Understanding that distinction early saves a lot of confusion later when a bill for model inference arrives despite using “free” tooling.

    What a Free AI Agent Actually Is

    An AI agent is a system that combines a language model with the ability to take actions — calling APIs, executing code, reading and writing files, or triggering workflows — rather than just returning text. A free ai agent, in the context most DevOps teams care about, is one built from open-source components: an open agent framework, a self-hosted orchestration layer, and either a locally-run model or a pay-as-you-go API with a free tier.

    This is different from commercial “AI agent” products that bundle hosting, model access, and a UI into a single subscription. Those can be worth paying for once you scale, but they aren’t necessary to get started. If you already run n8n or a similar automation stack, you likely have most of the plumbing needed to build one.

    Open-Source Agent Frameworks

    A handful of frameworks dominate the free ai agent ecosystem:

  • LangChain / LangGraph — a Python and JavaScript framework for chaining LLM calls, tools, and memory into agent loops. Well-documented, large community, steep learning curve for complex graphs.
  • CrewAI — a lighter-weight framework focused on multi-agent collaboration, where several agents with defined roles work together on a task.
  • AutoGen — Microsoft’s framework for building conversational multi-agent systems, useful when agents need to negotiate or critique each other’s output.
  • n8n’s native AI Agent node — not a coding framework but a visual workflow builder with an agent node built in, letting you wire an LLM to tools without writing orchestration code.
  • All four are open source and free to self-host. The real cost driver is the model you connect them to, not the framework.

    Self-Hosted Runtimes vs. Managed Platforms

    You have two broad deployment paths:

    1. Self-host the agent framework on your own VPS or Kubernetes cluster, connecting it to either a local model (via Ollama or similar) or a hosted API.
    2. Use a managed platform’s free tier, which handles hosting for you but caps usage, request volume, or feature access.

    Self-hosting gives you full control over data, logging, and cost, at the price of operational responsibility. Managed free tiers are faster to start with but rarely scale past prototyping without a paid upgrade.

    Setting Up a Free AI Agent on a VPS

    For most small teams, the fastest path to a working free ai agent is a small VPS running Docker, with the agent framework and its dependencies containerized. This keeps the setup reproducible and easy to tear down if you want to switch frameworks later.

    A minimal docker-compose.yml for an n8n-based agent stack looks like this:

    version: "3.8"
    services:
      n8n:
        image: n8nio/n8n:latest
        restart: unless-stopped
        ports:
          - "5678:5678"
        environment:
          - N8N_HOST=agent.example.com
          - N8N_PROTOCOL=https
          - GENERIC_TIMEZONE=UTC
        volumes:
          - n8n_data:/home/node/.n8n
    
    volumes:
      n8n_data:

    If you’re building the agent in Python with LangChain instead, the pattern is similar — a single container running your agent script, with environment variables holding API keys and a mounted volume for persistent memory or logs. Bring the stack up with:

    docker compose up -d
    docker compose logs -f n8n

    If you’re new to this pattern, our guide on how to build AI agents with n8n walks through the node-by-node setup, and the general n8n automation guide covers self-hosting fundamentals if you haven’t deployed n8n before.

    Choosing a Model Backend

    The agent framework is only half the stack — you also need a model. Three realistic free-tier-friendly options:

  • Local models via Ollama — genuinely free once the hardware is paid for, no per-request cost, but requires enough RAM/VRAM to run a usable model and generally produces weaker reasoning than top-tier hosted models.
  • Free API tiers — several model providers offer limited free monthly quotas, useful for prototyping a free ai agent before deciding whether to pay for higher throughput.
  • Open-weight models on your own GPU instance — more capable than most local CPU setups but requires a GPU-backed VPS, which pushes you out of “free” territory quickly.
  • For prototyping, local models via Ollama are usually the most honestly “free” option, since there’s no metered API cost while you iterate on prompts and tool definitions.

    Provisioning the VPS Itself

    Whatever framework you pick, you need a VPS with enough RAM to run Docker plus the agent process comfortably — 2-4GB is workable for a lightweight agent hitting a hosted API, more if you’re running a local model. Providers like DigitalOcean and Hetzner both offer entry-level instances suitable for this kind of workload, and either works fine as long as you size the instance to your model’s memory footprint rather than guessing.

    Free AI Agent Tools Beyond Chat-Style Assistants

    Not every useful agent looks like a chatbot. Some of the most practical free ai agent deployments are narrow, task-specific automations wired into an existing pipeline:

  • A code-review agent that comments on pull requests using a self-hosted LLM
  • A log-triage agent that watches container logs and flags anomalies
  • A content or SEO agent that drafts and scores article outlines against defined criteria
  • A support-ticket triage agent that tags and routes incoming tickets before a human sees them
  • If you’re exploring agents for a specific business function rather than general-purpose automation, it’s worth reading domain-specific guides — for example our pieces on building customer service AI agents or SEO AI agents — since the tool integrations and evaluation criteria differ meaningfully by use case even when the underlying framework is the same.

    Comparing Framework Overhead

    Before committing to a framework, weigh the operational overhead against what you actually need:

    | Consideration | Lightweight (n8n node) | Full framework (LangChain/CrewAI) |
    |—|—|—|
    | Setup time | Low | Moderate to high |
    | Custom tool integration | Limited to available nodes/HTTP requests | Full programmatic control |
    | Multi-agent orchestration | Manual, workflow-based | Native support in most frameworks |
    | Debugging | Visual execution log | Requires custom logging |

    Teams already comfortable with visual workflow tools often get a working free ai agent running faster with n8n than by writing framework code from scratch, even though the framework route offers more flexibility long-term.

    Security and Operational Considerations

    A free ai agent that can execute code, call external APIs, or write to a database is a real production system, not a toy, and should be treated with the same care as any other service with credentials attached.

  • Never give an agent broader API scopes or filesystem access than the specific task requires.
  • Log every tool call the agent makes, including inputs and outputs, so you can audit what it actually did.
  • Rate-limit and sandbox any code-execution tool the agent has access to.
  • Rotate and scope API keys separately from your other production credentials.
  • Treat any agent with write access to production systems as requiring the same review process as a human-authored change.
  • These practices matter more, not less, when the agent is “free” — there’s a tendency to treat low-cost tooling as low-stakes, which isn’t true once the agent has real permissions. If you’re deploying agents with meaningful access, it’s worth reading a dedicated guide on AI agent security before going further than a local prototype.


    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 there a truly free AI agent with no hidden costs?
    The framework and hosting software can be entirely free if self-hosted, but you’ll still pay for the VPS or server it runs on, and for any LLM API calls it makes unless you’re running a fully local model. “Free ai agent” generally means free software, not zero infrastructure cost.

    What’s the cheapest way to run a free AI agent for testing?
    Run an open-source framework in Docker on a small VPS, connected to a local model via Ollama for the prototyping phase. This avoids per-request API costs while you validate the agent’s logic, and you can switch to a hosted model later if local performance isn’t sufficient.

    Do I need Kubernetes to self-host an AI agent?
    No. A single Docker Compose file on one VPS is enough for most single-agent or small multi-agent setups. Kubernetes becomes worth the added complexity only once you’re running many agents concurrently or need auto-scaling.

    Can a free AI agent framework handle production workloads?
    Yes, provided you treat the deployment with normal production practices — monitoring, logging, credential scoping, and backups. The framework being open source doesn’t mean the deployment is inherently less reliable; reliability comes from how it’s operated, not its license.

    Conclusion

    Building a free ai agent is realistic for most DevOps teams: open-source frameworks like LangChain, CrewAI, and n8n’s agent node are mature enough for real use, and a small self-hosted VPS is enough infrastructure to get started. The tradeoff isn’t cost versus capability — it’s who manages the operational burden. Self-hosting hands that burden to you in exchange for full control and no framework licensing fees, while managed platforms take on the operations work in exchange for a subscription once you outgrow their free tier. For teams that already run Docker-based infrastructure, starting with a self-hosted free ai agent stack is a low-risk way to learn what agent automation can actually do for your workflows before deciding whether a paid platform is worth it. For deployment fundamentals, the official Docker documentation and Kubernetes documentation remain the most reliable references once you’re ready to scale past a single VPS.

  • How to Create AI Agents: A DevOps Deployment Guide

    How to Create AI Agents: A Practical Guide for Developers and Sysadmins

    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’re a developer or sysadmin trying to figure out how to create AI agents that actually run in production — not just in a notebook demo — this guide is for you. We’ll skip the marketing fluff and walk through the real infrastructure decisions: containerization, orchestration, model serving, and deployment patterns that hold up under real traffic.

    AI agents — autonomous or semi-autonomous programs that use large language models (LLMs) to reason, call tools, and complete multi-step tasks — have moved from research labs into everyday DevOps workflows. Teams use them for log triage, incident response, infrastructure provisioning, and customer support automation. But most tutorials stop at “pip install” and never address how to actually deploy and operate these agents reliably.

    Why Create AI Agents Instead of Using a SaaS Tool?

    Before you commit engineering time, it’s worth asking why you’d build a custom agent instead of subscribing to a hosted platform. Three reasons come up repeatedly:

  • Data residency and compliance. Self-hosting keeps sensitive logs, credentials, and customer data off third-party servers.
  • Cost control at scale. SaaS agent platforms often charge per-execution; a self-hosted agent on your own compute can be dramatically cheaper once volume grows.
  • Custom tool integration. Internal APIs, proprietary databases, and legacy systems rarely have first-class connectors in commercial agent platforms.
  • If none of those apply to your situation, a hosted product like OpenAI’s Assistants API might genuinely be the faster path. But if you need control over infrastructure, keep reading.

    Core Components of an AI Agent Stack

    Every production AI agent, regardless of framework, is built from the same basic layers:

  • LLM backend — the reasoning engine (hosted API like OpenAI/Anthropic, or a self-hosted model via Ollama)
  • Orchestration layer — the framework that manages prompts, memory, and tool calls (LangChain, LlamaIndex, CrewAI, or a custom loop)
  • Tool/function layer — the code the agent can actually execute (shell commands, API calls, database queries)
  • State/memory store — Redis, Postgres, or a vector database for conversation history and retrieval
  • Execution environment — usually a container, so the agent’s tool calls are sandboxed and reproducible
  • Getting the execution environment right is where most home-grown agent projects fall apart. An agent that can run arbitrary shell commands on your host is a security incident waiting to happen — which is exactly why containerization matters here, not just for portability but for isolation.

    Setting Up the Environment

    We’ll build a minimal but production-realistic agent using Python, the OpenAI API, and Docker for isolation. This pattern generalizes to Anthropic’s Claude API or a self-hosted model with minimal changes.

    Step 1: Project Structure and Dependencies

    Start with a clean project layout:

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

    Create a requirements.txt so the environment is reproducible:

    pip freeze > requirements.txt

    Step 2: Write the Agent Loop

    The core of an agent is a loop: the model reasons about the task, decides whether to call a tool, executes it, and feeds the result back in. Here’s a minimal but functional version:

    # agent.py
    import os
    import json
    from openai import OpenAI
    
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    
    def get_disk_usage():
        import subprocess
        result = subprocess.run(["df", "-h", "/"], capture_output=True, text=True)
        return result.stdout
    
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_disk_usage",
                "description": "Return current disk usage for the root filesystem",
                "parameters": {"type": "object", "properties": {}},
            },
        }
    ]
    
    def run_agent(user_prompt):
        messages = [{"role": "user", "content": user_prompt}]
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages,
            tools=tools,
        )
        msg = response.choices[0].message
    
        if msg.tool_calls:
            for call in msg.tool_calls:
                if call.function.name == "get_disk_usage":
                    result = get_disk_usage()
                    messages.append(msg)
                    messages.append({
                        "role": "tool",
                        "tool_call_id": call.id,
                        "content": result,
                    })
            final = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
            return final.choices[0].message.content
        return msg.content
    
    if __name__ == "__main__":
        print(run_agent("How much disk space is free on this server?"))

    This is intentionally simple: one tool, one loop. Real agents chain multiple tool calls, but the pattern is the same — model decides, code executes, result feeds back.

    Step 3: Containerize the Agent

    Running tool calls directly on your host is risky. Wrap the agent in Docker so its filesystem access, network access, and process list are isolated:

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

    Build and run it with the API key injected at runtime, never baked into the image:

    docker build -t ai-agent-demo .
    docker run --rm -e OPENAI_API_KEY=$OPENAI_API_KEY ai-agent-demo

    For agents that need to run shell commands as a genuine capability, add resource limits and a read-only root filesystem where possible:

    docker run --rm 
      --memory=512m --cpus=1 
      --read-only --tmpfs /tmp 
      -e OPENAI_API_KEY=$OPENAI_API_KEY 
      ai-agent-demo

    This single change — running the agent as a constrained container instead of a bare process — closes off most of the accidental-damage scenarios that make people nervous about giving an LLM shell access in the first place.

    Choosing a Framework vs. Rolling Your Own

    Once the basic loop works, you’ll want to decide whether to adopt a framework. If you’re new to this, our guide on setting up a self-hosted media server covers a similar build-vs-buy tradeoff for infrastructure decisions, and the same logic applies here.

  • LangChain — the most widely adopted, huge ecosystem of integrations, but can feel heavy for simple use cases.
  • CrewAI — built specifically for multi-agent collaboration (agents that delegate to other agents).
  • LlamaIndex — strongest when your agent’s primary job is retrieval over documents.
  • Custom loop — as shown above; best when you have one or two well-defined tools and want full control over latency and cost.
  • For teams running dozens of agents in production, the framework choice matters less than the operational discipline around it: logging every tool call, rate-limiting API usage, and having a kill switch.

    Deploying Agents to a VPS

    Once your container works locally, deploying it to a VPS is straightforward with Docker Compose. A reasonable production setup includes a reverse proxy, environment-based secrets, and log persistence:

    # docker-compose.yml
    version: "3.9"
    services:
      ai-agent:
        build: .
        restart: unless-stopped
        environment:
          - OPENAI_API_KEY=${OPENAI_API_KEY}
        mem_limit: 512m
        cpus: 1.0
        volumes:
          - ./logs:/app/logs

    Deploy with:

    docker compose up -d
    docker compose logs -f ai-agent

    For the underlying compute, a small VPS is usually enough for a single agent handling moderate traffic — you don’t need GPU infrastructure unless you’re self-hosting the LLM itself. Providers like DigitalOcean offer droplets that are well suited to this kind of lightweight, containerized workload, with predictable pricing and a straightforward API for scaling up if your agent’s usage grows. If you want lower base costs for a always-on agent process, Hetzner is worth comparing for the same workload.

    We cover general container orchestration patterns in more depth in our Docker Compose production guide, which is directly applicable once you’re running more than one agent.

    Monitoring and Observability

    Agents fail differently than normal applications — they can loop indefinitely, call tools with bad arguments, or silently degrade in output quality without ever throwing an exception. Treat observability as mandatory, not optional:

  • Log every prompt, tool call, and response with timestamps and token counts.
  • Set hard timeouts on the agent loop to prevent runaway tool-call chains.
  • Track API cost per agent run — a bug in your loop can turn into a large bill overnight.
  • Alert on error rates and unusual latency spikes.
  • A service like BetterStack can centralize your agent’s logs and uptime monitoring in one dashboard, which is far easier to reason about than grepping container logs during an incident. If your agent is exposed via a public API endpoint, putting it behind Cloudflare adds a layer of DDoS protection and rate limiting without much configuration overhead.

    Security Considerations When You Create AI Agents

    Security deserves its own section because it’s the part most tutorials skip entirely.

  • Never give an agent raw shell access without a sandbox. Use containers, restricted user accounts, and allowlisted commands.
  • Validate tool arguments before execution. An LLM can hallucinate a destructive command; your code, not the model, is the last line of defense.
  • Rotate and scope API keys. Use a key with the minimum permissions the agent actually needs.
  • Rate-limit tool calls that touch external APIs or billing-sensitive services.
  • Log everything. If an agent does something unexpected, you need an audit trail to reconstruct what happened.
  • These aren’t theoretical concerns — there have been real incidents of agents deleting production data or leaking credentials because a developer trusted model output without a validation layer in between.

    Scaling Beyond a Single Agent

    Once you’re comfortable with one agent, the natural next step is orchestrating several agents that specialize in different tasks — one for monitoring, one for deployment, one for customer-facing chat. At that point you’re effectively running a small distributed system, and the same DevOps fundamentals apply: health checks, graceful restarts, and centralized logging. Docker Compose can handle a handful of agents; beyond that, Kubernetes or Nomad becomes worth the added complexity.

    A practical migration path looks like this:

    1. Validate the agent loop locally with a single container.
    2. Add resource limits and logging, deploy via Docker Compose on a VPS.
    3. Introduce a message queue (Redis or RabbitMQ) if agents need to communicate.
    4. Move to Kubernetes only once you have more than 4-5 distinct agent services.

    Skipping straight to Kubernetes for a single agent is a common and avoidable mistake — it adds operational overhead without solving a problem you have yet.

    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: What’s the fastest way to create AI agents without writing custom code?
    A: Frameworks like CrewAI or LangChain’s agent executors let you define tools and prompts declaratively, cutting setup time significantly compared to a fully custom loop. They trade some control for speed of development.

    Q: Do I need a GPU to run an AI agent?
    A: No, not if you’re calling a hosted LLM API (OpenAI, Anthropic, etc.). You only need GPU infrastructure if you’re self-hosting the language model itself, such as running Llama or Mistral locally via Ollama.

    Q: How do I prevent an AI agent from running dangerous commands?
    A: Sandbox execution in a container with resource limits, validate all tool arguments in code before running them, and use an allowlist of permitted commands rather than trusting free-form model output.

    Q: What’s the difference between an AI agent and a chatbot?
    A: A chatbot responds conversationally; an agent takes autonomous action by calling tools, executing code, or interacting with external systems to complete a task, often across multiple steps without human intervention at each one.

    Q: How much does it cost to run a self-hosted AI agent?
    A: Compute costs are usually minimal (a small VPS suffices for most workloads), but LLM API costs scale with usage. Budget for token costs per request and set hard caps to avoid runaway spending from looping agents.

    Q: Can I run multiple AI agents on the same server?
    A: Yes, using Docker Compose to isolate each agent as its own container with defined memory and CPU limits. For more than a handful of agents, consider moving to Kubernetes for better orchestration and scaling.

    Wrapping Up

    Learning to create AI agents that survive contact with production traffic comes down to treating them like any other service: containerize them, monitor them, limit their blast radius, and log everything. The LLM is just one component in a larger system — the DevOps fundamentals around it are what determine whether your agent is a reliable tool or a 3am incident.

    Start small: one container, one tool, hard resource limits. Expand only when you have a concrete reason to.