Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Stable Diffusion Ubuntu
GUIDEInstall Guides

How to Install Stable Diffusion (Automatic1111) on Ubuntu 24.04

24 min read

How to Install Stable Diffusion (Automatic1111) on Ubuntu 24.04

Generating AI images on your own GPU VPS lets you skip subscription fees, remove rate limits, keep prompts and outputs private, and run any model or custom LoRA you want. This guide walks through installing Stable Diffusion WebUI (the Automatic1111 project) on a fresh Ubuntu 24.04 server, from NVIDIA drivers through to a hardened systemd service with nginx reverse proxy, authentication, and a working API.

Skip the setup? Deploy Stable Diffusion in one click with our pre-configured GPU Server image. Launch a GPU VPS now and start generating in under five minutes.

Table of Contents

  • What is Stable Diffusion?
  • Why Self-Host Stable Diffusion?
  • Prerequisites
  • Step 1: Install NVIDIA Drivers and CUDA
  • Step 2: Install Python 3.10
  • Step 3: Clone Automatic1111 and Install Dependencies
  • Step 4: Download Models
  • Step 5: First Launch and Test
  • Step 6: Remote Access and Launch Flags
  • Step 7: nginx Reverse Proxy with Authentication
  • Step 8: Run as a systemd Service
  • Step 9: Essential Extensions
  • Step 10: Using the API
  • Dreambooth and LoRA Training Overview
  • Security Hardening
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Stable Diffusion?

    Stable Diffusion is an open-weights latent diffusion model that turns text prompts into images. Originally released by Stability AI in 2022, it has become the foundation for most open-source image generation work. Unlike closed services such as Midjourney or DALL-E, you get the full model weights and can run them on your own hardware, fine-tune them, combine them with community checkpoints, and integrate them into any pipeline without asking permission.

    AUTOMATIC1111's Stable Diffusion WebUI is the most widely used interface for the model. It wraps the underlying PyTorch pipeline in a browser-based UI with every feature the community has built over the past three years: text-to-image, image-to-image, inpainting, outpainting, upscaling, ControlNet, LoRA loading, X/Y/Z plotting, prompt matrices, and a complete REST API. It supports all major Stable Diffusion families:

    • SD 1.5 -- The original workhorse. 512x512 native resolution, thousands of community checkpoints on Civitai, low VRAM requirements (4-6 GB), and the widest LoRA/embedding ecosystem.
    • SDXL -- Released mid-2023. Native 1024x1024 output, much stronger prompt adherence, a two-stage base + refiner pipeline, and a large and still-growing set of fine-tunes (Juggernaut XL, RealVisXL, Pony Diffusion, Animagine XL).
    • SD 3 / SD 3.5 -- Released late 2024. Uses a new MMDiT architecture with three text encoders for much better typography and multi-subject scenes. Requires more VRAM (12 GB+ comfortable).
    • Flux.1 (dev and schnell) -- Black Forest Labs' 12B parameter model. Top-tier quality, runs under Automatic1111 with the Forge fork or via ComfyUI.
    The WebUI also supports every tooling layer you need for production work: VAE selection, hires-fix upscaling, face restoration with CodeFormer and GFPGAN, batch processing, inpaint-only models, sampler comparison, and prompt weighting syntax like (word:1.3) and [word:0.7].

    Why Self-Host Stable Diffusion?

    Running Stable Diffusion on your own GPU VPS instead of paying for Midjourney, DALL-E, or a SaaS image generator has concrete, measurable advantages.

    • Flat monthly cost vs. per-image pricing. Midjourney's Standard plan is $30/month for 15 hours of fast GPU time (roughly 900 images). A GPU VPS running SDXL generates an image every 4-8 seconds, so a 30-day month at even light utilization produces tens of thousands of images at the same flat price -- and unused capacity carries no overage charge.
    • Unlimited generations. No daily caps, no token quotas, no "relax mode" queueing. If your GPU is idle, you can run it flat-out. Batch jobs, sweeps over samplers and seeds, and synthetic dataset generation all become practical.
    • Complete privacy. Prompts, reference images, LoRAs, and generated outputs never leave your server. This matters for client work under NDA, product concept art, medical or legal imagery, personal photos used as reference, and any commercial workflow where IP leaks are unacceptable.
    • NSFW and artistic freedom. Commercial services aggressively filter prompts and outputs. Stable Diffusion on your own hardware has no filter -- you decide what is acceptable for your use case. This is the single most common reason creators, artists, and adult-content producers self-host.
    • Custom models, LoRAs, and embeddings. Civitai hosts tens of thousands of community checkpoints for every style imaginable: photorealism, anime, architectural renders, specific artists, specific characters. You can download any of them, stack multiple LoRAs in a single prompt, and train your own on photos of your product, your face, or your art style.
    • ControlNet and advanced pipelines. Pose control, depth maps, canny edges, scribble-to-image, QR code monster, tile-based upscaling, reference-only generation -- these exist only in the open-source ecosystem.
    • API integration. A self-hosted WebUI exposes a full REST API. You can generate images from your SaaS app, your Discord bot, your CMS, or your ComfyUI workflow without signing a per-call usage contract.
    • Commercial use without licensing fees. SD 1.5 and SDXL are released under permissive licences that allow commercial use. You can sell the generated images, use them in products, and build businesses on top.

    Prerequisites

    For a smooth install and realistic generation speeds, you need:

    • Ubuntu 24.04 LTS (22.04 also works, same steps) with root or sudo access.
    • NVIDIA GPU with 16 GB+ VRAM. SD 1.5 runs on 4-6 GB, SDXL wants 10-12 GB, SD3 and Flux prefer 16 GB+. For production-grade throughput pick an L40S, A6000, A100, or RTX 4090 class card. 8 GB cards work for SD 1.5 and low-res SDXL but limit you on batch size, resolution, and ControlNet stacking.
    • 100 GB+ disk. Models are large. A single SDXL checkpoint is 6-7 GB. Expect 200-500 GB if you collect models from Civitai.
    • 16 GB+ system RAM. PyTorch and the model loader are memory-hungry during startup.
    • A domain name pointed at your server's IP, if you plan to use nginx + HTTPS.
    • Basic comfort with the Linux command line.
    If you don't have a suitable server, VPS-Server.host's GPU Server plans include an NVIDIA L40S with 48 GB VRAM, pre-installed CUDA, and a one-click Stable Diffusion option. That removes Steps 1 and 2 of this guide entirely.

    Step 1: Install NVIDIA Drivers and CUDA

    SSH into your server as a sudo-capable user and update the system first.

    bash
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y build-essential wget curl git software-properties-common

    Check that the GPU is visible to the kernel.

    bash
    lspci | grep -i nvidia

    You should see the card listed. Install the recommended NVIDIA driver.

    bash
    sudo apt install -y ubuntu-drivers-common
    sudo ubuntu-drivers autoinstall
    sudo reboot

    After the server comes back, verify the driver loaded.

    bash
    nvidia-smi

    You should see the driver version, CUDA version, and your GPU with memory usage. PyTorch ships its own CUDA runtime, so you do not need to install the CUDA toolkit from NVIDIA separately for Automatic1111 -- the driver is enough. If you want the toolkit for other workloads, install it with:

    bash
    sudo apt install -y nvidia-cuda-toolkit

    Step 2: Install Python 3.10

    Automatic1111 expects Python 3.10.x specifically. Ubuntu 24.04 ships with Python 3.12, which is not compatible with several pinned dependencies in the WebUI's requirements.txt. You have two clean options.

    Option A: deadsnakes PPA (recommended, simpler)

    bash
    sudo add-apt-repository -y ppa:deadsnakes/ppa
    sudo apt update
    sudo apt install -y python3.10 python3.10-venv python3.10-dev

    Verify:

    bash
    python3.10 --version
    

    Python 3.10.14

    Option B: pyenv (better if you want multiple Python versions)

    bash
    curl https://pyenv.run | bash

    Add to ~/.bashrc

    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc source ~/.bashrc

    Install build dependencies

    sudo apt install -y make libssl-dev zlib1g-dev libbz2-dev libreadline-dev \ libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev \ libxmlsec1-dev libffi-dev liblzma-dev

    pyenv install 3.10.14 pyenv global 3.10.14

    Either way, you now have Python 3.10 available.

    Step 3: Clone Automatic1111 and Install Dependencies

    Create a dedicated user for the WebUI so it never runs as root.

    bash
    sudo useradd -m -s /bin/bash sduser
    sudo usermod -aG sudo sduser
    sudo su - sduser

    Clone the repository into the home directory.

    bash
    cd ~
    git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
    cd stable-diffusion-webui

    The WebUI ships with a launcher script that creates a virtual environment, installs PyTorch with the correct CUDA build, and pulls down all Python dependencies on first run. You don't run pip install manually -- the launcher handles it. But before the first run, confirm the script will use Python 3.10.

    bash
    which python3.10
    

    /usr/bin/python3.10 (or ~/.pyenv/shims/python3.10 with pyenv)

    Edit webui-user.sh to pin the interpreter and set your preferred launch flags.

    bash
    nano webui-user.sh

    Set these variables:

    bash
    #!/bin/bash
    export python_cmd="python3.10"
    export COMMANDLINE_ARGS="--listen --port 7860 --enable-insecure-extension-access --api --xformers"
    export TORCH_COMMAND="pip install torch==2.1.2 torchvision==0.16.2 --index-url https://download.pytorch.org/whl/cu121"

    Flag breakdown:

    • --listen -- bind to 0.0.0.0 so the WebUI is reachable from outside the server (we'll put it behind nginx + auth).
    • --port 7860 -- default port, change if it conflicts.
    • --enable-insecure-extension-access -- required to install extensions when --listen is active.
    • --api -- enables the REST API at /sdapi/v1/*.
    • --xformers -- memory-efficient attention, 30-40% faster sampling on most GPUs.
    Save and exit.

    Step 4: Download Models

    Models go into models/Stable-diffusion/. The WebUI will not start without at least one checkpoint. Download a sensible starter set.

    SD 1.5 base

    bash
    cd ~/stable-diffusion-webui/models/Stable-diffusion
    wget https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors

    SDXL base 1.0

    bash
    wget https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors

    SDXL refiner 1.0

    bash
    wget https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/resolve/main/sd_xl_refiner_1.0.safetensors

    VAE (optional but recommended for SDXL)

    bash
    cd ~/stable-diffusion-webui/models/VAE
    wget https://huggingface.co/stabilityai/sdxl-vae/resolve/main/sdxl_vae.safetensors

    For higher-quality community fine-tunes, browse Civitai and download .safetensors files into the same folder. Juggernaut XL, RealVisXL, and DreamShaper are reliable starting points for photoreal work. Anything XL goes in models/Stable-diffusion/, LoRAs go in models/Lora/, textual inversion embeddings go in embeddings/.

    Step 5: First Launch and Test

    From the stable-diffusion-webui directory:

    bash
    ./webui.sh

    First launch takes 5-15 minutes: it creates venv/, downloads PyTorch (~2 GB with CUDA 12.1), installs xformers, pulls CLIP and other sub-models, and compiles a few C extensions. Watch the log for errors. You should eventually see:

    text
    Running on local URL:  http://0.0.0.0:7860

    Open http://YOUR_SERVER_IP:7860 in a browser. You should see the WebUI. Pick the SDXL base checkpoint from the top-left dropdown, type a prompt, hit Generate. The first generation is slower (model loads into VRAM). Subsequent ones should complete in 4-10 seconds on an L40S at 1024x1024 with 25 steps.

    If the UI loads but generation errors, check the terminal for a traceback. Common first-run issues are covered in Troubleshooting.

    Stop the server with Ctrl+C before moving on.

    Step 6: Remote Access and Launch Flags

    Exposing port 7860 directly to the internet is a bad idea -- the WebUI has no built-in authentication and extensions can execute arbitrary code. The correct pattern is:

  • Bind the WebUI to 0.0.0.0 so it's reachable from localhost and from nginx on the same box.
  • Firewall port 7860 so only localhost can reach it directly.
  • Put nginx in front on port 443 with HTTP Basic Auth and a real TLS certificate.
  • Lock down the WebUI port now.

    bash
    sudo ufw allow 22/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw deny 7860/tcp
    sudo ufw enable

    Useful additional launch flags you may want later:

    • --medvram / --lowvram -- offload parts of the model to system RAM. Adds latency, saves VRAM. Needed on 8 GB cards for SDXL.
    • --no-half-vae -- fixes NaN output on some cards when using SDXL.
    • --opt-sdp-attention -- PyTorch native scaled-dot-product attention as an alternative to xformers.
    • --share -- creates a Gradio tunnel. Convenient for quick demos, bad for production.
    • --autolaunch -- opens a browser automatically. Useless on a headless VPS.
    • --administrator -- skips the warning about running as root. Don't.
    • --gradio-auth user:password -- minimal built-in auth. Acceptable for solo use but weaker than nginx Basic Auth.

    Step 7: nginx Reverse Proxy with Authentication

    Install nginx and Certbot.

    bash
    sudo apt install -y nginx apache2-utils certbot python3-certbot-nginx

    Create a Basic Auth password file.

    bash
    sudo htpasswd -c /etc/nginx/.sd_htpasswd yourusername
    

    enter password twice

    Create the site config.

    bash
    sudo nano /etc/nginx/sites-available/stable-diffusion

    Paste this configuration. Replace sd.example.com with your domain.

    nginx
    server {
        listen 80;
        server_name sd.example.com;
        return 301 https://$host$request_uri;
    }

    server { listen 443 ssl http2; server_name sd.example.com;

    # TLS certs populated by Certbot ssl_certificate /etc/letsencrypt/live/sd.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/sd.example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;

    # Large uploads for img2img reference images and ControlNet client_max_body_size 100M;

    # Basic Auth gate auth_basic "Stable Diffusion WebUI"; auth_basic_user_file /etc/nginx/.sd_htpasswd;

    # Long timeouts for slow generations (SDXL 2048x2048 hires fix can take minutes) proxy_read_timeout 600s; proxy_send_timeout 600s; proxy_connect_timeout 60s;

    # Gradio websocket + streaming proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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; proxy_buffering off;

    location / { proxy_pass http://127.0.0.1:7860; }

    # Optionally protect the API with a separate credential set or IP allowlist location /sdapi/ { # allow 203.0.113.0/24; # deny all; proxy_pass http://127.0.0.1:7860; } }

    Enable the site, test, and reload.

    bash
    sudo ln -s /etc/nginx/sites-available/stable-diffusion /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl reload nginx

    Issue a TLS certificate.

    bash
    sudo certbot --nginx -d sd.example.com

    Certbot auto-edits the config with the correct cert paths and sets up renewal via systemd timer.

    Now change the WebUI launch flags to bind only to localhost (nginx will reach it over the loopback).

    bash
    # In webui-user.sh
    export COMMANDLINE_ARGS="--listen --server-name 127.0.0.1 --port 7860 --enable-insecure-extension-access --api --xformers"

    Step 8: Run as a systemd Service

    You want the WebUI to survive reboots, restart on crash, and log to journald. Create a unit file.

    bash
    sudo nano /etc/systemd/system/stable-diffusion.service
    ini
    [Unit]
    Description=Stable Diffusion WebUI (Automatic1111)
    After=network-online.target
    Wants=network-online.target

    [Service] Type=simple User=sduser Group=sduser WorkingDirectory=/home/sduser/stable-diffusion-webui Environment="PATH=/home/sduser/stable-diffusion-webui/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ExecStart=/home/sduser/stable-diffusion-webui/webui.sh Restart=on-failure RestartSec=15 TimeoutStartSec=600 TimeoutStopSec=60

    Resource and security hardening

    LimitNOFILE=65536 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=false ReadWritePaths=/home/sduser/stable-diffusion-webui ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true

    [Install] WantedBy=multi-user.target

    Enable and start:

    bash
    sudo systemctl daemon-reload
    sudo systemctl enable --now stable-diffusion.service
    sudo systemctl status stable-diffusion.service
    journalctl -u stable-diffusion.service -f

    The first start still takes a few minutes for any missed dependency download. Subsequent restarts should be ready in 30-60 seconds.

    Common service commands:

    bash
    sudo systemctl restart stable-diffusion
    sudo systemctl stop stable-diffusion
    journalctl -u stable-diffusion -n 200 --no-pager

    Step 9: Essential Extensions

    The WebUI's power is largely in its extensions. Install from the Extensions > Install from URL tab (you need --enable-insecure-extension-access for this to work when --listen is set).

    • sd-webui-controlnet -- the single most important extension. Gives you pose control (OpenPose), depth guidance (MiDaS, ZoeDepth), edge guidance (Canny, HED), scribble, segmentation, reference-only, tile upscaling, and more. Install, then download the ControlNet SDXL models from https://huggingface.co/lllyasviel/sd_control_collection into extensions/sd-webui-controlnet/models/.
    text
    https://github.com/Mikubill/sd-webui-controlnet
    • adetailer (!After Detailer) -- automatically detects faces, hands, eyes, and full bodies, masks them, and runs a second inpainting pass. Fixes the classic "good image, broken face" problem in one click.
    text
    https://github.com/Bing-su/adetailer
    • Ultimate SD Upscale -- tiled upscaling that can take a 1024x1024 image to 4K or 8K while adding detail, not just interpolating pixels.
    text
    https://github.com/Coyote-A/ultimate-upscale-for-automatic1111
    • sd-webui-regional-prompter -- different prompts for different regions of the image (e.g. "red hair on the left, blue hair on the right").
    text
    https://github.com/hako-mikan/sd-webui-regional-prompter
    • Civitai Helper -- shows model previews, trigger words, and version info from Civitai directly in the WebUI model browser.
    text
    https://github.com/butaixianran/Stable-Diffusion-Webui-Civitai-Helper
    • sd-dynamic-prompts -- wildcard and combinatorial prompt syntax for large batch sweeps.
    text
    https://github.com/adieyal/sd-dynamic-prompts

    Restart the WebUI from the Extensions tab (Apply and restart UI) after installing each group.

    Step 10: Using the API

    With --api enabled, the WebUI exposes a full REST interface at https://sd.example.com/sdapi/v1/*. Docs are self-served at /docs (FastAPI Swagger UI).

    Text-to-image

    Save this as txt2img.sh:

    bash
    #!/bin/bash
    curl -s -u yourusername:yourpassword \
      -X POST https://sd.example.com/sdapi/v1/txt2img \
      -H "Content-Type: application/json" \
      -d '{
        "prompt": "a photograph of a red fox in a snowy forest at golden hour, highly detailed, cinematic lighting",
        "negative_prompt": "cartoon, drawing, illustration, lowres, blurry, bad anatomy",
        "steps": 30,
        "cfg_scale": 7,
        "width": 1024,
        "height": 1024,
        "sampler_name": "DPM++ 2M Karras",
        "seed": -1,
        "batch_size": 1,
        "n_iter": 1
      }' | jq -r '.images[0]' | base64 -d > fox.png

    echo "Saved fox.png"

    The response images array contains base64-encoded PNGs. seed: -1 randomises; pass a specific integer to reproduce a previous generation.

    Image-to-image

    bash
    #!/bin/bash
    INPUT_B64=$(base64 -w0 input.jpg)

    curl -s -u yourusername:yourpassword \ -X POST https://sd.example.com/sdapi/v1/img2img \ -H "Content-Type: application/json" \ -d "{ \"init_images\": [\"$INPUT_B64\"], \"prompt\": \"oil painting in the style of Van Gogh, swirling brush strokes, vivid colours\", \"denoising_strength\": 0.6, \"steps\": 30, \"cfg_scale\": 7, \"width\": 1024, \"height\": 1024, \"sampler_name\": \"DPM++ 2M Karras\" }" | jq -r '.images[0]' | base64 -d > output.png

    denoising_strength controls how much of the input is preserved: 0.2 is a gentle touch-up, 0.7 is a near-total re-imagining.

    Switch checkpoint via API

    bash
    curl -s -u yourusername:yourpassword \
      -X POST https://sd.example.com/sdapi/v1/options \
      -H "Content-Type: application/json" \
      -d '{"sd_model_checkpoint": "sd_xl_base_1.0.safetensors"}'

    Get progress during a long generation

    bash
    curl -s -u yourusername:yourpassword \
      https://sd.example.com/sdapi/v1/progress | jq

    List available samplers, models, LoRAs

    bash
    curl -s -u U:P https://sd.example.com/sdapi/v1/samplers | jq
    curl -s -u U:P https://sd.example.com/sdapi/v1/sd-models | jq
    curl -s -u U:P https://sd.example.com/sdapi/v1/loras | jq

    Python client example

    python
    import base64, requests
    from io import BytesIO
    from PIL import Image

    AUTH = ("yourusername", "yourpassword") URL = "https://sd.example.com/sdapi/v1/txt2img"

    payload = { "prompt": "ultra-detailed product photo of a matte black ceramic coffee mug on a concrete table, studio lighting", "negative_prompt": "lowres, blurry, watermark, text", "steps": 30, "cfg_scale": 7, "width": 1024, "height": 1024, "sampler_name": "DPM++ 2M Karras", }

    r = requests.post(URL, json=payload, auth=AUTH, timeout=300) r.raise_for_status() img_b64 = r.json()["images"][0] Image.open(BytesIO(base64.b64decode(img_b64))).save("mug.png")

    Dreambooth and LoRA Training Overview

    Fine-tuning Stable Diffusion on your own images lets you create a model that reliably generates a specific person, product, or style. Two main techniques:

    • LoRA (Low-Rank Adaptation) -- trains a small adapter (10-200 MB) that plugs into the base model. Fast (15-60 minutes on an L40S), small, stackable with other LoRAs, and the dominant format on Civitai. Best for characters, styles, and concepts.
    • Dreambooth -- fine-tunes the entire model. Produces a full-size checkpoint (2-7 GB), slower (1-4 hours), and not stackable, but can capture harder subjects with higher fidelity.
    Popular training tools:

    • kohya_ss GUI (https://github.com/bmaltais/kohya_ss) -- the most widely used trainer. Web UI, supports SD 1.5, SDXL, and SD3 LoRA and full fine-tunes. Install in its own venv alongside the WebUI.
    • sd-scripts -- the underlying CLI that kohya_ss wraps. Use it directly for headless or scripted training.
    • OneTrainer (https://github.com/Nerogar/OneTrainer) -- modern GUI with cleaner UX than kohya for first-time users.
    Minimum viable LoRA recipe for a character: 15-30 images of the subject at varied angles and lighting, captioned with a unique trigger word plus generic descriptions, trained at learning rate 1e-4 for 1500-3000 steps with rank 32 dim. Drop the .safetensors into models/Lora/ and invoke in your prompt with <lora:my_character:0.8>.

    Training benefits most from 24 GB+ VRAM; SDXL LoRAs at 1024x1024 resolution need real headroom. This is where the GPU Server plan pays off -- the same box hosts inference and training without swapping hardware.

    Security Hardening

    Even behind nginx + Basic Auth, the WebUI's extension system can execute arbitrary Python, so the blast radius of a compromise is "full code execution as the sduser account." Raise the bar.

    • Don't run as root. The sduser account above already handles this.
    • Never expose port 7860 to the internet. The ufw deny 7860/tcp rule enforces it.
    • Use a long, unique Basic Auth password, and consider putting a second layer in front -- Cloudflare Access, a WireGuard VPN, or an IP allowlist in nginx.
    • Patch regularly. cd stable-diffusion-webui && git pull every few weeks. Upstream fixes security bugs quietly.
    • Audit extensions before installing. Each extension is a GitHub repo with full code execution rights inside the WebUI process. Install only what you need, from authors you recognise.
    • Separate the API user from the UI user. In nginx you can add a second Basic Auth file for /sdapi/ with different credentials, or restrict the API path to specific source IPs with allow/deny.
    • Keep models and outputs on encrypted disks if you handle client work or anything with privacy implications.
    • Disable --share (Gradio tunnels) in production. They bypass your firewall entirely.
    • Monitor journald and nginx access logs. journalctl -u stable-diffusion -f and /var/log/nginx/access.log will show you failed auth attempts and suspicious paths.
    • Back up the models/Lora/, embeddings/, and outputs/ directories. Models you can re-download; trained LoRAs and finished work you cannot.

    Troubleshooting

    CUDA out of memory during generation. Reduce resolution, reduce batch size, enable --medvram or --lowvram in webui-user.sh, or switch from SDXL to SD 1.5. On SDXL specifically, turning off the refiner or running it as a second pass (instead of ensemble-of-experts) saves several GB.

    AssertionError: Torch not compiled with CUDA enabled. PyTorch was installed without CUDA support. Delete the venv and relaunch:

    bash
    rm -rf venv
    ./webui.sh
    Verify your TORCH_COMMAND in webui-user.sh includes --index-url https://download.pytorch.org/whl/cu121 (or cu118 for older drivers).

    NaN output / black images with SDXL. Add --no-half-vae to COMMANDLINE_ARGS. This is a known issue with the base SDXL VAE in fp16 on certain GPUs.

    xformers fails to build or import. xformers pins a specific PyTorch version. If your Torch was upgraded, the installed xformers may be incompatible. Either remove --xformers and use --opt-sdp-attention instead (comparable speed on modern GPUs), or pip install --force-reinstall xformers==0.0.23.post1 inside the venv.

    WebUI starts but generation hangs forever. Check nvidia-smi -- is the GPU actually being used? If memory is allocated but compute is 0%, you likely have a driver/PyTorch mismatch. Reboot, check nvidia-smi again, and reinstall PyTorch with a matching CUDA build.

    Permission denied writing to outputs. ProtectHome=false in the systemd unit handles this; if you changed paths, add them to ReadWritePaths=.

    nginx returns 502 Bad Gateway. The WebUI process died or hasn't finished starting. sudo systemctl status stable-diffusion and journalctl -u stable-diffusion -n 100.

    nginx returns 504 Gateway Timeout on long generations. Raise proxy_read_timeout in the nginx config. 600s is enough for almost everything; push to 1800s for heavy hires-fix or big batch jobs.

    Extensions tab shows Extension access disabled because of command line flags. You used --listen without --enable-insecure-extension-access. Add it and restart.

    Models don't appear in the dropdown. They must be in models/Stable-diffusion/ with the .safetensors or .ckpt extension. Click the refresh button next to the checkpoint selector, or restart the service.

    FAQ

    SD 1.5 vs SDXL vs SD 3 -- which should I use? SD 1.5 if you have an older/smaller GPU (4-8 GB), want the largest community ecosystem, or need the fastest iteration. SDXL for general-purpose high-quality work at 1024x1024 on a 12 GB+ GPU -- this is the sweet spot for most users in 2025. SD 3 / 3.5 when you need better text rendering inside images and stronger multi-subject compositions. Flux.1 dev if you want absolute top-tier quality and have 24 GB VRAM to spare.

    What's the minimum VRAM I need? For SD 1.5 at 512x512 with --medvram, 4 GB works but is slow. For SDXL at 1024x1024, 12 GB is comfortable, 10 GB works with --medvram, and 8 GB requires tiling tricks. For SD 3 and Flux, plan on 16 GB minimum and 24 GB for a smooth experience. Training LoRAs on SDXL wants 16-24 GB.

    Can I use Stable Diffusion images commercially? Yes, for SD 1.5 and SDXL. Both are released under licences that allow commercial use. SD 3 has a more restrictive community licence for companies above a revenue threshold -- check the Stability AI community license if you're a commercial user. Also verify the licence of any community checkpoint or LoRA you load from Civitai; a small subset is marked non-commercial.

    How does this compare to Midjourney? Midjourney produces beautiful images with very little prompt engineering but offers no control over the pipeline: no ControlNet, no LoRAs, no inpainting primitives, no API for most plans, aggressive content filters, and a fixed $10-$60/month cost. Stable Diffusion on your own GPU gives you everything the open-source community has built, full API access, no content restrictions, and flat monthly VPS pricing -- but you need to learn the tools to get Midjourney-level output quality. For hobbyists focused on "pretty pictures" Midjourney is easier; for builders, commercial users, and anyone needing control, self-hosted SD wins.

    What is ControlNet and why does everyone talk about it? ControlNet lets you guide image generation with a second input beyond the text prompt: a pose skeleton, a depth map, an edge map, a scribble, a segmentation mask, or another reference image. That means you can take a photograph of someone, extract their pose, and generate a completely different person in the exact same pose. Or take a rough architectural sketch and turn it into a photorealistic rendering. It's the single biggest reason professional workflows use Stable Diffusion over closed alternatives.

    Do I need the refiner for SDXL? The refiner adds detail and cleans up noise in the final 20% of steps. It helps for photoreal work but adds latency and VRAM use. Most community checkpoints based on SDXL (Juggernaut, RealVisXL) don't need a refiner -- they've already been fine-tuned past the base model's weaknesses.

    Can I run multiple GPUs? Automatic1111 runs on a single GPU per process. To use multiple GPUs, run multiple instances on different ports with CUDA_VISIBLE_DEVICES=0 / =1 / etc., and load-balance them from your application. For true multi-GPU inference on a single request, use ComfyUI or a custom pipeline with accelerate.

    Why Automatic1111 over ComfyUI or Fooocus? A1111 has the biggest feature surface, the most extensions, and a familiar tabbed UI. ComfyUI is a node-based editor that gives you fine-grained pipeline control and is the preferred interface for Flux and advanced workflows -- but it has a steeper learning curve. Fooocus is a deliberately stripped-down SDXL interface optimised for ease of use; it's the best first experience for non-technical users. Many operators run all three on the same server and use whichever fits the task.

    How do I update the WebUI?

    bash
    sudo systemctl stop stable-diffusion
    sudo -u sduser -i
    cd stable-diffusion-webui
    git pull
    exit
    sudo systemctl start stable-diffusion
    Watch the journal for dependency upgrade issues on the first start after a pull.

    Next Steps

    You now have a hardened, API-enabled Stable Diffusion WebUI running on your GPU VPS. From here, three directions are worth exploring.

    • Add ComfyUI alongside A1111. ComfyUI's node-based interface unlocks Flux.1, advanced multi-pass pipelines, and workflow sharing from the r/StableDiffusion community. Install at github.com/comfyanonymous/ComfyUI on a different port (e.g. 8188), add a second nginx location block, and share the same models/ directory via symlinks.
    • Install Fooocus as a simplified SDXL interface. github.com/lllyasviel/Fooocus gives you a Midjourney-style single-input experience built on SDXL. Useful for team members who shouldn't have to learn samplers and CFG scales.
    • Train your first LoRA. Install kohya_ss, gather 20-30 reference images, and train a character or style LoRA in an evening. This is where self-hosting pays off permanently -- your LoRAs live on your server, work offline, and cost nothing to run.

    Ready to Run Stable Diffusion?

    Generation speed scales directly with GPU class. On VPS-Server.host's GPU Server plans you get:

    • NVIDIA L40S with 48 GB VRAM -- enough headroom for SDXL at full resolution with ControlNet stacks, Flux.1 dev, simultaneous inference + training, and batch sizes that keep the GPU pinned at 100%.
    • Pre-installed CUDA and NVIDIA drivers, so Steps 1-2 of this guide are already done.
    • One-click Stable Diffusion WebUI image available at provision time.
    • Flat monthly billing with no per-image or per-token metering. Run the GPU 24/7 if you want to.
    • NVMe storage sized for hundreds of checkpoints and LoRAs.
    See GPU Server plans and launch in minutes →

    Questions about sizing, training workloads, or migrating from Midjourney? Contact our team and we'll spec the right plan for your workflow.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket