Skip to content

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.

Terminal window
# Backend fat jar
cd stackrivet-server
./mvnw -pl stackrivet-app -am package -DskipTests # → stackrivet-app/target/stackrivet-app.jar
# Static admin bundle
cd ../stackrivet-admin-ui
pnpm install && pnpm build # → dist/

Load configuration from the environment, then run the jar:

Terminal window
cd stackrivet-server
set -a && source .env && set +a # datasource, STACKRIVET_REDIS_*, JWT secret, storage creds
export JAVA_HOME=$(/usr/libexec/java_home -v 21) # JDK 21
java -jar stackrivet-app/target/stackrivet-app.jar

The app starts Tomcat on :8080 and runs Flyway; startup time depends on the machine and database. Confirm:

Terminal window
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:

Terminal window
STACKRIVET_PROFILE=prod
STACKRIVET_PORT=8080
STACKRIVET_MANAGEMENT_PORT=9090
STACKRIVET_MANAGEMENT_ADDRESS=127.0.0.1
STACKRIVET_DB_VENDOR=mysql
SPRING_DATASOURCE_URL=jdbc:mysql://db.example.com:3306/stackrivet?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&sslMode=VERIFY_CA
SPRING_DATASOURCE_USERNAME=stackrivet
SPRING_DATASOURCE_PASSWORD=change-me
STACKRIVET_REDIS_HOST=redis.example.com
STACKRIVET_REDIS_PASSWORD=change-me
STACKRIVET_SECURITY_JWT_SECRET=replace-with-at-least-32-random-bytes
STACKRIVET_STORAGE_TYPE=s3
STACKRIVET_S3_ENDPOINT=https://s3.example.com
STACKRIVET_S3_BUCKET=stackrivet
STACKRIVET_S3_ACCESS_KEY=change-me
STACKRIVET_S3_SECRET_KEY=change-me

Minimal 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;
}
}
ShapeLayout
Local devVite dev server + Spring Boot + Docker MySQL/PostgreSQL + MinIO
Small-team productionNginx → static admin + Spring Boot app → managed MySQL/PostgreSQL → S3 / OSS
EnterpriseLoad 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.

  • Object storage, not local disk. Set STACKRIVET_STORAGE_TYPE to s3 or aliyun_oss (see Configure object storage); local files don’t survive a restart or scale-out.
  • Rotate the seeded admin password. The bootstrap admin account ships with a known development password — change it before exposing the app.
  • Set a strong STACKRIVET_SECURITY_JWT_SECRET and 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/health and /actuator/prometheus are 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.
SymptomCheck
port 8080 failed to startlsof -nP -iTCP:8080 -sTCP:LISTEN — kill the stale process
Login 401 with the right passwordSTACKRIVET_SECURITY_JWT_SECRET changed since the token was issued
Flyway checksum mismatchSee Database migrations → recover

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.