fix(docker): run container as non-root and exclude local files from image

- Add .dockerignore: a local .env, the live SQLite database in data/, .git,
  and node_modules were previously copied into the published image by COPY
- Run the app as the unprivileged node user; pre-create /app/data with
  matching ownership so named volumes inherit it
- Set NODE_ENV=production in the image
- Document the one-time volume chown needed when upgrading existing
  deployments
This commit is contained in:
2026-06-11 21:57:39 -06:00
parent 674506bd2d
commit b4824655dd
3 changed files with 33 additions and 1 deletions
+15
View File
@@ -0,0 +1,15 @@
.git
.github
node_modules
data
*.db
*.db-shm
*.db-wal
.env
.env.*
!.env.example
*.log
.claude
CLAUDE.md
TODO.md
docker-compose.yml
+11
View File
@@ -46,6 +46,17 @@ docker compose up -d
4. Use the setup wizard to configure your first checking account (organization info, bank info, routing/account numbers), or import an existing ezCheckPrinting `.mdb` file. 4. Use the setup wizard to configure your first checking account (organization info, bank info, routing/account numbers), or import an existing ezCheckPrinting `.mdb` file.
#### Upgrading from images before v0.5
The container now runs as the unprivileged `node` user (UID 1000). Existing data
volumes were written as root, so fix ownership once before upgrading:
```bash
docker compose down
docker run --rm -v check-printing-data:/data alpine chown -R 1000:1000 /data
docker compose up -d
```
### Development (local) ### Development (local)
```bash ```bash
+7 -1
View File
@@ -1,5 +1,7 @@
FROM node:20-slim FROM node:20-slim
ENV NODE_ENV=production
# mdbtools for migration script (only needed on first run, stays in image for convenience) # mdbtools for migration script (only needed on first run, stays in image for convenience)
RUN apt-get update && apt-get install -y --no-install-recommends mdbtools && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y --no-install-recommends mdbtools && rm -rf /var/lib/apt/lists/*
@@ -10,9 +12,13 @@ RUN npm ci --omit=dev
COPY . . COPY . .
# Data volume: SQLite database and any runtime uploads # Data volume: SQLite database and any runtime uploads.
# Pre-create it owned by the unprivileged user so named volumes inherit ownership.
RUN mkdir -p /app/data && chown -R node:node /app
VOLUME ["/app/data"] VOLUME ["/app/data"]
USER node
EXPOSE 3000 EXPOSE 3000
CMD ["node", "src/app.js"] CMD ["node", "src/app.js"]