diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..4c428e0a32 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,97 @@ +# Git +.git +.gitignore + +# CI +.codeclimate.yml +.travis.yml +.taskcluster.yml + +# Docker +docker-compose.yml +.docker + +# Byte-compiled / optimized / DLL files +__pycache__/ +*/__pycache__/ +*/*/__pycache__/ +*/*/*/__pycache__/ +*.py[cod] +*/*.py[cod] +*/*/*.py[cod] +*/*/*/*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Virtual environment +.env/ +.venv/ +venv/ +venv* + +# PyCharm +.idea + +# Python mode for VIM +.ropeproject +*/.ropeproject +*/*/.ropeproject +*/*/*/.ropeproject + +# Vim swap files +*.swp +*/*.swp +*/*/*.swp +*/*/*/*.swp + +# ignore model directory, instead mount it with docker run +models \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..2feeb1c09a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,56 @@ +FROM pytorch/pytorch:1.12.1-cuda11.3-cudnn8-runtime +LABEL maintainer="fname.lname@domain.com" + +# install opencv åreqs +RUN apt-get update \ + && apt-get install libsm6 libxext6 libgl1-mesa-glx libglib2.0-0 libxrender1 wget --no-install-recommends -y + +# remove cache +RUN apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* + +# set username inside docker +ARG UNAME=user1 +ARG UID=1000 + +# add user UNAME as a member of the sudoers group +RUN useradd -rm --home-dir "/home/$UNAME" --shell /bin/bash -g root -G sudo -u "$UID" "$UNAME" +# activate user +USER "$UNAME" +WORKDIR "/home/$UNAME" + +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 +ENV PATH="/home/$UNAME/miniconda3/bin:${PATH}" +ARG PATH="/home/$UNAME/miniconda3/bin:${PATH}" + +# download and install miniconda +RUN wget \ + https://repo.anaconda.com/miniconda/Miniconda3-py38_23.1.0-1-Linux-x86_64.sh \ + && mkdir "/home/$UNAME/.conda" \ + && bash Miniconda3-py38_23.1.0-1-Linux-x86_64.sh -b \ + && rm -f Miniconda3-py38_23.1.0-1-Linux-x86_64.sh + +# copy env yaml file +COPY environment.yaml "/home/$UNAME" + +# create conda env +RUN conda init bash \ + && conda install -n base conda-libmamba-solver \ + && conda config --set solver libmamba \ + && conda env create -f environment.yaml + +# add conda env activation to bashrc +RUN echo "conda activate control" >> ~/.bashrc + +# copy all files from current dir except those in .dockerignore +COPY . "/home/$UNAME/ControlNet" + +# change file ownership to docker user +USER root +RUN chown -R "$UNAME" "/home/$UNAME/ControlNet" +USER "$UNAME" + +# switch to ControlNet dir +WORKDIR "/home/$UNAME/ControlNet" +CMD ["/bin/bash"] \ No newline at end of file diff --git a/README.md b/README.md index 7e240b1821..16cff8a483 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,17 @@ We provide 9 Gradio apps with these models. All test images can be found at the folder "test_imgs". +## Run with Docker + +Alternatively, build and run docker image after models have been downloaded to `ControlNet/models`. + + bash scripts/build_docker.sh # build docker image to set up environment + bash scripts/run_docker.sh -p 8000 # run docker with an external port 0.0.0.0:8000 exposed + +Example run gradio_scribble2image.py + + python gradio_scribble2image.py # gradio app will be hosted at localhost:8000 + ## ControlNet with Canny Edge Stable Diffusion 1.5 + ControlNet (using simple Canny edge detection) diff --git a/scripts/build_docker.sh b/scripts/build_docker.sh new file mode 100644 index 0000000000..c45c106827 --- /dev/null +++ b/scripts/build_docker.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t controlnet:latest --build-arg UID=$(id -u) . diff --git a/scripts/run_docker.sh b/scripts/run_docker.sh new file mode 100644 index 0000000000..36249a3bdd --- /dev/null +++ b/scripts/run_docker.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +def_cont_name=controlnet_cont + +helpFunction() +{ + echo "" + echo "Usage: $0 -p port" + echo -e "\t-p http_port" + exit 1 # Exit script after printing help +} + +while getopts "p:" opt +do + case "$opt" in + p ) port="$OPTARG" ;; + ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent + esac +done + +# Print helpFunction in case parameters are empty +if [ -z "$port" ] +then + echo "Some or all of the parameters are empty"; + helpFunction +fi + +# Check if the container is running +if [ "$(docker ps -q -f name=$def_cont_name)" ]; then + # Stop the container + echo "Stopping docker container '$def_cont_name'" + docker stop "$def_cont_name" + docker rm "$def_cont_name" + echo "Stopped & removed container '$def_cont_name'" +fi + +# 7860 is gradio's default port +docker run \ + -ti --rm \ + -p "0.0.0.0:$port:7860" \ + -v "$PWD/models:/home/user1/ControlNet/models" \ + --gpus "device=0" \ + --name "$def_cont_name" \ + controlnet:latest