Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
*.egg-info/
dist/
build/
.pytest_cache/
.coverage
htmlcov/
.tox/
.mypy_cache/
.ruff_cache/

# Virtual environments
venv/
env/
ENV/
.venv/

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# Git
.git/
.gitignore
.github/

# Docker
.dockerignore
Dockerfile*
docker-compose*.yml

# Project specific - LARGE DIRECTORIES
data/
mlruns/
site/
all_code_and_configs.txt
arla_monorepo_workspace.egg-info/
logs/
*.log
*.db
*.sqlite

# Rust build artifacts
**/target/
**/*.so
Cargo.lock

# Documentation
docs/
*.md
!README.md # Keep README.md as it's needed by Poetry

# Environment files
.env*
!.env.example

# Notebooks
*.ipynb
.ipynb_checkpoints/

# Testing
coverage.xml
*.cover
.hypothesis/

# Package managers
poetry.lock.bak
pip-log.txt

# OS files
Thumbs.db
.DS_Store

# Temporary files
*.tmp
*.bak
*.swp
*~

# Archives
*.tar
*.tar.gz
*.zip
*.gz

# Media files (if you have any)
*.mp4
*.avi
*.mov
*.jpg
*.jpeg
*.png
*.gif
!docs/**/*.png
!docs/**/*.jpg
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ jobs:
run: poetry install

- name: "Build and deploy documentation"
run: poetry run mkdocs gh-deploy --force
run: poetry run mkdocs gh-deploy --force
91 changes: 61 additions & 30 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,38 +1,69 @@
# Build stage
FROM python:3.11.9-slim as builder

ENV POETRY_HOME="/opt/poetry"
ENV POETRY_NO_INTERACTION=1
ENV POETRY_VIRTUALENVS_CREATE=false
ENV PATH="$POETRY_HOME/bin:$PATH"

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
graphviz-dev \
libgraphviz-dev \
pkg-config \
curl \
&& curl -sSL https://install.python-poetry.org | python -
# ==============================================================================
# ARLA Project Dockerfile - Optimized for Development Speed
# ==============================================================================

WORKDIR /app
COPY . .
RUN poetry install --without dev

# Runtime stage
FROM python:3.11.9-slim

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
graphviz \
gifsicle \
# Set environment variables for Poetry
ENV POETRY_HOME="/opt/poetry" \
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_CREATE=true \
POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_CACHE_DIR=/opt/poetry-cache \
PATH="$POETRY_HOME/bin:$PATH"

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
graphviz \
graphviz-dev \
libgraphviz-dev \
pkg-config \
curl \
gifsicle \
&& curl -sSL https://install.python-poetry.org | python - \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.11/site-packages/ /usr/local/lib/python3.11/site-packages/
COPY --from=builder /usr/local/bin/ /usr/local/bin/
COPY --from=builder /app .

# Create the full directory structure that Poetry expects
RUN mkdir -p \
/app/agent-core/src/agent_core \
/app/agent-engine/src/agent_engine \
/app/agent-sim/src/agent_sim \
/app/agent-concurrent/src/agent_concurrent \
/app/agent-persist/src/agent_persist \
/app/simulations \
/app/data \
/app/mlruns

# Copy all pyproject.toml files first for dependency resolution
COPY pyproject.toml poetry.lock* ./
COPY agent-core/pyproject.toml ./agent-core/pyproject.toml
COPY agent-engine/pyproject.toml ./agent-engine/pyproject.toml
COPY agent-sim/pyproject.toml ./agent-sim/pyproject.toml
COPY agent-concurrent/pyproject.toml ./agent-concurrent/pyproject.toml
COPY agent-persist/pyproject.toml ./agent-persist/pyproject.toml

# Create minimal __init__.py files so packages can be found
RUN touch /app/agent-core/src/agent_core/__init__.py && \
touch /app/agent-engine/src/agent_engine/__init__.py && \
touch /app/agent-sim/src/agent_sim/__init__.py && \
touch /app/agent-concurrent/src/agent_concurrent/__init__.py && \
touch /app/agent-persist/src/agent_persist/__init__.py

