# 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 <service-name>

# 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 <service-name>

# Restart a service
docker compose restart <service-name>

# Rebuild and restart service
docker compose up -d --build <service-name>

# 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
