# Agent Guidelines for Ansible Infrastructure Repository This repository contains Docker Compose infrastructure configurations for deploying self-hosted productivity services. This document provides guidelines for AI coding agents working in this repository. ## Project Overview **Type:** Docker Compose Infrastructure Project **Primary Technology:** Docker, Docker Compose **Purpose:** Deployment configurations for self-hosted productivity stack including Nextcloud, OnlyOffice, Excalidraw, and Obsidian ## Repository Structure ``` /home/liph/programming/ansible/ └── nextcloud/ ├── docker-compose.yml # Main orchestration file (5 services) └── .env # Environment variables ``` ## Commands ### Docker Compose Operations ```bash # Navigate to service directory cd nextcloud/ # Start all services docker compose up -d # Start specific service docker compose up -d # Stop all services docker compose down # Stop and remove volumes (DESTRUCTIVE) docker compose down -v # View logs for all services docker compose logs -f # View logs for specific service docker compose logs -f # Restart a service docker compose restart # Rebuild and restart service docker compose up -d --build # Validate docker-compose.yml syntax docker compose config # List running services docker compose ps ``` ### Service Names - `excalidraw` - Drawing/whiteboard tool (port 3009) - `next-db` - PostgreSQL 18 database - `next` - Nextcloud main application (port 8808) - `onlyoffice` - Document server (port 8000) - `obsidian` - Note-taking app (ports 3004-3005) ### Testing No automated tests exist. Manual testing workflow: 1. Validate syntax: `docker compose config` 2. Start services: `docker compose up -d` 3. Check health: `docker compose ps` 4. Review logs: `docker compose logs` 5. Test endpoints: `curl localhost:8808` (Nextcloud), etc. ## Code Style Guidelines ### YAML Formatting (docker-compose.yml) **Indentation:** - Use 2 spaces for indentation (NO tabs) - Maintain consistent indentation levels **Structure:** ```yaml services: service-name: image: docker.io/image:tag container_name: container-name depends_on: - dependency ports: - "host:container" environment: - KEY=value - KEY=${ENV_VAR} volumes: - volume_name:/container/path - ./host/path:/container/path restart: unless-stopped networks: - network_name ``` **Naming Conventions:** - Container names: Use kebab-case (e.g., `next-db`, `next-redis`) - Service names: Use snake_case or kebab-case consistently - Volume names: Use snake_case (e.g., `nextcloud_data`, `pg_data`) - Network names: Use snake_case with project prefix (e.g., `nextcloud_network`) **Environment Variables:** - Reference .env variables using `${VAR_NAME}` syntax - Never hardcode sensitive data (passwords, secrets) in docker-compose.yml - Use explicit environment variable declarations with `-` prefix **Image Specifications:** - Always use fully qualified image names: `docker.io/image:tag` - Pin specific versions for production (avoid `:latest` in production) - Current exception: development environment uses `:latest` tags **Volumes:** - Named volumes for persistent data (defined in volumes section) - Bind mounts for configuration files using `./relative/path` - Always specify volume mount destination path - CRITICAL: Never leave empty volume definitions (e.g., `- :/path`) **Comments:** - Use `#` for comments - Add comments above service definitions to describe purpose - Comment out optional services with `# ` prefix on each line ### Environment Files (.env) **Format:** ```bash # Database Configuration DB_PASSWORD=secure_password_here DB_USERNAME=nextcloud DB_DATABASE_NAME=nextcloud DB_HOST=next-db # User/Group IDs PUID=33 PGID=1000 ``` **Rules:** - One variable per line: `KEY=value` - No spaces around `=` - No quotes needed for values - Group related variables with comment headers - Never commit sensitive values (use placeholders or .env.example) - All variables must have values (no empty assignments) ### Security Guidelines 1. **Secrets Management:** - Never hardcode passwords in docker-compose.yml - Use .env file for credentials (ensure .env is in .gitignore) - Consider Docker secrets for sensitive production data - Rotate default passwords immediately 2. **Current Security Issues to Fix:** - Line 53 in docker-compose.yml: Remove hardcoded admin password - .env file: All database credentials are empty - Consider enabling JWT for OnlyOffice (currently disabled) 3. **Network Security:** - Use isolated Docker networks for service communication - Only expose necessary ports to host - Consider reverse proxy (nginx/traefik) for HTTPS termination ### Error Handling **Validation Steps Before Committing:** 1. Run `docker compose config` to validate YAML syntax 2. Ensure all volume mount paths are complete 3. Verify all environment variables are defined in .env 4. Check for hardcoded secrets 5. Confirm port conflicts with `docker compose ps` **Common Issues:** - Empty volume definitions: Always specify source and destination - Missing environment variables: Define all referenced vars in .env - Port conflicts: Use `docker ps` to check existing port bindings - Network errors: Ensure services on same network can communicate ### Configuration Management **Volume Mapping Patterns:** ```yaml # Named volume (recommended for data) volumes: - nextcloud_data:/var/www/html # Bind mount with SELinux label (for config) volumes: - ./config:/var/www/html/config:Z # Bind mount with shared label volumes: - ./vault:/vault:z ``` **Restart Policies:** - Use `restart: unless-stopped` for production services - Avoid `restart: always` (harder to stop deliberately) - Use `restart: on-failure` for development/debugging ### Database Configuration **PostgreSQL Environment Variables:** - `POSTGRES_DB` - Database name - `POSTGRES_USER` - Database user - `POSTGRES_PASSWORD` - Database password **Nextcloud Database Connection:** - `POSTGRES_HOST` - Hostname (service name: `next-db`) - Must match database service configuration ### Best Practices 1. **Service Dependencies:** - Use `depends_on` to define startup order - Note: `depends_on` doesn't wait for "ready" state 2. **Resource Limits:** - Consider adding memory/CPU limits for production - Current config uses `mem_swappiness: -1` for Nextcloud 3. **Timezone Configuration:** - Set `TZ` environment variable for correct timestamps - Current: `TZ=Europe/Zurich` (Excalidraw), `TZ=Etc/UTC` (Obsidian) 4. **Data Persistence:** - Always use named volumes for important data - Define volumes in top-level `volumes:` section - Backup volume data regularly 5. **Making Changes:** - Test changes in development before production - Use `docker compose config` to validate - Review diff carefully before applying - Document breaking changes ## Development Workflow 1. Make changes to docker-compose.yml or .env 2. Validate: `docker compose config` 3. Apply changes: `docker compose up -d` 4. Verify: `docker compose ps && docker compose logs` 5. Test affected services manually 6. Document changes in commit message ## Critical Fixes Needed - [ ] Complete empty volume mount paths (lines 21, 55-57, 74, 89-90) - [ ] Remove hardcoded admin password (line 53) - [ ] Populate database credentials in .env file - [ ] Add .gitignore to exclude .env from version control - [ ] Consider adding docker-compose.override.yml for local development