---
title: "LXC Migration Automation Guide"
description: "Step-by-step guide for using lxc-docker-create.sh and fix-docker-apparmor.sh to migrate VMs to LXC containers. Includes complete workflow, data migration commands, time estimates, and troubleshooting."
type: runbook
domain: vm-management
tags: [proxmox, lxc, migration, docker, apparmor, scripts, automation]
---

# LXC Migration Automation Scripts

This guide covers automation scripts for migrating VM-based Docker containers to LXC containers.

## Scripts Overview

### 1. `lxc-docker-create.sh` - LXC Container Creation

Automates the creation of LXC containers with Docker pre-installed and configured for container workloads.

**Usage:**
```bash
./lxc-docker-create.sh <VMID> <HOSTNAME> <IP> <DISK_SIZE> <MEMORY> <CORES> [PROXMOX_HOST]
```

**Example (local Proxmox):**
```bash
./lxc-docker-create.sh 214 docker-pittsburgh-lxc 10.10.0.214 128G 16384 4
```

**Example (remote Proxmox):**
```bash
./lxc-docker-create.sh 214 docker-pittsburgh-lxc 10.10.0.214 128G 16384 4 root@10.10.0.11
```

**What it does:**
- Creates LXC container with specified resources
- Configures AppArmor for Docker compatibility
- Enables nesting and keyctl features
- Installs Docker and docker-compose-plugin
- Sets container to start on boot

**Time:** ~10 minutes (includes Docker installation)

---

### 2. `fix-docker-apparmor.sh` - Docker Compose AppArmor Fix

Adds AppArmor unconfined security options to all services in docker-compose.yml files. Required for Docker containers running inside LXC.

**Usage:**
```bash
./fix-docker-apparmor.sh <LXC_IP> [COMPOSE_DIR]
```

**Example:**
```bash
./fix-docker-apparmor.sh 10.10.0.214
./fix-docker-apparmor.sh 10.10.0.214 /home/cal/container-data
```

**What it does:**
- SSHs into the LXC container
- Finds all docker-compose.yml files
- Adds `security_opt: ["apparmor=unconfined"]` to each service
- Creates backups of original files

**Time:** ~1-2 minutes

---

## Complete Migration Workflow

### Wave 2 Example: VM 114 (Pittsburgh) → LXC 214

#### Step 1: Create LXC Container
```bash
cd /mnt/NV2/Development/claude-home/vm-management/scripts

./lxc-docker-create.sh 214 docker-pittsburgh-lxc 10.10.0.214 128G 16384 4 root@10.10.0.11
```

**Wait ~10 minutes for Docker installation**

#### Step 2: Copy SSH Key (if needed)
```bash
ssh root@10.10.0.11 "cat ~/.ssh/id_rsa.pub | pct exec 214 -- tee /root/.ssh/authorized_keys"
```

Or setup password-less SSH to LXC:
```bash
ssh root@10.10.0.11 "
ssh-keyscan -H 10.10.0.214 >> ~/.ssh/known_hosts 2>/dev/null
pct exec 214 -- mkdir -p /root/.ssh
cat ~/.ssh/id_rsa.pub | pct exec 214 -- tee -a /root/.ssh/authorized_keys
"
```

#### Step 3: Migrate Data

**Option A: rsync from VM (recommended)**
```bash
# From Proxmox host - direct rsync from old VM to new LXC
ssh root@10.10.0.11 "
rsync -avz --info=progress2 \
  /mnt/vm114/home/cal/container-data/ \
  root@10.10.0.214:/home/cal/container-data/
"
```

**Option B: Mount and copy from backup**
```bash
# If VM is already shut down and you have backups/snapshots
ssh root@10.10.0.11 "
mount /dev/vm114-vg/vm114-data /mnt/vm114
rsync -avz /mnt/vm114/home/cal/container-data/ root@10.10.0.214:/home/cal/container-data/
"
```

#### Step 4: Fix AppArmor in Docker Compose Files
```bash
./fix-docker-apparmor.sh 10.10.0.214
```