# Install all dependencies including local packages in editable mode
# This will work now because the directory structure exists
RUN $POETRY_HOME/bin/poetry install --without dev --no-root && \
$POETRY_HOME/bin/poetry run pip install -e ./agent-core -e ./agent-engine -e ./agent-sim -e ./agent-concurrent -e ./agent-persist && \
rm -rf $POETRY_CACHE_DIR

# Set Python path
ENV PYTHONPATH="/app/agent-core/src:/app/agent-engine/src:/app/agent-sim/src:/app/agent-concurrent/src:/app/agent-persist/src:/app/simulations"

# Default command - keep container running
CMD ["tail", "-f", "/dev/null"]
39 changes: 34 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,47 @@ RENDER_DIR ?= data/gif_renders
FPS ?= 15
WORKERS ?= 4

# --- Build Configuration ---
# Enable Docker BuildKit for better caching and parallel builds
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1

# --- Core Docker Commands ---

## up: Build images, start services, and initialize the database.
up:
@echo "🚀 Building images and starting all services..."
@docker compose up -d --build
@echo "⏳ Waiting 10 seconds for services to stabilize..."
@sleep 10
@echo " Using BuildKit for optimized caching..."
@DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker compose up -d --build
@echo "⏳ Waiting for services to be healthy..."
@docker compose exec -T db sh -c 'until pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB; do sleep 1; done' || true
@docker compose exec -T redis sh -c 'until redis-cli ping; do sleep 1; done' || true
@echo "🔑 Initializing database tables..."
@make init-db
@echo "✅ All services are up and the database is initialized."
@echo ""
@echo "📊 Service Status:"
@docker compose ps
@echo ""
@echo "🔗 Available endpoints:"
@echo " - Application shell: docker compose exec app bash"
@echo " - MLflow UI: http://localhost:5001 (admin/password)"
@echo " - Dozzle logs: http://localhost:9999"
@echo " - PostgreSQL: localhost:5432"
@echo " - Redis: localhost:6379"

## up-rebuild: Force rebuild all images from scratch (ignores cache).
up-rebuild:
@echo "🔨 Force rebuilding all images from scratch..."
@DOCKER_BUILDKIT=1 docker compose build --no-cache
@echo "🚀 Starting services with fresh images..."
@docker compose up -d
@echo "⏳ Waiting for services to be healthy..."
@docker compose exec -T db sh -c 'until pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB; do sleep 1; done' || true
@docker compose exec -T redis sh -c 'until redis-cli ping; do sleep 1; done' || true
@echo "🔑 Initializing database tables..."
@make init-db
@echo "✅ All services are up with fresh builds."

## down: Stop and remove all containers, networks, and volumes.
down:
Expand All @@ -49,7 +78,7 @@ logs:
## init-db: Connects to the DB and creates all necessary tables.
init-db:
@echo "Initializing database and creating tables..."
@docker compose exec app poetry run python -m agent_sim.infrastructure.database.init_db
@docker compose exec app /opt/poetry/bin/poetry run python -m agent_sim.infrastructure.database.init_db

## setup: Create the .env file from the example template.
setup:
Expand All @@ -67,7 +96,7 @@ run:
@sleep 5
@echo "▶️ Submitting experiment from: $(FILE)"
# This command will now succeed because the 'app' container is running.
@docker compose exec app poetry run agentsim run-experiment $(FILE)
@docker compose exec app /opt/poetry/bin/poetry run agentsim run-experiment $(FILE)

## run-local: Run a single, local simulation for quick testing and debugging.
run-local:
Expand Down
3 changes: 1 addition & 2 deletions agent-sim/src/agent_sim/infrastructure/tasks/celery_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")

# --- MODIFIED: Explicitly list all modules containing tasks ---
app = Celery(
"agent_sim",
include=[
Expand All @@ -32,9 +31,9 @@
# which helps resolve import paths when the task is executed.
"simulations.berry_sim.run",
"simulations.schelling_sim.run",
"simulations.tragedy_of_the_commons.run",
],
)
# --- END MODIFICATION ---

app.conf.worker_pool_restarts = True
app.conf.worker_pool = "prefork"
Expand Down
Loading