mirror of
https://github.com/TautvydasDerzinskas/Thingport.git
synced 2026-10-18 20:59:55 -05:00
339 lines
18 KiB
Markdown
339 lines
18 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
|
|
|
|
If you do 3D printing, you probably discover models across **MakerWorld, Printables, Thingiverse, and other 3D model platforms**.
|
|
|
|
Over time, those bookmarks, downloads, ZIP files, and random folders become a mess.
|
|
|
|
**Thingport is your personal, self-hosted 3D model library.**
|
|
|
|
Bring your models together in one place, keep them organized, and preview them directly in your browser.
|
|
|
|
Instead of having your collection scattered across different websites and your filesystem, Thingport gives you a single place to manage the models you actually want to keep.
|
|
|
|
## 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%"></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 and Thingiverse](docs/features/importing.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)**
|
|
- **[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, Thingiverse, and Printables 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
|
|
|
|
Printables imports work with no setup. MakerWorld and Thingiverse each need a credential from your own account first. Connect them under **Configuration → Providers** (from the user menu): right-click a provider to connect or disconnect it. Admins can turn any provider off for the whole instance under **Administration → Providers**. See **[docs/PROVIDER_SETUP.md](docs/PROVIDER_SETUP.md)** for how to create a Thingiverse Access Token and how to grab a MakerWorld session cookie.
|
|
|
|
## 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.
|