#### Step 5: Start Containers
```bash
ssh root@10.10.0.214

# Navigate to service directory
cd /home/cal/container-data/[service-name]

# Start containers
docker compose up -d

# Check status
docker compose ps
docker compose logs -f
```

#### Step 6: Verify and Test
- Test service functionality
- Check container logs for errors
- Verify network connectivity
- Test external access (if applicable)

#### Step 7: Update Documentation
- Mark VM as migrated in wave plan
- Document any issues encountered
- Update service inventory with new IP

---

## Time Estimates

| Step | Duration | Notes |
|------|----------|-------|
| Create LXC | 10 min | Includes Docker installation |
| Setup SSH | 1 min | One-time setup |
| Data migration | Varies | Depends on data size (58GB ≈ 60 min @ 16MB/s) |
| Fix AppArmor | 2 min | Automated script |
| Start containers | 5 min | Per service stack |
| **Total (small data)** | **~20 min** | For <10GB data |
| **Total (large data)** | **~80 min** | For ~60GB data like Wave 1 |

---

## Migration Waves Reference

Based on `vm-management/wave1-migration-results.md`:

### Remaining Migrations

| Wave | VM  | Hostname | Services | Data Size | LXC ID | Priority |
|------|-----|----------|----------|-----------|--------|----------|
| 2 | 114 | Pittsburgh | Docker services | ~30GB | 214 | High |
| 3 | 112 | Louisville | Docker services | ~20GB | 212 | High |
| 4 | 115 | Denver | Docker services | ~25GB | 215 | Medium |
| 5 | 113 | Fresno | Docker services | ~15GB | 213 | Medium |
| 6 | Multiple | Misc services | Varies | Varies | TBD | Low |

---

## Troubleshooting

### Container Creation Fails
- **Check:** Template exists: `pct list | grep template`
- **Check:** VMID not in use: `pct list | grep <VMID>`
- **Check:** Sufficient storage: `pvesm status`

### SSH Connection Failed
- **Check:** Container is running: `pct status <VMID>`
- **Check:** SSH key copied: `pct exec <VMID> -- cat /root/.ssh/authorized_keys`
- **Check:** Network connectivity: `ping <IP>`

### Docker Containers Won't Start
- **Check:** AppArmor fix applied: `grep security_opt docker-compose.yml`
- **Check:** Docker service running: `systemctl status docker`
- **Check:** Container logs: `docker compose logs`

### Data Migration Slow
- **Use:** rsync with compression: `rsync -avz`
- **Use:** Direct VM-to-LXC transfer (avoid copying to intermediate location)
- **Monitor:** Network usage: `iftop` or `nload`

---

## Best Practices

1. **Always create backups** before destroying source VMs
2. **Test services** thoroughly before decommissioning VMs
3. **Document changes** in wave results files
4. **Monitor resources** during migration (CPU, RAM, disk I/O)
5. **Schedule migrations** during low-usage periods
6. **Keep scripts updated** with learnings from each wave

---

## Script Maintenance

### Adding New Features

Both scripts are designed to be easily extended:

- **lxc-docker-create.sh**: Add additional package installations, configuration steps, or validation checks
- **fix-docker-apparmor.sh**: Modify the Python script to add additional docker-compose fixes

### Testing Changes

Before using updated scripts in production:
1. Test on a non-critical VM migration
2. Verify all steps complete successfully
3. Check container functionality post-migration
4. Document any new issues or improvements

---

## Related Documentation

- [Wave 1 Migration Results](../wave1-migration-results.md) - Lessons learned from first migration
- [Migration Quick Start](../migration-quick-start.md) - Fast reference guide
- [LXC Migration Plan](../lxc-migration-plan.md) - Overall migration strategy
- [VM Management Context](../CONTEXT.md) - VM infrastructure overview

---

## Support

For issues or questions:
1. Check troubleshooting section above
2. Review wave results for similar issues
3. Check Proxmox logs: `journalctl -u pve-container@<VMID>`
4. Review Docker logs: `docker compose logs`
