Reuse shared ComfyUI runtime for Deck-owned LTX video
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
|
||||
WORKDIR /app
|
||||
COPY deploy/image-requirements.lock /app/deploy/image-requirements.lock
|
||||
COPY deploy/tts-requirements.lock /app/deploy/tts-requirements.lock
|
||||
COPY audio_policy.py prompt_enhancer.py prompt_enhancer_worker.py api_compat.py stt.py execution_setup.py tts_runtime.py tts_test.py tts_worker.py auto_test.py chat_test.py endpoint.py inference.py docker_support.py image_encoder_node.py image_runtime.py image_test.py image_upload.py profiles.py capacity.py server.py runtime.py video.py video_proxy.py catalog.py hub_auth.py auth.py collect_hardware.py dashboard_data.py dashboard_history.py /app/
|
||||
COPY audio_policy.py prompt_enhancer.py prompt_enhancer_worker.py api_compat.py stt.py execution_setup.py tts_runtime.py tts_test.py tts_worker.py auto_test.py chat_test.py endpoint.py inference.py docker_support.py image_encoder_node.py image_runtime.py image_test.py image_upload.py profiles.py capacity.py server.py runtime.py video.py video_proxy.py video_comfy.py video_comfy_node.py video_comfy_proxy.py catalog.py hub_auth.py auth.py collect_hardware.py dashboard_data.py dashboard_history.py /app/
|
||||
COPY video-ui.js stt-ui.js tts-ui.js auto-test-ui.js chat-test-ui.js endpoint-ui.js docker-ui.js image-test-ui.js profiles-ui.js dashboard-ui.js index.html app.js studio.js runtime-ui.js catalog-ui.js style.css dashboard.css themes.css login.html login.js access-ui.js network-ui.js /app/
|
||||
COPY network/__init__.py network/client.py network/config.py network/rpc.py /app/network/
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 HOME=/tmp \
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
ARG DECK_RUNTIME_IMAGE
|
||||
FROM ${DECK_RUNTIME_IMAGE}
|
||||
USER root
|
||||
WORKDIR /app
|
||||
COPY deploy/image-requirements.lock /app/deploy/image-requirements.lock
|
||||
COPY deploy/tts-requirements.lock /app/deploy/tts-requirements.lock
|
||||
COPY audio_policy.py prompt_enhancer.py prompt_enhancer_worker.py api_compat.py stt.py execution_setup.py tts_runtime.py tts_test.py tts_worker.py auto_test.py chat_test.py endpoint.py inference.py docker_support.py image_encoder_node.py image_runtime.py image_test.py image_upload.py profiles.py capacity.py server.py runtime.py video.py video_proxy.py video_comfy.py video_comfy_node.py video_comfy_proxy.py catalog.py hub_auth.py auth.py collect_hardware.py dashboard_data.py dashboard_history.py /app/
|
||||
COPY video-ui.js stt-ui.js tts-ui.js auto-test-ui.js chat-test-ui.js endpoint-ui.js docker-ui.js image-test-ui.js profiles-ui.js dashboard-ui.js index.html app.js studio.js runtime-ui.js catalog-ui.js style.css dashboard.css themes.css login.html login.js access-ui.js network-ui.js /app/
|
||||
COPY network/__init__.py network/client.py network/config.py network/rpc.py /app/network/
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 HOME=/tmp \
|
||||
DECK_BIND_HOST=0.0.0.0 DECK_STATE_DIR=/var/lib/deck \
|
||||
DECK_REQUIRE_SETUP=1 DECK_LOCAL_HARDWARE=1 DECK_LOCATION=Athena-Debian \
|
||||
DECK_NETWORK_MODE=disabled
|
||||
USER 65534:65534
|
||||
CMD ["python3", "server.py", "--port", "8108"]
|
||||
+10
-7
@@ -14,7 +14,7 @@ import urllib.request
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
LABEL = 'de.casaderoll.athena-deck.standalone'
|
||||
FILES = ['prompt_enhancer.py','prompt_enhancer_worker.py','image_upload.py','audio_policy.py','deploy/tts-requirements.lock','stt.py','stt-ui.js','api_compat.py','execution_setup.py','tts_runtime.py','tts_test.py','tts_worker.py','tts-ui.js','auto_test.py','auto-test-ui.js','chat_test.py','chat-test-ui.js','endpoint.py','inference.py','endpoint-ui.js','docker_support.py','docker-ui.js','deploy/docker_helper.py','deploy/setup_docker_helper.py','image_encoder_node.py','image_runtime.py','image_test.py','image-test-ui.js','profiles.py','profiles-ui.js','capacity.py','runtime.py','runtime-ui.js','video.py','video_proxy.py','video-ui.js','catalog.py','hub_auth.py','catalog-ui.js','server.py','auth.py','collect_hardware.py','dashboard_data.py','dashboard_history.py','dashboard-ui.js','dashboard.css','themes.css','deploy/import_dashboard_history.py','index.html','app.js','studio.js','style.css','login.html','login.js','access-ui.js','network-ui.js','network/__init__.py','network/client.py','network/config.py','network/rpc.py','deploy/Dockerfile','deploy/image-requirements.lock']
|
||||
FILES = ['deploy/Dockerfile.app-update','video_comfy.py','video_comfy_node.py','video_comfy_proxy.py','prompt_enhancer.py','prompt_enhancer_worker.py','image_upload.py','audio_policy.py','deploy/tts-requirements.lock','stt.py','stt-ui.js','api_compat.py','execution_setup.py','tts_runtime.py','tts_test.py','tts_worker.py','tts-ui.js','auto_test.py','auto-test-ui.js','chat_test.py','chat-test-ui.js','endpoint.py','inference.py','endpoint-ui.js','docker_support.py','docker-ui.js','deploy/docker_helper.py','deploy/setup_docker_helper.py','image_encoder_node.py','image_runtime.py','image_test.py','image-test-ui.js','profiles.py','profiles-ui.js','capacity.py','runtime.py','runtime-ui.js','video.py','video_proxy.py','video-ui.js','catalog.py','hub_auth.py','catalog-ui.js','server.py','auth.py','collect_hardware.py','dashboard_data.py','dashboard_history.py','dashboard-ui.js','dashboard.css','themes.css','deploy/import_dashboard_history.py','index.html','app.js','studio.js','style.css','login.html','login.js','access-ui.js','network-ui.js','network/__init__.py','network/client.py','network/config.py','network/rpc.py','deploy/Dockerfile','deploy/image-requirements.lock']
|
||||
|
||||
|
||||
def run(*args, check=True, interactive=False):
|
||||
@@ -64,13 +64,15 @@ def free_port(port):
|
||||
raise RuntimeError('Der gewünschte Loopback-Port ist bereits belegt.') from None
|
||||
|
||||
|
||||
def build():
|
||||
def build(runtime_image=None):
|
||||
digest = hashlib.sha256()
|
||||
for name in FILES:
|
||||
digest.update(name.encode());digest.update((ROOT/name).read_bytes())
|
||||
tag = 'athena-deck-standalone:'+digest.hexdigest()[:16]
|
||||
print('Eigenes Deck-Image bauen (keine Modelle oder llama.cpp-Builds).',flush=True)
|
||||
result = run('docker','build','--label',LABEL+'=image','-t',tag,'-f',str(ROOT/'deploy/Dockerfile'),str(ROOT),interactive=True)
|
||||
dockerfile='deploy/Dockerfile.app-update' if runtime_image else 'deploy/Dockerfile'
|
||||
extra=['--build-arg','DECK_RUNTIME_IMAGE='+runtime_image] if runtime_image else []
|
||||
result = run('docker','build',*extra,'--label',LABEL+'=image','-t',tag,'-f',str(ROOT/dockerfile),str(ROOT),interactive=True)
|
||||
return tag
|
||||
|
||||
|
||||
@@ -187,7 +189,7 @@ def install(args):
|
||||
print('Generierter API-Token: geschützte Datei '+str(base/'bootstrap/api-token.txt')+'. In Passwortmanager übernehmen und Datei danach entfernen.')
|
||||
|
||||
|
||||
def update(base, rollback=False, force=False, api_ports=None):
|
||||
def update(base, rollback=False, force=False, api_ports=None, reuse_runtime=False):
|
||||
config=load_manifest(base)
|
||||
previous=owned(config['name'],base)
|
||||
if not previous:
|
||||
@@ -195,14 +197,14 @@ def update(base, rollback=False, force=False, api_ports=None):
|
||||
selected_ports=config.get('api_ports',[]) if api_ports is None else parse_api_ports(api_ports)
|
||||
if config['port'] in selected_ports:raise RuntimeError('Verwaltungsport und API-Ports müssen verschieden sein.')
|
||||
for port in set(selected_ports)-set(config.get('api_ports',[])):free_port(port)
|
||||
image=config.get('previous_image') if rollback else build()
|
||||
image=config.get('previous_image') if rollback else build(config['image'] if reuse_runtime else None)
|
||||
if not image:raise RuntimeError('Kein vorheriger Build gespeichert.')
|
||||
if image==config['image'] and selected_ports==config.get('api_ports',[]) and not force:
|
||||
print('Dieser Quellstand ist bereits installiert.');return
|
||||
backup_name=config['name']+'-previous'
|
||||
if inspect(backup_name):raise RuntimeError('Rückfall-Containername belegt. Keine Änderung ausgeführt.')
|
||||
stamp=str(time.time_ns())
|
||||
shutil.copytree(base/'state',base/'backups'/stamp,ignore=shutil.ignore_patterns('tts-runtime','tts-tests','models','runtime','runtime-verification','image-tests','image-verification','image-verification-*','image-runtime','router-verification-*'))
|
||||
shutil.copytree(base/'state',base/'backups'/stamp,ignore=shutil.ignore_patterns('tts-runtime','tts-tests','models','runtime','runtime-verification','image-tests','image-verification','image-verification-*','image-runtime','video-runtime','video-verification','video-verification-*','comfy-work','router-verification-*'))
|
||||
was_running=previous['State']['Running']
|
||||
if was_running:run('docker','stop','--time','15',config['name'])
|
||||
run('docker','rename',config['name'],backup_name)
|
||||
@@ -235,6 +237,7 @@ def main():
|
||||
parser.add_argument('--directory',type=Path,default=Path('/opt/athena-deck-standalone'))
|
||||
parser.add_argument('--name',default='athena-deck-standalone')
|
||||
parser.add_argument('--port',type=int,default=8110)
|
||||
parser.add_argument('--reuse-runtime',action='store_true',help='Bei reinen App-Updates vorhandenes Deck-Image mit seinen Laufzeiten wiederverwenden; keine Laufzeitinstallation.')
|
||||
parser.add_argument('--api-ports',help='Separater API-Port oder Bereich, z. B. 8120-8124. Installationsstandard: 8120-8124; Updates behalten den bisherigen Bereich.')
|
||||
parser.add_argument('--gpu-telemetry',action='store_true',help='Vorhandenes NVIDIA Container Toolkit für Messwerte und Fit-Prüfung nutzen; installiert keine Treiber.')
|
||||
args=parser.parse_args()
|
||||
@@ -270,7 +273,7 @@ def main():
|
||||
if item:run('docker','start',config['name'])
|
||||
else:launch(config)
|
||||
ready(config);print('Deck bereit.')
|
||||
elif args.update or args.rollback:update(args.directory,args.rollback,api_ports=args.api_ports)
|
||||
elif args.update or args.rollback:update(args.directory,args.rollback,api_ports=args.api_ports,reuse_runtime=args.reuse_runtime)
|
||||
|
||||
if __name__=='__main__':
|
||||
try:main()
|
||||
|
||||
Reference in New Issue
Block a user