Install with Docker Compose
Thingport runs from pre-built images on the GitHub Container Registry, so there's no build step and no need to clone the repository. It works on any Docker host, including a NAS such as Synology, QNAP or Unraid.
On Unraid, TrueNAS SCALEor CasaOS? Follow the platform guide instead. They use each platform's own app-data paths and setup screens.
Requirements
- Docker with the Compose plugin (
docker compose versionshould work). - A few hundred MB of RAM for the stack: Postgres, FlareSolverr, the API and the web app. Disk space depends on the size of your library.
Just want to try it? On Linux or macOS, one command creates a
thingportfolder with the same two files as step 1, generates the secrets in.envand starts Thingport:curl -fsSL https://thingport.net/install.sh | shIt uses port 80 and a
thingportfolder where you run it. To pick both yourself:curl -fsSL https://thingport.net/install.sh | WEB_PORT=8080 sh -s -- ~/thingportTo change other settings later, edit
.envin that folder (see step 1) and rundocker compose up -dthere again. You can read the script before running it. Then continue at 3. Sign up.
1. Create the files
Create a folder for Thingport, for example ~/thingport, and add these two files to it.
docker-compose.yml
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:
# Pin to a release instead of :latest, e.g. :1.2.0, or :1 for every 1.x (or a build, :sha-a8fef7d):
# BACKEND_IMAGE=ghcr.io/tautvydasderzinskas/thingport-backend:1.2.0
# Or :dev for every backend change as it's merged, before it's released (expect the odd rough edge).
image: ${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: nginx serving the app and proxying /api/* to the backend (see frontend/nginx.conf).
frontend:
# Pin to a release instead of :latest, e.g. :1.2.0, or :1 for every 1.x (or a build, :sha-a8fef7d):
# FRONTEND_IMAGE=ghcr.io/tautvydasderzinskas/thingport-frontend:1.2.0
# Or :dev for every frontend change as it's merged, before it's released (expect the odd rough edge).
image: ${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
At minimum, set AUTH_SECRET (it signs login tokens; generate one with openssl rand -hex 32) and POSTGRES_PASSWORD. Everything else has sensible defaults.
# 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 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>
# first-run default only; once Thingport has started, change it in Administration -> Connections -> FlareSolverr
FLARESOLVERR_URL=http://flaresolverr:8191/v1
TZ=UTC2. Start Thingport
docker compose up -dThingport is then available at http://<host>:<WEB_PORT>. The default port is 80.
3. Sign up
Open Thingport in your browser and register. The first account you register becomes the admin. Then set up your providers so you can import from MakerWorld, Thingiverse and MyMiniFactory. Printables works right away.
4. Check System Health
Open Administration → Overview → System Health and click Run full test. Ideally everything is green. Anything marked Required or Recommended that isn't green means Thingport, or part of it, won't work properly until it's fixed, and each problem says how. See System Health.
Updating
Pull the latest images and recreate the containers. Your database and files live in Docker volumes and are kept.
docker compose pull
docker compose up -dTo stay on a specific build, set BACKEND_IMAGE and FRONTEND_IMAGE in .env to a pinned tag, as shown in the comments in the compose file.
Building from source
To build the images yourself instead of pulling them:
git clone https://github.com/TautvydasDerzinskas/Thingport.git
cd Thingport
cp .env.example .env
docker compose up -dFor hot-reload development, see Development setup.