Collect, organize, preview, and manage your 3D printing models
from the places where you discover them.
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.
![]() Dashboard | ![]() Models | ![]() Model Details |
![]() 3D Preview | ![]() Collections | ![]() Tags |
![]() Downloads | ![]() My Models | ![]() Dark Theme |
![]() Thingport Grab β Printables | ![]() Thingport Grab β Thingiverse | ![]() Thingport Grab β MakerWorld |
Thingport ships two small companion tools, each downloadable from the in-app Download page or GitHub Releases:
Printables imports work with no setup. MakerWorld and Thingiverse each need a credential from your own account first -- see docs/PROVIDER_SETUP.md for how to create a Thingiverse Access Token and how to grab a MakerWorld session cookie.
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).
Create a folder for Thingport and add these two files to it:
docker-compose.ymlservices:
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}
- INITIAL_ADMIN_EMAIL=${INITIAL_ADMIN_EMAIL:-}
- 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
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
.env# Required
# AUTH_SECRET signs login tokens -- use your own random value
AUTH_SECRET=b1193c7014e833a063f750d6e4644d615e90e6ee81dbde619e1818e9675a3374
# the first account to register with this email becomes admin
INITIAL_ADMIN_EMAIL=you@example.com
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 verification emails
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>
FLARESOLVERR_URL=http://flaresolverr:8191/v1
TZ=UTC
Then start it:
docker compose up -d
Thingport will be available at http://<host>:<WEB_PORT> (default port 80).
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.
If Thingport is useful to you, consider supporting its development:
91 commits
TypeScript
91.0%
JavaScript
6.0%
Go
1.7%
Collect, organize, preview, and manage your 3D printing models
from the places where you discover them.
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.
![]() Dashboard | ![]() Models | ![]() Model Details |
![]() 3D Preview | ![]() Collections | ![]() Tags |
![]() Downloads | ![]() My Models | ![]() Dark Theme |
![]() Thingport Grab β Printables | ![]() Thingport Grab β Thingiverse | ![]() Thingport Grab β MakerWorld |
Thingport ships two small companion tools, each downloadable from the in-app Download page or GitHub Releases:
Printables imports work with no setup. MakerWorld and Thingiverse each need a credential from your own account first -- see docs/PROVIDER_SETUP.md for how to create a Thingiverse Access Token and how to grab a MakerWorld session cookie.
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).
Create a folder for Thingport and add these two files to it:
docker-compose.ymlservices:
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}
- INITIAL_ADMIN_EMAIL=${INITIAL_ADMIN_EMAIL:-}
- 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
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
.env# Required
# AUTH_SECRET signs login tokens -- use your own random value
AUTH_SECRET=b1193c7014e833a063f750d6e4644d615e90e6ee81dbde619e1818e9675a3374
# the first account to register with this email becomes admin
INITIAL_ADMIN_EMAIL=you@example.com
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 verification emails
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>
FLARESOLVERR_URL=http://flaresolverr:8191/v1
TZ=UTC
Then start it:
docker compose up -d
Thingport will be available at http://<host>:<WEB_PORT> (default port 80).
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.
If Thingport is useful to you, consider supporting its development:
91 commits
TypeScript
91.0%
JavaScript
6.0%
Go
1.7%