Skip to content

Commit cae1586

Browse files
1 parent 802d0bc commit cae1586

File tree

13 files changed

+285
-21
lines changed

13 files changed

+285
-21
lines changed

docker-compose.yml

100644100755
Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
x-base_service: &base_service
2-
ports:
3-
- "${WEBUI_PORT:-7860}:7860"
4-
volumes:
5-
- &v1 ./data:/data
6-
- &v2 ./output:/output
7-
stop_signal: SIGKILL
8-
tty: true
9-
deploy:
10-
resources:
11-
reservations:
12-
devices:
13-
- driver: nvidia
14-
device_ids: ['0']
15-
capabilities: [compute, utility]
2+
ports:
3+
- "${WEBUI_PORT:-7860}:7860"
4+
volumes:
5+
- &v1 ./data:/data
6+
- &v2 ./output:/output
7+
stop_signal: SIGKILL
8+
tty: true
9+
deploy:
10+
resources:
11+
reservations:
12+
devices:
13+
- driver: nvidia
14+
device_ids: ["0"]
15+
capabilities: [compute, utility]
1616

1717
name: webui-docker
1818

@@ -38,6 +38,21 @@ services:
3838
environment:
3939
- CLI_ARGS=--no-half --precision full --allow-code --enable-insecure-extension-access --api
4040

41+
forge: &forge
42+
<<: *base_service
43+
profiles: ["forge"]
44+
build: ./services/AUTOMATIC1111-forge
45+
image: sd-auto-forge:78
46+
environment:
47+
- CLI_ARGS=--allow-code --xformers --enable-insecure-extension-access --api
48+
49+
forge-cpu:
50+
<<: *forge
51+
profiles: ["forge-cpu"]
52+
deploy: {}
53+
environment:
54+
- CLI_ARGS=--no-half --precision full --allow-code --enable-insecure-extension-access --api
55+
4156
comfy: &comfy
4257
<<: *base_service
4358
profiles: ["comfy"]
@@ -46,7 +61,6 @@ services:
4661
environment:
4762
- CLI_ARGS=
4863

