Skip to content

Latest commit

 

History

History
180 lines (138 loc) · 7.93 KB

File metadata and controls

180 lines (138 loc) · 7.93 KB

Deploying stlToSolid on a NAS — step by step

Runs the web app as one Docker container on a home NAS, reachable from any browser on your LAN (and optionally over Tailscale). Written for a small x86_64 NAS running Docker; the steps are the same on any consumer NAS or Linux box, and only the notes at the end are vendor-specific.

Placeholders used throughout:

Placeholder Meaning Example
<your-nas> the NAS hostname or LAN IP nas.local, 192.0.2.10
<share-path> the shared folder you deploy into /volume1/apps
<port> the LAN port the app listens on 8321

Step 1 — Check the hardware

  • x86_64 CPU — the tested platform. Current pymeshlab and cadquery-ocp releases do publish Linux aarch64 wheels, so an ARM NAS is no longer ruled out by packaging alone — but nothing in this stack has been verified on ARM Linux, and the Poisson step has already proven platform-sensitive (it crashes on macOS arm64). Treat ARM as untested, not supported.
  • RAM — 8 GB minimum, 16 GB comfortable. A 2-million-triangle scan peaks at several GB during Poisson repair.

Step 2 — Prepare the NAS (one-time)

On a vendor NAS (menu names vary by firmware; these are typical):

  1. App Center → install Docker (packaged as "DockerEngine" on some firmwares). Confirm over SSH: docker compose version.
  2. App Center → install Git (optional — the deploy script falls back to a throw-away alpine/git container if there is no git binary).
  3. Control Panel → Shared Folders → create a plain share for apps (no encryption needed; the app stores only uploaded meshes and generated STEP files, purged after 24 h). Its path is your <share-path>.
  4. Enable SSH (Control Panel → Terminal & SNMP) and log in as an admin user.

On any other NAS: install Docker (with Compose v2), create a folder, enable SSH.

Step 3 — Clone the repository

cd <share-path>
git clone https://github.com/Crypto69/stlToSolid.git
cd stlToSolid
chmod -R a+rX .       # some NAS shares strip file modes on checkout; harmless elsewhere
mkdir -p data         # job storage, bind-mounted to /data inside the container

Step 4 — Build the image

docker compose build

Builds natively on the NAS (a few minutes on a NAS CPU; it downloads the ~2 GB CAD stack the first time). Do not copy an image built on an Apple-silicon Mac unless you built it with --platform linux/amd64.

If the build fails with a download timeout in pip or apt-get, just run it again — it is a mirror hiccup, not a code problem (pip is set to 300 s / 10 retries; pymeshlab alone is a 106 MB wheel).

Step 5 — Start it

docker compose up -d
docker compose ps                          # state: running
curl -s http://127.0.0.1:<port>/ | head    # serves the UI's index.html

Open http://<your-nas>:<port> in a browser, drop an STL, press Convert. The report card with green PASS gates is the acceptance test. The badge top-right shows version · commit · build time (also at /api/version).

Step 6 — Update to a new version

cd <share-path>/stlToSolid
./deploy.sh            # pulls main, fixes share file modes, builds, restarts
./deploy.sh --no-pull  # rebuild what is checked out, without pulling

A restart kills in-flight conversions; re-run them from the browser.

If the project's git history was ever rewritten upstream (force-push), a plain pull refuses. Reset once, then deploy as usual:

git fetch origin && git reset --hard origin/main && ./deploy.sh

Step 7 — Tune it (optional)

All settings live in docker-compose.yml; edit, then docker compose up -d.

Setting Default Meaning
ports 8321:8000 LAN port (change the left side)
STLTOSOLID_JOB_TTL 86400 seconds before job directories are deleted
STLTOSOLID_CONCURRENCY 1 parallel conversions; keep 1 unless RAM is plentiful
STLTOSOLID_MAX_UPLOAD 200 MB maximum upload size
STLTOSOLID_WORKERS 2 shells (bodies and cavities) converted at once inside one job; each worker holds a few hundred MB
STLTOSOLID_SHELL_TIMEOUT 900 seconds a shell may run in a worker before it is built faceted instead; 0 means no limit
STLTOSOLID_AXIS_BUDGET 120 seconds one shell's extrusion-axis search may take before the best candidate so far is used; 0 means no limit
mem_limit 12g container memory cap; lower it if other services suffer

data/ is disposable: rm -rf data/* with the container stopped is always safe. There is no database and nothing to back up.

Step 8 — HTTPS over Tailscale (optional)

If the NAS is on your tailnet, Tailscale can front the app with HTTPS without opening anything to the internet:

tailscale serve --bg --https=8443 http://127.0.0.1:<port>
tailscale serve status

The app is then at https://<your-nas>.<your-tailnet>.ts.net:8443 — run tailscale status to see your own tailnet name. Use a port nothing else is serving (tailscale serve status lists the entries). The app has no login: anyone on your LAN or tailnet can use it, which is the intended scope.

Step 9 — Run the test suite on the NAS (optional)

tests/ and samples/ are not baked into the image. Mount them from the checkout (copy your sample meshes into samples/ first):

docker compose run --rm \
  -v "$PWD/tests:/app/tests:ro" -v "$PWD/samples:/app/samples:ro" \
  stltosolid sh -c 'pip install -q pytest httpx && python -m pytest -q -m "not slow"'
# use `-m slow` instead for the scan end-to-ends (takes minutes)

This is also where the scan path gets proven: Poisson repair does not work on macOS arm64, so a large scan converting to a valid solid here is the platform acceptance test.

After a reboot

restart: unless-stopped brings the container back by itself. Check docker compose ps; if you use the Tailscale front, run tailscale serve status and repeat the serve command if its entry is gone.

Vendor NAS notes

These apply to several vendor firmwares; check the equivalents on yours.

  • Docker CLI may be off the default PATH — it often lives under the Docker app's own bin directory. Find it with find / -name docker -type f 2>/dev/null | head and add that directory to PATH in your shell rc. If the daemon is down, start the Docker app in the admin UI and the containers come back.
  • git may be an alias, not a binary that scripts can call, and may also live under an app directory. deploy.sh copes: it reads .git/HEAD itself and pulls through an alpine/git container when needed.
  • Share ACLs strip file modes on clone/pull: run chmod -R a+rX . in the repo directory afterwards (deploy.sh does this for you).
  • SSH auto-block: a burst of SSH connections can blacklist your client IP (ping works, SSH times out). Unblock under the vendor security panel, or connect from your other address (LAN vs tailnet).

Troubleshooting

Symptom Fix
Build fails in apt-get / pip with a timeout Mirror hiccup — rerun ./deploy.sh.
Upload rejected with 413 File exceeds STLTOSOLID_MAX_UPLOAD — raise it in compose environment.
Button stuck on "Waiting in queue…" A previous conversion is still running (they are serialised). Scans take minutes on a small CPU — docker compose logs -f.
Conversion dies with no result, container fine The worker was OOM-killed under mem_limit — raise the limit or convert a decimated mesh.
Errors mentioning pymeshlab / Qt on scan uploads The image installs libgl1 libglu1-mesa libxrender1 libxext6 libsm6 libx11-6 fontconfig libcom-err2 libp11-kit0 libgpg-error0; docker compose exec stltosolid python -c "import pymeshlab" should print nothing. Rebuild with --no-cache if not.
UI loads but every API call 404s Stale image — docker compose build --no-cache.
Port already in use Change the left side of ports: in compose (and the tailscale serve target).