I am currently trying to explore of a way on how to possibly make my dockerfile generic where it can be used by any .net projects.
My docker file looks like this. I have parameterized the base image to be used. And now I want to try to parameterized the EntryPoint instead of writing "mydotnet.dll" I want it to be passed as a variable/argument during docker build.
My docker file
ARG var1
FROM $var1
WORKDIR /app/
COPY . .
EXPOSE 80
ENTRYPOINT ["dotnet", "mydotnet.dll"]
Related
I'm a newbie to docker, sorry if my question is too basic. I saw dockerfile like this:
FROM diamol/maven AS builder
WORKDIR /usr/src/iotd
COPY pom.xml .
RUN mvn -B dependency:go-offline
COPY . .
RUN mvn package
FROM diamol/openjdk
WORKDIR /app
COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar .
EXPOSE 80
ENTRYPOINT ["java", "-jar", "/app/iotd-service-0.1.0.jar"]
I'm confused about COPY . . instruction, what does the first period and second period COPY . . mean?
Also, if I want to copy all files of the current working directory from my host machine into the image, then how can I modify COPY . . so that the first period means currenty directory of my machine?
In the Dockerfile COPY directive, the last argument is the path inside the container, relative to the current WORKDIR. All of the preceding arguments are paths inside the build context, the host directory passed as an argument to docker build.
I want to copy all files of the current working directory from my host machine into the image, then how can I modify COPY . . ...?
You probably don't need to. So long as you docker build . naming the current directory . as the last argument, that's exactly what COPY . . does. That instruction means to copy . – the entirety of the build context, from the original host system – to . – the current directory, inside the image.
WORKDIR /usr/src/iotd # `COPY anything .` will put it here inside the image
COPY pom.xml . # Copy a single file into that WORKDIR
COPY . . # Copy the entire build context into the WORKDIR
I've mentioned "build context" a couple of times. That is the directory argument to docker build
docker build \
-t myname/some-image: tag \
. # <--- the build context directory
or that you specify in a docker-compose.yml file
version: '3.8'
services:
one:
build: ./one # <-- this directory
two:
build:
context: ./two # <-- this directory
except that the files mentioned in a .dockerignore file are removed first.
In the question title you also ask
does dockerfile's instruction execute in order?
They do. The newer BuildKit backend has some capability to execute build stages not necessarily in the order they're written, but it ensures that you get the same results as if all of the COPY and RUN instructions from a previous stage had run before a COPY --from=... in a later stage happens.
From my perspective, one of the best ways to know all the details for COPY and WORKDIR docker commands is to go through following official documentation.
You can either search for COPY and WORKDIR keywords on the home page at below first link or please refer to last two links and find all the details including examples.
https://docs.docker.com/engine/reference/builder/
https://docs.docker.com/engine/reference/builder/#copy
https://docs.docker.com/engine/reference/builder/#workdir
I have written the following Dockerfile to containerize a maven build:
FROM maven AS builder
WORKDIR /build
COPY . /build
RUN mvn -Dmaven.repo.local=.m2/repository clean test clover:instrument clover:clover clover:check findbugs:check package site
FROM amazoncorretto:8
COPY --from=builder /build/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
The second stage copies the jar file built by the first stage so that it can be used by its ENTRYPOINT but I'd also like the docker host to get a copy of the entire target directory from the container because it holds other build artefacts like code coverage and analysis reports.
Specifically, I'd like the copy to happen as part of the docker build -t fakefirehose . Is this possible?
Here I have a Dockerfile.
Notice I am using a large base image with many libraries (~2Gb), running my build, then copying the output to a smaller image for execution. I understand this to be a common practice.
# Create a base from the .net core 2.2 debian image
FROM microsoft/dotnet:2.2-sdk AS base #<======== Base image (debian)
WORKDIR /app
# Expose ports 80 and 443
EXPOSE 80 #<======== Expose ports
EXPOSE 443
FROM base AS publish
WORKDIR /app
# Copy projects and src files into build image
COPY ./src/. ./src/.
# Run publish
RUN dotnet publish ./src/Core/helloworld.Core.csproj -c Release -o /app
# Create final image #<========= Completely new image (alpine)
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine3.9 AS final
WORKDIR /app
# Copy app from publish
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "helloworld.Core.dll"]
Do things that I do to the base image, like expose ports, extend to the final image?
The EXPOSE directive seems to be for documentation purposes mostly (only?).
From the documentation:
The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published
So I do not see any reason to declare this anywhere other than the final step / Dockerfile.
That said, any EXPOSE directive in a parent image - either multi-stage or not - will be reflected in the metadata of any subsequent child image.
Example:
# Dockerfile
FROM scratch AS base
EXPOSE 80
FROM base
ENV HELLO world
Then run:
$ docker build -t temp .
$ docker image inspect temp
Which will output (among other things):
"ExposedPorts": {
"80/tcp": {}
},
You should declare the ports in your docker-compose.yml file.
You can find reference for that here https://docs.docker.com/compose/networking/
Trying to access the command line args from a dotnet core console application in docker.
This is basically just the default template with default docker compose / dockerfile template.
Tried a few different approaches.
Add args to ENTRYPOINT in dockerfile
Added args to CMD in dockerfile
Added args under build in the docker-compose file
Cant get it to pass it on, how is this usually handled?
Test repo: https://github.com/lasrol/DotnetCoreDockerArgs
CMD is meant as an alternative to ENTRYPOINT, or a way to supply arguments to an entrypoint.
Rather than doing:
ENTRYPOINT ["dotnet", "TestDocker.dll", $arg1, $arg2]
CMD ["arg1", "arg2"]
Which will repeat the arguments,
Try:
ENTRYPOINT ["dotnet", "TestDocker.dll", "arg1", "arg2"]
or if you want to use both, simply use CMD for all the arguments only.
ENTRYPOINT ["dotnet", "TestDocker.dll"]
CMD ["arg1", "arg2"]
https://docs.docker.com/engine/reference/builder/#cmd
What is the correct syntax for specifying an executable entrypoint? For instance, I build a project which produces an executable (e.g. "example.exe") which gets copied to the docker container under C:\app. I cannot seem to get the Dockerfile entrypoint correct, it always fails always relating to not being able to find the specified exe, the path being invalid, etc. The Dockerfile looks like:
FROM microsoft/aspnet:4.6.2-windowsservercore
ARG source=.
WORKDIR /app
COPY $source .
ENTRYPOINT ["/app/example.exe"]
I've tried numerous strings in the entrypoint:
example.exe
C:\\app\\example.exe
/app/example.exe
none of these strings work so I'm confused on how to run that exe as the entrypoint.
Or perhaps I'm misunderstanding the use of "entrypoint" and I need to use something else like "run"?
I had to use the "shell" form:
FROM microsoft/aspnet:4.6.2-windowsservercore
ARG source=.
WORKDIR /app
COPY $source .
ENTRYPOINT "example.exe"