All apps · 0 apps
MakerWorks-v2
Docker app from schartrand77's Repository
Overview
Readme
View on GitHubMakerWorks Storefront
MakerWorks Storefront is a production-grade 3D printing commerce platform: customer-facing storefront, instant quoting, checkout, and a full operations backend for fulfillment teams.
It is built for print labs and shops that need one system for sales, manufacturing, and inventory-aware planning.
Suite Demo Walkthrough
A fully synthetic demo walkthrough is available for documenting the end-to-end MakerWorks, StockWorks, and PrintLab flow:
- Full walkthrough:
docs/wiki/Suite-Demo-Walkthrough.md - Screenshot assets:
docs/wiki/assets/suite-screenshots/ - Demo data scripts:
npm run suite:demo:seed,npm run suite:demo:screenshots,npm run suite:demo:wiki
The demo uses sample data only. PrintLab screenshots default to synthetic fixture views so printer controls, live serials, camera feeds, and private printer state are not captured.
MakerWorks Model-to-Cart Flow
The walkthrough covers discovery, model detail, instant quote, checkout, customer order tracking, and admin production views.


Suite Operations Views
StockWorks and PrintLab screenshots show the same synthetic order context moving through inventory planning, material transactions, printer routing, and submitted job tracking.


What This App Does
- Runs a public 3D print storefront (discover, product pages, upload, cart, checkout).
- Prices configurable print jobs using material, machine time, labor, and policy rules.
- Manages order lifecycle from quote to fulfillment, including customer approvals and revisions.
- Supports admin workflows for production queues, printer assignment, analytics, and backup/restore.
- Connects optional external systems for payments, inventory, printer telemetry, and notifications.
Recent Frontend Upgrades
- Discover now supports typed search tokens, shareable presets, relevance reasons, ready-to-print inventory-aware filtering, and explainable risk/ship-speed sorting.
- Model detail now includes creator quality scoring, printability checks, lineage/remix history, part-aware review comments with pins, and richer quote explainability.
- Checkout now includes a persistent mini-summary, configuration comparison, organization billing controls, department-aware procurement routing, and lead-time confidence details.
- Customer order pages expose production milestones, estimate calibration, failure-recovery guidance, approvals, revisions, and timeline history.
- Organization workflows now include shared discover presets, project workspaces, department budgets, and approval-routing configuration.
Core Product Areas
Customer Commerce
- Browse catalog and collections.
- Upload STL/OBJ/3MF/AMF/PLY/WRL/VRML/GLB/GLTF/USD/USDZ/USDA/USDC/ZIP files.
- Configure print options and get instant estimates.
- Review print feasibility, material recommendations, tolerance class, and quote breakdowns before adding to cart.
- Checkout with card, cash, no-charge contribution, invoice, PO, or quote-request modes.
- Track orders, respond to approvals, and request revisions/reprints.
- Review project workspaces, pinned part comments, and production progress timelines.
Shop Operations
- Manage models, product templates, featured content, and pricing profiles.
- Operate printer queues and production assignment tools.
- Monitor analytics, demand forecasting, and material optimization.
- Run backups/restores and environment validation from admin tooling.
Integrations
OrderWorks (legacy compatibility)
OrderWorks is legacy compatibility context and is no longer part of the active checkout or production handoff path. MakerWorks keeps OrderWorks-compatible surfaces for historical data and inbound compatibility, while new production execution should use the MakerWorks order lifecycle and PrintLab handoff.
- Core client/service:
lib/orderworks.ts - Sync logic:
lib/orderworks-sync.ts - Status mapping:
lib/orderworks-status.ts - Admin endpoints:
- Public bridge endpoint:
app/api/makerworks/jobs/route.ts
Stockworks (inventory + material intelligence)
MakerWorks includes Stockworks integration for filament/material inventory, consumption, and warnings.

- Core client:
lib/stockworks-client.ts - Inventory domain modules:
- API routes:
PrintLab (printer routing + production handoff)
MakerWorks can hand production context to PrintLab for printer-aware routing and job tracking. The demo walkthrough captures this with synthetic printer fixtures only.

