Stable Diffusion WebUI, better known as AUTOMATIC1111, is a browser interface for generating images with Stable Diffusion models, with support for checkpoints, LoRA adapters, extensions and an HTTP API. In this tutorial you will install it on an Ubuntu 24.04 server with an NVIDIA GPU, load the SDXL base model, run it as a systemd service under a dedicated user and publish it through Nginx with HTTPS and a password.

Prerequisites

To follow this guide you need:

  • A server running Ubuntu 24.04 LTS with an NVIDIA GPU. SDXL needs 8 GB of VRAM or more; older SD 1.5 models run with 4 to 6 GB.
  • A non-root user with sudo privileges.
  • At least 16 GB of RAM and 40 GB of free disk space. The Python environment takes about 10 GB and each checkpoint 2 to 7 GB.
  • A domain name, such as sd.your_domain, with a DNS A record pointing to your_server_ip, for the HTTPS step.
  • Nginx installed, and UFW allowing OpenSSH and Nginx Full.

Step 1 - Installing the NVIDIA driver

The WebUI uses PyTorch with CUDA, which only needs the NVIDIA driver on the host. The CUDA libraries are installed inside the Python environment. Let Ubuntu pick the recommended driver:

sudo apt update
sudo ubuntu-drivers install
sudo reboot

After the reboot, confirm that the driver sees the GPU:

nvidia-smi
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.xx.xx              Driver Version: 570.xx.xx      CUDA Version: 12.8     |
...
|   0  NVIDIA L4                      Off |   00000000:00:05.0 Off |                    0 |

If the command is not found or reports no devices, fix the driver before continuing; the WebUI will otherwise fall back to an unusable CPU mode.

Step 2 - Installing Python 3.11 and system dependencies

Ubuntu 24.04 ships Python 3.12, which the pinned PyTorch version in AUTOMATIC1111 does not support. The project's own instructions for Ubuntu 24.04 use Python 3.11 from the deadsnakes PPA:

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install -y python3.11 python3.11-venv

Install the remaining libraries: git and wget for downloads, libgl1 and libglib2.0-0 for OpenCV, and google-perftools, which the launch script uses to load the TCMalloc allocator and reduce memory fragmentation:

sudo apt install -y git wget libgl1 libglib2.0-0 google-perftools

Verify the interpreter:

python3.11 --version
Python 3.11.x

Step 3 - Creating a user and cloning the WebUI

The launch script refuses to run as root, and a dedicated user keeps the model files and the web process isolated from your login account. Create the sdwebui user:

sudo useradd -m -s /bin/bash sdwebui

Clone the repository into its home directory:

sudo -u sdwebui git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git /home/sdwebui/stable-diffusion-webui

The repository contains the folders you will use most:

FolderPurpose
models/Stable-diffusion/Checkpoints (.safetensors)
models/Lora/LoRA adapters
models/VAE/Standalone VAE files
outputs/Generated images
extensions/Installed extensions

Step 4 - Configuring webui-user.sh

webui.sh reads its settings from webui-user.sh in the same directory. Open it as the sdwebui user:

sudo -u sdwebui nano /home/sdwebui/stable-diffusion-webui/webui-user.sh

The file is fully commented out. Uncomment and set these two lines:

python_cmd="python3.11"
export COMMANDLINE_ARGS="--xformers --medvram-sdxl"

These options do the following:

  • python_cmd makes the script create its virtual environment with Python 3.11.
  • --xformers installs and enables memory efficient attention, which lowers VRAM use and speeds up generation.
  • --medvram-sdxl moves parts of SDXL models out of VRAM when they are not in use, so SDXL fits on 8 to 12 GB cards. Remove it on 16 GB or larger GPUs.

The WebUI listens on 127.0.0.1:7860 by default. Leave it that way: Nginx will be the only public entry point. Do not add --listen unless you want the unauthenticated interface on every network interface.

For cards with less memory, replace the arguments with --xformers --medvram (6 GB) or --xformers --lowvram (4 GB), which trade speed for memory.

Step 5 - Downloading the SDXL base model

If models/Stable-diffusion/ is empty on first launch, the WebUI tries to download a default SD 1.5 model. Download SDXL 1.0 base from Stability AI's Hugging Face repository instead (about 7 GB):

sudo -u sdwebui wget -P /home/sdwebui/stable-diffusion-webui/models/Stable-diffusion/ \
  https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors

Check the file size when the download finishes:

ls -lh /home/sdwebui/stable-diffusion-webui/models/Stable-diffusion/
-rw-r--r-- 1 sdwebui sdwebui 6.5G ... sd_xl_base_1.0.safetensors