49-
5064
comfy-cpu:
5165
<<: *comfy
5266
profiles: ["comfy-cpu"]
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
FROM alpine/git:latest as download
2+
3+
COPY clone.sh /clone.sh
4+
5+
RUN . /clone.sh stable-diffusion-webui-assets https://github.com/AUTOMATIC1111/stable-diffusion-webui-assets.git 6f7db241d2f8ba7457bac5ca9753331f0c266917
6+
7+
RUN . /clone.sh stable-diffusion-stability-ai https://github.com/Stability-AI/stablediffusion.git cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf \
8+
&& rm -rf assets data/**/*.png data/**/*.jpg data/**/*.gif
9+
10+
RUN . /clone.sh BLIP https://github.com/salesforce/BLIP.git 48211a1594f1321b00f14c9f7a5b4813144b2fb9
11+
RUN . /clone.sh k-diffusion https://github.com/crowsonkb/k-diffusion.git ab527a9a6d347f364e3d185ba6d714e22d80cb3c
12+
RUN . /clone.sh clip-interrogator https://github.com/pharmapsychotic/clip-interrogator 2cf03aaf6e704197fd0dae7c7f96aa59cf1b11c9
13+
RUN . /clone.sh generative-models https://github.com/Stability-AI/generative-models 45c443b316737a4ab6e40413d7794a7f5657c19f
14+
RUN . /clone.sh huggingface_guess https://github.com/lllyasviel/huggingface_guess.git 70942022b6bcd17d941c1b4172804175758618e2
15+
RUN . /clone.sh google_blockly_prototypes https://github.com/lllyasviel/google_blockly_prototypes.git 1e98997c7fedaf5106af9849b6f50ebe5c4408f1
16+
RUN . /clone.sh stable-diffusion-webui-assets https://github.com/AUTOMATIC1111/stable-diffusion-webui-assets.git 6f7db241d2f8ba7457bac5ca9753331f0c266917
17+
18+
19+
FROM pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime
20+
21+
ENV DEBIAN_FRONTEND=noninteractive PIP_PREFER_BINARY=1
22+
23+
RUN --mount=type=cache,target=/var/cache/apt \
24+
apt-get update && \
25+
# we need those
26+
apt-get install -y fonts-dejavu-core rsync git jq moreutils aria2 \
27+
# extensions needs those
28+
ffmpeg libglfw3-dev libgles2-mesa-dev pkg-config libcairo2 libcairo2-dev build-essential
29+
30+
31+
ENV ROOT=/stable-diffusion-webui-forge
32+
33+
WORKDIR /
34+
RUN --mount=type=cache,target=/root/.cache/pip \
35+
git clone https://github.com/lllyasviel/stable-diffusion-webui-forge.git && \
36+
cd $ROOT && \
37+
pip install -r requirements_versions.txt
38+
39+
RUN pip install -U typing_extensions
40+
41+
COPY --from=download /repositories/ ${ROOT}/repositories/
42+
RUN mkdir ${ROOT}/interrogate && cp ${ROOT}/repositories/clip-interrogator/clip_interrogator/data/* ${ROOT}/interrogate
43+
44+
RUN --mount=type=cache,target=/root/.cache/pip \
45+
pip install pyngrok xformers==0.0.27 \
46+
git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379 \
47+
git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1 \
48+
git+https://github.com/mlfoundations/open_clip.git@v2.20.0
49+
50+
# there seems to be a memory leak (or maybe just memory not being freed fast enough) that is fixed by this version of malloc
51+
# maybe move this up to the dependencies list.
52+
RUN apt-get -y install libgoogle-perftools-dev && apt-get clean
53+
ENV LD_PRELOAD=libtcmalloc.so
54+
55+
COPY . /docker
56+
57+
#RUN \
58+
# mv ${ROOT}/style.css ${ROOT}/user.css && \
59+
# one of the ugliest hacks I ever wrote \
60+
#sed -i 's/in_app_dir = .*/in_app_dir = True/g' /opt/conda/lib/python3.10/site-packages/gradio/routes.py && \
61+
#git config --global --add safe.directory '*'
62+
63+
WORKDIR ${ROOT}
64+
ENV NVIDIA_VISIBLE_DEVICES=all
65+
ENV CLI_ARGS=""
66+
EXPOSE 7860
67+
ENTRYPOINT ["/docker/entrypoint.sh"]
68+
CMD python -u webui.py --listen --port 7860 ${CLI_ARGS}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
set -Eeox pipefail
4+
5+
mkdir -p /repositories/"$1"
6+
cd /repositories/"$1"
7+
git init
8+
git remote add origin "$2"
9+
10+
if [ -n "$3" ]; then
11+
git fetch origin "$3" --depth=1
12+
git reset --hard "$3"
13+
fi
14+
15+
rm -rf .git
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python3
2+
3+
"""Checks and sets default values for config.json before starting the container."""
4+
5+
import json
6+
import re
7+
import os.path
8+
import sys
9+
10+
DEFAULT_FILEPATH = '/data/config/forge/config.json'
11+
12+
DEFAULT_OUTDIRS = {
13+
"outdir_samples": "",
14+
"outdir_txt2img_samples": "/output/txt2img",
15+
"outdir_img2img_samples": "/output/img2img",
16+
"outdir_extras_samples": "/output/extras",
17+
"outdir_grids": "",
18+
"outdir_txt2img_grids": "/output/txt2img-grids",
19+
"outdir_img2img_grids": "/output/img2img-grids",
20+
"outdir_save": "/output/saved",
21+
"outdir_init_images": "/output/init-images",
22+
}
23+
RE_VALID_OUTDIR = re.compile(r"(^/output(/\.?[\w\-\_]+)+/?$)|(^\s?$)")
24+
25+
DEFAULT_OTHER = {
26+
"font": "DejaVuSans.ttf",
27+
}
28+
29+
def dict_to_json_file(target_file: str, data: dict):
30+
"""Write dictionary to specified json file"""
31+
32+
with open(target_file, 'w') as f:
33+
json.dump(data, f)
34+
35+
def json_file_to_dict(config_file: str) -> dict|None:
36+
"""Load json file into a dictionary. Return None if file does not exist."""
37+
38+
if os.path.isfile(config_file):
39+
with open(config_file, 'r') as f:
40+
return json.load(f)
41+
else:
42+
return None
43+
44+
def replace_if_invalid(value: str, replacement: str, pattern: str|re.Pattern[str]) -> str:
45+
"""Returns original value if valid, fallback value if invalid"""
46+
47+
if re.match(pattern, value):
48+
return value
49+
else:
50+
return replacement
51+
52+
def check_and_replace_config(config_file: str, target_file: str = None):
53+
"""Checks given file for invalid values. Replaces those with fallback values (default: overwrites file)."""
54+
55+
# Get current user config, or empty if file does not exists
56+
data = json_file_to_dict(config_file) or {}
57+
58+
# Check and fix output directories
59+
for k, def_val in DEFAULT_OUTDIRS.items():
60+
if k not in data:
61+
data[k] = def_val
62+
else:
63+
data[k] = replace_if_invalid(value=data[k], replacement=def_val, pattern=RE_VALID_OUTDIR)
64+
65+
# Check and fix other default settings
66+
for k, def_val in DEFAULT_OTHER.items():
67+
if k not in data:
68+
data[k] = def_val
69+
70+
# Write results to file
71+
dict_to_json_file(target_file or config_file, data)
72+
73+
if __name__ == '__main__':
74+
if len(sys.argv) > 1:
75+
check_and_replace_config(*sys.argv[1:])
76+
else:
77+
check_and_replace_config(DEFAULT_FILEPATH)
78+
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/bash
2+
3+
set -Eeuo pipefail
4+
5+
# TODO: move all mkdir -p ?
6+
mkdir -p /data/config/forge/scripts/
7+
# mount scripts individually
8+
9+
echo $ROOT
10+
ls -lha $ROOT
11+
12+
find "${ROOT}/scripts/" -maxdepth 1 -type l -delete
13+
cp -vrfTs /data/config/forge/scripts/ "${ROOT}/scripts/"
14+
15+
# Set up config file
16+
python /docker/config.py /data/config/forge/config.json
17+
18+
if [ ! -f /data/config/forge/ui-config.json ]; then
19+
echo '{}' >/data/config/forge/ui-config.json
20+
fi
21+
22+
if [ ! -f /data/config/forge/styles.csv ]; then
23+
touch /data/config/forge/styles.csv
24+
fi
25+
26+
# copy models from original models folder
27+
mkdir -p /data/models/VAE-approx/ /data/models/karlo/
28+
29+
rsync -a --info=NAME ${ROOT}/models/VAE-approx/ /data/models/VAE-approx/
30+
rsync -a --info=NAME ${ROOT}/models/karlo/ /data/models/karlo/
31+
32+
declare -A MOUNTS
33+
34+
MOUNTS["/root/.cache"]="/data/.cache"
35+
MOUNTS["${ROOT}/models"]="/data/models"
36+
37+
MOUNTS["${ROOT}/embeddings"]="/data/embeddings"
38+
MOUNTS["${ROOT}/config.json"]="/data/config/forge/config.json"
39+
MOUNTS["${ROOT}/ui-config.json"]="/data/config/forge/ui-config.json"
40+
MOUNTS["${ROOT}/styles.csv"]="/data/config/forge/styles.csv"
41+
MOUNTS["${ROOT}/extensions"]="/data/config/forge/extensions"
42+
MOUNTS["${ROOT}/config_states"]="/data/config/forge/config_states"
43+
44+
# extra hacks
45+
MOUNTS["${ROOT}/repositories/CodeFormer/weights/facelib"]="/data/.cache"
46+
47+
for to_path in "${!MOUNTS[@]}"; do
48+
set -Eeuo pipefail
49+
from_path="${MOUNTS[${to_path}]}"
50+
rm -rf "${to_path}"
51+
if [ ! -f "$from_path" ]; then
52+
mkdir -vp "$from_path"
53+
fi
54+
mkdir -vp "$(dirname "${to_path}")"
55+
ln -sT "${from_path}" "${to_path}"
56+
echo Mounted $(basename "${from_path}")
57+
done
58+
59+
echo "Installing extension dependencies (if any)"
60+
61+
# because we build our container as root:
62+
chown -R root ~/.cache/
63+
chmod 766 ~/.cache/
64+
65+
shopt -s nullglob
66+
# For install.py, please refer to https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Developing-extensions#installpy
67+
list=(./extensions/*/install.py)
68+
for installscript in "${list[@]}"; do
69+
EXTNAME=$(echo $installscript | cut -d '/' -f 3)
70+
# Skip installing dependencies if extension is disabled in config
71+
if $(jq -e ".disabled_extensions|any(. == \"$EXTNAME\")" config.json); then
72+
echo "Skipping disabled extension ($EXTNAME)"
73+
continue
74+
fi
75+
PYTHONPATH=${ROOT} python "$installscript"
76+
done
77+
78+
if [ -f "/data/config/forge/startup.sh" ]; then
79+
pushd ${ROOT}
80+
echo "Running startup script"
81+
. /data/config/forge/startup.sh
82+
popd
83+
fi
84+
85+
exec "$@"

services/AUTOMATIC1111/Dockerfile

100644100755
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ WORKDIR /
3030
RUN --mount=type=cache,target=/root/.cache/pip \
3131
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git && \
3232
cd stable-diffusion-webui && \
33-
git reset --hard v1.9.4 && \
33+
git reset --hard v1.10.1 && \
3434
pip install -r requirements_versions.txt
3535

36+
RUN pip install -U typing_extensions
3637

3738
ENV ROOT=/stable-diffusion-webui
3839

services/AUTOMATIC1111/clone.sh

100644100755
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
#!/bin/bash
22

3-
set -Eeuox pipefail
3+
set -Eeox pipefail
44

55
mkdir -p /repositories/"$1"
66
cd /repositories/"$1"
77
git init
88
git remote add origin "$2"
9-
git fetch origin "$3" --depth=1
10-
git reset --hard "$3"
9+
10+
if [ -n "$3" ]; then
11+
git fetch origin "$3" --depth=1
12+
git reset --hard "$3"
13+
fi
14+
1115
rm -rf .git

services/AUTOMATIC1111/config.py

100644100755
File mode changed.

services/comfy/Dockerfile

100644100755
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM pytorch/pytorch:2.3.0-cuda12.1-cudnn8-runtime
1+
FROM pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime
22

33
ENV DEBIAN_FRONTEND=noninteractive PIP_PREFER_BINARY=1
44

@@ -9,7 +9,6 @@ RUN --mount=type=cache,target=/root/.cache/pip \
99
git clone https://github.com/comfyanonymous/ComfyUI.git ${ROOT} && \
1010
cd ${ROOT} && \
1111
git checkout master && \
12-
git reset --hard 276f8fce9f5a80b500947fb5745a4dde9e84622d && \
1312
pip install -r requirements.txt
1413

1514
WORKDIR ${ROOT}

services/comfy/extra_model_paths.yaml

100644100755
File mode changed.

0 commit comments

Comments
 (0)