# Deploy Django Admin for CART

This guide explains how to deploy the Django admin interface on Apache with mod_wsgi.

## Prerequisites

- Ubuntu/Debian server with Apache2 installed
- MySQL (for production) or SQLite (development only)
- Python 3.10+ with uv package manager

## 1. Prepare the Server

Update system and install packages:

```bash
# Update system
sudo apt update && sudo apt upgrade -y

# Install required packages
sudo apt install -y apache2 libapache2-mod-wsgi-py3 python3-venv mysql-server default-mysql-client git

# Enable mod_wsgi
sudo a2enmod wsgi
```

## 2. Deploy the Application

Create application directory and deploy code:

```bash
# Create application directory
sudo mkdir -p /opt/cart-admin
sudo chown $USER:$USER /opt/cart-admin

# Clone or copy your repository
cd /opt/cart-admin
git clone https://github.com/karol/cart.git .

# Copy admin folder contents to root (required for Apache config)
cp -r admin/* .

# Or copy files manually (recommended for production)
# scp -r admin/* user@server:/opt/cart-admin/

# Install dependencies with uv
uv sync --frozen

# Create virtual environment for Apache
uv venv .venv
```

**Alternative: Use pip if uv not available**

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

## 3. Configure Environment

Create production `.env`:

```bash
cp .env.example .env
```

Edit `.env` with production values:
- `DATABASE_URL`: MySQL URL for production or SQLite path for dev
- `DJANGO_SECRET_KEY`: Generate a new secure key
- `DJANGO_DEBUG`: false
- `DJANGO_ALLOWED_HOSTS`: your-domain.com,127.0.0.1
- `DJANGO_LOG_LEVEL`: WARNING

Generate new secret key:

```bash
source .venv/bin/activate
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
```

## 4. Collect Static Files

Run migrations first, then collect static files:

```bash
source .venv/bin/activate
python manage.py migrate

# Collect static files into STATIC_ROOT
python manage.py collectstatic --noinput
```

Static files are now in `/opt/cart-admin/staticfiles/`

## 5. Configure Apache

Copy the provided config and customize for your environment:

```bash
# Copy dev config as starting point
sudo cp /opt/cart-admin/admin/deploy/dev.elektrownia.net.conf /etc/apache2/sites-available/cart-admin.conf

# Edit for your domain and paths
sudo nano /etc/apache2/sites-available/cart-admin.conf
```

Or create your own from scratch (see Section 6 for example).

## 6. Apache Virtual Host Configuration

**Alternative: Use the provided dev config** (in `/admin/deploy/dev.elektrownia.net.conf`)

**Or create custom config:**

File: `/etc/apache2/sites-available/cart-admin.conf`

```apache
<VirtualHost *:80>
    ServerName admin.cart.local
    DocumentRoot /opt/cart-admin/staticfiles

    # Log files
    ErrorLog ${APACHE_LOG_DIR}/cart-admin-error.log
    CustomLog ${APACHE_LOG_DIR}/cart-admin-access.log combined

    # WSGI configuration
    WSGIDaemonProcess cart-admin python-home=/opt/cart-admin/.venv python-path=/opt/cart-admin
    WSGIProcessGroup cart-admin
    WSGIScriptAlias / /opt/cart-admin/cart/wsgi.py

    # Allow access to WSGI application
    <Directory /opt/cart-admin>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    # Serve static files directly from Apache
    Alias /static/ /opt/cart-admin/staticfiles/
    <Directory /opt/cart-admin/staticfiles>
        Require all granted
    </Directory>
</VirtualHost>
```

## 7. Enable the Site

Enable the new site and restart Apache:

```bash
# Enable the new site
sudo a2ensite cart-admin.conf

# Disable default site (optional)
sudo a2dissite 000-default.conf

# Test Apache configuration
sudo apache2ctl configtest

# Restart Apache
sudo systemctl restart apache2
```

## 8. Configure MySQL (for Production)

Login to MySQL and create database:

