Merge pull request 'Add Dockerfile and compose setup for self-hosting' (#2) from docker into main

Reviewed-on: https://git.srazka.com/reudy-net/Papure/pulls/2
Reviewed-by: reudy <jakubadorfman@proton.me>
This commit is contained in:
reudy 2026-09-27 00:35:21 +02:00
commit 24ebbd9056
5 changed files with 72 additions and 0 deletions

9
.dockerignore Normal file
View file

@ -0,0 +1,9 @@
.git
.claude
node_modules
.svelte-kit
build
memos
Dockerfile
compose.yaml
*.md

14
Dockerfile Normal file
View file

@ -0,0 +1,14 @@
# Build the static PWA, then serve it with nginx.
FROM node:24-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:1.29-alpine
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO /dev/null http://127.0.0.1/ || exit 1

View file

@ -12,6 +12,14 @@ npm run check # type-check
npm run build # static PWA in build/ — serve it from any static host (HTTPS for PWA install) npm run build # static PWA in build/ — serve it from any static host (HTTPS for PWA install)
``` ```
## Docker
```sh
docker compose up -d --build # http://localhost:8080 (set PAPURE_PORT to change)
```
The image builds the PWA and serves it with nginx. Put an HTTPS reverse proxy in front of it: installing the PWA and the offline service worker both need HTTPS. To update, `git pull` and run the same command again.
## Using it ## Using it
- **Tools** (bottom bar): Text `T`, Pen `P`, Highlighter `H`, Eraser `E`, Import PDF, Undo/Redo, zoom. The pen's eraser end erases too. - **Tools** (bottom bar): Text `T`, Pen `P`, Highlighter `H`, Eraser `E`, Import PDF, Undo/Redo, zoom. The pen's eraser end erases too.

8
compose.yaml Normal file
View file

@ -0,0 +1,8 @@
services:
papure:
build: .
image: papure
restart: unless-stopped
# Put an HTTPS reverse proxy in front: the PWA install and service worker need HTTPS.
ports:
- "${PAPURE_PORT:-8080}:80"

33
docker/nginx.conf Normal file
View file

@ -0,0 +1,33 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
gzip on;
gzip_types text/css application/javascript application/json application/manifest+json image/svg+xml;
# Hashed build output never changes.
location /_app/immutable/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
# The service worker and app shell must be re-checked so updates reach clients.
location = /service-worker.js {
add_header Cache-Control "no-cache";
try_files $uri =404;
}
# nginx's default MIME table has no entry for the PWA manifest.
location ~ \.webmanifest$ {
types { }
default_type application/manifest+json;
add_header Cache-Control "no-cache";
}
# Client-side app: unknown paths fall back to the SPA shell.
location / {
add_header Cache-Control "no-cache";
try_files $uri $uri/ /index.html;
}
}