Replace start-gpu.sh with install-local-gpu.sh + bring-up-local-gpu.sh
install-local-gpu.sh (run once): - Installs nvidia-container-toolkit (Ubuntu/Debian/RHEL auto-detected) - Installs docker-dns-fix.service systemd unit: permanent iptables DNS fix that runs after docker.service on every boot, without touching ufw - Restarts Docker and applies the rule immediately - Verifies GPU is accessible inside Docker bring-up-local-gpu.sh (run each time): - Thin wrapper: docker compose -f docker-compose.gpu.yml up -d --build - Accepts pass-through args (down, logs -f, --no-build, etc.) - BUILDID=$(date +%s) ./bring-up-local-gpu.sh for pip cache bust README Quick Start, Updates, and Troubleshooting updated accordingly. https://claude.ai/code/session_01WVDg7amsy1TTtxvpku7bcM
This commit is contained in:
@@ -7,30 +7,22 @@ A self-hosted, web-based AI photo editor. Paint over any object, describe what y
|
|||||||
### GPU machine (recommended — free inference, best quality)
|
### GPU machine (recommended — free inference, best quality)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Prerequisites: Docker + nvidia-container-toolkit
|
|
||||||
# Install toolkit once (Ubuntu/Debian):
|
|
||||||
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
|
|
||||||
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-ctk.gpg
|
|
||||||
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
|
|
||||||
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-ctk.gpg] https://#g' \
|
|
||||||
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
|
||||||
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
|
|
||||||
sudo nvidia-ctk runtime configure --runtime=docker
|
|
||||||
sudo systemctl restart docker
|
|
||||||
|
|
||||||
# Verify GPU passes through into Docker:
|
|
||||||
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
|
|
||||||
|
|
||||||
# Clone and run:
|
|
||||||
git clone https://github.com/outis1one/editmaskwithai
|
git clone https://github.com/outis1one/editmaskwithai
|
||||||
cd editmaskwithai
|
cd editmaskwithai
|
||||||
chmod +x start-gpu.sh
|
|
||||||
./start-gpu.sh
|
# One-time setup: installs nvidia-container-toolkit, configures Docker,
|
||||||
|
# and sets up a permanent DNS fix so the container can download models.
|
||||||
|
chmod +x install-local-gpu.sh
|
||||||
|
./install-local-gpu.sh
|
||||||
|
|
||||||
|
# Start the app (run this each time):
|
||||||
|
chmod +x bring-up-local-gpu.sh
|
||||||
|
./bring-up-local-gpu.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Open **http://localhost:3080**
|
Open **http://localhost:3080**
|
||||||
|
|
||||||
**First startup downloads the AI model for your GPU (5–20 GB, one time).** Models are cached in a Docker volume and survive rebuilds.
|
**First startup downloads the AI model for your GPU (~13 GB, one time).** Models are cached in `./data/hf_cache/` and survive rebuilds.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -53,7 +45,7 @@ Open **http://localhost:3080**
|
|||||||
```bash
|
```bash
|
||||||
git pull
|
git pull
|
||||||
# GPU:
|
# GPU:
|
||||||
./start-gpu.sh # applies DNS fix then rebuilds + starts
|
./bring-up-local-gpu.sh
|
||||||
# or cloud (no GPU):
|
# or cloud (no GPU):
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
@@ -61,7 +53,7 @@ docker compose up -d --build
|
|||||||
If pip packages seem stale after a pull (e.g., wrong diffusers version), force a pip layer rebuild without re-downloading the entire PyTorch base image:
|
If pip packages seem stale after a pull (e.g., wrong diffusers version), force a pip layer rebuild without re-downloading the entire PyTorch base image:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
BUILDID=$(date +%s) ./start-gpu.sh --build
|
BUILDID=$(date +%s) ./bring-up-local-gpu.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -211,19 +203,19 @@ If Docker created `./data/` as root and you can't write there without `sudo`, yo
|
|||||||
|
|
||||||
**AI models not downloading (container DNS blocked)**
|
**AI models not downloading (container DNS blocked)**
|
||||||
|
|
||||||
If the container can't reach HuggingFace (`Errno -3` in logs), your host firewall is blocking outbound DNS queries from the Docker bridge. The fix below restores Docker's default behaviour — it does **not** affect container isolation (filesystem, network namespace, PID namespace all remain separate):
|
If you ran `./install-local-gpu.sh`, this is already permanently fixed. Otherwise, the container's host firewall is blocking outbound DNS from the Docker bridge — apply the fix manually (does **not** affect container isolation):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo iptables -I DOCKER-USER -p udp --dport 53 -j ACCEPT
|
sudo iptables -I DOCKER-USER -p udp --dport 53 -j ACCEPT
|
||||||
docker compose -f docker-compose.gpu.yml restart
|
./bring-up-local-gpu.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The container will now resolve hostnames and download the models automatically (~13 GB on first run, then cached). Watch progress:
|
The container will now resolve hostnames and download models automatically (~13 GB on first run, then cached). Watch progress:
|
||||||
```bash
|
```bash
|
||||||
docker compose -f docker-compose.gpu.yml logs -f | grep -E "local_gpu|Cached|failed"
|
docker compose -f docker-compose.gpu.yml logs -f | grep -E "local_gpu|Cached|failed"
|
||||||
```
|
```
|
||||||
|
|
||||||
**If you can't run the iptables command**, download with a Docker helper container instead (no host Python needed):
|
**Alternative: download with a Docker helper container** (no iptables, no host Python needed):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Inpainting model (~6.5 GB) — needed for AI Edit, Make less symmetrical, etc.
|
# Inpainting model (~6.5 GB) — needed for AI Edit, Make less symmetrical, etc.
|
||||||
|
|||||||
Executable
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# bring-up-local-gpu.sh — start the GPU container.
|
||||||
|
#
|
||||||
|
# Run this each time you want to start the app.
|
||||||
|
# Run ./install-local-gpu.sh once first on a new machine.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./bring-up-local-gpu.sh # start (detached, rebuild if needed)
|
||||||
|
# ./bring-up-local-gpu.sh --no-build # start without rebuilding
|
||||||
|
# ./bring-up-local-gpu.sh down # stop and remove container
|
||||||
|
# ./bring-up-local-gpu.sh logs -f # tail logs
|
||||||
|
#
|
||||||
|
# Force pip layer rebuild (e.g. after requirements change):
|
||||||
|
# BUILDID=$(date +%s) ./bring-up-local-gpu.sh
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
exec docker compose -f docker-compose.gpu.yml up -d --build
|
||||||
|
else
|
||||||
|
exec docker compose -f docker-compose.gpu.yml "$@"
|
||||||
|
fi
|
||||||
Executable
+107
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# install-local-gpu.sh — one-time setup for local GPU inference.
|
||||||
|
#
|
||||||
|
# Run this once on a new machine. It:
|
||||||
|
# 1. Installs the NVIDIA container toolkit (so Docker can use the GPU)
|
||||||
|
# 2. Installs a systemd service that permanently fixes Docker container DNS
|
||||||
|
# (allows containers to resolve hostnames — does not touch ufw)
|
||||||
|
# 3. Restarts Docker so both changes take effect
|
||||||
|
# 4. Verifies the GPU is accessible inside Docker
|
||||||
|
#
|
||||||
|
# After this, use ./bring-up-local-gpu.sh each time to start the app.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ── Must run as root (or via sudo) ───────────────────────────────────────────
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
exec sudo bash "$0" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=================================================="
|
||||||
|
echo " EditmaskwithAI — Local GPU one-time setup"
|
||||||
|
echo "=================================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# ── 1. NVIDIA container toolkit ──────────────────────────────────────────────
|
||||||
|
if command -v nvidia-ctk &>/dev/null; then
|
||||||
|
echo "✓ nvidia-container-toolkit already installed — skipping"
|
||||||
|
else
|
||||||
|
echo "Installing nvidia-container-toolkit..."
|
||||||
|
. /etc/os-release
|
||||||
|
case "$ID" in
|
||||||
|
ubuntu|debian)
|
||||||
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
|
||||||
|
| gpg --dearmor -o /usr/share/keyrings/nvidia-ctk.gpg
|
||||||
|
curl -fsSL "https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list" \
|
||||||
|
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-ctk.gpg] https://#g' \
|
||||||
|
| tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y nvidia-container-toolkit
|
||||||
|
;;
|
||||||
|
rhel|fedora|rocky|centos|almalinux)
|
||||||
|
dnf install -y nvidia-container-toolkit
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "⚠ Unrecognised distro ($ID). Install nvidia-container-toolkit manually."
|
||||||
|
echo " See: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
nvidia-ctk runtime configure --runtime=docker
|
||||||
|
|
||||||
|
# ── 2. Permanent Docker DNS fix via systemd ───────────────────────────────────
|
||||||
|
# Adds a rule to the DOCKER-USER iptables chain so containers can resolve
|
||||||
|
# hostnames. Runs after docker.service on every boot. Does NOT touch ufw.
|
||||||
|
echo ""
|
||||||
|
echo "Installing docker-dns-fix systemd service..."
|
||||||
|
|
||||||
|
cat > /etc/systemd/system/docker-dns-fix.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Allow Docker containers to resolve DNS (DOCKER-USER iptables rule)
|
||||||
|
After=docker.service
|
||||||
|
Requires=docker.service
|
||||||
|
BindsTo=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/sh -c \
|
||||||
|
'iptables -C DOCKER-USER -p udp --dport 53 -j ACCEPT 2>/dev/null || \
|
||||||
|
iptables -I DOCKER-USER -p udp --dport 53 -j ACCEPT'
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable docker-dns-fix.service
|
||||||
|
echo "✓ docker-dns-fix.service installed and enabled"
|
||||||
|
|
||||||
|
# ── 3. Restart Docker ─────────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "Restarting Docker..."
|
||||||
|
systemctl restart docker
|
||||||
|
sleep 2
|
||||||
|
echo "✓ Docker restarted"
|
||||||
|
|
||||||
|
# ── 4. Apply DNS rule now (don't wait for next boot) ─────────────────────────
|
||||||
|
systemctl start docker-dns-fix.service
|
||||||
|
echo "✓ DNS fix applied"
|
||||||
|
|
||||||
|
# ── 5. Verify GPU access ─────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "Verifying GPU access inside Docker..."
|
||||||
|
if docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi &>/dev/null; then
|
||||||
|
echo "✓ GPU is accessible inside Docker"
|
||||||
|
else
|
||||||
|
echo "⚠ GPU check failed. Is the NVIDIA driver installed on the host?"
|
||||||
|
echo " Check: nvidia-smi"
|
||||||
|
echo " Minimum driver version: 525"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=================================================="
|
||||||
|
echo " Setup complete."
|
||||||
|
echo " Start the app with: ./bring-up-local-gpu.sh"
|
||||||
|
echo "=================================================="
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# start-gpu.sh — start the GPU container with Docker DNS fixed.
|
|
||||||
#
|
|
||||||
# The iptables rule restores Docker's default outbound DNS behaviour.
|
|
||||||
# It does NOT affect container isolation (namespaces, filesystems, etc.).
|
|
||||||
# The rule is lost on reboot, so this script re-applies it each time.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# ./start-gpu.sh # start (detached, with build)
|
|
||||||
# ./start-gpu.sh --build # force rebuild
|
|
||||||
# ./start-gpu.sh logs -f # tail logs
|
|
||||||
# ./start-gpu.sh down # stop and remove container
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Apply DNS fix on Linux hosts that have iptables.
|
|
||||||
# Skipped silently on macOS and Windows (WSL without iptables).
|
|
||||||
if command -v iptables &>/dev/null && command -v sudo &>/dev/null; then
|
|
||||||
if ! sudo iptables -C DOCKER-USER -p udp --dport 53 -j ACCEPT 2>/dev/null; then
|
|
||||||
sudo iptables -I DOCKER-USER -p udp --dport 53 -j ACCEPT
|
|
||||||
echo "[start-gpu] Docker DNS fix applied (iptables DOCKER-USER)"
|
|
||||||
else
|
|
||||||
echo "[start-gpu] Docker DNS rule already present — skipping"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Default: start detached with build. Pass any args to override.
|
|
||||||
if [ $# -eq 0 ]; then
|
|
||||||
exec docker compose -f docker-compose.gpu.yml up -d --build
|
|
||||||
else
|
|
||||||
exec docker compose -f docker-compose.gpu.yml "$@"
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user