1

I'm using Docker Compose to create a container for a Spring Boot application.

I'm receiving the following errors when I do docker-compose up:

Recreating backend_springboot ... error

ERROR: for backend_springboot Cannot start service service: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"sh -c java -Dspring.config.location=/application.properties -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar\": stat sh -c java -Dspring.config.location=/application.properties -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar: no such file or directory": unknown

ERROR: for service Cannot start service service: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"sh -c java -Dspring.config.location=/application.properties -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar\": stat sh -c java -Dspring.config.location=/application.properties -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar: no such file or directory": unknown

My structure:

├── docker-compose.yml
├── spring-boot
│   ├── Dockerfile
│   ├── application.properties
│   └── backofficeservices-0.0.1.jar

docker-compose.yml

version: '3'
services:
  service:
    container_name: backend_springboot
    build: ./spring-boot
    ports:
      - "80:8080"
    restart: always

spring-boot/Dockerfile

FROM openjdk:8-jre-alpine as gradle

COPY backofficeservices-0.0.1.jar /app.jar

COPY application.properties /application.properties

ENV JAVA_OPTS=""

ENTRYPOINT ["sh -c java -Dspring.config.location=/application.properties -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar"]

EXPOSE 8080

As far as I know, the application.properties is not found. I will appreciate any help to detect my error.

My goal is to run my Spring Boot app applying the application.properties I have there.

RRGT19
  • 1,437
  • 3
  • 28
  • 54
  • Did you make sure you mounted the file that it says it can't find to the docker container? – bturner1273 Feb 19 '20 at 22:14
  • @bturner1273 yes, well, I have added an instruction to copy the file `application.properties` from my machine to the container, is the second instruction at `spring-boot/Dockerfile`. – RRGT19 Feb 19 '20 at 22:16
  • huh... in your error message application.properties is spelled aplication.properties. Could it just be that you typed it wrong somewhere and docker is looking for the wrong file? – bturner1273 Feb 19 '20 at 22:20
  • @bturner1273 nice catch. I fixed the name but, still receiving the same error. – RRGT19 Feb 19 '20 at 22:24
  • Huh try mounting to your running container and CD and ls ing around to see if your files are actually copying as expected – bturner1273 Feb 19 '20 at 23:08
  • Just comment/omit the code asking for the file first obviously – bturner1273 Feb 19 '20 at 23:09
  • @bturner1273 The container is "restarting" and don't want to change the status to do "exec -it bash". No matter what I do, it's always restarting. I cannot enter inside of it. This is so confusing to me... – RRGT19 Feb 19 '20 at 23:20

1 Answers1

2

You have specified an ENTRYPOINT using a single "word". When you launch the container, it is trying to run that as a single "word" – it is looking for a binary named sh -c java ..., with spaces and all as part of the filename. If your command has multiple "words" and you're using the JSON-array form, you have to correctly manually split it up into words yourself.

ENTRYPOINT ["sh", "-c", "java -Dspring.config.location=..."]

A Dockerfile CMD and ENTRYPOINT are fairly similar; both provide part of the command the container ultimately runs. If you only need one of them I'd recommend using CMD instead, for two reasons: it makes it easier to get a debugging shell on the built image docker run --rm -it myimage /bin/sh, and there's a fairly standard pattern of using an ENTRYPOINT script to do some initial setup and then exec "$@" to run the CMD.

CMD ["sh", "-c", "java -Dspring.config.location=..."]

If you have this form, Docker can provide the sh -c ... wrapper for you.

CMD java -Dspring.config.location=...

With a little bit more cleanup, that would leave the final Dockerfile something like

FROM openjdk:8-jre-alpine
COPY backofficeservices-0.0.1.jar /app.jar
COPY application.properties /application.properties
ENV JAVA_OPTS=""
CMD java \
      -Dspring.config.location=/application.properties \
      -Djava.security.egd=file:/dev/./urandom \
      $JAVA_OPTS \
      -jar /app.jar
EXPOSE 8080
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • It's running, thanks a lot my friend. I didn't know all the tricks that you said. Just one question, how can I add the `ENV JAVA_OPTS=""` into the `CMD`? I just need to add it before the `-jar....` line? – RRGT19 Feb 20 '20 at 01:31
  • Yes; I added it to my answer. (I had been under the impression the JVM handles it on its own, but [it's actually used by things like Tomcat startup scripts](https://stackoverflow.com/questions/5241743/how-do-i-use-the-java-opts-environment-variable) and not the JVM proper.) – David Maze Feb 20 '20 at 02:12