From 24eaa526a61cfb5667749660a2bd0814c837a34d Mon Sep 17 00:00:00 2001 From: Lark <165338234+larkbirdy@users.noreply.github.com> Date: Wed, 15 May 2024 00:35:58 -0700 Subject: [PATCH] add relay node --- .gitignore | 2 + Makefile | 11 ++ README.md | 59 +-------- docker-compose.yml | 82 +++++------- services/comfy/Dockerfile | 22 ---- services/comfy/entrypoint.sh | 31 ----- services/comfy/extra_model_paths.yaml | 25 ---- services/invoke/Dockerfile | 53 -------- services/invoke/entrypoint.sh | 45 ------- services/relay-node/Dockerfile | 30 +++++ services/relay-node/wait-for-it.sh | 182 ++++++++++++++++++++++++++ 11 files changed, 266 insertions(+), 276 deletions(-) create mode 100644 Makefile delete mode 100644 services/comfy/Dockerfile delete mode 100755 services/comfy/entrypoint.sh delete mode 100644 services/comfy/extra_model_paths.yaml delete mode 100644 services/invoke/Dockerfile delete mode 100755 services/invoke/entrypoint.sh create mode 100644 services/relay-node/Dockerfile create mode 100644 services/relay-node/wait-for-it.sh diff --git a/.gitignore b/.gitignore index 2a011a1..92d6a07 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ # VSCode specific *.code-workspace /.vscode + +.idea/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eb861aa --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +.PHONY: start +start: + docker compose --profile "combined-cpu" up --build + +.PHONY: download +download: + docker compose --profile download up --build + +.PHONY: clean +clean: + docker system prune -a --volumes --force diff --git a/README.md b/README.md index 95e10c3..b432132 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,7 @@ -# Stable Diffusion WebUI Docker +# Stable Diffusion Miner Docker -Run Stable Diffusion on your machine with a nice UI without any hassle! +```bash +make download -## Setup & Usage - -Visit the wiki for [Setup](https://github.com/AbdBarho/stable-diffusion-webui-docker/wiki/Setup) and [Usage](https://github.com/AbdBarho/stable-diffusion-webui-docker/wiki/Usage) instructions, checkout the [FAQ](https://github.com/AbdBarho/stable-diffusion-webui-docker/wiki/FAQ) page if you face any problems, or create a new issue! - -## Features - -This repository provides multiple UIs for you to play around with stable diffusion: - -### [AUTOMATIC1111](https://github.com/AUTOMATIC1111/stable-diffusion-webui) - -[Full feature list here](https://github.com/AUTOMATIC1111/stable-diffusion-webui-feature-showcase), Screenshots: - -| Text to image | Image to image | Extras | -| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| ![](https://user-images.githubusercontent.com/24505302/189541954-46afd772-d0c8-4005-874c-e2eca40c02f2.jpg) | ![](https://user-images.githubusercontent.com/24505302/189541956-5b528de7-1b5d-479f-a1db-d3f5a53afc59.jpg) | ![](https://user-images.githubusercontent.com/24505302/189541957-cf78b352-a071-486d-8889-f26952779a61.jpg) | - -### [InvokeAI](https://github.com/invoke-ai/InvokeAI) - -[Full feature list here](https://github.com/invoke-ai/InvokeAI#features), Screenshots: - -| Text to image | Image to image | Extras | -| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| ![](https://user-images.githubusercontent.com/24505302/195158552-39f58cb6-cfcc-4141-9995-a626e3760752.jpg) | ![](https://user-images.githubusercontent.com/24505302/195158553-152a0ab8-c0fd-4087-b121-4823bcd8d6b5.jpg) | ![](https://user-images.githubusercontent.com/24505302/195158548-e118206e-c519-4915-85d6-4c248eb10fc0.jpg) | - -### [ComfyUI](https://github.com/comfyanonymous/ComfyUI) - -[Full feature list here](https://github.com/comfyanonymous/ComfyUI#features), Screenshot: - -| Workflow | -| -------------------------------------------------------------------------------- | -| ![](https://github.com/comfyanonymous/ComfyUI/raw/master/comfyui_screenshot.png) | - -## Contributing - -Contributions are welcome! **Create a discussion first of what the problem is and what you want to contribute (before you implement anything)** - -## Disclaimer - -The authors of this project are not responsible for any content generated using this interface. - -This license of this software forbids you from sharing any content that violates any laws, produce any harm to a person, disseminate any personal information that would be meant for harm, spread misinformation and target vulnerable groups. For the full list of restrictions please read [the license](./LICENSE). - -## Thanks - -Special thanks to everyone behind these awesome projects, without them, none of this would have been possible: - -- [AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) -- [InvokeAI](https://github.com/invoke-ai/InvokeAI) -- [ComfyUI](https://github.com/comfyanonymous/ComfyUI) -- [CompVis/stable-diffusion](https://github.com/CompVis/stable-diffusion) -- [Sygil-webui](https://github.com/Sygil-Dev/sygil-webui) -- and many many more. +make start +``` diff --git a/docker-compose.yml b/docker-compose.yml index a1cc6c2..78b4e66 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,23 +1,29 @@ version: '3.9' x-base_service: &base_service - ports: - - "${WEBUI_PORT:-7860}:7860" - volumes: - - &v1 ./data:/data - - &v2 ./output:/output - stop_signal: SIGKILL - tty: true - deploy: - resources: - reservations: - devices: - - driver: nvidia - device_ids: ['0'] - capabilities: [compute, utility] + ports: + - "${WEBUI_PORT:-7860}:7860" + volumes: + - &v1 ./data:/data + - &v2 ./output:/output + stop_signal: SIGKILL + tty: true + networks: + - mynetwork + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: ['0'] + capabilities: [compute, utility] name: webui-docker +networks: + mynetwork: + driver: bridge + services: download: build: ./services/download/ @@ -27,7 +33,7 @@ services: auto: &automatic <<: *base_service - profiles: ["auto"] + profiles: ["auto", "combined"] build: ./services/AUTOMATIC1111 image: sd-auto:72 environment: @@ -35,39 +41,23 @@ services: auto-cpu: <<: *automatic - profiles: ["auto-cpu"] + profiles: ["auto-cpu", "combined-cpu"] deploy: {} environment: - CLI_ARGS=--no-half --precision full --allow-code --enable-insecure-extension-access --api - invoke: &invoke - <<: *base_service - profiles: ["invoke"] - build: ./services/invoke/ - image: sd-invoke:30 - environment: - - PRELOAD=true - - CLI_ARGS=--xformers - - # invoke-cpu: - # <<: *invoke - # profiles: ["invoke-cpu"] - # environment: - # - PRELOAD=true - # - CLI_ARGS=--always_use_cpu - - comfy: &comfy - <<: *base_service - profiles: ["comfy"] - build: ./services/comfy/ - image: sd-comfy:6 - environment: - - CLI_ARGS= - - - comfy-cpu: - <<: *comfy - profiles: ["comfy-cpu"] - deploy: {} + relay-node: + networks: + - mynetwork + ports: + - "${RELAY_NODE_PORT:-6387}:6387" + profiles: ["relay-node", "combined", "combined-cpu"] + build: + context: ./services/relay-node + args: + - ETH_PRIVATE_KEY=${ETH_PRIVATE_KEY} + depends_on: + - auto-cpu environment: - - CLI_ARGS=--cpu + - ETH_PRIVATE_KEY=${ETH_PRIVATE_KEY} + - SD_URL=${SD_URL:-http://auto-cpu:7860} diff --git a/services/comfy/Dockerfile b/services/comfy/Dockerfile deleted file mode 100644 index f813c68..0000000 --- a/services/comfy/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM pytorch/pytorch:2.1.2-cuda12.1-cudnn8-runtime - -ENV DEBIAN_FRONTEND=noninteractive PIP_PREFER_BINARY=1 - -RUN apt-get update && apt-get install -y git && apt-get clean - -ENV ROOT=/stable-diffusion -RUN --mount=type=cache,target=/root/.cache/pip \ - git clone https://github.com/comfyanonymous/ComfyUI.git ${ROOT} && \ - cd ${ROOT} && \ - git checkout master && \ - git reset --hard d1f3637a5a944d0607b899babd8ff11d87100503 && \ - pip install -r requirements.txt - -WORKDIR ${ROOT} -COPY . /docker/ -RUN chmod u+x /docker/entrypoint.sh && cp /docker/extra_model_paths.yaml ${ROOT} - -ENV NVIDIA_VISIBLE_DEVICES=all PYTHONPATH="${PYTHONPATH}:${PWD}" CLI_ARGS="" -EXPOSE 7860 -ENTRYPOINT ["/docker/entrypoint.sh"] -CMD python -u main.py --listen --port 7860 ${CLI_ARGS} diff --git a/services/comfy/entrypoint.sh b/services/comfy/entrypoint.sh deleted file mode 100755 index b4299a7..0000000 --- a/services/comfy/entrypoint.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -set -Eeuo pipefail - -mkdir -vp /data/config/comfy/custom_nodes - -declare -A MOUNTS - -MOUNTS["/root/.cache"]="/data/.cache" -MOUNTS["${ROOT}/input"]="/data/config/comfy/input" -MOUNTS["${ROOT}/output"]="/output/comfy" - -for to_path in "${!MOUNTS[@]}"; do - set -Eeuo pipefail - from_path="${MOUNTS[${to_path}]}" - rm -rf "${to_path}" - if [ ! -f "$from_path" ]; then - mkdir -vp "$from_path" - fi - mkdir -vp "$(dirname "${to_path}")" - ln -sT "${from_path}" "${to_path}" - echo Mounted $(basename "${from_path}") -done - -if [ -f "/data/config/comfy/startup.sh" ]; then - pushd ${ROOT} - . /data/config/comfy/startup.sh - popd -fi - -exec "$@" diff --git a/services/comfy/extra_model_paths.yaml b/services/comfy/extra_model_paths.yaml deleted file mode 100644 index eb374eb..0000000 --- a/services/comfy/extra_model_paths.yaml +++ /dev/null @@ -1,25 +0,0 @@ -a111: - base_path: /data - - checkpoints: models/Stable-diffusion - configs: models/Stable-diffusion - vae: models/VAE - loras: models/Lora - upscale_models: | - models/RealESRGAN - models/ESRGAN - models/SwinIR - models/GFPGAN - hypernetworks: models/hypernetworks - controlnet: models/ControlNet - gligen: models/GLIGEN - clip: models/CLIPEncoder - embeddings: embeddings - - custom_nodes: config/comfy/custom_nodes - - # TODO: I am unsure about these, need more testing - # style_models: config/comfy/style_models - # t2i_adapter: config/comfy/t2i_adapter - # clip_vision: config/comfy/clip_vision - # diffusers: config/comfy/diffusers diff --git a/services/invoke/Dockerfile b/services/invoke/Dockerfile deleted file mode 100644 index 209c368..0000000 --- a/services/invoke/Dockerfile +++ /dev/null @@ -1,53 +0,0 @@ -FROM alpine:3.17 as xformers -RUN apk add --no-cache aria2 -RUN aria2c -x 5 --dir / --out wheel.whl 'https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/6.0.0/xformers-0.0.21.dev544-cp310-cp310-manylinux2014_x86_64-pytorch201.whl' - - -FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime - -ENV DEBIAN_FRONTEND=noninteractive PIP_EXISTS_ACTION=w PIP_PREFER_BINARY=1 - -# patch match: -# https://github.com/invoke-ai/InvokeAI/blob/main/docs/installation/INSTALL_PATCHMATCH.md -RUN --mount=type=cache,target=/var/cache/apt \ - apt-get update && \ - apt-get install make g++ git libopencv-dev -y && \ - apt-get clean && \ - cd /usr/lib/x86_64-linux-gnu/pkgconfig/ && \ - ln -sf opencv4.pc opencv.pc - - -ENV ROOT=/InvokeAI -RUN git clone https://github.com/invoke-ai/InvokeAI.git ${ROOT} -WORKDIR ${ROOT} - -RUN --mount=type=cache,target=/root/.cache/pip \ - git reset --hard f3b2e02921927d9317255b1c3811f47bd40a2bf9 && \ - pip install -e . - - -ARG BRANCH=main SHA=f3b2e02921927d9317255b1c3811f47bd40a2bf9 -RUN --mount=type=cache,target=/root/.cache/pip \ - git fetch && \ - git reset --hard && \ - git checkout ${BRANCH} && \ - git reset --hard ${SHA} && \ - pip install -U -e . - -RUN --mount=type=cache,target=/root/.cache/pip \ - --mount=type=bind,from=xformers,source=/wheel.whl,target=/xformers-0.0.21-cp310-cp310-linux_x86_64.whl \ - pip install -U opencv-python-headless triton /xformers-0.0.21-cp310-cp310-linux_x86_64.whl && \ - python3 -c "from patchmatch import patch_match" - - -COPY . /docker/ - -ENV NVIDIA_VISIBLE_DEVICES=all -ENV PYTHONUNBUFFERED=1 PRELOAD=false HF_HOME=/root/.cache/huggingface CONFIG_DIR=/data/config/invoke CLI_ARGS="" -EXPOSE 7860 - -ENTRYPOINT ["/docker/entrypoint.sh"] -CMD invokeai --web --host 0.0.0.0 --port 7860 --root_dir ${ROOT} --config ${CONFIG_DIR}/models.yaml \ - --outdir /output/invoke --embedding_directory /data/embeddings/ --lora_directory /data/models/Lora \ - --no-nsfw_checker --no-safety_checker ${CLI_ARGS} - diff --git a/services/invoke/entrypoint.sh b/services/invoke/entrypoint.sh deleted file mode 100755 index 348bb2b..0000000 --- a/services/invoke/entrypoint.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -set -Eeuo pipefail - -declare -A MOUNTS - -mkdir -p ${CONFIG_DIR} ${ROOT}/configs/stable-diffusion/ - -# cache -MOUNTS["/root/.cache"]=/data/.cache/ - -# this is really just a hack to avoid migrations -rm -rf ${HF_HOME}/diffusers - -# ui specific -MOUNTS["${ROOT}/models/codeformer"]=/data/models/Codeformer/ -MOUNTS["${ROOT}/models/gfpgan/GFPGANv1.4.pth"]=/data/models/GFPGAN/GFPGANv1.4.pth -MOUNTS["${ROOT}/models/gfpgan/weights"]=/data/models/GFPGAN/ -MOUNTS["${ROOT}/models/realesrgan"]=/data/models/RealESRGAN/ - -MOUNTS["${ROOT}/models/ldm"]=/data/.cache/invoke/ldm/ - -# hacks - -for to_path in "${!MOUNTS[@]}"; do - set -Eeuo pipefail - from_path="${MOUNTS[${to_path}]}" - rm -rf "${to_path}" - mkdir -p "$(dirname "${to_path}")" - # ends with slash, make it! - if [[ "$from_path" == */ ]]; then - mkdir -vp "$from_path" - fi - - ln -sT "${from_path}" "${to_path}" - echo Mounted $(basename "${from_path}") -done - -if "${PRELOAD}" == "true"; then - set -Eeuo pipefail - invokeai-configure --root ${ROOT} --yes - cp ${ROOT}/configs/models.yaml ${CONFIG_DIR}/models.yaml -fi - -exec "$@" diff --git a/services/relay-node/Dockerfile b/services/relay-node/Dockerfile new file mode 100644 index 0000000..d254c39 --- /dev/null +++ b/services/relay-node/Dockerfile @@ -0,0 +1,30 @@ +# Use an official Golang image as the base image +FROM golang:1.22 + +ARG ETH_PRIVATE_KEY +ENV ETH_PRIVATE_KEY=${ETH_PRIVATE_KEY} + +# Set the working directory inside the container +WORKDIR /app + +# Install necessary packages +RUN apt-get update && apt-get install -y git curl + +# Copy wait-for-it.sh into the image +COPY wait-for-it.sh /usr/local/bin/wait-for-it.sh +RUN chmod +x /usr/local/bin/wait-for-it.sh + +# Clone the repository +RUN git clone https://github.com/cuckoo-network/cuckoo.git + +# Navigate to the specific directory +WORKDIR /app/cuckoo/packages/node + +# Build the Go application with specified flags +RUN go build -tags netgo -ldflags '-s -w' -o app + +# Set the environment variable +ENV NODE_TYPE=MINER + +# Define the command to run the application +CMD ["/usr/local/bin/wait-for-it.sh", "auto-cpu:7860", "--", "./app"] diff --git a/services/relay-node/wait-for-it.sh b/services/relay-node/wait-for-it.sh new file mode 100644 index 0000000..d990e0d --- /dev/null +++ b/services/relay-node/wait-for-it.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash +# Use this script to test if a given TCP host/port are available + +WAITFORIT_cmdname=${0##*/} + +echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + else + echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" + fi + WAITFORIT_start_ts=$(date +%s) + while : + do + if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then + nc -z $WAITFORIT_HOST $WAITFORIT_PORT + WAITFORIT_result=$? + else + (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 + WAITFORIT_result=$? + fi + if [[ $WAITFORIT_result -eq 0 ]]; then + WAITFORIT_end_ts=$(date +%s) + echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" + break + fi + sleep 1 + done + return $WAITFORIT_result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $WAITFORIT_QUIET -eq 1 ]]; then + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + else + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + fi + WAITFORIT_PID=$! + trap "kill -INT -$WAITFORIT_PID" INT + wait $WAITFORIT_PID + WAITFORIT_RESULT=$? + if [[ $WAITFORIT_RESULT -ne 0 ]]; then + echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + fi + return $WAITFORIT_RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + WAITFORIT_hostport=(${1//:/ }) + WAITFORIT_HOST=${WAITFORIT_hostport[0]} + WAITFORIT_PORT=${WAITFORIT_hostport[1]} + shift 1 + ;; + --child) + WAITFORIT_CHILD=1 + shift 1 + ;; + -q | --quiet) + WAITFORIT_QUIET=1 + shift 1 + ;; + -s | --strict) + WAITFORIT_STRICT=1 + shift 1 + ;; + -h) + WAITFORIT_HOST="$2" + if [[ $WAITFORIT_HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + WAITFORIT_HOST="${1#*=}" + shift 1 + ;; + -p) + WAITFORIT_PORT="$2" + if [[ $WAITFORIT_PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + WAITFORIT_PORT="${1#*=}" + shift 1 + ;; + -t) + WAITFORIT_TIMEOUT="$2" + if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + WAITFORIT_TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + WAITFORIT_CLI=("$@") + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} +WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} +WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} +WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} + +# Check to see if timeout is from busybox? +WAITFORIT_TIMEOUT_PATH=$(type -p timeout) +WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) + +WAITFORIT_BUSYTIMEFLAG="" +if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then + WAITFORIT_ISBUSY=1 + # Check if busybox timeout uses -t flag + # (recent Alpine versions don't support -t anymore) + if timeout &>/dev/stdout | grep -q -e '-t '; then + WAITFORIT_BUSYTIMEFLAG="-t" + fi +else + WAITFORIT_ISBUSY=0 +fi + +if [[ $WAITFORIT_CHILD -gt 0 ]]; then + wait_for + WAITFORIT_RESULT=$? + exit $WAITFORIT_RESULT +else + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + wait_for_wrapper + WAITFORIT_RESULT=$? + else + wait_for + WAITFORIT_RESULT=$? + fi +fi + +if [[ $WAITFORIT_CLI != "" ]]; then + if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then + echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" + exit $WAITFORIT_RESULT + fi + exec "${WAITFORIT_CLI[@]}" +else + exit $WAITFORIT_RESULT +fi