I want to run docker container with sidecar by this tutorial.
For example, i have java spring boot application. Then i made such Dockerfile:
# Dockerfile for GitLab CI/CD
FROM maven:3.5.2-jdk-8-alpine AS MAVEN_BUILD
ARG SPRING_ACTIVE_PROFILE
MAINTAINER SlandShow
COPY pom.xml /build/
COPY src /build/src/
WORKDIR /build/
RUN mvn clean install -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE && mvn package -B -e -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE
FROM openjdk:8-alpine
WORKDIR /app
COPY --from=MAVEN_BUILD /build/target/task-0.0.1-SNAPSHOT.jar /app/task-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java", "-jar", "task-0.0.1-SNAPSHOT.jar"]
After that i build docker image and run it:
$ docker build .
$ docker container run -p 8010:8010 <imageId>
Docker-CLI returns hash for started contaner. For example- cc82fa748a62de634893f5594a334ada2854f0be0dff8149efb28ae67c98191c.
Then i'am trying to start sidecar:
docker run -pid=container:cc82fa748a62de634893f5594a334ada2854f0be0dff8149efb28ae67c98191c -p 8080:8080 brendanburns/topz:db0fa58 /server --addr=0.0.0.0:8080
And get:
docker: invalid publish opts format (should be name=value but got '8080:8080').
What's wrong with it?
My fault, i forgot - before -p...
Related
I have created a project like https://github.com/senolatac/demo-multi-module-docker and I have implemented some docker multi-stage https://docs.docker.com/language/java/run-tests/ examples.
Here is my Dockerfile:
FROM --platform=linux/x86_64 gradle:7.5.1-jdk17-alpine AS base
COPY --chown=gradle:gradle . /app
WORKDIR /app
FROM base as test
CMD ["./gradlew", "test"]
FROM base as build
RUN ./gradlew build -x test
# create-image -> DOCKER_BUILDKIT=0 docker build --tag sb-web-image --target web .
# run -> docker run -it --rm --name sb-web-container -p 8085:8080 sb-web-image
FROM --platform=linux/x86_64 openjdk:17-alpine as web
COPY --from=build /app/web/build/libs/*.jar /web.jar
CMD ["java", "-Dspring-boot.run.profiles=default", "-jar", "/web.jar"]
# create-image -> DOCKER_BUILDKIT=0 docker build --tag sb-worker-image --target worker .
# run -> docker run -it --rm --name sb-worker-container -p 8086:8080 sb-worker-image
FROM --platform=linux/x86_64 openjdk:17-alpine as worker
COPY --from=build /app/worker/build/libs/*.jar /worker.jar
CMD ["java", "-Dspring-boot.run.profiles=default", "-jar", "/worker.jar"]
# create-image -> DOCKER_BUILDKIT=0 docker build --tag sb-web-image --build-arg JAR_FILE=web/build/libs/\*.jar --target generic .
# run -> docker run -it --rm --name sb-web-container -p 8086:8080 sb-web-image
FROM --platform=linux/x86_64 openjdk:17-alpine as generic
ARG JAR_FILE
COPY --from=build /app/${JAR_FILE} /app.jar
CMD ["java", "-Dspring-boot.run.profiles=default", "-jar", "/app.jar"]
My project has two different modules. To run these modules on Docker, firstly I should create two different images then run them as two different docker container. But my purpose is so simple: Create a single image and run containers from that image. Do you have suggestion about it?
You can straightforwardly override the CMD when you run the application, so you just need to COPY all of the jar files into the single image.
FROM --platform=linux/x86_64 gradle:7.5.1-jdk17-alpine AS build
COPY --chown=gradle:gradle . /app
WORKDIR /app
RUN ./gradlew build -x test
FROM --platform=linux/x86_64 openjdk:17-alpine
WORKDIR /app
COPY --from=build /app/web/build/libs/*.jar ./web.jar
COPY --from=build /app/worker/build/libs/*.jar ./worker.jar
ENV SPRINGBOOT_RUN_PROFILES=default
EXPOSE 8080
CMD ["java", "-jar", "./web.jar"]
docker build -t sb-image .
docker run -d --name sb-web -p 8085:8080 sb-image
docker run -d --name sb-worker -p 8086:8080 sb-image \
java -jar ./worker.jar
So, note that there is only one final stage, but it COPY --from=build both jar files into it. I pick one of them to be the default CMD, and when I run the other, I provide an additional command after the docker run image-name. (Compose command: and Kubernetes args: can do the same thing.)
This looks like a Spring Boot application. I've set the profile property as an environment variable rather than a command-line option, which shortens the command line. If your applications share a code base, you can also get a smaller image by unpacking the fat jars, though this requires an additional build stage.
Using the docker build command line I can pass in a build secret as follows
docker build \
--secret=id=gradle.properties,src=$HOME/.gradle/gradle.properties \
--build-arg project=template-ms \
.
Then use it in a Dockerfile
# syntax = docker/dockerfile:1.0-experimental
FROM gradle:jdk12 AS build
COPY *.gradle .
RUN --mount=type=secret,target=/home/gradle/gradle.properties,id=gradle.properties gradle dependencies
COPY src/ src/
RUN --mount=type=secret,target=/home/gradle/gradle.properties,id=gradle.properties gradle build
RUN ls -lR build
FROM alpine AS unpacker
ARG project
COPY --from=build /home/gradle/build/libs/${project}.jar /tmp
RUN mkdir -p /opt/ms && unzip -q /tmp/${project}.jar -d /opt/ms && \
mv /opt/ms/BOOT-INF/lib /opt/lib
FROM openjdk:12
EXPOSE 8080
WORKDIR /opt/ms
USER nobody
CMD ["java", "-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000", "-Dnetworkaddress.cache.ttl=5", "org.springframework.boot.loader.JarLauncher"]
HEALTHCHECK --start-period=600s CMD curl --silent --output /dev/null http://localhost:8080/actuator/health
COPY --from=unpacker /opt/lib /opt/ms/BOOT-INF/lib
COPY --from=unpacker /opt/ms/ /opt/ms/
I want to do a build using docker-compose, but I can't find in the docker-compose.yml reference how to pass the secret.
That way the developer just needs to type in docker-compose up
You can use environment or args to pass variables to container in docker-compose.
args:
- secret=id=gradle.properties,src=$HOME/.gradle/gradle.properties
environment:
- secret=id=gradle.properties,src=$HOME/.gradle/gradle.properties
I'm trying to configure my docker container so it's possible to ssh into it (the container will be run on Azure). I managed to create an image that enables user to ssh into a container created from that image, the Dockerfile looks like that (it's not mine, I found it on the internet):
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
EXPOSE 2222
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
COPY sshd_config /etc/ssh
RUN echo 'root:Docker' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed 's#session\s*required\s*pam_loginuid.so#session optional pam_loginuid.so#g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
CMD ["/usr/sbin/sshd", "-D"]
I'm using mcr.microsoft.com/dotnet/core/sdk:2.2-stretch because it's what I need later on to run the application.
Having the Dockerfile above, I run docker build . -t ssh. I can confirm that it's possible to ssh into a container created from ssh image with following instructions:
docker run -d -p 0.0.0.0:2222:22 --name ssh ssh
ssh root#localhost -p 2222
My application's Dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["Application.WebAPI/Application.WebAPI.csproj", "Application.WebAPI/"]
COPY ["Processing.Dependency/Processing.Dependency.csproj", "Processing.Dependency/"]
COPY ["Processing.QueryHandling/Processing.QueryHandling.csproj", "Processing.QueryHandling/"]
COPY ["Model.ViewModels/Model.ViewModels.csproj", "Model.ViewModels/"]
COPY ["Core.Infrastructure/Core.Infrastructure.csproj", "Core.Infrastructure/"]
COPY ["Model.Values/Model.Values.csproj", "Model.Values/"]
COPY ["Sql.Business/Sql.Business.csproj", "Sql.Business/"]
COPY ["Model.Events/Model.Events.csproj", "Model.Events/"]
COPY ["Model.Messages/Model.Messages.csproj", "Model.Messages/"]
COPY ["Model.Commands/Model.Commands.csproj", "Model.Commands/"]
COPY ["Sql.Common/Sql.Common.csproj", "Sql.Common/"]
COPY ["Model.Business/Model.Business.csproj", "Model.Business/"]
COPY ["Processing.MessageBus/Processing.MessageBus.csproj", "Processing.MessageBus/"]
COPY [".Processing.CommandHandling/Processing.CommandHandling.csproj", "Processing.CommandHandling/"]
COPY ["Processing.EventHandling/Processing.EventHandling.csproj", "Processing.EventHandling/"]
COPY ["Sql.System/Sql.System.csproj", "Sql.System/"]
COPY ["Application.Common/Application.Common.csproj", "Application.Common/"]
RUN dotnet restore "Application.WebAPI/Application.WebAPI.csproj"
COPY . .
WORKDIR "/src/Application.WebAPI"
RUN dotnet build "Application.WebAPI.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "Application.WebAPI.csproj" -c Release -o /app
FROM ssh AS final
WORKDIR /app
EXPOSE 80
EXPOSE 443
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Application.WebApi.dll"]
As you can see I'm using ssh image as a base image in the final stage. Even though I was able to sshe into the container created from ssh image, I'm unable to ssh into a container created from the latter Dockerfile. Here is the docker-compose.yml I'm using in order to ease starting the container:
version: '3.7'
services:
application.webapi:
image: application.webapi
container_name: webapi
ports:
- "0.0.0.0:5000:80"
- "0.0.0.0:2222:22"
build:
context: .
dockerfile: Application.WebAPI/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=docker
When I run docker exec -it webapi bashand execute service ssh status, I'm getting [FAIL] sshd is not running ... failed! - but when I do service ssh start and try to ssh into that container, it works. Unfortunately this approach is not acceptable, ssh daemon should launch itself on startup.
I tried using cron and other stuff available on debian but it's a slim version and systemd is not available there - I'm also not fond of installing hundreds of things on slim versions.
Do you have any ideas what could be wrong here?
You have conflicting startup command definitions in your final image. Note that CMD does not simply run a command in your image, it defines the startup command, and has a complex interaction with ENTRYPOINT (in short: if both are present, CMD just supplies extra arguments to ENTRYPOINT).
You can see the table of possibilities in the Dockerfile documentation: https://docs.docker.com/engine/reference/builder/. In addition, there's a bonus complication when you mix and match CMD and ENTRYPOINT in different layers:
Note: If CMD is defined from the base image, setting ENTRYPOINT will reset CMD to an empty value. In this scenario, CMD must be defined in the current image to have a value.
As far as I know, you can't get what you want just by layering images. You will need to create a startup script in your final image that both runs sshd -D and then runs dotnet Application.WebApi.dll.
I made a webapp in Java and I would like to test the site locally using Docker.
The war file I created works perfectly but to be read correctly it must be inserted inside this path:
/tomcat/webapps/ROOT/
For these reasons I decided to use this form:
https://hub.docker.com/_/tomcat
In particular I decided to use this Dockerfile:
https://github.com/docker-library/tomcat/blob/ec2d88f0a3b34292c1693e90bdf786e2545a157e/9.0/jre11-slim/Dockerfile
I added this code towards the end:
...
EXPOSE 8080
CMD ["cd /usr/local/tomcat/webapps/"]
CMD ["mv ROOT ROOT.old"]
CMD ["mkdir ROOT"]
COPY ./esercitazione.1.maven/ /usr/local/tomcat/webapps/ROOT/
CMD ["catalina.sh", "run"]
I used this code at the Windows 10 prompt:
D:
cd "D:\DATI\Docker-Tomcat-Win10"
docker build -t tomcat-9-java-11:v2.0 .
docker run -it --rm --name tomcat-9-java-11-container -p 8888:8080 tomcat-9-java-11:v2.0
When I enter this link on the browser:
http://192.168.99.103:8888/
I see this:
https://prnt.sc/n2vti1
I'm a beginner with both Docker and Tomcat and I need a little help.
Inside this path I put my unzipped .war file:
D:\DATI\Docker-Tomcat-Win10\esercitazione.1.maven
Thank you
%%%%%%%%%%%%%%%%%%%%%%%%%%
#Shree Tiwari
%%%%%%%%%%%%%%%%%%%%%%%%%%
First of all thank you for your help!
I deleted all the containers and all the images on Docker and used your Dockerfile (I only changed the name of the folder containing the .war files to be tested).
FROM tomcat:9-jre8
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:MaxPermSize=256m -XX:MaxMetaspaceSize=128m"
WORKDIR /usr/local/tomcat/webapps/
RUN rm -rf /usr/local/tomcat/webapps/*
COPY ./webapps/*.war /usr/local/tomcat/webapps
EXPOSE 8080
CMD ["catalina.sh", "run"]
I placed the .war file at this address:
D:\DATI\Docker-Tomcat-Win10\webapps\esercitazione.1.maven.war
I opened the Windows prompt and I typed:
D:
cd "D:\DATI\Docker-Tomcat-Win10"
docker build -t tomcat:v1.0 .
docker run -it --rm --name tomcat-container -p 8888:8080 tomcat:v1.0
I entered this URL in the browser:
http://192.168.99.103:8888/esercitazione.1.maven/
then this other:
http://192.168.99.103:8888/
Unfortunately none of them went well.
The only mistake I encountered when creating the image is this:
"SECURITY WARNING: You are building to Docker image from Windows against a non-Windows Docker host. Files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories."
%%%%%%%%%%%%%%%%%%%%%%%%%%
#Miq
%%%%%%%%%%%%%%%%%%%%%%%%%%
First of all thank you for your help!
I also tested your code but it doesn't work.
Dockerfile:
FROM tomcat:9-jre11-slim
RUN mv webapps/ROOT webapps/ROOT.old && mkdir webapps/ROOT
COPY ./esercitazione.1.maven/ webapps/ROOT/
Code:
D:
cd "D:\DATI\Docker-Tomcat-Win10"
docker build -t tomcat:v2.0 .
docker run -it --rm --name tomcat-container tomcat:v2.0
Browser:
http://192.168.99.103:8080/
Other tests:
FROM tomcat:9-jre11-slim
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:MaxPermSize=256m -XX:MaxMetaspaceSize=128m"
RUN mv webapps/ROOT webapps/ROOT.old && mkdir webapps/ROOT
WORKDIR /usr/local/tomcat/webapps/
RUN rm -rf /usr/local/tomcat/webapps/ROOT/*
COPY ./webapps/*.war /usr/local/tomcat/webapps/ROOT/
EXPOSE 8080
CMD ["catalina.sh", "run"]
docker ps -a
docker images
docker stop tomcat-container
docker rmi tomcat:v3.0
D:
cd "D:\DATI\Docker-Tomcat-Win10"
docker build -t tomcat:v3.0 .
docker run -d --name tomcat-container -p 8888:8080 tomcat:v3.0
http://192.168.99.103:8888/
%%%%%%%%%%%%%%%%%%%%%%%%%%
Other tests: (8 April 2019)
FROM tomcat:9.0.17-jre11-slim
LABEL Author="Nome Cognome"
EXPOSE 8080
RUN rm -fr /usr/local/tomcat/webapps/ROOT
COPY ./esercitazione.1.maven.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh", "run"]
>
docker build -t tomcat-eb:v.9.0.17 .
docker run -it --rm -p 8888:8080 tomcat-eb:v.9.0.17
>
I'm going here:
http://192.168.99.103:8888
and the browser sends me here:
https://192.168.99.103:8443
%%%%%%%%%%%%%%%%%%%%%%%%%%
Other tests: (I choose another image)
FROM tomee:8-jre-8.0.0-M2-webprofile
LABEL Author="Nome Cognome"
EXPOSE 8080
RUN rm -fr /usr/local/tomcat/webapps/ROOT
COPY ./esercitazione.1.maven.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh", "run"]
>
docker build -t tomcat-eb:v.9.0.17 .
docker run -it --rm -p 8888:8080 tomcat-eb:v.9.0.17
>
If I go here:
http://192.168.99.103:8888
I see Tomcat home, non my webapp.
Is this a problem without a solution?
The biggest problem I see here is that you use CMD instead RUN in your dockerfile. CMD is to define a command that will be run when container is ran. With the Dockerfile you have now, only the last one is executed when you start your container and all of those mkdirs, moves, etc. are never executed. As said, you need to use RUN keywords to indicate command that build process should execute and commit as image layer. You probably also do not need the catalina.sh CMD as it might come from the image you base on, but you need to check it on doc page for the base image or take a peek to it's Dockerfile or use docker history imagename To see the layers and commands used to create them.
I took a deeper look into this and the base image you use. In addition to the CMD's your problem is that you change the workdir by running cd commands. catalina.sh exists in $CATALINA_HOME dir, which then is marked as workdir in base image. When you change the active directory by executing cd it breaks the image runtime.
I'd suggest you try with following dockerfile:
FROM tomcat:9-jre11-slim
RUN mv webapps/ROOT webapps/ROOT.old && mkdir webapps/ROOT
COPY ./esercitazione.1.maven/ webapps/ROOT/
No need to use EXPOSE and CMD as they are defined in base image. also, base image defines WORKDIR to $CATALINA_HOME and that's where you will be when executing any following commands (treat WORKDIR as cd but in docker style).
Hope that helps.
First you need to compile your Code to a war file then you can use below Dockerfile
FROM tomcat:9-jre8
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:MaxPermSize=256m -XX:MaxMetaspaceSize=128m"
WORKDIR /usr/local/tomcat/webapps/
RUN rm -rf /usr/local/tomcat/webapps/*
COPY ./esercitazione.1.maven/*.war /usr/local/tomcat/webapps
EXPOSE 8080
CMD ["catalina.sh", "run"]
I use the following docker file which works as expected
The project is a cli and when I run command docker run -it cli
I got error from the cli (which is ok since the entry point is just running fzr ENTRYPOINT ["./fzr”])
Typically I run in on my machine like fzr -help or fzr version etc
I want that when I use command like docker run -it cli that I will be able to run commands inside the container
like fzr -help and fzr version, how can I do that ?
FROM golang:1.10.5 AS build-env
ADD https://github.com/golang/dep/releases/download/v0.4.2/dep-linux-amd64 /usr/bin/dep
RUN chmod +x /usr/bin/dep
RUN mkdir -p $GOPATH/src/github.com/fzr
WORKDIR $GOPATH/src/github.com/fzr
COPY Gopkg.toml Gopkg.lock ./
# install project dep
RUN dep ensure
COPY . ./
RUN go build -o /fzr
FROM scratch
COPY --from=build-env /fzr ./
ENTRYPOINT ["./fzr"]
TL;DR;
docker run -it cli version
If you set ENTRYPOINT to your binary then everything that you pass after image name will be used as arg to that binary. If for some reason you need to overwrite entrypoint use --entrypoint flag to docker run.