Docker isn't just about launching daemon processes. It is completely ant to launch a batch that is executed only once.
However, starting a container with the docker
command is painful. Use docker-compose
in batch as well.
This time I would like to run a simple CLI program written in Java as a batch.
https://github.com/knjname/2018-02_DockerComposeBatchExample
You can download from here.
I made it with Spring boot. Do something like the following: It just prints batch arguments and environment variables.
//Something like the main function when you bite CommandLineRunner with Spring boot
@Override
public void run(String[] args) throws Exception {
System.out.println("Batch run!!!");
System.out.println(" args: " + String.join(", ", args));
System.out.println(" env: " + System.getenv("MY_ENV_VALUE"));
}
It doesn't matter, but if you want to make something that doesn't matter in Java, use Spring Boot.
This is the content to import the JAR built in the previous stage (... AS builder
) into the container in the latter half and run the java -jar built JAR
.
FROM library/openjdk:9.0.1-11-jre-slim AS builder
ADD . /app
WORKDIR /app
RUN ./gradlew bootRepackage
RUN mv /app/build/libs/*.jar /app.jar
FROM library/openjdk:9.0.1-11-jre-slim
COPY --from=builder /app.jar /app.jar
ENTRYPOINT [ "java", "-jar", "/app.jar" ]
Since the end is ENTRYPOINT, you can pass arguments to the batch.
For the time being, the environment variables for the batch are given as MY_ENV_VALUE
. Actually, I think that it will give the connection destination of the database. In addition, the batch file export directory is also specified here as the volume specification.
docker-compose.yml
version: "3.4"
services:
batch:
#Docker build the above Docker. -image when built with t myjavabatch:I think it will be something like myjavabatch
build: ./
environment:
MY_ENV_VALUE: "foobarbaz"
# restart:I don't need always
# ports:I don't even need
# network_mode: "host"Even if you specify, there should be no problem unlike daemons.
#It is better to make a batch-only image of Docker instead of using it on the Web.
As always, don't start as below. This will start the service (daemon).
$ docker-compose up -d
Disposable containers that start when you want to start like a batch are basically started with --rm
as shown below.
$ docker-compose run --rm batch batch arguments
By the way, if you can't get a TTY above (such as running from crontab), it won't work. Let's specify -T
.
$ docker-compose run --rm -T batch batch arguments
However, there are still traps.
For now (as of 02/06/2018), docker-compose run
assigns container names in sequence, such as base name_run_1
, but _1
is covered and cannot be started. You may.
Let's explicitly name the container with a random number so that it will not be covered.
$ docker-compose run --rm -T --name `uuidgen`batch batch arguments
This is perfect.
Let's also create a wrapper shell for the above command.
wrapper.sh
#!/bin/bash
docker-compose run --rm -T --name `uuidgen` batch "$@"
If you call the batch via the trumpet shell, it's perfect. : smile_cat:
$ ./wrapper.sh my java batch is forever!!
If you want to run it regularly with cron, use crontab -e
to define a cron entry like the one below.
crontab
# /dev/Don't throw it to null. Systemd for modern OS-Let's give it to cat.
0 * * * * cd /my/path/to/project && ./wrapper.sh my java batch is forever!!! 2>&1 | systemd-cat
Batch execution with docker-compose is nothing special. (I want to believe it is not)
Let's challenge!!
Recommended Posts