My app can't create log files when it starts up inside Docker
I spent the weekend pouring over the Docker docs and playing around with the toy applications and example projects. I’m now trying to write a super-simple web service of my own and run it from inside a container. In the container, I want my app (a Spring Boot app under the hood) — called bootup — to have the following directory structure:
/opt/ bootup/ bin/ bootup.jar ==> the app logs/ bootup.log ==> log file; GETS CREATED BY THE APP @ STARTUP config/ application.yml ==> app config file logback.groovy ==> log config file
It’s very important to note that when I run my app locally on my host machine – outside of Docker – everything works perfectly fine, including the creation of log files to my host’s
/opt/bootup/logs directory. The app endpoints serve up the correct content, etc. All is well and dandy.
So I created the following
FROM openjdk:8 RUN mkdir /opt/bootup RUN mkdir /opt/bootup/logs RUN mkdir /opt/bootup/config RUN mkdir /opt/bootup/bin ADD build/libs/bootup.jar /opt/bootup/bin ADD application.yml /opt/bootup/config ADD logback.groovy /opt/bootup/config WORKDIR /opt/bootup/bin EXPOSE 9200 ENTRYPOINT java -Dspring.config=/opt/bootup/config -jar bootup.jar
I then build my image via:
docker build -t bootup .
I then run my container:
docker run -it -p 9200:9200 -d --name bootup bootup
CONTAINER ID IMAGE COMMAND ... 3f1492790397 bootup "/bin/sh -c 'java ..."
So far, so good!
My app should then be serving a simple web page at
localhost:9200, so I open my browser to
http://localhost:9200 and I get nothing.
When I use
docker exec -it 3f1492790397 bash to “ssh” into my container, I see everything looks fine, except the
/opt/bootup/logs directory, which should have a
bootup.log file in it — created at startup — is instead empty.
I tried using
docker attach 3f1492790397 and then hitting
http://localhost:9200 in my browser, to see if that would generated some standard output (my app logs both to
/opt/bootup/logs/bootup.log as well as the console) but that doesn’t yield any output.
So I think what’s happening is that my app (for some reason) doesn’t have permission to create its own log file when the container starts up, and puts the app in a weird state, or even prevents it from starting up altogether.
So I ask:
- Is there a way to see what user my app is starting up as?; or
- Is there a way to tail standard output while the container is starting? Attaching after startup doesn’t help me because I think by the time I run the
docker attachcommand the app has already choked
Thanks in advance!
One Solution collect form web for “My app can't create log files when it starts up inside Docker”
I don’t know why your app isn’t working, but can answer your questions-
Is there a way to see what user my app is starting up as?; or
A: Docker containers run as root unless otherwise specified.
Is there a way to tail standard output while the container is starting? Attaching after startup doesn’t help me because I think by the time I run the docker attach command the app has already choked
A: Docker containers dump stdout/stderr to the Docker logs by default. There are two ways to see these- 1 is to run the container with the flag -it instead of -d to get an interactive session that will list the stdout from your container. The other is to use the
docker logs *container_name* command on a running or stopped container.
docker attach 3f1492790397
This doesn’t do what you are hoping for. What you want is
docker exec (probably
docker exec -it bootup bash), which will give you a shell in the scope of the container which will let you check for your log files or try and hit the app using curl from inside the container.
Why do I get no output?
Hard to say without the info from the earlier commands. Is your app listening on 0.0.0.0 or on localhost (your laptop browser will look like an external machine to the container)? Does your app require a supervisor process that isn’t running? Does it require some other JAR files that are on the CLASSPATH on your laptop but not in the container? Are you running docker using Docker-Machine (in which case
localhost is probably not the name of the container)?