From f4a6350300e03fb0aa7619d02a4704434dd5e89c Mon Sep 17 00:00:00 2001 From: whitehara <58582589+whitehara@users.noreply.github.com> Date: Mon, 26 Feb 2024 18:30:05 +0200 Subject: [PATCH] feat: add docker files (#1418) * Add docker files * Add python precompiled cache file in the image * Add Notes in docker.md * Create docker-publish.yml * Modify docker-compose.yml not to use the bind mount * Update torch version * Change --share to --listen * Update torch version * Change '--share' to '--listen` * adjust code comments * Update requirements-docker.txt * chore: code cleanup - default_model env var isn't necessary as model is included in default preset, same for speed - ENV CMDARGS --listen is now synched with docker-compose.yml file - remove * Change entry_with_update.py to launch.py in entrypoint.sh * Change CMD in Dockerfile * Change default CMDARGS to --listen in Dockerfile * Modify CMD in Dockerfile * Fix docker-compose.yml * Import files from models,outputs * docs: change wording in docker.md, change git clone URL, add quotes to port mapping * docs: remove docker publish github action, remove pre-built image from docs * Modify modules versions for linux/arm64 * docs: update docker readme --------- Co-authored-by: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> Co-authored-by: Manuel Schmid Co-authored-by: Manuel Schmid --- .dockerignore | 1 + Dockerfile | 29 ++++++++++++++++++ docker-compose.yml | 38 ++++++++++++++++++++++++ docker.md | 66 +++++++++++++++++++++++++++++++++++++++++ entrypoint.sh | 33 +++++++++++++++++++++ modules/config.py | 25 +++++++++++++--- modules/util.py | 2 +- readme.md | 4 +++ requirements_docker.txt | 5 ++++ 9 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 docker.md create mode 100755 entrypoint.sh create mode 100644 requirements_docker.txt diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..485dee64b --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.idea diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..2aea28106 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM nvidia/cuda:12.3.1-base-ubuntu22.04 +ENV DEBIAN_FRONTEND noninteractive +ENV CMDARGS --listen + +RUN apt-get update -y && \ + apt-get install -y curl libgl1 libglib2.0-0 python3-pip python-is-python3 git && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +COPY requirements_docker.txt requirements_versions.txt /tmp/ +RUN pip install --no-cache-dir -r /tmp/requirements_docker.txt -r /tmp/requirements_versions.txt && \ + rm -f /tmp/requirements_docker.txt /tmp/requirements_versions.txt +RUN pip install --no-cache-dir xformers==0.0.22 --no-dependencies +RUN curl -fsL -o /usr/local/lib/python3.10/dist-packages/gradio/frpc_linux_amd64_v0.2 https://cdn-media.huggingface.co/frpc-gradio-0.2/frpc_linux_amd64 && \ + chmod +x /usr/local/lib/python3.10/dist-packages/gradio/frpc_linux_amd64_v0.2 + +RUN adduser --disabled-password --gecos '' user && \ + mkdir -p /content/app /content/data + +COPY entrypoint.sh /content/ +RUN chown -R user:user /content + +WORKDIR /content +USER user + +RUN git clone https://github.com/lllyasviel/Fooocus /content/app +RUN mv /content/app/models /content/app/models.org + +CMD [ "sh", "-c", "/content/entrypoint.sh ${CMDARGS}" ] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..dee7b3e7c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,38 @@ +version: '3.9' + +volumes: + fooocus-data: + +services: + app: + build: . + image: fooocus + ports: + - "7865:7865" + environment: + - CMDARGS=--listen # Arguments for launch.py. + - DATADIR=/content/data # Directory which stores models, outputs dir + - config_path=/content/data/config.txt + - config_example_path=/content/data/config_modification_tutorial.txt + - path_checkpoints=/content/data/models/checkpoints/ + - path_loras=/content/data/models/loras/ + - path_embeddings=/content/data/models/embeddings/ + - path_vae_approx=/content/data/models/vae_approx/ + - path_upscale_models=/content/data/models/upscale_models/ + - path_inpaint=/content/data/models/inpaint/ + - path_controlnet=/content/data/models/controlnet/ + - path_clip_vision=/content/data/models/clip_vision/ + - path_fooocus_expansion=/content/data/models/prompt_expansion/fooocus_expansion/ + - path_outputs=/content/app/outputs/ # Warning: If it is not located under '/content/app', you can't see history log! + volumes: + - fooocus-data:/content/data + #- ./models:/import/models # Once you import files, you don't need to mount again. + #- ./outputs:/import/outputs # Once you import files, you don't need to mount again. + tty: true + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: ['0'] + capabilities: [compute, utility] diff --git a/docker.md b/docker.md new file mode 100644 index 000000000..36cfa632a --- /dev/null +++ b/docker.md @@ -0,0 +1,66 @@ +# Fooocus on Docker + +The docker image is based on NVIDIA CUDA 12.3 and PyTorch 2.0, see [Dockerfile](Dockerfile) and [requirements_docker.txt](requirements_docker.txt) for details. + +## Quick start + +**This is just an easy way for testing. Please find more information in the [notes](#notes).** + +1. Clone this repository +2. Build the image with `docker compose build` +3. Run the docker container with `docker compose up`. Building the image takes some time. + +When you see the message `Use the app with http://0.0.0.0:7865/` in the console, you can access the URL in your browser. + +Your models and outputs are stored in the `fooocus-data` volume, which, depending on OS, is stored in `/var/lib/docker/volumes`. + +## Details + +### Update the container manually + +When you are using `docker compose up` continuously, the container is not updated to the latest version of Fooocus automatically. +Run `git pull` before executing `docker compose build --no-cache` to build an image with the latest Fooocus version. +You can then start it with `docker compose up` + +### Import models, outputs +If you want to import files from models or the outputs folder, you can uncomment the following settings in the [docker-compose.yml](docker-compose.yml): +``` +#- ./models:/import/models # Once you import files, you don't need to mount again. +#- ./outputs:/import/outputs # Once you import files, you don't need to mount again. +``` +After running `docker compose up`, your files will be copied into `/content/data/models` and `/content/data/outputs` +Since `/content/data` is a persistent volume folder, your files will be persisted even when you re-run `docker compose up --build` without above volume settings. + + +### Paths inside the container + +|Path|Details| +|-|-| +|/content/app|The application stored folder| +|/content/app/models.org|Original 'models' folder.
Files are copied to the '/content/app/models' which is symlinked to '/content/data/models' every time the container boots. (Existing files will not be overwritten.) | +|/content/data|Persistent volume mount point| +|/content/data/models|The folder is symlinked to '/content/app/models'| +|/content/data/outputs|The folder is symlinked to '/content/app/outputs'| + +### Environments + +You can change `config.txt` parameters by using environment variables. +**The priority of using the environments is higher than the values defined in `config.txt`, and they will be saved to the `config_modification_tutorial.txt`** + +Docker specified environments are there. They are used by 'entrypoint.sh' +|Environment|Details| +|-|-| +|DATADIR|'/content/data' location.| +|CMDARGS|Arguments for [entry_with_update.py](entry_with_update.py) which is called by [entrypoint.sh](entrypoint.sh)| +|config_path|'config.txt' location| +|config_example_path|'config_modification_tutorial.txt' location| + +You can also use the same json key names and values explained in the 'config_modification_tutorial.txt' as the environments. +See examples in the [docker-compose.yml](docker-compose.yml) + +## Notes + +- Please keep 'path_outputs' under '/content/app'. Otherwise, you may get an error when you open the history log. +- Docker on Mac/Windows still has issues in the form of slow volume access when you use "bind mount" volumes. Please refer to [this article](https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose) for not using "bind mount". +- The MPS backend (Metal Performance Shaders, Apple Silicon M1/M2/etc.) is not yet supported in Docker, see https://github.com/pytorch/pytorch/issues/81224 +- You can also use `docker compose up -d` to start the container detached and connect to the logs with `docker compose logs -f`. This way you can also close the terminal and keep the container running. \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 000000000..d0dba09c2 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +ORIGINALDIR=/content/app +# Use predefined DATADIR if it is defined +[[ x"${DATADIR}" == "x" ]] && DATADIR=/content/data + +# Make persistent dir from original dir +function mklink () { + mkdir -p $DATADIR/$1 + ln -s $DATADIR/$1 $ORIGINALDIR +} + +# Copy old files from import dir +function import () { + (test -d /import/$1 && cd /import/$1 && cp -Rpn . $DATADIR/$1/) +} + +cd $ORIGINALDIR + +# models +mklink models +# Copy original files +(cd $ORIGINALDIR/models.org && cp -Rpn . $ORIGINALDIR/models/) +# Import old files +import models + +# outputs +mklink outputs +# Import old files +import outputs + +# Start application +python launch.py $* diff --git a/modules/config.py b/modules/config.py index 6800c0042..328878ccb 100644 --- a/modules/config.py +++ b/modules/config.py @@ -10,8 +10,16 @@ from modules.util import get_files_from_folder, makedirs_with_log from modules.flags import Performance, MetadataScheme -config_path = os.path.abspath("./config.txt") -config_example_path = os.path.abspath("config_modification_tutorial.txt") +def get_config_path(key, default_value): + env = os.getenv(key) + if env is not None and isinstance(env, str): + print(f"Environment: {key} = {env}") + return env + else: + return os.path.abspath(default_value) + +config_path = get_config_path('config_path', "./config.txt") +config_example_path = get_config_path('config_example_path', "config_modification_tutorial.txt") config_dict = {} always_save_keys = [] visited_keys = [] @@ -123,7 +131,12 @@ def get_dir_or_set_default(key, default_value, as_array=False, make_directory=Fa if key not in always_save_keys: always_save_keys.append(key) - v = config_dict.get(key, None) + v = os.getenv(key) + if v is not None: + print(f"Environment: {key} = {v}") + config_dict[key] = v + else: + v = config_dict.get(key, None) if isinstance(v, str): if make_directory: @@ -165,13 +178,17 @@ def get_dir_or_set_default(key, default_value, as_array=False, make_directory=Fa path_fooocus_expansion = get_dir_or_set_default('path_fooocus_expansion', '../models/prompt_expansion/fooocus_expansion') path_outputs = get_path_output() - def get_config_item_or_set_default(key, default_value, validator, disable_empty_as_none=False): global config_dict, visited_keys if key not in visited_keys: visited_keys.append(key) + v = os.getenv(key) + if v is not None: + print(f"Environment: {key} = {v}") + config_dict[key] = v + if key not in config_dict: config_dict[key] = default_value return default_value diff --git a/modules/util.py b/modules/util.py index 29d48696b..c7923ec82 100644 --- a/modules/util.py +++ b/modules/util.py @@ -160,7 +160,7 @@ def generate_temp_filename(folder='./outputs/', extension='png'): random_number = random.randint(1000, 9999) filename = f"{time_string}_{random_number}.{extension}" result = os.path.join(folder, date_string, filename) - return date_string, os.path.abspath(os.path.realpath(result)), filename + return date_string, os.path.abspath(result), filename def get_files_from_folder(folder_path, exensions=None, name_filter=None): diff --git a/readme.md b/readme.md index 18b48f3ac..a1e62fa47 100644 --- a/readme.md +++ b/readme.md @@ -237,6 +237,10 @@ You can install Fooocus on Apple Mac silicon (M1 or M2) with macOS 'Catalina' or Use `python entry_with_update.py --preset anime` or `python entry_with_update.py --preset realistic` for Fooocus Anime/Realistic Edition. +### Docker + +See [docker.md](docker.md) + ### Download Previous Version See the guidelines [here](https://github.com/lllyasviel/Fooocus/discussions/1405). diff --git a/requirements_docker.txt b/requirements_docker.txt new file mode 100644 index 000000000..3cf4aa89d --- /dev/null +++ b/requirements_docker.txt @@ -0,0 +1,5 @@ +torch==2.0.1 +torchvision==0.15.2 +torchaudio==2.0.2 +torchtext==0.15.2 +torchdata==0.6.1