Deployment
StackRivet deploys as a single backend jar plus a static admin bundle. Flyway migrates the database automatically on startup, so a deploy is: build, set environment, run.
Build the artifacts
Section titled “Build the artifacts”# Backend fat jarcd stackrivet-server./mvnw -pl stackrivet-app -am package -DskipTests # → stackrivet-app/target/stackrivet-app.jar
# Static admin bundlecd ../stackrivet-admin-uipnpm install && pnpm build # → dist/Run the backend
Section titled “Run the backend”Load configuration from the environment, then run the jar:
cd stackrivet-serverset -a && source .env && set +a # datasource, STACKRIVET_REDIS_*, JWT secret, storage credsexport JAVA_HOME=$(/usr/libexec/java_home -v 21) # JDK 21java -jar stackrivet-app/target/stackrivet-app.jarThe app starts Tomcat on :8080 and runs Flyway; startup time depends on the machine and database. Confirm:
curl http://127.0.0.1:9090/actuator/health # {"status":"UP"}Serve the admin dist/ as static files (e.g. behind Nginx), proxying /api/* to the application port. Keep /actuator/* on the management port behind your operations network if you expose it.
Minimal production-style .env:
STACKRIVET_PROFILE=prodSTACKRIVET_PORT=8080STACKRIVET_MANAGEMENT_PORT=9090STACKRIVET_MANAGEMENT_ADDRESS=127.0.0.1STACKRIVET_DB_VENDOR=mysqlSPRING_DATASOURCE_URL=jdbc:mysql://db.example.com:3306/stackrivet?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&sslMode=VERIFY_CASPRING_DATASOURCE_USERNAME=stackrivetSPRING_DATASOURCE_PASSWORD=change-meSTACKRIVET_REDIS_HOST=redis.example.comSTACKRIVET_REDIS_PASSWORD=change-meSTACKRIVET_SECURITY_JWT_SECRET=replace-with-at-least-32-random-bytesSTACKRIVET_STORAGE_TYPE=s3STACKRIVET_S3_ENDPOINT=https://s3.example.comSTACKRIVET_S3_BUCKET=stackrivetSTACKRIVET_S3_ACCESS_KEY=change-meSTACKRIVET_S3_SECRET_KEY=change-meMinimal Nginx shape:
server { listen 443 ssl http2; server_name stackrivet.example.com; root /srv/stackrivet-admin-ui/dist;
location / { try_files $uri $uri/ /index.html; }
location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}Topologies
Section titled “Topologies”| Shape | Layout |
|---|---|
| Local dev | Vite dev server + Spring Boot + Docker MySQL/PostgreSQL + MinIO |
| Small-team production | Nginx → static admin + Spring Boot app → managed MySQL/PostgreSQL → S3 / OSS |
| Enterprise | Load balancer → multiple app nodes → HA database + enterprise object storage + OIDC/SAML/LDAP |
Because request processing is designed to remain horizontally scalable — upload routing follows the active storage capabilities, heavy work runs as async tasks, and lists are paginated — scaling out is adding nodes behind the load balancer. Local and OSS uploads transit an app node; S3 can advertise byte-bound direct and multipart paths.
Production must-dos
Section titled “Production must-dos”- Object storage, not local disk. Set
STACKRIVET_STORAGE_TYPEtos3oraliyun_oss(see Configure object storage); local files don’t survive a restart or scale-out. - Rotate the seeded admin password. The bootstrap
adminaccount ships with a known development password — change it before exposing the app. - Set a strong
STACKRIVET_SECURITY_JWT_SECRETand keep all secrets in the environment, never in the repo. - Redis is required — it backs JWT revocation and the health check.
- Restrict the actuator/metrics endpoints.
/actuator/healthand/actuator/prometheusare reachable without auth on the management port by design; put them behind a network ACL in production. - Managed, backed-up database. Use a managed MySQL/PostgreSQL with a tested backup-and-restore procedure.
Recover from a stuck start
Section titled “Recover from a stuck start”| Symptom | Check |
|---|---|
port 8080 failed to start | lsof -nP -iTCP:8080 -sTCP:LISTEN — kill the stale process |
| Login 401 with the right password | STACKRIVET_SECURITY_JWT_SECRET changed since the token was issued |
| Flyway checksum mismatch | See Database migrations → recover |
Edition boundary
Section titled “Edition boundary”Helm, multi-instance availability and SSO integration are not shipped Community capabilities. They may be evaluated through a scoped Enterprise pilot; see the pricing page. Community is documented for a single application instance behind Nginx.