diff --git a/.gitignore b/.gitignore index 38abc08..f27ee46 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ coverage data/db* data/user-uploads/* data/temp/* -!data/user-uploads/.gitkeep \ No newline at end of file +!data/user-uploads/.gitkeep diff --git a/Dockerfile b/Dockerfile index 506e880..f3c33a4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ +# Builder image runs on the build platform so we can install dependencies FROM --platform=$BUILDPLATFORM oven/bun:1.2 AS base LABEL maintainer="Grimoire Developers " LABEL description="Bookmark manager for the wizards" @@ -8,24 +9,13 @@ FROM base AS builder RUN mkdir -p /etc/s6-overlay/s6-rc.d/grimoire /etc/s6-overlay/s6-rc.d/user/contents.d /app/data -# Different build strategy based on architecture ARG TARGETARCH -RUN if [ "${TARGETARCH}" = "arm64" ]; then \ - # ARM64 build - avoid libc-bin issues - apt-get update && \ - apt-mark hold libc-bin && \ +RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ xz-utils wget python3 python3-pip build-essential && \ - rm -rf /var/lib/apt/lists/*; \ - else \ - # Standard installation for other architectures - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - xz-utils python3 python3-pip wget build-essential && \ - rm -rf /var/lib/apt/lists/*; \ - fi + rm -rf /var/lib/apt/lists/*; -ARG S6_OVERLAY_VERSION=3.1.6.2 +ARG S6_OVERLAY_VERSION=3.2.1.0 RUN case "${TARGETARCH}" in \ "amd64") S6_ARCH="x86_64" ;; \ "arm64") S6_ARCH="aarch64" ;; \ @@ -73,7 +63,27 @@ ENV NODE_ENV=production \ NODE_OPTIONS="--max-old-space-size=4096" RUN bun --bun run build -FROM base AS release +FROM --platform=$TARGETPLATFORM oven/bun:1.2 AS release +RUN adduser --disabled-password --gecos '' --uid 10001 grimoire +RUN mkdir -p /etc/s6-overlay/s6-rc.d/grimoire /etc/s6-overlay/s6-rc.d/user/contents.d /app/data +ARG TARGETARCH +ARG S6_OVERLAY_VERSION=3.2.1.0 +RUN case "${TARGETARCH}" in \ + "amd64") S6_ARCH="x86_64" ;; \ + "arm64") S6_ARCH="aarch64" ;; \ + "386") S6_ARCH="i686" ;; \ + "arm/v7") S6_ARCH="armhf" ;; \ + "arm/v6") S6_ARCH="arm" ;; \ + *) S6_ARCH="x86_64" && echo "Warning: Unknown architecture ${TARGETARCH}, defaulting to x86_64" ;; \ + esac && \ + echo "Architecture: Docker ${TARGETARCH} -> s6-overlay ${S6_ARCH}" && \ + wget -q -O /tmp/s6-overlay-noarch.tar.xz https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz && \ + wget -q -O /tmp/s6-overlay-${S6_ARCH}.tar.xz https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz && \ + tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz && \ + tar -C / -Jxpf /tmp/s6-overlay-${S6_ARCH}.tar.xz && \ + rm /tmp/s6-overlay-*xz +COPY docker/etc/s6-overlay /etc/s6-overlay/ +RUN chmod +x /etc/s6-overlay/s6-rc.d/grimoire/run RUN mkdir -p /app/data && chown -R grimoire:grimoire /app/data && chmod 766 /app/data WORKDIR /app @@ -94,8 +104,7 @@ ENV NODE_ENV=production \ BODY_SIZE_LIMIT=${BODY_SIZE_LIMIT:-5000000} RUN chmod +x /docker-entrypoint.sh -USER grimoire EXPOSE ${PORT} HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:$PORT/api/health || exit 1 -ENTRYPOINT ["/docker-entrypoint.sh"] +ENTRYPOINT ["/init"] diff --git a/bun.lockb b/bun.lockb deleted file mode 100755 index 1578df8..0000000 Binary files a/bun.lockb and /dev/null differ diff --git a/docker/etc/s6-overlay/s6-rc.d/grimoire/run b/docker/etc/s6-overlay/s6-rc.d/grimoire/run index 45d1335..a9c5f1c 100644 --- a/docker/etc/s6-overlay/s6-rc.d/grimoire/run +++ b/docker/etc/s6-overlay/s6-rc.d/grimoire/run @@ -1,9 +1,12 @@ #!/command/with-contenv bash +chown -R grimoire:grimoire /app/data +chmod 755 /app/data + cd /app # Run migrations first -/usr/local/bin/bun run run-migrations +s6-setuidgid grimoire /usr/local/bin/bun run run-migrations # Start the application -exec /usr/local/bin/bun ./build/index.js +exec s6-setuidgid grimoire /usr/local/bin/bun ./build/index.js diff --git a/package.json b/package.json index 165c430..185e145 100644 --- a/package.json +++ b/package.json @@ -38,64 +38,64 @@ }, "type": "module", "devDependencies": { - "@libsql/client": "^0.11.0", - "@sveltejs/adapter-auto": "^3.2.4", + "@libsql/client": "^0.15.7", + "@sveltejs/adapter-auto": "^3.3.1", "@sveltejs/kit": "^2.5.27", "@tailwindcss/typography": "^0.5.14", "@types/adm-zip": "^0.5.5", - "@types/bun": "^1.1.9", - "@types/express": "^4.17.21", + "@types/bun": "^1.2.13", + "@types/express": "^4.17.22", "@types/express-http-proxy": "^1.6.6", "@types/swagger-ui": "^3.52.4", - "@typescript-eslint/eslint-plugin": "^8.5.0", - "@typescript-eslint/parser": "^8.5.0", - "@vitest/coverage-v8": "^2.1.1", - "autoprefixer": "^10.4.20", - "drizzle-kit": "^0.24.2", - "eslint": "^9.10.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-perfectionist": "^3.6.0", - "eslint-plugin-svelte": "^2.44.0", - "postcss": "^8.4.47", + "@typescript-eslint/eslint-plugin": "^8.32.1", + "@typescript-eslint/parser": "^8.32.1", + "@vitest/coverage-v8": "^2.1.9", + "autoprefixer": "^10.4.21", + "drizzle-kit": "^0.31.1", + "eslint": "^9.27.0", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-perfectionist": "^3.9.1", + "eslint-plugin-svelte": "^2.46.1", + "postcss": "^8.5.3", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.6", - "prettier-plugin-tailwindcss": "^0.6.6", - "release-it": "^17.6.0", - "svelte": "^4.2.19", + "prettier-plugin-tailwindcss": "^0.6.11", + "release-it": "^19.0.2", + "svelte": "^4.2.20", "svelte-adapter-bun": "^0.5.2", - "svelte-check": "^4.0.2", - "tailwindcss": "^3.4.11", - "tslib": "^2.7.0", - "typescript": "^5.6.2", - "vite": "^5.4.5", - "vitest": "^2.1.1" + "svelte-check": "^4.2.1", + "tailwindcss": "^3.4.17", + "tslib": "^2.8.1", + "typescript": "^5.8.3", + "vite": "^5.4.19", + "vitest": "^2.1.9" }, "dependencies": { "@extractus/article-extractor": "^8.0.10", "@lucia-auth/adapter-drizzle": "^1.1.0", - "@sveltejs/vite-plugin-svelte": "^3.1.2", + "@sveltejs/vite-plugin-svelte": "^4.0.4", "@tabler/icons": "^3.16.0", "@tabler/icons-svelte": "^3.16.0", "@tailwindcss/line-clamp": "^0.4.4", "@types/html-to-text": "^9.0.4", "@types/sanitize-html": "^2.13.0", "adm-zip": "^0.5.16", - "chalk": "^5.3.0", - "daisyui": "^4.12.10", - "dotenv": "^16.4.5", - "drizzle-orm": "^0.33.0", + "chalk": "^5.4.1", + "daisyui": "^4.12.24", + "dotenv": "^16.5.0", + "drizzle-orm": "^0.43.1", "es-toolkit": "^1.31.0", "eslint-plugin-drizzle": "^0.2.3", - "express": "^4.21.0", + "express": "^4.21.2", "fuse.js": "^7.0.0", "html-to-text": "^9.0.5", "joi": "^17.13.3", - "lucia": "^3.2.0", + "lucia": "^3.2.2", "node-parse-bookmarks": "^1.0.3", "sanitize-html": "^2.13.0", "svelte-french-toast": "^1.2.0", "svelte-select": "^5.8.3", - "swagger-ui": "^5.17.14", - "url-metadata": "^4.1.1" + "swagger-ui": "^5.21.0", + "url-metadata": "^4.1.4" } }