SBT Deploy Plugin to easily deploy your project.
Please apply changes to project/plugins.sbt:
remove:
resolvers += "JAnalyse Repository" at "http://www.janalyse.fr/repository/"
replace:
addSbtPlugin("com.github.shmishleniy" % "sbt-deploy-ssh" % "0.1.x")
with
addSbtPlugin("io.github.shmishleniy" % "sbt-deploy-ssh" % "0.1.x")
Read documentation here below or check example project.
You will be able to deploy your project with deploy-ssh task.
Usage example: deploySsh yourServerName1 yourServerName2 ...
SBT's documentation on how to use plugins
- Installation
- Configuration
- Configs
- Locations
- Artifacts
- Execute scripts before/after deploy
- Link to task
- Start deploy
Add to your project/plugins.sbt file:
addSbtPlugin("io.github.shmishleniy" % "sbt-deploy-ssh" % "0.1.5")Add import to your project build file
import deployssh.DeploySSH._Enable plugin in your project.
For example in your build.sbt
lazy val myProject = project.enablePlugins(DeploySSH)You can specify configs that will be used for deployment.
You can use .conf files or set configs directly in project settings.
Allowed config fields:
name- your server name. Should be unique in all loaded configs. (Duplication will be overridden)host- ip adress or hostname of the serveruser- ssh username. If missing or empty will be used your current user (user.name)password- ssh password. If missing or empty will be used ssh keypassphrase- passphrase for ssh key. Remove or leave empty for ssh key without passphraseport- ssh port. If missing or empty will be used22sshDir- directory with you ssh keys. This directory should containidentity,id_dsa,id_ecdsa,id_ed25519orid_rsa(the first matched file in the folder will be used for auth). By defaultuser.name/.sshdirectory. This field is not allowed to be empty in.conffile. You should remove this field from config in.conffile to use default value.sshKeyFile- add additional private key file name that will be used for ssh connection. This file name will be added to head of the default list [identity,id_dsa,id_ecdsa,id_ed25519,id_rsa]. This field is not allowed to be empty in.conffile. You should remove this field from config in.conffile to use default value.
name and host fields are mandatory
To set server configs in project settings use ServerConfig class and deployConfigs task key (see details below in Locations section)
case class ServerConfig
( name: String
, host: String
, user: Option[String] = None
, password: Option[String] = None
, passphrase: Option[String] = None
, port: Option[Int] = None
, sshDir: Option[String] = None
, sshKeyFile: Option[String] = None
)Example of the .conf
servers = [
#connect to the server via `22` port and ssh key that located in `user.name/.ssh/` directory, user is current `user.name`
{
name = "server_0"
host = "127.0.0.1"
},
#connect to the server via `22` port and ssh key with name `id_a12` that located in `/tmp/.sshKeys/` directory, user is `ssh_test`
{
name = "server_1"
host = "169.254.0.2"
user = "ssh_test"
sshDir = "/tmp/.sshKeys"
sshKeyFile = "id_a12" #custom private key file name
}
]
There are four places where you can store your server config (All configs will be loaded and merged).
- External config file that located somewhere on your PC
- Config file located in your project directory
- Config file located in user home directory
- Set server configs directly in project settings
lazy val myProject = project.enablePlugins(DeploySSH).settings(
//load build.conf from external path
deployExternalConfigFiles ++= Seq("/home/myUser/Documents/build.conf"),
//load build2.conf from `myProjectDir` and load build3.conf from `myProjectDir/project`
deployResourceConfigFiles ++= Seq("build2.conf", "project/build3.conf"),
//load build4.conf from user home directory (in example `/home/myUser/build4.conf`)
deployHomeConfigFiles ++= Seq("build4.conf"),
//configuration in project setttings
deployConfigs ++= mySettings,
deployConfigs ++= Seq(
ServerConfig("server_6", "169.254.0.3"),
ServerConfig("server_7", "169.254.0.4")
)
)
lazy val mySettings = Seq(
ServerConfig("server_5", "169.254.0.2")
)Set artifacts to deploy
lazy val myProject = project.enablePlugins(DeploySSH).settings(
version := "1.1",
deployConfigs ++= Seq(
ServerConfig("server_5", "169.254.0.2")
),
deployArtifacts ++= Seq(
//`jar` file from `packageBin in Compile` task will be deployed to `/tmp/` directory
ArtifactSSH((packageBin in Compile).value, "/tmp/"),
//directory `stage` generated by `sbt-native-packager` will be deployed to `~/stage_1.1_release/` directory
ArtifactSSH((stage in Universal).value), s"stage_${version.value}_release/")
)
)Deploy execution for this config:
deploy-ssh server_5
or
deploySsh server_5
Use deploySshExecBefore and deploySshExecAfter to execute any bash commands before and after deploy.
Any exception in deploySshExecBefore and deploySshExecAfter will abort deploy for all servers.
To skip deploy only for current server you should wrap exception to SkipDeployException.
For example stop and update and run your app, copy with scp needed application.conf depends on server name:
lazy val myProject = project.enablePlugins(DeploySSH).settings(
deployConfigs ++= Seq(
ServerConfig("server_5", "169.254.0.2")
),
deploySshExecBefore ++= Seq(
(ssh: SSH) => {
ssh.execOnce("touch pid")
val pid = ssh.execOnceAndTrim("cat pid")
if ("".equals(pid)) {
//skip deploy to current server
throw new SkipDeployException(new RuntimeException("missing pid"))
}
ssh.execOnceAndTrim(s"kill $pid")
}
),
deploySshExecAfter ++= Seq(
(ssh: SSH) => {
ssh.scp { scp =>
scp.send(file(s"./src/main/resources/application-${ssh.options.name.get}.conf"), s"/home/app/application.conf")))
}
ssh.execOnce("nohup ./myApp/run & echo $! > ~/pid")
ssh.execOnce("touch pid")
val pid = ssh.execOnceAndTrim("cat pid")
if ("".equals(pid)) {
//stop deploy to all servers
throw new RuntimeException("missing pid. please check package")
}
}
)
)If you need execute deploy in your task you can use deploySshTask and deploySshServersNames to config args for deploySsh. Or cast deploySsh to task.
lazy val myProject = project.enablePlugins(DeploySSH).settings(
deployConfigs ++= Seq(
ServerConfig("server_5", "169.254.0.2"),
ServerConfig("server_6", "169.254.0.3")
),
deploySshServersNames ++= Seq("server_5", "server_6"),
publishLocal := deploySshTask //or deploySsh.toTask(" server_5 server_6")
)After confuguration you will be able to:
deploySsh yourServerName1 yourServerName2 ...
You should set deploySshServersNames list of server names that will be deployed and execute deploySshTask from console or link it to other task.