I have problem with my spring boot app.
If I docker-compose up, I see this error ->
Error: Invalid or corrupt jarfile /bin/sh
MongoDb, prometheus and grafana start correctly.
Dockerfile
FROM openjdk:11-jre-slim as build
ADD target/rest-test-0.0.1-SNAPSHOT.jar .
EXPOSE 8000
CMD java -jar rest-test-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-Dspring.profiles.active=prod","-jar"]
docker-compose.yml
version: "3.8"
services:
rest-test:
build: .
restart: always
ports:
- "8000:8080"
depends_on:
- mongo_db
environment:
- "SPRING_PROFILES_ACTIVE=prod"
mongo_db:
image: "mongo:latest"
restart: always
ports:
- "27018:27017"
prometheus:
image: "prom/prometheus"
restart: always
depends_on:
- rest-test
ports:
- "9090:9090"
grafana:
image: "grafana/grafana"
restart: always
depends_on:
- rest-test
ports:
- "3000:3000"
That ENTRYPOINT line doesn't fit here, and you should remove it. If you do need JVM options, include them in the java command.
CMD java -Dspring.profiles.active=prod -jar rest-test-0.0.1-SNAPSHOT.jar
# no ENTRYPOINT
You're seeing two things happen in your original Dockerfile. Since CMD is a bare string, Docker automatically wraps it in /bin/sh -c; and since you have both ENTRYPOINT and CMD, the CMD gets passed as arguments to the ENTRYPOINT. This results in the nonsensical command
java -D... -jar /bin/sh -c 'java -jar rest-test-0.0.1-SNAPSHOT.jar'
which produces the error you see.
There is no requirement that an image have an ENTRYPOINT; in many cases specifying only CMD is easier to manage (for example, you can docker run --rm -it your-image sh to get an interactive debugging shell on a built image). If you do split CMD and ENTRYPOINT, either the ENTRYPOINT should be written so it accepts a complete command as arguments or the ENTRYPOINT should itself be a complete command and the CMD its arguments.
# "Container as command" pattern: lets you
# docker run ... the-image -arg1 -arg2
# where the arguments get passed to the application
ENTRYPOINT ["java", "-Dspring.profiles.active-prod", "-jar", "rest-test-0.0.1-SNAPSHOT.jar"]
CMD []
# empty CMD is optional
# both must be JSON arrays, you do not want the `sh -c` wrapper
Related
I'm not able to detach from a Docker container after I attached to it.
Dockerfile to define the container:
FROM adoptopenjdk/openjdk16:debian
WORKDIR /app
STOPSIGNAL SIGTERM
RUN apt-get update && apt-get install -y curl && apt clean
CMD curl -so server.jar https://ci.tivy.ca/job/Airplane-1.17/lastSuccessfulBuild/artifact/launcher-airplane.jar && java -jar server.jar
Build the container with: docker build -t minecraft .
docker-compose file:
version: "3.7"
services:
mc:
container_name: mc
ports:
- 25565:25565
image: minecraft
volumes:
- type: bind
source: /root/mc
target: /app
Start the container with: docker-compose up mc
I tryed to attach to console with docker attach mc, it works. But I'm not unable to detach from screen. Ctrl+C not work. Ctrl+P and Ctrl+Q not work. Writing stop (command that will stop the java process) not working
I tryed to attach with docker attach --detach-keys="ctrl-d" mc but is not working
Java process never ends
Found fix myself. Need to insert stdin_open and ttyin docker-compose file. New docker-compose.yml:
version: "3.7"
services:
mc:
container_name: mc
ports:
- 25565:25565
image: minecraft
volumes:
- type: bind
source: /root/mc
target: /app
stdin_open: true
tty: true
Will set this answer as solution in two days because of stackoverflow rules
Hi I need to dockerize a system. the way I have to do this like below
steps:
up dynamodb local instance ( just for up ).
run a custom script to create tables ( have to go through this to create the tables ).
then run the system.
I wrote a compose file also. the way I did that was, like below
version: "3"
services:
dynamodb:
image: amazon/dynamodb-local
ports:
- "8000:8000"
networks:
- custom-network
volumes:
- "db-data:/home/dynamodblocal/data"
app:
container_name: my-app
build:
context: .
dockerfile: Dockerfile
args:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
URL: ${URL}
env_file:
- docker.env
depends_on:
- dynamodb
networks:
- custom-network
volumes:
db-data:
networks:
custom-network:
docker file as below. ( sorry had to hide sensitive details )
FROM debian:buster
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
ARG URL
RUN echo "deb http://ftp.us.debian.org/debian sid main" >> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install openjdk-8-jdk maven awscli -y
RUN aws s3 cp ${URL} db-updater.jar
RUN echo local > input
# there are few lines of configs that wrote to input file
RUN cat input | java -jar db-updater.jar http://dynamodb:8000
WORKDIR /opt/app
COPY . .
RUN mvn package
EXPOSE 8080
CMD ["java","-cp","./app/target/app-1.0.0.jar:./app/target/lib/*"]
my problem is looks like dynamodb do not start before the script run. so script throws a error as can't connect to server.
if I could write a custom a dynamodb with executed script that is also great. please help
Commands in a Dockerfile can never interact with other Docker containers. The general pattern is that an image is built once and reused, so you could delete and recreate your DynamoDB container, or run the same image on a different system, and the database setup wouldn't have happened. Mechanically, the Dockerfile runs in an environment where it's not connected to the Compose networking system, so attempts at connecting between containers will generally fail with a "no such host" error.
A typical pattern is to use an entrypoint script to do first-time setup when the container launches. For example, you could write a simple shell script:
#!/bin/sh
# Seed the database
java -jar db-updater.jar http://dynamodb:8000 < input
# Run whatever the main container command is
exec "$#"
You can then include this in your Dockerfile:
COPY entrypoint.sh . # probably included in the `COPY . .` line
ENTRYPOINT ["./entrypoint.sh"] # must be JSON-array syntax
# replaces `RUN java -jar db-updater.jar`
CMD ["java", "-cp", ...] # as in the current Dockerfile
If you only need this to run once when you first set up the container stack, you could also seed the data on your host.
# Outside Docker
aws s3 cp ... db-updater.jar
./make-seed-data.sh > input
# Start the DynamoDB container (only)
docker-compose up -d dynamodb
# Load the seed data
java -jar db-updater.jar -url http://localhost:8000 < input
# Now start the rest of the application
docker-compose up -d
This would let you remove the code to build the input file and download the updater tool from your Dockerfile. It would also let you remove the AWS credentials from the build sequence (very important: it may be possible to find them in plain text looking at the image's docker history).
I am trying to set up a very simple Docker container, that will execute a Jar file. I want an image that will run a simple Jar. I dont need anything else special.
So far my docker-compose.yml looks like this, but it doesn't start correctly:
version: "3.3"
services:
myapp:
image: openjdk:8
container_name: "myapp"
restart: always
ports:
- 8091:8091
volumes:
- "./meanwhile-in-hell.jar:/app.jar"
command: ['java', '-jar', '/app.jar']
STATUS
Restarting (1) 2 seconds ago
Using the command: ['java', '-jar', '/app.jar'] option, I see this in the Docker logs:
Error: Invalid or corrupt jarfile /app.jar
If I change to use entrypoint: [ "sh", "-c", "java -jar /app.jar" ], I see the same error.
The Jar file is absolutely fine and not corrupt. I have run it manually on another tomcat:8-alpine container I have running and it starts up successfully.
I'm building a postgres+java container, and I'd like to open a shell into the java "service". That service exits immediately after starting, how can I do to open a shell into it?
I see it in docker ps -a but it has already exited.
The file I'm using is this .yaml with docker-compose
version: '3.1'
services:
db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: postgres
volumes:
- datavolume:/var/lib/postgresql
java:
image: openjdk:8
volumes:
datavolume:
A Docker container generally runs a single process. In the same way that just running a JVM without an application attached to it isn't really meaningful, running a Docker container with a JVM but no actual application added to it isn't that useful.
You should write a Dockerfile that adds your application's jar file to a base Java image; for instance
FROM openjdk:8
COPY app.jar /
CMD ["java", "-jar", "/app.jar"]
and then your docker-compose.yml file can have instructions to build and run this image
services:
java:
build: .
If you just want a shell in a copy of the image to poke around and see what's there, you can generally run
docker run --rm -it openjdk:8 sh
The standard openjdk Dockerfile doesn't explicitly declare any specific ENTRYPOINT or CMD so it will exit immediately when run. (It probably inherits a default /bin/sh, but with no command to run, that will also exit immediately.) You can declare some other command: in the Dockerfile to cause the "service" to not exit, but it's not really doing anything useful for you.
I have the following docker file to run my java application
FROM gidikern/rhel-oracle-jre
RUN mkdir /application
WORKDIR /application
CMD "java -Dspring.profiles.active=sprofileName -jar my.war --spring.config.location=./application.properties > app.log > 2>&1"
and i'm running using docker-compose:
backend_app:
restart: always
image: my-app-runner:latest
ports:
- "8080:8080"
volumes:
- ./app/my.war:/application/my.war:Z
- ./app/application.properties:/application/application.properties:Z
- /srv/docker/backend_app/logs:/application/my.log:Z
tty: true
however when i start i get that my app exited with code 0 constantly.
I can't find what is wrong.
The problem was actually with my base image gidikern/rhel-oracle-jre
I tested and even basic commands like ls didn't work..
Switched to openjdk for now and it is fine.
Very probably there's an error in your application. To debug I suggest you to run the container in shell and to execute the java command manually to see what's happening.
In other words:
docker run -it --name app-debug my-app-runner:latest /bin/bash
java -Dspring.profiles.active=sprofileName -jar my.war --spring.config.location=./application.properties