# Docker Deployment Guide for EAR Project

This guide provides instructions for deploying the EAR Laravel application using Docker in a staging environment with domain configuration support.

## Prerequisites

- Docker (version 20.10 or higher)
- Docker Compose (version 2.0 or higher)
- Git
- Basic knowledge of Docker and Laravel

## Quick Start

### Automated Deployment

The easiest way to deploy the application is using the provided deployment script:

```bash
# Make the script executable (if not already)
chmod +x deploy-staging.sh

# Run the deployment script
./deploy-staging.sh
```

The script will:
- Check for Docker and Docker Compose installation
- Create environment configuration
- Generate secure passwords and application keys
- Prompt for domain name configuration
- Build and start all containers
- Run Laravel setup commands
- Provide access information

### Manual Deployment

If you prefer manual deployment:

1. **Copy environment file:**
   ```bash
   cp .env.staging .env
   ```

2. **Configure environment variables:**
   Edit `.env` file and set:
   - `APP_KEY` (generate with `php artisan key:generate`)
   - `DB_PASSWORD` and `DB_ROOT_PASSWORD` (use secure passwords)
   - `DOMAIN_NAME` (your domain or localhost)
   - `APP_URL` (http://your-domain.com or http://localhost)

3. **Build and start containers:**
   ```bash
   docker-compose build
   docker-compose up -d
   ```

4. **Run Laravel setup:**
   ```bash
   docker-compose exec app php artisan key:generate
   docker-compose exec app php artisan migrate
   docker-compose exec app php artisan config:cache
   docker-compose exec app php artisan route:cache
   docker-compose exec app php artisan view:cache
   docker-compose exec app php artisan storage:link
   ```

## Architecture

The Docker setup includes the following services:

### Application Container (`app`)
- **Base Image:** PHP 8.3 FPM Alpine
- **Components:** PHP-FPM, Nginx, Supervisor
- **Purpose:** Runs the Laravel application
- **Port:** Internal (proxied through nginx service)

### Database Container (`mysql`)
- **Image:** MySQL 8.0
- **Purpose:** Application database
- **Port:** 3306 (exposed)
- **Data:** Persistent volume (`mysql_data`)

### Cache Container (`redis`)
- **Image:** Redis 7 Alpine
- **Purpose:** Session storage, caching, queue backend
- **Port:** 6379 (internal)
- **Data:** Persistent volume (`redis_data`)

### Reverse Proxy (`nginx`)
- **Image:** Nginx Alpine
- **Purpose:** SSL termination, domain routing, static file serving
- **Ports:** 80 (HTTP), 443 (HTTPS)
- **Configuration:** `docker/nginx/staging.conf`

## Domain Configuration

### Setting Up Your Domain

1. **During deployment:**
   The deployment script will prompt for your domain name.

2. **Manual configuration:**
   Edit `.env` file:
   ```env
   DOMAIN_NAME=your-domain.com
   APP_URL=http://your-domain.com
   ```

3. **DNS Configuration:**
   Point your domain's A record to your server's IP address.

### SSL/HTTPS Setup

To enable HTTPS:

1. **Obtain SSL certificates:**
   ```bash
   # Using Let's Encrypt (example)
   certbot certonly --standalone -d your-domain.com
   
   # Copy certificates to docker/ssl/
   cp /etc/letsencrypt/live/your-domain.com/fullchain.pem docker/ssl/cert.pem
   cp /etc/letsencrypt/live/your-domain.com/privkey.pem docker/ssl/key.pem
   ```

2. **Enable HTTPS in nginx configuration:**
   Edit `docker/nginx/staging.conf` and uncomment the HTTPS server block.

3. **Update environment:**
   ```env
   APP_URL=https://your-domain.com
   ```

4. **Restart containers:**
   ```bash
   docker-compose restart nginx
   ```

## File Structure

```
project-root/
├── Dockerfile                          # Main application container
├── docker-compose.yml                  # Service orchestration
├── deploy-staging.sh                   # Automated deployment script
├── .env.staging                        # Staging environment template
├── docker/
│   ├── nginx/
│   │   ├── nginx.conf                  # Main nginx configuration
│   │   ├── default.conf                # App container nginx config
│   │   └── staging.conf                # Reverse proxy configuration
│   ├── php/
│   │   ├── php.ini                     # PHP configuration
│   │   └── php-fpm.conf                # PHP-FPM pool configuration
│   ├── supervisor/
│   │   └── supervisord.conf            # Process management
│   └── ssl/                            # SSL certificates directory
└── storage/                            # Application storage (mounted)
```

## Management Commands

### Container Management
```bash
# View running containers
docker-compose ps

# View logs
docker-compose logs -f

# View specific service logs
docker-compose logs -f app

# Stop all services
docker-compose down

# Restart services
docker-compose restart

# Rebuild containers
docker-compose build --no-cache
```

### Laravel Commands
```bash
# Access application container
docker-compose exec app bash

# Run artisan commands
docker-compose exec app php artisan [command]

# Examples:
docker-compose exec app php artisan migrate
docker-compose exec app php artisan queue:work
docker-compose exec app php artisan cache:clear
```

### Database Management
```bash
# Access MySQL
docker-compose exec mysql mysql -u root -p

# Backup database
docker-compose exec mysql mysqldump -u root -p ear_staging > backup.sql

# Restore database
docker-compose exec -T mysql mysql -u root -p ear_staging < backup.sql
```

## Monitoring and Maintenance

### Health Checks
- Application: `http://your-domain.com/health`
- Container status: `docker-compose ps`

### Log Locations
- Application logs: `storage/logs/`
- Nginx logs: Container `/var/log/nginx/`
- PHP-FPM logs: Container `/var/log/php-fpm-*.log`
- Supervisor logs: Container `/var/log/supervisor/`

### Performance Tuning

1. **PHP-FPM Configuration:**
   Edit `docker/php/php-fpm.conf` to adjust worker processes based on your server resources.

2. **Nginx Configuration:**
   Modify `docker/nginx/nginx.conf` for worker processes and connections.

3. **Database Optimization:**
   Consider adding MySQL configuration file for production use.

## Troubleshooting

### Common Issues

1. **Permission Errors:**
   ```bash
   docker-compose exec app chown -R www-data:www-data /var/www/html/storage
   docker-compose exec app chmod -R 755 /var/www/html/storage
   ```

2. **Database Connection Issues:**
   - Ensure MySQL container is running: `docker-compose ps`
   - Check database credentials in `.env`
   - Wait for database initialization (30-60 seconds)

3. **Asset Compilation Issues:**
   ```bash
   docker-compose exec app npm install
   docker-compose exec app npm run build
   ```

4. **Cache Issues:**
   ```bash
   docker-compose exec app php artisan config:clear
   docker-compose exec app php artisan cache:clear
   docker-compose exec app php artisan view:clear
   ```

### Debug Mode

To enable debug mode temporarily:
```bash
# Edit .env
APP_DEBUG=true

# Restart application
docker-compose restart app
```

**Remember to disable debug mode in production!**

## Security Considerations

1. **Environment Variables:**
   - Use strong, unique passwords
   - Never commit `.env` files to version control
   - Regularly rotate secrets

2. **Network Security:**
   - Use HTTPS in production
   - Configure firewall rules
   - Limit database access

3. **Container Security:**
   - Regularly update base images
   - Scan for vulnerabilities
   - Use non-root users where possible

4. **Application Security:**
   - Keep Laravel and dependencies updated
   - Enable security headers
   - Configure proper CORS settings

## Backup Strategy

### Automated Backup Script
Create a backup script for regular backups:

```bash
#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
docker-compose exec -T mysql mysqldump -u root -p$DB_ROOT_PASSWORD ear_staging > "backup_${DATE}.sql"
tar -czf "storage_backup_${DATE}.tar.gz" storage/
```

### Restore Process
```bash
# Restore database
docker-compose exec -T mysql mysql -u root -p ear_staging < backup_file.sql

# Restore storage
tar -xzf storage_backup_file.tar.gz
```

## Support

For issues and questions:
1. Check the troubleshooting section above
2. Review Docker and Laravel logs
3. Consult the main project documentation
4. Check Docker Compose and Laravel documentation

## Contributing

When contributing to the Docker setup:
1. Test changes in a clean environment
2. Update documentation accordingly
3. Follow Docker best practices
4. Ensure compatibility with existing setup
