How to run sbt as daemon?
Looks like sbt
requested input from your terminal. If it does not really need input (which is probably the case when you run program in background), you can run it like this:
sbt run </dev/null >output-file &
See this answer for details.
EDIT
Ok, now that was a puzzle. Short answer: run sbt
as follows:
setsid nohup sbt run &
Rationale:
The reason why sbt
stops is arrival of SIGTTOU
signal. It is delivered to background process in several cases, which include modifying terminal configuration. This is our case because according to strace -f sbt run &
, sbt
does a lot of black magic under the hood like this:
[pid 16600] execve("/usr/bin/sh", ["sh", "-c", "stty -g < /dev/tty"], [/* 75 vars */] <unfinished ...>
To work this around, you can run sbt
in a different session to detach it from current terminal, so that it won't open /dev/tty and mess with our terminal.
Running SBT as Daemon
We launch test/demo apps with SBT in init.d all the time:
#!/bin/sh
# test lift web app
case "$1" in
'start')
cd /home/demouser/wa/HTML5DemoLift231/HTML5demo/
sbt jetty run
;;
'stop')
cd /home/demouser/wa/HTML5DemoLift231/HTML5demo/
sbt jetty stop
;;
*)
echo "Usage: $0 { start | stop }"
;;
esac
exit 0
This just works - we have had no problems with it. It may be different with a non-web app though.
How to keep sbt running (as a daemon process) after executing a command
sbt "; <command>; console"
does the trick. Note the initial semicolon is required.
Is there a simple way to fork a server process in sbt before starting test against that server?
fork
doesn't run task in parallel - it just makes sure that tests are run in a separate JVM which helps with things like shutdown webhooks or disconnecting from services that doesn't handle resource release properly (e.g. DB connection that never calls disconnect).
If you want to use the same sbt to start server AND run test against that instance (which sounds like easily breakable antipattern BTW) you can use somethings like:
reStart
it:test
reStop
However that would be tricky because reStart
yields immediately so tests would start when the server setup started but not necessarily completed. Race condition, failing tests, or blocking all tests until server finishes starting.
This is why nobody does it. Much easier to handle solution is to:
- start the server in test in some
beforeAll
method and make this method complete only after server is responding to queries - shutdown it in some
afterAll
method (or somehow handle both of these using something likecats.effect.Resource
or similar) - depending on situation:
- running tests sequentially to avoid starting two instances at the same time or
- generating config for each test so that they could be run in parallel without clashing on ports allocations
Anything else is just a hack that is going to fail sooner rather than later.
Running sbt in docker as non-root user
I understand that all of the "RUN" commands in your Dockerfile are as a root
user.
SBT downloading Scala: Check where it is downloading. SBT by default downloads dependencies on ~/.ivy2
(and/or ~/.m2
). If you change user, your home also changes, so it will look for dependencies in /home/jenkins/.ivy2
, then on .ivy2
(double-check on this), which do not have those dependencies downloaded already, so it tries to download them.
About the var/cache/apt/archives/lock
, it is trying to install via SBT via apt with your jenkins user, when you need to be privileged user to use apt. Your app-user should not need to install anything (or anything that requires root access), but rather build an image with all required installs and then use it as a separate user. Also, if apt gives you headaches, you can just install via download into folder, something like:
RUN \
curl -fsL http://downloads.typesafe.com/scala/$SCALA_VERSION/scala-$SCALA_VERSION.tgz | tar xfz - -C /usr/local && \
ln -s /usr/local/scala-$SCALA_VERSION/bin/* /usr/local/bin/
PS: You may want to run your container always as jenkins user, in that case you can use USER jenkins
after you finished installations and do any additional unprivileged operations there.
Sbt-native-packager cannot connect to Docker daemon
I finally solved it by installing Sbt instead of Docker. I also use Docker in Docker service from Gitlab now that basically helps me avoid the problem above.
image: docker:19.03.12
services:
- mysql:latest
- docker:19.03.12-dind
docker:image:
needs: ["test"]
stage: deploy
before_script:
- apk update
- apk --no-cache add openjdk11
- export PATH="/usr/local/sbt/bin:$PATH"
- apk update && apk add bash ca-certificates wget tar && mkdir -p "/usr/local/sbt" && wget -qO - --no-check-certificate "https://github.com/sbt/sbt/releases/download/v1.5.5/sbt-1.5.5.tgz" | tar xz -C /usr/local/sbt --strip-components=1 && sbt sbtVersion
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- sbt docker:publishLocal
- docker tag x:latest registry.gitlab.com/x/y:0.1-SNAPSHOT-$(date +%Y-%m-%d-%H-%M)
- docker push registry.gitlab.com/x/y/project-$(date +%Y-%m-%d-%H-%M)
only:
- master
running daemon in background in scala console
Figured it out thanks to @som-snytt's link to @michael.kebe's answer on this SO entry: How does the “scala.sys.process” from Scala 2.9 work?
val pb = Process("""program""").run
Does exactly what I wanted
Related Topics
Execute Two Commands with Docker Exec
Gcc Compiled Binaries Give "Cannot Execute Binary File"
Provide Password to Ssh Command Inside Bash Script, Without The Usage of Public Keys and Expect
Permissions Required to Move File to Different Directory in Unix/Linux
List of All Folders and Sub-Folders
How to Deploy a Container into a Specific Node in a Docker Swarm
Access Permissions of /Dev/Mem
How to Improve Performance of Linux Pipes
How to Query X11 Display Resolution
Is There an Acceptable Linux Targeted Gui Client for Git-Svn
How to Access Team Foundation Server (Tfs) from Linux
Run ASP.NET Core App Under Linux on Startup
How to Get All Parent Processes and All Subprocesses with 'Pstree'
A Running Bash Script Is Hung Somewhere. How to Find Out What Line It Is On