Running an Agent with Docker
Introduction
This example shows how to run an agent using the uAgents library inside a Docker container with Docker Compose. It walks you through setting up everything you need so you can easily build and run the agent.
Please check out the example code in our examples repo (opens in a new tab) to run this locally.
Supporting Documents
- Almanac contract overview .
- How to create an agent .
- Registering in the Almanac Contract .
- Creating an interval task
- Communicating with other agents
Pre-requisites
- Python: Download and install from Python official website (opens in a new tab).
- Poetry: Install by following the instructions on Poetry's official website (opens in a new tab).
- Docker: Download and install from Docker official website (opens in a new tab).
- Docker Compose: Download and install from Docker Compose official documentation (opens in a new tab).
Project Structure
.agent_with_docker ├── docker-compose.yml ├── Dockerfile ├── poetry.lock ├── pyproject.toml ├── README.md └── src └── agent.py
Agent with Docker
agent.py
This example demonstrates a simple agent-based communication system using the uAgents library. The data_sender
agent sends a DataPacket
message to the data_receiver
agent every 4 seconds. Upon receiving the message, data_receiver
logs it and sends an acknowledgment back to data_sender. Both agents log the messages they receive. The agents are running with Docker Compose using Docker.
agent.pyfrom uagents import Agent, Bureau, Context, Model class DataPacket(Model): message: str data_sender = Agent(name="data_sender", seed="data_sender recovery phrase") data_receiver = Agent(name="data_receiver", seed="data_receiver recovery phrase") @data_sender.on_interval(period=4.0) async def send_data_packet(ctx: Context): """ Event handler that gets triggered at regular intervals (every 4 seconds). Args: ctx (Context): The context in which the event is triggered. Returns: None: This function does not return any value but sends a DataPacket message from data_sender to data_receiver at intervals of (every 4 seconds). """ await ctx.send( data_receiver.address, DataPacket(message="Initiating data transfer") ) @data_sender.on_message(model=DataPacket) async def data_sender_message_handler(ctx: Context, sender: str, msg: DataPacket): """ Event handler that gets triggered when data_sender receives a DataPacket message. Args: ctx (Context): The context in which the event is triggered. sender (str): The address of the sender. msg (DataPacket): The message received. Returns: None: This function does not return any value but logs the received message. """ ctx.logger.info(f"Data Sender received a message from {sender}: {msg.message}") @data_receiver.on_message(model=DataPacket) async def data_receiver_message_handler(ctx: Context, sender: str, msg: DataPacket): """ Event handler that gets triggered when data_receiver receives a DataPacket message. Args: ctx (Context): The context in which the event is triggered. sender (str): The address of the sender. msg (DataPacket): The message received. Returns: None: This function does not return any value but logs the received message and sends an acknowledgment back to data_sender. """ ctx.logger.info(f"Data Receiver received a message from {sender}: {msg.message}") await ctx.send( data_sender.address, DataPacket(message="Acknowledging data transfer") ) bureau = Bureau() bureau.add(data_sender) bureau.add(data_receiver) if __name__ == "__main__": bureau.run()
Dockerfile
This Dockerfile sets up a Python environment with Poetry for dependency management. It installs necessary system packages, sets up the working directory, installs dependencies specified in pyproject.toml
, and runs agent.py
using Poetry. The application listens on port 8000.
DockerfileFROM python:3.12-slim ENV PATH="$PATH:/root/.local/bin" RUN apt-get update && \ apt-get install -y curl gcc && \ curl -sSL https://install.python-poetry.org/ | python3 - WORKDIR /app ADD pyproject.toml poetry.lock /app/ RUN poetry install ADD . /app EXPOSE 8000 ENTRYPOINT ["poetry", "run"] CMD ["python", "agent.py"]
docker-compose.yml
This Docker Compose configuration builds and runs a Python app using Poetry. It maps the current directory to the container, exposes port 8000, and starts the agent.py
script.
docker-compose.ymlversion: '3.8' services: app: build: . container_name: poetry_app volumes: - .:/app ports: - "8000:8000" command: poetry run python src/agent.py
Poetry Dependencies
[tool.poetry.dependencies] python = "^3.10" uagents = { version = "^0.13.0", python = ">=3.10,<3.13" }
How to Run This Example
- Navigate to the root Folder of the Example.
- Run
docker-compose build
- Run
docker-compose up
Expected Output
Creating network "agent_with_docker_default" with the default driver Creating poetry_app ... done Attaching to poetry_app poetry_app | INFO: [data_receiver]: Data Receiver received a message from agent1qdccxu8z03y3m27p22emtuffjxng8ks3pm69yn703eec6pk5a8p5vzf97qz: Initiating data transfer poetry_app | INFO: [bureau]: Starting server on http://0.0.0.0:8000 (Press CTRL+C to quit) poetry_app | INFO: [data_sender]: Data Sender received a message from agent1qg0ejev64auhjg7c7xsd32v7npflvhvs5afe43r4gzm4eqmhqgxs7mlfss0: Acknowledging data transfer poetry_app | INFO: [data_receiver]: Data Receiver received a message from agent1qdccxu8z03y3m27p22emtuffjxng8ks3pm69yn703eec6pk5a8p5vzf97qz: Initiating data transfer