```bash
sudo mysql
```

```sql
CREATE DATABASE cart;
CREATE USER 'cart_user'@'localhost' IDENTIFIED BY 'secure-password';
GRANT ALL PRIVILEGES ON cart.* TO 'cart_user'@'localhost';
FLUSH PRIVILEGES;
exit;
```

Update `DATABASE_URL` in `.env`:

```
DATABASE_URL=mysql://cart_user:secure-password@127.0.0.1:3306/cart
```

Install MySQL driver in virtual environment:

```bash
source /opt/cart-admin/.venv/bin/activate
uv pip install mysqlclient

# Run migrations
python manage.py migrate
```

## 9. Create Superuser

```bash
source /opt/cart-admin/.venv/bin/activate
python manage.py createsuperuser
```

## 10. Configure Firewall (if using UFW)

```bash
sudo ufw allow ssh
sudo ufw allow 'Apache'
sudo ufw enable
```

## 11. Access the Admin

Navigate to: `http://your-server-ip/admin/`

First time: Create superuser with `python manage.py createsuperuser`

## 12. Configure Apache Log Cleanup

Edit logrotate configuration:

```bash
sudo nano /etc/logrotate.d/cart-admin
```

Add these lines:

```logrotate
/var/log/apache2/cart-admin-error.log
/var/log/apache2/cart-admin-access.log
    {
        daily
        missingok
        rotate 14
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        postrotate
            /usr/lib/apache2/apache2ctl graceful > /dev/null 2>&1 || true
        endscript
    }
```

## 13. Security Hardening

Set proper permissions:

```bash
sudo chown -R www-data:www-data /opt/cart-admin/staticfiles
sudo chmod -R 755 /opt/cart-admin/staticfiles
sudo chmod 640 /opt/cart-admin/.env
sudo chown www-data:www-data /opt/cart-admin/.env
```

**Restrict Apache access to trusted IPs (optional)**

Add to `cart-admin.conf` inside `<Directory>`:

```apache
Require ip 192.168.1.0/24
Require ip 10.0.0.0/8
```

## 14. Update Django Settings

In `admin/.env` or `admin/cart/settings.py`:

- `DEBUG = False` (**critical!**)
- `ALLOWED_HOSTS = ['your-domain.com', 'your-server-ip']`
- `SECURE_SSL_REDIRECT = True` (if using HTTPS)
- `SESSION_COOKIE_SECURE = True`
- `CSRF_COOKIE_SECURE = True`

## 15. Configure HTTPS (with Let's Encrypt)

```bash
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d admin.your-domain.com
```

## Troubleshooting

Check Apache logs:

```bash
sudo tail -f /var/log/apache2/cart-admin-error.log
```

Check Apache status:

```bash
sudo systemctl status apache2
```

Test WSGI configuration:

```bash
sudo apache2ctl -M | grep wsgi
```

Check virtualenv activation:

```bash
echo $VIRTUAL_ENV
```

Verify static files exist:

```bash
ls -la /opt/cart-admin/staticfiles/
```

## Alternative: Use Gunicorn Instead of mod_wsgi

If you prefer Gunicorn over Apache WSGI:

Install Gunicorn:

```bash
uv pip install gunicorn
```

Create systemd service:

```bash
sudo nano /etc/systemd/system/cart-admin.service
```

```ini
[Unit]
Description=CART Django Admin Gunicorn
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/opt/cart-admin
Environment="PATH=/opt/cart-admin/.venv/bin"
ExecStart=/opt/cart-admin/.venv/bin/gunicorn --config gunicorn.conf.py cart.wsgi:application

Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

Then use Nginx as reverse proxy:

```bash
sudo nano /etc/nginx/sites-available/cart-admin
```

```nginx
server {
    listen 80;
    server_name admin.your-domain.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /static/ {
        alias /opt/cart-admin/staticfiles/;
    }
}
```

Enable and start:

```bash
sudo systemctl enable --now cart-admin
```