Use .safetensors files whenever possible. Older .ckpt files are Python pickles and can run arbitrary code when loaded, so only use them from sources you trust.

Step 6 - Running the first launch

The first launch creates the virtual environment in venv/ and installs PyTorch, xformers and the rest of the dependencies. It takes 5 to 15 minutes depending on bandwidth. Run it interactively so you can watch for errors:

sudo -iu sdwebui
cd ~/stable-diffusion-webui
./webui.sh

When the installation finishes and the model loads, the script prints the local URL:

Model loaded in 12.3s (...).
Running on local URL:  http://127.0.0.1:7860

In a second SSH session, confirm that the interface answers:

curl -sI http://127.0.0.1:7860 | head -n 1
HTTP/1.1 200 OK

Stop the process with Ctrl+C in the first session and type exit to return to your own user. From now on systemd will run it.

Step 7 - Running the WebUI as a systemd service

Create a unit file so the WebUI starts at boot and restarts if it crashes:

sudo nano /etc/systemd/system/sdwebui.service
[Unit]
Description=Stable Diffusion WebUI (AUTOMATIC1111)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=sdwebui
Group=sdwebui
WorkingDirectory=/home/sdwebui/stable-diffusion-webui
ExecStart=/home/sdwebui/stable-diffusion-webui/webui.sh
Restart=on-failure
RestartSec=15

[Install]
WantedBy=multi-user.target

Load the unit and start it:

sudo systemctl daemon-reload
sudo systemctl enable --now sdwebui

Follow the logs until the model is loaded:

sudo journalctl -u sdwebui -f
... Running on local URL:  http://127.0.0.1:7860

Press Ctrl+C to leave the log view; the service keeps running.

Step 8 - Publishing the WebUI with Nginx, HTTPS and a password

The WebUI has no login of its own by default, so protect it with HTTP basic authentication in Nginx. Install apache2-utils for the htpasswd tool and create a user, replacing your_user:

sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.sdwebui-htpasswd your_user

Create the server block, replacing sd.your_domain:

sudo nano /etc/nginx/sites-available/sdwebui
server {
    listen 80;
    listen [::]:80;
    server_name sd.your_domain;

    client_max_body_size 50M;

    location / {
        auth_basic "Stable Diffusion";
        auth_basic_user_file /etc/nginx/.sdwebui-htpasswd;

        proxy_pass http://127.0.0.1:7860;
        proxy_http_version 1.1;
        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 600s;
    }
}

The Upgrade and Connection headers are needed because the Gradio interface uses WebSockets for progress updates, and the long read timeout covers slow generations. Enable the site and reload Nginx:

sudo ln -s /etc/nginx/sites-available/sdwebui /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Request a Let's Encrypt certificate. Certbot adds the HTTPS configuration and the HTTP to HTTPS redirect to this server block:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d sd.your_domain

Verify that the site now asks for credentials:

curl -sI https://sd.your_domain | head -n 1
HTTP/2 401

Open https://sd.your_domain in a browser, sign in, select sd_xl_base_1.0.safetensors in the checkpoint dropdown and generate an image at 1024x1024 with 25 to 30 sampling steps. Generated files are saved under outputs/txt2img-images/.

Troubleshooting

torch.OutOfMemoryError: CUDA out of memory. Add --medvram (or --lowvram on 4 GB cards) to COMMANDLINE_ARGS, lower the resolution or batch size, then restart the service with sudo systemctl restart sdwebui.

Images come out black or the log shows A tensor with all NaNs was produced in VAE. The SDXL VAE overflows in half precision on some GPUs. Add --no-half-vae to COMMANDLINE_ARGS and restart.

Cannot locate TCMalloc warning at startup. The google-perftools package is missing. Install it as shown in step 2; the warning is harmless but memory use is higher without it.

A new checkpoint does not appear in the dropdown. Confirm the file is in models/Stable-diffusion/ and owned by sdwebui, then click the refresh button next to the checkpoint selector.

Nginx returns 502 Bad Gateway. The service is still starting or has crashed. Check sudo systemctl status sdwebui and the last lines of sudo journalctl -u sdwebui.

Conclusion

Stable Diffusion WebUI now runs on your Ubuntu 24.04 GPU server as a systemd service, loads SDXL and is reachable only through Nginx with HTTPS and a password. From here you can add LoRA adapters to models/Lora/, enable the HTTP API with the --api flag for scripted generation, and back up the models/ and outputs/ folders regularly.