- Demo fixtures:
scripts/suite-demo-seed.ts - Screenshot capture:
scripts/capture-suite-screenshots.ts - Full PrintLab walkthrough:
docs/wiki/Suite-Demo-Walkthrough.md#printlab
Upgrade Planning
- See
UPGRADE_RECOMMENDATIONS.mdfor a prioritized backlog covering PostgreSQL, Node.js, and dependency migration waves.
Quick Start
Docker (recommended)
- Copy environment template:
cp .env.example .env
- Set required values (
DATABASE_URL,JWT_SECRET, admin credentials, and optional integrations).- Optional for automated backups: set
BACKUP_SCHEDULE_ENABLED=1and tuneBACKUP_*retention vars.
- Optional for automated backups: set
- Start services:
docker compose up --build -d
- Open
http://localhost:3000.
Local Node Runtime
Requirements:
- Node.js 20+
- PostgreSQL 15+
- Install dependencies:
npm ci
- Configure env:
cp .env.example .env
- Generate Prisma client and run migrations:
npm run prisma:generate
npm run prisma:migrate
- Bootstrap admin:
npm run bootstrap:admin
- Run the app:
npm run dev
Environment Configuration
Use .env.example as source of truth. Key variable groups:
- Minimal boot environment:
DATABASE_URL,JWT_SECRET,BASE_URL,STORAGE_DIR, and bootstrap admin values when needed. - Backup/restore (optional local overrides):
PG_DUMP_BIN,PSQL_BIN - Backup scheduling/retention:
BACKUP_DOCKER_SERVICE,BACKUP_SCHEDULE_ENABLED,BACKUP_SCHEDULE_TIME_UTC,BACKUP_RUN_ON_START,BACKUP_PRUNE_ON_BACKUP,BACKUP_RETENTION_DAYS,BACKUP_RETENTION_MAX_COUNT - Backup runtime mode:
SKIP_DOCKER,PG_DUMP_BIN,PSQL_BIN - Backup destination path:
BACKUP_DIR(defaults toSTORAGE_DIR/backups) - Optional legacy overrides:
STRIPE_*,PAYPAL_*,ORDERWORKS_*,STOCKWORKS_*,PRINTLAB_*,SMTP_*,VAPID_*,DISCORD_*,NEXT_PUBLIC_BRAND_*, and direct-upload URL settings.
Payments, email, suite integrations, notifications, direct-upload URLs, and branding can be configured after login from Admin -> Suite setup. Environment variables continue to override saved suite settings during migration; remove an env value only after saving and testing the matching in-app setting.
Admin Password Guardrails
ADMIN_PASSWORD is now validated with security guardrails:
- Must be at least 12 characters.
- Must not be a weak/default value such as
changeme,change-me-please,password,admin,default,secret,test, ordev.
Enforcement behavior:
npm run bootstrap:adminskips admin bootstrap when the password is weak in non-production environments.- In production (
NODE_ENV=production), weakADMIN_PASSWORDcauses bootstrap to fail fast. /api/admin/env-checknow flags weakADMIN_PASSWORDand weak/shortJWT_SECRETas insecure config.
Backups On Unraid
Use these settings when running MakerWorks as a single container on Unraid (non-compose runtime).
Unraid Restart Behavior
On Unraid, the container "autostart" toggle and Docker restart behavior are separate concerns.
Autostartmeans Unraid starts the container when the array or Docker service starts.- It does not guarantee the container will be relaunched after the app process exits.
- For crash recovery, set the container restart policy to
unless-stopped.
If MakerWorks still stops instead of staying up, the container is usually exiting during startup rather than failing a health check. This image does not define a Docker HEALTHCHECK; the main process exits only when a startup command fails.
Current startup chain inside the container:
node scripts/start-production.js
On Unraid, the primary MakerWorks container sets START_PROCESSING_WORKER=1 by default. That starts image and preview processing inside the same container as the web app, so uploaded cover images use the same DATABASE_URL, STORAGE_DIR, and storage mount as MakerWorks itself. Do not create or tune a separate worker container for normal Unraid installs.
Most common reasons the container exits on Unraid:
- PostgreSQL is not reachable from
DATABASE_URL npx prisma migrate deployfails against the target databaseADMIN_PASSWORDis weak/invalid in production andbootstrap-admin.jsrefuses to continue- a pending restore manifest exists but
psqlor the referenced backup is missing
Useful checks from inside the MakerWorks container:
printenv DATABASE_URL | sed 's#://.*:.*@#://***:***@#'
which psql
which pg_dump
node scripts/restore.js
npx prisma migrate deploy
node scripts/bootstrap-admin.js
curl -fsS http://127.0.0.1:3000/api/health
If the container is stopping, inspect its last logs in Unraid first. A restart policy will only help if Docker is configured to restart the container after a non-zero exit.
Required container mappings
- Map your storage share to
/app/storage(example host path:/mnt/user/makerworks/storage) - Optional dedicated backup mapping:
- Container path:
/app/backups - Host path:
/mnt/user/makerworks/storage/backups
- Container path:
Required backup env vars
SKIP_DOCKER=1PG_DUMP_BIN=/usr/bin/pg_dumpPSQL_BIN=/usr/bin/psqlBACKUP_DIR=/app/backups(if you created the dedicated/app/backupsmapping)
If BACKUP_DIR is not set, backups default to STORAGE_DIR/backups (usually /app/storage/backups).
Verify backup tooling in the app container
Run inside the MakerWorks container:
which pg_dump
pg_dump --version
echo "$SKIP_DOCKER $PG_DUMP_BIN $PSQL_BIN $BACKUP_DIR"
Expected:
which pg_dumpreturns/usr/bin/pg_dumppg_dump --versionprints PostgreSQL versionSKIP_DOCKERis1
Run and verify a backup
npm run backup
ls -lah "${BACKUP_DIR:-$STORAGE_DIR/backups}"
find "${BACKUP_DIR:-$STORAGE_DIR/backups}" -maxdepth 2 -type f -name "db.sql"
Expected:
- backup logs include
Running pg_dumpandBackup stored at ... find ... db.sqlreturns at least one file path
Note: ls -lah on the backup root may show total 0 even when backups are valid, because files are inside timestamped subfolders. Use the find command above to confirm db.sql exists.
Common failure causes
pg_dump executable was not found:PG_DUMP_BINis wrong or not present in container.- fix by using
/usr/bin/pg_dumpand redeploying the container.
- backup folder created but empty:
- backup failed before dump completed; check
npm run backuplogs. - verify DB host in
DATABASE_URLis reachable from the MakerWorks container.
- backup failed before dump completed; check
Bulk Model Import
For self-hosted/operator use, you can bulk upload a mapped folder of model files through the normal upload API.
Supported file types:
.stl.obj.3mf.zip
Run it with explicit args:
npm run bulk:upload-models -- --dir /app/imports/models --base-url http://127.0.0.1:3000 --email admin@example.com --password your-password
Docker Compose usage
The compose file now includes:
- a
./imports:/app/importsvolume on thewebcontainer BULK_UPLOAD_DIR=/app/importsBULK_UPLOAD_BASE_URL=http://127.0.0.1:3000
Run inside the web container:
docker compose exec web npm run bulk:upload-models -- --dir /app/imports --email admin@example.com --password your-password
Unraid usage
Recommended Unraid setup:
- Map a host folder to
/app/imports - Set
BULK_UPLOAD_DIR=/app/imports - Leave
BULK_UPLOAD_BASE_URL=http://127.0.0.1:3000
Then run inside the web container:
npm run bulk:upload-models -- --dir /app/imports --email admin@example.com --password your-password
Notes for Unraid:
- Use the container path, not the host path, when passing
--dir http://127.0.0.1:3000is the right target when running the script inside the MakerWorks container- The Unraid template now includes an optional
/app/importspath mapping for this script
Useful options:
--material PLA--tags "batch-import,archive"--description "Imported from mapped folder"--limit 25--dry-run--no-cover-match
Behavior:
- Recursively scans the target folder.
- Uploads each supported model file as its own model.
- If a same-basename image exists beside a model, it will be used as the cover automatically.
- examples:
part01.stl+part01.jpg,part01-cover.png
- examples:
- Uses env fallbacks from
.env.exampleunder theBULK_UPLOAD_*names.
Operational Commands
npm run dev
npm run build
npm run lint
npm run typecheck
npm test
npm run prisma:deploy
npm run backup
npm run backup:scheduler
backup:scheduler is intended to run as a separate long-lived process/container and uses UTC schedule + retention env vars from .env.
Order Receipt PDFs
MakerWorks generates plain-English transaction PDFs for customer orders under STORAGE_DIR/orders/{orderId}/receipts/.
Customers can download receipts from /api/customer/orders/{orderId}/receipt.
Admins and staff can download or regenerate receipts from /api/admin/orders/{orderId}/receipt.
Receipt generation runs best-effort during checkout, admin order creation, and payment sync; download routes regenerate the PDF on demand.
Architecture
- Frontend/API: Next.js App Router + React + TypeScript
- Data: PostgreSQL + Prisma
- Storage: local filesystem (
STORAGE_DIR) with optional external file base URL - Queue/processing support: BullMQ + Redis-compatible backend (when configured)
License
MIT (LICENSE)
Support
Issues: https://github.com/schartrand77/mkw2/issues
Documentation
- User Manual:
docs/user-manual.md - Wiki Index:
docs/wiki/README.md - Wiki Home:
docs/wiki/Home.md
Install MakerWorks-v2 on Unraid in a few clicks.
Find MakerWorks-v2 in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/schartrand77/mkw2:latestRuntime arguments
- Web UI
http://[IP]:[PORT:3000]/- Network
makerworks-net- Shell
bash- Privileged
- false
Template configuration
Port the MakerWorks Next.js server listens on
- Target
- 3000
- Default
- 3000
- Value
- 3000
Persistent directory for uploaded models, covers, and avatars
- Target
- /app/storage
- Default
- /mnt/user/makerworks/storage
- Value
- /mnt/user/makerworks/storage
Persistent backup destination (set BACKUP_DIR to this container path)
- Target
- /app/backups
- Default
- /mnt/user/makerworks/storage/backups
- Value
- /mnt/user/makerworks/storage/backups
Optional mapped folder used by the bulk upload script. Put source STL/OBJ/3MF/AMF/PLY/WRL/VRML/GLB/GLTF/USD/USDZ/USDA/USDC/ZIP files here and run the importer against /app/imports.
- Target
- /app/imports
- Default
- /mnt/user/makerworks/imports
- Value
- /mnt/user/makerworks/imports
Postgres connection string (must be reachable from the container)
- Default
- postgresql://postgres:postgres@postgres:5432/makerworks?schema=public
- Value
- postgresql://postgres:postgres@postgres:5432/makerworks?schema=public
Redis connection string used for BullMQ processing queues
- Default
- redis://makerworks-redis:6379
- Value
- redis://makerworks-redis:6379
Public URL users access (used for redirects/cookies)
- Default
- https://makerworks.example.com
- Value
- https://makerworks.example.com
Secret used to sign user sessions (set to a long random string)
Email for the bootstrap administrator account
- Default
- admin@example.com
- Value
- admin@example.com
Password for the bootstrap administrator (rotated on change)
Display name for the bootstrap administrator account
- Default
- Admin
- Value
- Admin
Internal storage path (leave at /app/storage unless customizing)
- Default
- /app/storage
- Value
- /app/storage
Optional direct hostname (e.g., https://upload.example.com) used only for uploads to bypass Cloudflare/Tunnel size limits
Default in-container folder scanned by the bulk upload importer
- Default
- /app/imports
- Value
- /app/imports
URL used by the bulk upload importer when run inside the container. Leave at http://127.0.0.1:3000 for Unraid.
- Default
- http://127.0.0.1:3000
- Value
- http://127.0.0.1:3000
Optional S3 bucket (leave blank to store uploads locally on STORAGE_DIR)
Region/endpoint for the S3 bucket (e.g., us-east-1)
Access key for the configured S3-compatible storage
Secret key for the configured S3-compatible storage
Set to true when BASE_URL is HTTPS so auth cookies are secure
- Default
- true
- Value
- true
Set to 1 on Unraid/non-compose runtimes so backups/restores use local client tools instead of docker compose exec
- Default
- 1
- Value
- 1
Backup destination inside the container. Must point to a mapped path (recommended: /app/backups).
- Default
- /app/backups
- Value
- /app/backups
Path to pg_dump binary used by backup when SKIP_DOCKER=1 (or docker compose path fails)
- Default
- /usr/bin/pg_dump
- Value
- /usr/bin/pg_dump
Path to psql binary used by restore when SKIP_DOCKER=1 (or docker compose path fails)
- Default
- /usr/bin/psql
- Value
- /usr/bin/psql
Docker Compose DB service name used for pg_dump/psql when compose mode is enabled
- Default
- db
- Value
- db
Enable daily scheduled backups (1=true, 0=false)
- Default
- 1
- Value
- 1
Daily backup time in UTC (HH:mm)
- Default
- 03:00
- Value
- 03:00
Run one backup when scheduler starts (1=true, 0=false)
- Default
- 0
- Value
- 0
Prune old backups immediately after each successful backup
- Default
- 1
- Value
- 1
Keep backups newer than this many days (0 disables age-based retention)
- Default
- 14
- Value
- 14
Always keep at least this many newest backups (0 disables count-based retention)
- Default
- 30
- Value
- 30
Queue retry attempts before moving a failed job to dead-letter handling
- Default
- 5
- Value
- 5
Exponential backoff delay (ms) between queue retries
- Default
- 5000
- Value
- 5000
Run the image/preview processor inside this MakerWorks container so it uses the same DATABASE_URL and STORAGE_DIR settings
- Default
- 1
- Value
- 1
Concurrency for image processing inside this container
- Default
- 2
- Value
- 2
Concurrency for preview processing inside this container
- Default
- 1
- Value
- 1
Printer preset for speed/energy math (BAMBU_X1C, BAMBU_P1S, PRUSA_MK4, PRUSA_MK3S, CREALITY_K1_MAX, CREALITY_ENDER3_V2, ANYCUBIC_KOBRA2, GENERIC_FDM)
- Default
- BAMBU_X1C
- Value
- BAMBU_X1C
Electricity rate (per kWh) used for energy estimates
- Default
- 0.14
- Value
- 0.14
Price of a 1kg PLA spool (USD) used for estimator
- Default
- 25.00
- Value
- 25.00
Price of a 1kg PETG spool (USD) used for estimator
- Default
- 28.00
- Value
- 28.00
Expose PLA per-kg cost to the client (used for cart price previews)
- Default
- 25.00
- Value
- 25.00
Expose PETG per-kg cost to the client
- Default
- 28.00
- Value
- 28.00
Extra cost rate per additional color beyond the first (server-side)
- Default
- 0.05
- Value
- 0.05
Expose the color surcharge rate to the client UI
- Default
- 0.05
- Value
- 0.05
How many color slots the cart exposes (raise to 8+ if you have multiple AMS units)
- Default
- 4
- Value
- 4
Back-end currency (USD or CAD)
- Default
- USD
- Value
- USD
Client-facing currency label (must match CURRENCY)
- Default
- USD
- Value
- USD
Optional CAD override for PLA per-kg cost
Optional CAD override for PETG per-kg cost
Optional CAD override for energy rate per hour
Optional CAD minimum price override
Extra hourly surcharge after first hour (USD context)
Extra hourly surcharge after first hour (CAD context)
Stripe secret key (starts with sk_live_ or sk_test_)
Stripe publishable key used by the in-app checkout UI
Stripe webhook signing secret for /api/stripe/webhook
Stripe shipping rate ID required when shipped checkout is enabled
Days until due for Stripe invoices sent from invoice checkout
- Default
- 14
- Value
- 14
Set to 1 after Stripe Tax registrations and product tax settings are configured
- Default
- 0
- Value
- 0
Internal PrintLab URL reachable from the MakerWorks container on the shared Docker network
- Default
- http://PrintLab:8080
- Value
- http://PrintLab:8080
Optional Authorization header for MakerWorks-to-PrintLab admin API calls, for example a Basic or Bearer value
Optional PrintLab session cookie for MakerWorks-to-PrintLab admin API calls
Optional PrintLab API key for MakerWorks-to-PrintLab API calls when PrintLab is configured to accept one
Header name used with PRINTLAB_API_KEY
- Default
- X-API-Key
- Value
- X-API-Key
Shared secret MakerWorks expects for inbound job updates to /api/makerworks/jobs (send via Authorization Bearer token or MakerWorks signature header)
Shared secret expected on PrintLab callbacks into MakerWorks
Internal StockWorks URL reachable from the MakerWorks container on the shared Docker network
- Default
- http://StockWorks:8000
- Value
- http://StockWorks:8000
Optional StockWorks admin username for MakerWorks-to-StockWorks inventory checks
Optional StockWorks admin password for MakerWorks-to-StockWorks inventory checks
Optional StockWorks username fallback
Optional StockWorks password fallback
Optional JSON color override map for StockWorks filament availability
Optional seasonal theme: christmas, halloween, easter, valentines, or maythefourth
Contact email shown on the site
- Default
- info@makerworks.app
- Value
- info@makerworks.app
Display name shown across the storefront and emails
- Default
- MakerWorks
- Value
- MakerWorks
Optional suffix shown next to the logo (leave blank to hide)
- Default
- v2
- Value
- v2
Label used for the pickup location in checkout copy
- Default
- MakerWorks lab
- Value
- MakerWorks lab
Default handle placeholder for social profile fields
- Default
- @makerworks
- Value
- @makerworks
SMTP host for verification emails
SMTP port
SMTP username
SMTP password
Use TLS/SSL (true/false) depending on your SMTP provider
From address for verification/receipt emails
- Default
- MakerWorks Receipts <receipts@makerworks.app>
- Value
- MakerWorks Receipts <receipts@makerworks.app>
Reply-to address for outgoing emails
- Default
- MakerWorks <info@makerworks.app>
- Value
- MakerWorks <info@makerworks.app>
Optional bot token used for Discord announcements
Discord channel ID used for announcements
Bot token used for admin notifications (falls back to DISCORD_BOT_TOKEN when unset)
Discord channel ID for admin-only alerts (new users/uploads)