-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDockerfile_WebUI
147 lines (128 loc) · 9.52 KB
/
Dockerfile_WebUI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
FROM python:3.10.6
ARG PROXY
ARG PORT=7860
# 设置pip源为阿里云pip源
ENV PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
# debian 下安装访问 http://deb.debian.org/debian 等需要设置代理
# ENV http_proxy="http://${PROXY}"
# ENV https_proxy="http://${PROXY}"
# 安装基础包
RUN --mount=type=cache,target=/var/cache/apt \
export http_proxy="http://${PROXY}" https_proxy="http://${PROXY}" && \
env | grep proxy && echo "----- install vim net-tools telnet libgl1 -----" && \
apt-get update && \
apt-get install -y vim-tiny net-tools telnet && \
# resolv ImportError: libGL.so.1: cannot open shared object file: No such file or directory
# when Launching Web UI with arguments
# see https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/10411
apt-get install -y libgl1
# 多分一层,避免因 git clone 失败前面的包要重新安装
# RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui sd-webui && \
#############################################################################################
#
# 要求在 host 上已经 clone 好的 stable-diffusion-webui 的同级目录下执行,即 Dockerfile 和 stable-diffusion-webui 平级,例如
# -rw-r--r-- 1 root root 8550 Dec 7 23:26 Dockerfile
# drwxr-xr-x 2 root root 4096 Dec 5 18:01 extensions/
# drwxr-xr-x 2 root root 4096 Dec 7 21:54 huggingface.co/
# drwxr-xr-x 14 root root 4096 Dec 7 17:46 models/
# drwxr-xr-x 16 root root 4096 Dec 7 23:30 stable-diffusion-webui/
#
COPY ./stable-diffusion-webui /home/sd-webui
WORKDIR /home/sd-webui
# 提前于 webui.sh 安装 torch, torchvision, 方便 docker build 缓存;
# torch版本号来自 stable-diffusion-webui/modules/launch_utils.py
# grep "torch_command = os.environ.get('TORCH_COMMAND'" modules/launch_utils.py | cut -d '"' -f 2 | cut -d '{' -f 1 | xargs -I {} python3 -m {} https://download.pytorch.org/whl/cu118
RUN --mount=type=cache,target=/root/.cache/pip ls -l /root/.cache/pip && \
# 安装 torch 不能设置代理,否则2g+的包下载不下来
export http_proxy="" https_proxy="" all_proxy="" && \
env | grep proxy && echo "----- install torch and torchvision -----" && \
# resolv the err: Using SOCKS proxy, but the 'socksio' package is not installed
# pip install httpx[socks] && \
python3 -m pip install torch==2.0.1 torchvision==0.15.2 --extra-index-url https://download.pytorch.org/whl/cu118
# 提前于 webui.sh 安装 clip, openclip,安装 clip 需要开启代理,否则一定失败
RUN --mount=type=cache,target=/root/.cache/pip ls -l /root/.cache/pip && \
export http_proxy="http://${PROXY}" https_proxy="http://${PROXY}" && \
env | grep proxy && echo "----- install clip and open_clip -----" && \
grep "clip_package = os.environ.get('CLIP_PACKAGE'" modules/launch_utils.py | cut -d '"' -f 2 | xargs -I {} python3 -m pip install {} && \
grep "openclip_package = os.environ.get('OPENCLIP_PACKAGE'" modules/launch_utils.py | cut -d '"' -f 2 | xargs -I {} python3 -m pip install {}
# 安装 xformers 前去掉代理 (109.1 MB),否则极容易中断
RUN --mount=type=cache,target=/root/.cache/pip ls -l /root/.cache/pip && \
export http_proxy="" https_proxy="" all_proxy="" && \
env | grep proxy && echo "----- install xformers -----" && \
grep "xformers_package = os.environ.get('XFORMERS_PACKAGE'" modules/launch_utils.py | cut -d "'" -f 4 | xargs -I {} python3 -m pip install -U -I --no-deps {} && \
python3 -m pip install ngrok
# 创建 clone.sh 脚本文件
RUN echo "#!/bin/bash" > ./clone.sh && \
echo "set -Eeuox pipefail" >> ./clone.sh && \
echo 'mkdir -p ./repositories/"$1"' >> ./clone.sh && \
echo 'cd ./repositories/"$1"' >> ./clone.sh && \
echo "git init" >> ./clone.sh && \
echo 'git remote add origin "$2"' >> ./clone.sh && \
echo 'git fetch origin "$3" --depth=1' >> ./clone.sh && \
echo 'git reset --hard "$3"' >> ./clone.sh && \
chmod +x ./clone.sh
# 提前于 webui.sh 克隆仓库: Stable Diffusion, Stable Diffusion XL, K-diffusion, CodeFormer, BLIP
RUN grep "stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH'" modules/launch_utils.py | cut -d '"' -f 2 | \
xargs -I {} ./clone.sh "stable-diffusion-stability-ai" "https://github.com/Stability-AI/stablediffusion.git" {} && \
rm -rf assets data/**/*.png data/**/*.jpg data/**/*.gif
RUN grep "stable_diffusion_xl_commit_hash = os.environ.get('STABLE_DIFFUSION_XL_COMMIT_HASH'" modules/launch_utils.py | cut -d '"' -f 2 | \
xargs -I {} ./clone.sh "generative-models" "https://github.com/Stability-AI/generative-models.git" {}
RUN grep "k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH'" modules/launch_utils.py | cut -d '"' -f 2 | \
xargs -I {} ./clone.sh "k-diffusion" "https://github.com/crowsonkb/k-diffusion.git" {}
# CodeFormer 和 BLIP 两个的 github 仓库都需要加代理才能 clone 成功
RUN export http_proxy="http://${PROXY}" https_proxy="http://${PROXY}" && \
env | grep proxy && echo "----- clone CodeFormer and BLIP -----" && \
grep "codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH'" modules/launch_utils.py | cut -d '"' -f 2 | \
xargs -I {} ./clone.sh "CodeFormer" "https://github.com/sczhou/CodeFormer.git" {} && \
rm -rf assets inputs && \
grep "blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH'" modules/launch_utils.py | cut -d '"' -f 2 | \
xargs -I {} ./clone.sh "BLIP" "https://github.com/salesforce/BLIP.git" {}
COPY ./extensions/sd-webui-controlnet/requirements.txt /home/sd-webui/extensions/sd-webui-controlnet/
# 提前于 webui.sh 安装 CodeFormer requirements 和 stable-diffusion-webui 自身的 requirements_versions.txt
RUN --mount=type=cache,target=/root/.cache/pip ls -l /root/.cache/pip && \
echo "----- install CodeFormer requirements -----" && \
pip install -r ./repositories/CodeFormer/requirements.txt && \
echo "----- install requirements -----" && \
pip install -r requirements_versions.txt && \
export http_proxy="http://${PROXY}" https_proxy="http://${PROXY}" && \
env | grep proxy && echo "----- install requirements of sd-webui-controlnet -----" && \
pip install -r extensions/sd-webui-controlnet/requirements.txt
ARG AUTH=rtx3090:ST0Nbs5AL+5hy4J
# 因为容器已经提供了完美的隔离环境,不需要其他 python 隔离手段了,所以关闭 venv
ENV use_venv=0
ENV venv_dir="-"
# 设置命令行,加上 --skip-torch-cuda-test
ENV NVIDIA_VISIBLE_DEVICES=all
ENV COMMANDLINE_ARGS="--listen --port ${PORT} --allow-code --medvram --xformers --enable-insecure-extension-access --gradio-auth ${AUTH} --api --skip-torch-cuda-test"
ENV EXIT_ON_IMAGE_BUILD=1
# 修改 launch_utils.py,在 start() 函数开始时,设置一个退出点,以使 docker build 过程不要直接启动 webui 服务
RUN sed -i '/def start():/a \ \ \ \ \n\ \ \ \ # ------ make a docker build cache point ------ \n\ \ \ \ if os.getenv("EXIT_ON_IMAGE_BUILD") == "1":\n\ \ \ \ \ \ \ \ print("EXIT_ON_IMAGE_BUILD is 1, exiting.")\n\ \ \ \ \ \ \ \ sys.exit()\n' ./modules/launch_utils.py && \
# 在 start() 函数开始时清除代理设置
# sed -i '/def start():/a \ \ \ \ \n\ \ \ \ # ------ clean proxy begin ------ \n\ \ \ \ os.environ.pop("http_proxy", None)\n\ \ \ \ os.environ.pop("https_proxy", None)\n\ \ \ \ print("Current proxy settings:")\n\ \ \ \ for key in ["http_proxy", "https_proxy", "all_proxy"]:\n\ \ \ \ \ \ \ \ print(f"{key}={os.environ.get(key)}")\n\ \ \ \ # ------ clean proxy end ------\n\ \ \ \ ' ./modules/launch_utils.py && \
# 修改 repositories 代码文件,将 clip-vit-large-patch14 的路径改为本地路径,避免从 huggingface.co 下载
sed -i 's|"openai/clip-vit-large-patch14"|"/home/sd-webui/huggingface.co/openai/clip-vit-large-patch14"|g' ./repositories/stable-diffusion-stability-ai/ldm/modules/encoders/modules.py && \
sed -i 's|"openai/clip-vit-large-patch14"|"/home/sd-webui/huggingface.co/openai/clip-vit-large-patch14"|g' ./repositories/generative-models/sgm/modules/encoders/modules.py
# 执行 ./webui.sh, 意义在于让其检查下各个仓库的 git 版本及各个包是否都已安装好。没问题走到 start 函数时就退出
RUN chmod +x ./webui.sh && ./webui.sh -f
ENV EXIT_ON_IMAGE_BUILD=0
# remove --skip-torch-cuda-test
ENV COMMANDLINE_ARGS="--listen --port ${PORT} --allow-code --medvram --xformers --enable-insecure-extension-access --gradio-auth ${AUTH} --api"
EXPOSE ${PORT}
# #ENTRYPOINT ["/docker/entrypoint.sh"]
# CMD python -u webui.py --listen ${COMMANDLINE_ARGS}
CMD ./webui.sh -f
#
# ----- 用法 -----
# 构建镜像:
# nohup docker build -f ./Dockerfile_WebUI --build-arg PROXY=10.10.0.8:10887 --build-arg PORT=7880 --build-arg AUTH=admin:changeitsoon -t sd-webui:20231208 . > build.log 2>&1 &
# tail -100f build.log
#
# 启动容器前,创建好挂载目录
# mkdir -p models extensions huggingface.co outputs
#
# 用构建好的镜像,启动后台运行容器:
# docker run --name sd-webui --gpus all -d -p 7880:7880 -v "${PWD}/models:/home/sd-webui/models" -v "${PWD}/extensions:/home/sd-webui/extensions" -v"${PWD}/huggingface.co:/home/sd-webui/huggingface.co" -v"${PWD}/outputs:/home/sd-webui/outputs" sd-webui:20231208
#
# 用构建好的镜像,启动交互式容器(不启动 webui 服务):
# docker run --name sd-webui --gpus all -it -p 7880:7880 -v "${PWD}/models:/home/sd-webui/models" -v "${PWD}/extensions:/home/sd-webui/extensions" -v"${PWD}/huggingface.co:/home/sd-webui/huggingface.co" -v"${PWD}/outputs:/home/sd-webui/outputs" sd-webui:20231208 bash
#