mirror of
https://github.com/TautvydasDerzinskas/Thingport.git
synced 2026-10-21 22:22:24 -05:00
349 lines
19 KiB
Markdown
349 lines
19 KiB
Markdown
<div align="center">
|
|
|
|
<picture>
|
|
<source media="(prefers-color-scheme: dark)" srcset="frontend/src/assets/logos/thingport-lockup-compact-on-dark.svg">
|
|
<img src="frontend/src/assets/logos/thingport-lockup-compact-color.svg" alt="Thingport" width="320">
|
|
</picture>
|
|
|
|
<h3>Your personal 3D model library.</h3>
|
|
|
|
<p>
|
|
Collect, organize, preview, and manage your 3D printing models<br>
|
|
from the places where you discover them.
|
|
</p>
|
|
|
|
<p>
|
|
<a href="https://thingport.net/"><b>Website</b></a> ·
|
|
<a href="https://thingport.net/docs/">Docs</a> ·
|
|
<a href="https://thingport.net/features/">Features</a> ·
|
|
<a href="https://thingport.net/blog/">Blog</a>
|
|
</p>
|
|
|
|
<p>
|
|
<a href="https://thingport.net/"><img src="https://github.com/TautvydasDerzinskas/Thingport/actions/workflows/web-pages.yml/badge.svg" alt="Website build"></a>
|
|
<img src="https://github.com/TautvydasDerzinskas/Thingport/actions/workflows/frontend-image.yml/badge.svg" alt="Frontend">
|
|
<img src="https://github.com/TautvydasDerzinskas/Thingport/actions/workflows/backend-image.yml/badge.svg" alt="Backend">
|
|
<img src="https://github.com/TautvydasDerzinskas/Thingport/actions/workflows/bridge-release.yml/badge.svg" alt="Slicer Bridge">
|
|
<img src="https://github.com/TautvydasDerzinskas/Thingport/actions/workflows/extension-release.yml/badge.svg" alt="Thingport Grab">
|
|
</p>
|
|
|
|
</div>
|
|
|
|
## About
|
|
|
|
To put it simply, if you're into 3D printing, you probably look for models across multiple platforms, with **MakerWorld, Printables, Thingiverse, and MyMiniFactory** being some of the most popular ones. And, if you're anything like me, you've probably built up quite a collection of bookmarked models across these sites.
|
|
|
|
But there's a problem.
|
|
|
|
Sometimes, authors remove their models, and when you come back looking for something you bookmarked months ago, it's simply gone. Other times, authors update their models, and you discover that you actually preferred the older version.
|
|
|
|
And sometimes... the internet goes down. 🙃
|
|
|
|
Wouldn't it be nice to have your entire collection available locally, even when you're offline?
|
|
|
|
That's exactly what **Thingport** is here to solve.
|
|
|
|
**Thingport is a self-hosted 3D model library designed to make importing and syncing models between your own library and external providers as seamless as possible.**
|
|
|
|
You can sync collections from supported providers directly to your Thingport instance. And with collection syncing enabled, new models you bookmark on external sites can be automatically imported into your personal library.
|
|
|
|
No more worrying about losing access to your favourite models. Your library stays yours.
|
|
|
|
## Screenshots
|
|
|
|
<table>
|
|
<tr>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/01_dashboard.png" target="_blank"><img src="frontend/src/assets/screenshots/01_dashboard.png" width="100%" alt="Dashboard"></a><br><sub><b>Dashboard</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/02_models.png" target="_blank"><img src="frontend/src/assets/screenshots/02_models.png" width="100%" alt="Models"></a><br><sub><b>Models</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/03_model_details.png" target="_blank"><img src="frontend/src/assets/screenshots/03_model_details.png" width="100%" alt="Model details"></a><br><sub><b>Model Details</b></sub></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/04_model_details_3d_preview.png" target="_blank"><img src="frontend/src/assets/screenshots/04_model_details_3d_preview.png" width="100%" alt="3D preview"></a><br><sub><b>3D Preview</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/05_collections.png" target="_blank"><img src="frontend/src/assets/screenshots/05_collections.png" width="100%" alt="Collections"></a><br><sub><b>Collections</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/12_collection_sync.png" target="_blank"><img src="frontend/src/assets/screenshots/12_collection_sync.png" width="100%" alt="A synced collection's sync configuration"></a><br><sub><b>Synced Collection</b></sub></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/06_tags.png" target="_blank"><img src="frontend/src/assets/screenshots/06_tags.png" width="100%" alt="Tags"></a><br><sub><b>Tags</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/07_downloads.png" target="_blank"><img src="frontend/src/assets/screenshots/07_downloads.png" width="100%" alt="Downloads"></a><br><sub><b>Downloads</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/08_my_models.png" target="_blank"><img src="frontend/src/assets/screenshots/08_my_models.png" width="100%" alt="My models"></a><br><sub><b>My Models</b></sub></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/09_dark_theme.png" target="_blank"><img src="frontend/src/assets/screenshots/09_dark_theme.png" width="100%" alt="Dark theme"></a><br><sub><b>Dark Theme</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/10_profile.png" target="_blank"><img src="frontend/src/assets/screenshots/10_profile.png" width="100%" alt="Profile with activity heatmap"></a><br><sub><b>Profile & Activity</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/11_configuration_providers.png" target="_blank"><img src="frontend/src/assets/screenshots/11_configuration_providers.png" width="100%" alt="Configuration, Providers section"></a><br><sub><b>Configuration — Providers</b></sub></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/22_ai_suggestions.png" target="_blank"><img src="frontend/src/assets/screenshots/22_ai_suggestions.png" width="100%" alt="AI category suggestions to accept or reject"></a><br><sub><b>AI Categorization</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/23_ai_description_compare.png" target="_blank"><img src="frontend/src/assets/screenshots/23_ai_description_compare.png" width="100%" alt="An AI-improved description next to the original"></a><br><sub><b>Improved Descriptions</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/25_sign_in_sso.png" target="_blank"><img src="frontend/src/assets/screenshots/25_sign_in_sso.png" width="100%" alt="Sign-in page with a single sign-on button"></a><br><sub><b>Single Sign-On</b></sub></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/13_admin_overview.png" target="_blank"><img src="frontend/src/assets/screenshots/13_admin_overview.png" width="100%" alt="Administration overview with System Health"></a><br><sub><b>Administration</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/14_admin_providers.png" target="_blank"><img src="frontend/src/assets/screenshots/14_admin_providers.png" width="100%" alt="Administration, Providers page with on/off switches"></a><br><sub><b>Administration — Providers</b></sub></td>
|
|
<td width="33%"><a href="frontend/src/assets/screenshots/17_admin_ai.png" target="_blank"><img src="frontend/src/assets/screenshots/17_admin_ai.png" width="100%" alt="Administration, AI page with models and features"></a><br><sub><b>Administration — AI</b></sub></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="33%"><a href="extension/docs/screenshots/collection-printables.jpg" target="_blank"><img src="extension/docs/screenshots/collection-printables.jpg" width="100%" alt="Thingport Grab importing a Printables collection"></a><br><sub><b>Thingport Grab — Collections</b></sub></td>
|
|
<td width="33%"><a href="extension/docs/screenshots/panel-printables.jpg" target="_blank"><img src="extension/docs/screenshots/panel-printables.jpg" width="100%" alt="Thingport Grab on Printables"></a><br><sub><b>Thingport Grab — Printables</b></sub></td>
|
|
<td width="33%"><a href="extension/docs/screenshots/panel-thingiverse.jpg" target="_blank"><img src="extension/docs/screenshots/panel-thingiverse.jpg" width="100%" alt="Thingport Grab on Thingiverse"></a><br><sub><b>Thingport Grab — Thingiverse</b></sub></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="33%"><a href="extension/docs/screenshots/panel-makerworld.jpg" target="_blank"><img src="extension/docs/screenshots/panel-makerworld.jpg" width="100%" alt="Thingport Grab on MakerWorld"></a><br><sub><b>Thingport Grab — MakerWorld</b></sub></td>
|
|
<td width="33%"><a href="extension/docs/screenshots/collection-makerworld.jpg" target="_blank"><img src="extension/docs/screenshots/collection-makerworld.jpg" width="100%" alt="Thingport Grab syncing a MakerWorld collection"></a><br><sub><b>Thingport Grab — Sync a Collection</b></sub></td>
|
|
<td width="33%"><a href="extension/docs/screenshots/panel-myminifactory.jpg" target="_blank"><img src="extension/docs/screenshots/panel-myminifactory.jpg" width="100%" alt="Thingport Grab on MyMiniFactory"></a><br><sub><b>Thingport Grab — MyMiniFactory</b></sub></td>
|
|
</tr>
|
|
</table>
|
|
|
|
## Installation
|
|
|
|
> Step-by-step guides for Docker Compose, Unraid, TrueNAS SCALE and CasaOS are also on the
|
|
> **[Thingport website](https://thingport.net/docs/)**.
|
|
|
|
### Docker Compose
|
|
|
|
Runs entirely from the pre-built images on GHCR -- no local build, no git clone needed. Works on any Docker host, including a NAS (Synology, QNAP, Unraid, etc).
|
|
|
|
> **Unraid users:** see [docs/install/unraid/README.md](docs/install/unraid/README.md) for an Unraid-flavored compose
|
|
> file (appdata paths, Docker tab icons/WebUI) and Compose plugin setup steps.
|
|
>
|
|
> **TrueNAS SCALE users:** see [docs/install/truenas/README.md](docs/install/truenas/README.md) for a TrueNAS-flavored
|
|
> compose file (dataset-backed appdata paths) and both the Custom App (YAML) and SSH setup
|
|
> steps.
|
|
>
|
|
> **CasaOS users:** see [docs/install/casaos/README.md](docs/install/casaos/README.md) for a CasaOS-flavored compose
|
|
> file (`/DATA/AppData` appdata paths) and both the customized-app and SSH setup steps.
|
|
|
|
Create a folder for Thingport and add these two files to it:
|
|
|
|
<details>
|
|
<summary><code>docker-compose.yml</code></summary>
|
|
|
|
```yaml
|
|
services:
|
|
db:
|
|
image: postgres:16-alpine
|
|
restart: unless-stopped
|
|
environment:
|
|
- POSTGRES_USER=${POSTGRES_USER:-thingport}
|
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-thingport}
|
|
- POSTGRES_DB=${POSTGRES_DB:-thingport}
|
|
volumes:
|
|
- thingport_db:/var/lib/postgresql/data
|
|
networks:
|
|
- app-net
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-thingport}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
flaresolverr:
|
|
image: ghcr.io/flaresolverr/flaresolverr:latest
|
|
restart: unless-stopped
|
|
environment:
|
|
- LOG_LEVEL=${FLARESOLVERR_LOG_LEVEL:-info}
|
|
- TZ=${TZ:-UTC}
|
|
networks:
|
|
- app-net
|
|
|
|
backend:
|
|
image: ghcr.io/tautvydasderzinskas/thingport-backend:latest
|
|
restart: unless-stopped
|
|
environment:
|
|
- PUID=${PUID:-1000}
|
|
- PGID=${PGID:-1000}
|
|
- AUTH_SECRET=${AUTH_SECRET:-changeme-secret}
|
|
- AUTH_TOKEN_TTL=${AUTH_TOKEN_TTL:-43200}
|
|
- PUBLIC_URL=${PUBLIC_URL:-}
|
|
- SMTP_HOST=${SMTP_HOST:-}
|
|
- SMTP_PORT=${SMTP_PORT:-587}
|
|
- SMTP_SECURE=${SMTP_SECURE:-false}
|
|
- SMTP_USER=${SMTP_USER:-}
|
|
- SMTP_PASS=${SMTP_PASS:-}
|
|
- SMTP_FROM=${SMTP_FROM:-Thingport <no-reply@localhost>}
|
|
- FILE_STORAGE=/app/storage
|
|
- DATABASE_URL=postgresql://${POSTGRES_USER:-thingport}:${POSTGRES_PASSWORD:-thingport}@db:5432/${POSTGRES_DB:-thingport}?schema=public
|
|
- CORS_ORIGINS=${CORS_ORIGINS:-}
|
|
- FLARESOLVERR_URL=${FLARESOLVERR_URL:-http://flaresolverr:8191/v1}
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
flaresolverr:
|
|
condition: service_started
|
|
volumes:
|
|
- thingport_storage:/app/storage
|
|
# Optional consume folder: files and folders dropped in it are imported automatically
|
|
# (Administration -> Storage -> Consume Folder). Uncomment and point it at a host folder.
|
|
# - /path/to/consume:/app/consume
|
|
networks:
|
|
- app-net
|
|
|
|
frontend:
|
|
image: ghcr.io/tautvydasderzinskas/thingport-frontend:latest
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${WEB_PORT:-80}:80"
|
|
depends_on:
|
|
- backend
|
|
networks:
|
|
- app-net
|
|
|
|
volumes:
|
|
thingport_storage:
|
|
thingport_db:
|
|
|
|
networks:
|
|
app-net:
|
|
driver: bridge
|
|
```
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><code>.env</code></summary>
|
|
|
|
```env
|
|
# Required
|
|
# AUTH_SECRET signs login tokens -- use your own random value
|
|
AUTH_SECRET=b1193c7014e833a063f750d6e4644d615e90e6ee81dbde619e1818e9675a3374
|
|
POSTGRES_PASSWORD=change-this-password
|
|
|
|
# Optional (defaults shown)
|
|
PUID=1000
|
|
PGID=1000
|
|
WEB_PORT=80
|
|
POSTGRES_USER=thingport
|
|
POSTGRES_DB=thingport
|
|
# e.g. https://thingport.example.com -- needed for links in emails and for single sign-on (OIDC).
|
|
# Read on the first run only; after that it's managed in Administration -> Auth.
|
|
PUBLIC_URL=
|
|
# login token lifetime, in seconds
|
|
AUTH_TOKEN_TTL=43200
|
|
SMTP_HOST=
|
|
SMTP_PORT=587
|
|
SMTP_SECURE=false
|
|
SMTP_USER=
|
|
SMTP_PASS=
|
|
SMTP_FROM=Thingport <no-reply@localhost>
|
|
# first-run default only; once Thingport has started, change it in Administration -> Connections -> FlareSolverr
|
|
FLARESOLVERR_URL=http://flaresolverr:8191/v1
|
|
TZ=UTC
|
|
```
|
|
|
|
</details>
|
|
|
|
Then start it:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
Thingport will be available at `http://<host>:<WEB_PORT>` (default port 80). The first
|
|
account you register becomes the admin account.
|
|
|
|
Then open **Administration → Overview → System Health** and click **Run full test**. Ideally everything is green:
|
|
anything marked **Required** or **Recommended** that isn't means Thingport, or part of it, won't work properly until
|
|
it's fixed, and each problem says how. It's also the first place to look whenever something stops working. See
|
|
[System Health](docs/guides/system-health.md).
|
|
|
|
> **Just want to try it?** On Linux or macOS, one command creates a `thingport` folder with the same two files,
|
|
> generates the secrets in `.env` and starts Thingport on port 80:
|
|
>
|
|
> ```bash
|
|
> curl -fsSL https://thingport.net/install.sh | sh
|
|
> ```
|
|
>
|
|
> Edit `.env` there and run `docker compose up -d` again to change settings. Pick the folder and port up front with
|
|
> `curl -fsSL https://thingport.net/install.sh | WEB_PORT=8080 sh -s -- ~/thingport`. The script is
|
|
> [install.sh](install.sh) in this repo.
|
|
|
|
<details>
|
|
<summary>Building from source instead</summary>
|
|
|
|
```bash
|
|
git clone https://github.com/TautvydasDerzinskas/Thingport.git
|
|
cd Thingport
|
|
cp .env.example .env
|
|
docker compose up -d
|
|
```
|
|
|
|
This builds the images locally rather than pulling from GHCR.
|
|
|
|
</details>
|
|
|
|
### Consume folder
|
|
|
|
To have Thingport import whatever you drop into a folder on the server, uncomment the consume volume in
|
|
`docker-compose.yml`. See the [consume folder guide](docs/guides/consume-folder.md).
|
|
|
|
## Features
|
|
|
|
- **[Import from MakerWorld, Printables, Thingiverse, MyMiniFactory, Snapmaker Space, MakerOnline, Creality Cloud, NexPrint, Thangs and Cults3D](docs/features/importing.md)**
|
|
- **[Import bookmarklet](docs/guides/bookmarklet.md)**
|
|
- **[Synced collections](docs/guides/synced-collections.md)**
|
|
- **[Bring your existing library](docs/guides/existing-library.md)**
|
|
- **[Consume folder](docs/guides/consume-folder.md)**
|
|
- **[3D previews](docs/features/3d-previews.md)**
|
|
- **[AI categorization and descriptions](docs/guides/ai.md)**
|
|
- **[Organize and search](docs/features/organize-and-search.md)**
|
|
- **[Dashboard](docs/features/dashboard.md)**
|
|
- **[Profile and activity](docs/features/profile-and-activity.md)**
|
|
- **[Author pages](docs/features/authors.md)**
|
|
- **[Open in your slicer](docs/features/slicers.md)**
|
|
- **[Normalized MakerWorld 3MFs](docs/features/normalized-3mf.md)**
|
|
- **[Everything to print it](docs/features/supporting-files.md)**
|
|
- **[Download as ZIP](docs/features/downloads.md)**
|
|
- **[Plain files on your disk](docs/features/storage.md)**
|
|
- **[Multi-user](docs/features/multi-user.md)**
|
|
- **[Single sign-on](docs/guides/single-sign-on.md)**
|
|
- **[Administration](docs/features/administration.md)**
|
|
- **[System Health](docs/guides/system-health.md)**
|
|
- **[API token](docs/guides/api-token.md)**
|
|
- **[Connect an AI assistant (MCP)](docs/guides/mcp.md)**
|
|
- **[Light and dark themes, in English and Lithuanian](docs/features/appearance.md)**
|
|
- **[Self-hosted](#installation)**
|
|
|
|
## Companion Apps
|
|
|
|
Thingport ships two small companion tools, each downloadable from the in-app Download page or GitHub Releases:
|
|
|
|
- **[Thingport Bridge](bridge/README.md)** — a lightweight desktop helper that makes "Open in {Slicer}" work for slicers (Bambu Studio, PrusaSlicer, Cura, Anycubic Slicer Next) whose own URL-protocol handlers won't accept a link from a self-hosted domain.
|
|
- **[Thingport Grab](extension/README.md)** — a browser extension for Chrome, Edge and Firefox that imports MakerWorld, Printables, Thingiverse, MyMiniFactory, Snapmaker Space, MakerOnline, Creality Cloud, NexPrint, Thangs and Cults3D models straight from their own pages, without leaving the site (see the screenshots above). Even without a Thingport instance, it adds a "Download normalized" button to MakerWorld model pages that converts Bambu Studio projects into 3MFs other slicers open with their colours and settings. Get it from the [Chrome Web Store](https://chromewebstore.google.com/detail/nmblahmglpbplmfcggghdgohohlaeiee), [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/thingport-grab/) or [Microsoft Edge Add-ons](https://microsoftedge.microsoft.com/addons/detail/kahfidpmojfocohinlmglnfoaimocbol).
|
|
|
|
## Provider Setup
|
|
|
|
MakerWorld needs each user's session cookie, Printables works with no setup, and Thingiverse needs an App Token an admin sets once for the whole instance. The newer sites each need their own sign-in or key, mostly handed over by [Thingport Grab](extension/README.md); MakerOnline's files come only through Grab, and Printables, Thingiverse and MyMiniFactory work best with FlareSolverr. Connect them under **Configuration → Providers** (from the user menu): right-click a provider to connect it, or choose **About** for what it needs. Admins can turn any provider off for the whole instance under **Administration → Providers**. See **[docs/PROVIDER_SETUP.md](docs/PROVIDER_SETUP.md)** for a comparison of all ten, and a setup page for each.
|
|
|
|
## Contributing
|
|
|
|
Bug reports and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for the branch,
|
|
commit and pull request workflow, and [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for how to run
|
|
Thingport locally with hot reload.
|
|
|
|
### Honourable contributors
|
|
|
|
<table>
|
|
<tr>
|
|
<td align="center" width="140">
|
|
<a href="https://github.com/Ruivalim"><img src="https://avatars.githubusercontent.com/u/15039284?v=4&s=160" width="80" height="80" alt="Rui Valim"></a><br>
|
|
<sub><b>Ruivalim</b></sub><br>
|
|
<a href="https://github.com/Ruivalim"><img src="docs/assets/icons/github.svg" width="16" height="16" alt="GitHub"></a>
|
|
<a href="https://ruivalim.com.br"><img src="docs/assets/icons/website.svg" width="16" height="16" alt="Website"></a>
|
|
<a href="https://www.linkedin.com/in/rui-valim/"><img src="docs/assets/icons/linkedin.svg" width="16" height="16" alt="LinkedIn"></a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
## Support
|
|
|
|
If Thingport is useful to you, consider supporting its development:
|
|
|
|
- [GitHub Sponsors](https://github.com/sponsors/TautvydasDerzinskas)
|
|
- [Buy Me a Coffee](https://buymeacoffee.com/TautvydasDerzinskas)
|
|
|
|
## License
|
|
|
|
Thingport is free software: you can redistribute it and/or modify it under the terms of the
|
|
[GNU Affero General Public License, version 3](LICENSE) (AGPL-3.0-only), as published by the Free
|
|
Software Foundation.
|