An SBT plugin for local deployment of Scala applications. It packages your application into a versioned directory, manages symlinks for binary scripts, and helps track stale (old) installations.
- Per-app subdirectory — Each application gets its own folder (
<deployPath>/<name>/); all releases live inside it - Versioned deployments — Each deploy creates a timestamped and commit-tagged directory (
<name>-<version>-<timestamp>-<commit>) currentsymlink — Acurrentsymlink inside the app folder always points to the latest release- Shared
logsandconf—<deployPath>/<name>/logsand<deployPath>/<name>/confare created once and symlinked (as absolute paths) into every release directory; placeapplication.conf,logback.xml, and similar files there — they will be picked up by every release automatically conf/on the classpath — The sharedconf/directory is automatically prepended to the application's JVM classpath; Typesafe Config and Logback findapplication.confandlogback.xmlthere without any extra-Dflags- JVM args from file — If
<deployPath>/<name>/conf/jvm-argsexists, each non-empty, non-comment line is passed to the JVM at startup; update heap size or GC flags without rebuilding the application - Binary symlink management — Automatically creates symlinks for binary scripts in a configurable link directory
- Stale installation tracking — Lists deployments older than 30 days to help clean up disk space
- Dry-run preview — Inspect planned deployment paths before executing
- CI/CD friendly — All paths configurable via environment variables
- SBT 1.x
- sbt-native-packager with
JavaAppPackagingenabled in the consumer project — the plugin requiresJavaAppPackagingand uses its bash start script infrastructure
Add the plugin to your project/plugins.sbt:
addSbtPlugin("io.github.ssstlis" % "sbt-local-deploy" % "<version>")Enable the plugin in your build.sbt:
enablePlugins(JavaAppPackaging, LocalDeployPlugin)All tasks are scoped under the LocalDeploy configuration:
sbt LocalDeploy/deploy
sbt LocalDeploy/deployInfo
sbt LocalDeploy/staleInstallations
Stage and deploy your application:
sbt LocalDeploy/deploy
Optionally pass paths as arguments:
sbt "LocalDeploy/deploy /opt/myapp/releases /usr/local/bin"
Or set them via environment variables:
| Variable | Description |
|---|---|
LDP_APP_DEPLOY_PATH |
Root directory where releases are placed |
LDP_APP_DEPLOY_LINK_PATH |
Directory where symlinks are created |
The resulting on-disk layout for an app called foo deployed to /opt/releases:
/opt/releases/
└── foo/
├── conf/ ← shared, created once; put application.conf, logback.xml, etc. here
├── logs/ ← shared, created once
├── current -> foo-1.0.0-2024-06-01_12-00-00-abcd1234/ ← symlink, updated on each deploy
├── foo-1.0.0-2024-06-01_12-00-00-abcd1234/
│ ├── bin/
│ ├── lib/
│ ├── conf -> /opt/releases/foo/conf/ ← absolute symlink
│ └── logs -> /opt/releases/foo/logs/ ← absolute symlink
└── foo-0.9.0-2024-05-01_09-00-00-deadbeef/
├── ...
├── conf -> /opt/releases/foo/conf/ ← absolute symlink
└── logs -> /opt/releases/foo/logs/ ← absolute symlink
Each release directory is named:
<name>-<version>-<yyyy-MM-dd_HH-mm-ss>-<git-commit>
Show where files will be deployed without making any changes:
sbt LocalDeploy/deployInfo
List deployments older than 30 days:
sbt LocalDeploy/staleInstallations
stage(from sbt-native-packager) builds a universal distribution locallydeploycopies the staged output to<deployPath>/<name>/<name>-<version>-<time>-<commit>/- The
currentsymlink at<deployPath>/<name>/currentis updated to point to the new release directory <deployPath>/<name>/logsand<deployPath>/<name>/confare created if absent, then symlinked (with absolute paths) into the release as<release>/logsand<release>/conf; theconf/directory is the right place forapplication.conf,logback.xml, and any other per-environment configuration files- Binary symlinks are created (or updated) in the link path pointing to scripts inside the release
- A warning is printed if any existing installations in
<deployPath>/<name>/are older than 30 days
All deployment paths are configured via environment variables or task arguments — no extra build.sbt keys required beyond enabling the plugin.
Place a jvm-args file in the shared conf/ directory to pass extra arguments to the JVM at startup. Each line is one argument; lines starting with # and blank lines are ignored:
# Heap
-Xmx4g
-Xms4g
# GC
-XX:+UseG1GC
-XX:+UseStringDeduplication
The file is optional — if absent, startup proceeds normally.
Because conf/ is prepended to the classpath, Typesafe Config picks up conf/application.conf automatically (it takes priority over any embedded reference.conf in the JARs), and Logback picks up conf/logback.xml without any extra system properties.
Format code:
sbt fmt
Check formatting without changes:
sbt fmtCheck
Linting is powered by Scalafix and formatting by Scalafmt.
Apache-2.0