From eeacaca72518dce37775a812a31d161bfc08dbec Mon Sep 17 00:00:00 2001 From: Matt Lorentz Date: Tue, 3 Mar 2026 19:52:22 +0000 Subject: [PATCH] Fix a docker rebuild issue (#88) The Docker build wasn't making use of docker's cache because the .git directory was being copied into the build context. This means that even if the app did not change, if anything in git changed then docker would rebuild the entire app. This excludes the .git folder from the docker build, instead relying on the user to pass in the build hash at build time. Which is annoying but I don't think there's a better way around it. This was annoying me because I am deploying a self-hosted version of flotilla from a git branch via ansible and it was rebuilding flotilla every time. Co-authored-by: mplorentz Reviewed-on: https://gitea.coracle.social/coracle/flotilla/pulls/88 Co-authored-by: Matt Lorentz Co-committed-by: Matt Lorentz --- .dockerignore | 8 ++++++++ .env.local | 3 +++ Dockerfile | 26 ++++++++++++++++---------- README.md | 2 +- build.sh | 10 +++++++--- pnpm-lock.yaml | Bin 349786 -> 352190 bytes 6 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 .env.local diff --git a/.dockerignore b/.dockerignore index 29936490..ae84fa66 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,11 @@ node_modules android ios build + +# Git +.git +.gitignore + +# Env files (keep .env for build; exclude local overrides) +.env.local +.env.*.local \ No newline at end of file diff --git a/.env.local b/.env.local new file mode 100644 index 00000000..fe8387e3 --- /dev/null +++ b/.env.local @@ -0,0 +1,3 @@ +# VITE_PLATFORM_URL=http://localhost:1847 +# VITE_PLATFORM_RELAYS=wss://relay.nostrtalk.org/ +VITE_POMADE_SIGNERS=https://pomade.coracle.social,https://pomade.fiatjaf.com,http://localhost:3003 diff --git a/Dockerfile b/Dockerfile index 71905be1..18f909db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,30 @@ -FROM node:20-slim +# Stage 1: Build +# Uses .env from build context for config (logo, branding, etc.) +# Optional: docker build --build-arg VITE_BUILD_HASH=$(git rev-parse --short HEAD) -t flotilla . + +FROM node:20-bookworm AS builder -# Install pnpm RUN npm install -g pnpm@latest -# Set working directory WORKDIR /app -# Copy package files COPY package.json pnpm-lock.yaml ./ - -# Install dependencies RUN pnpm i -# Copy the rest of the application +# Copy everything (including .env when present) - build.sh will source it COPY . . -# Build the application +ARG VITE_BUILD_HASH +ENV VITE_BUILD_HASH=${VITE_BUILD_HASH} + ENV NODE_OPTIONS=--max_old_space_size=16384 RUN pnpm run build -# Default to serving the build directory -CMD ["npx", "serve", "-s", "build"] +FROM node:20-alpine +WORKDIR /app + +# Copy only the built output - no source, no .env, no dev deps +COPY --from=builder /app/build ./build + +CMD ["npx", "serve", "-s", "build"] diff --git a/README.md b/README.md index 29e880ec..a60d384a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ You can also optionally create an `.env` file and populate it with the following - `VITE_DEFAULT_PUBKEYS` - A comma-separated list of hex pubkeys for bootstrapping web of trust - `VITE_PLATFORM_URL` - The url where the app will be hosted - `VITE_PLATFORM_NAME` - The name of the app -- `VITE_PLATFORM_LOGO` - A logo url for the app +- `VITE_PLATFORM_LOGO` - A logo url for the app. Can be a local path or https link. Must be a PNG file. - `VITE_PLATFORM_RELAYS` - A list of comma-separated relay urls that will make flotilla operate in "platform mode". Disables all space browse/add/select functionality and makes the first platform relay the home page. - `VITE_PLATFORM_ACCENT` - A hex color for the app's accent color - `VITE_PLATFORM_DESCRIPTION` - A description of the app diff --git a/build.sh b/build.sh index 252fde49..1b632f25 100755 --- a/build.sh +++ b/build.sh @@ -5,6 +5,9 @@ temp_env=$(declare -p -x) if [ -f .env.template ]; then source .env.template fi +if [ -f .env ]; then + source .env +fi # Avoid overwriting env vars provided directly # https://stackoverflow.com/a/69127685/1467342 @@ -14,12 +17,13 @@ if [[ -z $VITE_BUILD_HASH ]]; then export VITE_BUILD_HASH=$(git rev-parse --short HEAD) fi -if [[ $VITE_PLATFORM_LOGO =~ ^https://* ]]; then - curl $VITE_PLATFORM_LOGO > static/logo.png +if [[ $VITE_PLATFORM_LOGO =~ ^https:// ]]; then + curl -fSL "$VITE_PLATFORM_LOGO" -o static/logo.png export VITE_PLATFORM_LOGO=static/logo.png fi -npx pwa-assets-generator +# Ensure generator uses local path (dotenv may have loaded URL from .env) +VITE_PLATFORM_LOGO="${VITE_PLATFORM_LOGO}" npx pwa-assets-generator npx vite build # Replace index.html variables with stuff from our env diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 38bdb75aa8aee4a49e0456a7d80f6a994f38a7f4..d447fc03ef18839e431e2d311dfcdbd692c7d2d3 100644 GIT binary patch delta 8345 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 JHnTn$_