From d501778ae5f68fe65b8142b64fdb91f45871cb97 Mon Sep 17 00:00:00 2001 From: Kawa Date: Wed, 12 Aug 2026 12:56:55 +0200 Subject: [PATCH] build: add container image and ignore rules Dockerfile builds a static-web-server image serving src/ with the third-party assets vendored in a first stage, so the runtime layer carries no Node and no shell tooling. WITH_FFMPEG=0 drops the 18.5 MB asm.js encoder for a smaller image, at the cost of fetching it at export time. .gitignore covers dist/, which the release scripts write on every run: without it a fresh clone reports the build output as untracked and publish.ps1 warns that the worktree is dirty on every build. Co-Authored-By: Claude Opus 5 (1M context) --- .dockerignore | 13 +++++++++++++ .gitignore | 9 +++++++++ Dockerfile | 48 ++++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 15 +++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5380e88 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +.git +.github +.playwright-mcp +node_modules +dist +build +electron +test +deploy +*.md + +# Always re-downloaded inside the build so the image is reproducible. +src/vendor diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f2b6ffa --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +node_modules/ +dist/ +build/icon.png + +# Populated by `npm run vendor` (~19 MB, mostly the ffmpeg asm.js build). +src/vendor/ + +.playwright-mcp/ +*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..44d9cde --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +# syntax=docker/dockerfile:1 +# +# Motionity is a static app, so the runtime image is a static file server and +# nothing else: no Node, no shell tooling, ~8 MB of base image. +# +# Build: docker build -t motionity:latest . +# Run: docker run --rm -p 8080:8080 motionity:latest +# +# WITH_FFMPEG=0 drops the 18.5 MB asm.js ffmpeg build from the image. MP4/GIF +# export then downloads it from archive.org on first use instead of working +# offline; everything else is unaffected. + +FROM node:22-alpine AS vendor +ARG WITH_FFMPEG=1 +WORKDIR /app +COPY scripts/vendor.mjs scripts/ +COPY src/index.html src/ +RUN if [ "$WITH_FFMPEG" = "1" ]; then \ + node scripts/vendor.mjs; \ + else \ + node scripts/vendor.mjs --skip-ffmpeg; \ + fi + +FROM ghcr.io/static-web-server/static-web-server:2-alpine + +COPY --chown=65534:65534 src/ /public/ +COPY --from=vendor --chown=65534:65534 /app/src/vendor/ /public/vendor/ + +ENV SERVER_ROOT=/public \ + SERVER_HOST=0.0.0.0 \ + SERVER_PORT=8080 \ + SERVER_COMPRESSION=true \ + SERVER_COMPRESSION_LEVEL=default \ + SERVER_CACHE_CONTROL_HEADERS=true \ + SERVER_LOG_LEVEL=warn \ + SERVER_SECURITY_HEADERS=false \ + SERVER_HEALTH=true + +USER 65534:65534 +EXPOSE 8080 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \ + CMD wget -q --spider http://127.0.0.1:8080/health || exit 1 + +# NOTE: browsers expose WebCodecs (the fast exporter) and IndexedDB (project +# saving) only in a secure context. Reaching this container over plain http:// +# from another machine disables both. Publish it behind TLS, or keep access on +# http://localhost. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..15b6882 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + motionity: + build: + context: . + # WITH_FFMPEG: "0" trims 18.5 MB by fetching the MP4/GIF encoder from + # archive.org at runtime instead of shipping it. + args: + WITH_FFMPEG: "1" + image: motionity:latest + ports: + - "8080:8080" + restart: unless-stopped + read_only: true + security_opt: + - no-new-privileges:true