I have a spring boot application that has program arguments such as --input-directory
and --output-directory
. I want to wrap the spring boot application in a Docker container, I also want the user to be able to specify custom values for the input-directory
and output-directory
arguments as directories on the host system. Ideally I’d like to able to do this via a command line similar to docker run graphql-extractor -e INPUT_DIRECTORY=D:javascript -e OUTPUT_DIRECTORY=D:graphql
or docker-compose run -e INPUT_DIRECTORY=D:javascript -e OUTPUT_DIRECTORY=D:graphql graphql-extractor
. How can I do this? I do not want the user to have to specify the volume via the -v argument. My attempt so far has a Dockerfile that looks like this
FROM openjdk:17-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
A docker-compose.yml that looks like this
version: '3.8'
services:
graphql-extractor:
build: .
environment:
INPUT_DIRECTORY: ${INPUT_DIRECTORY}
OUTPUT_DIRECTORY: ${OUTPUT_DIRECTORY}
volumes:
- ${INPUT_DIRECTORY:-./}:/app/input
- ${OUTPUT_DIRECTORY:-./}:/app/output
command: [
"--input-directory=/app/input",
"--output-directory=/app/output"
]
When I try to run this container like so docker-compose run -e INPUT_DIRECTORY=D:javascript -e OUTPUT_DIRECTORY=D:graphql graphql-extractor
the application does not find any files inside of /app/input, even though they exist on the host system. I also see the message
time="2024-11-11T12:06:32Z" level=warning msg="The "INPUT_DIRECTORY" variable is not set. Defaulting to a blank string."
time="2024-11-11T12:06:32Z" level=warning msg="The "OUTPUT_DIRECTORY" variable is not set. Defaulting to a blank string."
Even though I have set the environment variable via the -e flag on the docker-compose run
command line.
It seems as though the -e
or --env
flags of docker compose run
do not set the environment variables necessary for the compose file. If I do the following before running the docker compose
command, it works
set INPUT_DIRECTORY=D:/javascript
set OUTPUT_DIRECTORY=D:/graphql
2
Answers
When you use the set command you use the linux filesystem
D:/javascript
. When you run the docker compose you run it with the windows filesystemD:javascript
. What happens if you try to run in withdocker-compose run -e INPUT_DIRECTORY=D:/javascript -e OUTPUT_DIRECTORY=D:/graphql graphql-extractor
?You can set up your image such that the containerized copy of the application normally uses a fixed input and output path, especially if those paths are directories and not individual files.
(In a Spring Boot application you can set arbitrary Spring properties via environment variables, so change these names as needed to match your
@Value()
or@ConfigurationProperties
mappings.)Now when you run the application, you can map any host directory you need to those two container directories.
If you want to launch this via Compose then you can put those environment variables in the Compose file itself, using basically the syntax you’ve already shown. You don’t need to set
environment:
orcommand:
because the container paths are fixed.Note that I’m much more familiar with Unix syntax and I’ve used this here; the syntax for using Windows filesystem paths may be different. On a Unixy system, you also may need a
docker run -u
or Composeuser:
setting to run the container with a user ID that’s able to read or write the host system.