Have this Dockerfile
Dockerfile
FROM python:3.8
ADD Pipfile.lock /app/Pipfile.lock
ADD Pipfile /app/Pipfile
WORKDIR /app
COPY . /app
RUN pip install pipenv
RUN pipenv install --system --deploy --ignore-pipfile
ENV FLASK_APP=app/http/api/endpoints.py
ENV FLASK_RUN_PORT=4433
ENV FLASK_ENV=development
ENTRYPOINT ["python"]
CMD ["-m", "flask", "run"]
Why in the Docker container my app lands in
/app/app/http/api
App gets duplicated
How to copy it to:
/app/http/api
How can I fix it?
Update 1:
My docker-compose and Dockerfile and ls output.
https://0bin.net/paste/ePRws72M#IV8H6iRJ+UMJFr8lB7CRQYKwsnGYflsmOlyvFxZA7zE
You got two problems here
copy . /app copies the whole working directory from the host machine into the /app directory in the image. If you just want the ./app subdirectory change that to copy ./app /app
Your docker-compose mounts the current working directory of the host machine into the container under the mount point /app . This hides the existing directory /app of the image. So you will either need to copy your app to a different directory or use a different mount point for your volume
Related
I am learning Docker and looking at this Dockerfile example for React application
FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
CMD ["npm", "run", "start"]
To me it's saying
Grab image node:alpine from docker library
create WORKDIR called /app
copy the package.json file to the /app dir
copy the lock file also to /app dir
I don't understand what COPY ./ ./ is doing?
command npm install
then CMD npm run start
Am I interpreting this language correctly? Can anyone give me insight of what is actually going on?
Docker is an open-source containerization platform. Here we run our application in the container(which is managed by Docker Engine). Dockerfile contains all the commands. Also, you can say in Dockerfile that we write all the procedures to make a container runnable.
Coming back to your point...
Here COPY ./ ./ meaning is, COPY <source_path> <destination_path> and <source_path> is the path in your host machine and <destination_path> is path in your container machine
I will try to simplify the other contents in your Dockerfile...
FROM node:alpine : Pull image node:alpine from Docker Hub. Here node is the package name and alpine is the Linux distribution with very minimal and required packages.
WORKDIR /app: (Work Directory) In container you're setting up your WORKDIR as /app folder.
COPY package.json ./: COPY the package.json(host machine) file to ./(current directory) in your container
And other COPY will also work in the same way.
RUN npm i: RUN command npm i in container
CMD ["npm", "run", "start"]: CMD command will executed(npm run start) when Docker Container will start.
For more detail please see Dockerfile Documentation.
I have a problem implementing sharp for Dockerfile.
Error: 'sharp' is required to be installed in standalone mode for the image
optimization to function correctly
Next.js with sharp works fine for local developing:
next 12.0.1
sharp 0.30.2
node 16.xx
npm 8.xx
OS - macOS Monterey - 12.2.1, M1 PRO
next.config.js
module.exports = {
experimental: {
outputStandalone: true,
},
}
Dockerfile:
FROM node:16-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
# Rebuild the source code only when needed
FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build
# Production image, copy all the files and run next
FROM node:16-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/next-i18next.config.js ./
COPY --from=builder /app/next-sitemap.js ./cd
COPY --from=builder /app/jsconfig.json ./jsconfig.json
COPY --from=builder /app/data/ ./data
COPY --from=builder /app/components/ ./components
COPY --from=builder /app/utils/ ./utils
COPY --from=builder /app/assets/ ./assets
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
.env file:
NEXT_SHARP_PATH=/tmp/node_modules/sharp next start
Sharp is installed in package.json
I checked both Next/Vercel tuts:
https://nextjs.org/docs/messages/install-sharp
https://nextjs.org/docs/messages/sharp-missing-in-production
RUN Docker:
docker build --no-cache . -t website-app && docker run --name website -p 3000:3000 website-app
I figured it out.
I removed NEXT_SHARP_PATH=/tmp/node_modules/sharp next start from .env
Local docker doesn't work with node-sharp without NEXT_SHARP_PATH and that is weird.
But I deployed it in my K8s Cluster with Docker and it works as is expected.
npm i sharp
this fix the problem for me
What works for me, is to change the version of Alpine Linux in the Dockerfile:
FROM node:18-alpine AS deps (instead of node:16)
Adding or removing node-sharp in my .env file didn't work for me.
For the final step (the one labeled "runner") in your Dockerfile, replace the base image with node:16-slim. This image is Debian-based, so it is approximately 20 MB larger than the alpine variant, but it has the binaries required to run sharp.
When using a similar Dockerfile to yours, I found that the NEXT_SHARP_PATH environment variable was not needed when using a Debian-based Node image.
And for reference, here is the NextJS documentation about the error message: https://nextjs.org/docs/messages/sharp-missing-in-production
Update: You may also be able to specify the libc implementation found in your base Docker image by using the following flags:
RUN npm_config_platform=linux npm_config_arch=x64 npm_config_libc=glibc npm ci
For more information about what these flags are, see the documentation for sharp.
I have the following directory structure
|-Dockerfile
|-README.md
|-angula.json
|-package.json
|-...
|-src
|-index.html
|-main.ts
|-...
|app
|-app.component.html
|...
Now I want that everything is copied into a container when it is starting up. For that I put the following content into the Dockerfile:
From node:12.15.0-alpine
RUN mkdir -p /app
WORKDIR /app
COPY package.json /app/
RUN ["npm","install"]
COPY . /app
EXPOSE 4200/tcp
CMD ["npm", "start", "--", "--host", "0.0.0.0", "--poll", "500"]
When I now build and run the Dockerfile, I have the following issue, that the directory src and all its subdirectories are not copied.
When I run docker exec -it [container-name] sh and then type sh all files which are in the same directory as Dockerfile are there. However if I then go into the src folder it is empty.
I would expect that with the COPY . /app I am coping the complete folder and all its sub-directories to the container. Why is this not the case? What am I missing out?
It was a very stupid mistake... When I mounted the src directory I used ${pwd} instead of $(pwd), which lead to the empty folder, eventhough I copied previously.
After refactoring from docker-compose into separate Docker file for each project, I'm Unable to run the container, it simply exits. I'm using both docker and docker-compose since I'll have more projects down the road.
My docker files are as follows.
docker-compose.yml
version: '3'
services:
customer:
image: customer
container_name: customer
build:
context: ./Customer
dockerfile: Dockerfile
Customer/Dockerfile
FROM mcr.microsoft.com/dotnet/core/runtime:2.2
WORKDIR /Customer
EXPOSE 80
COPY ./bin/Release/netcoreapp2.2/ service/
ENTRYPOINT ["dotnet", "service/Customer.dll"]
Also I had this within docker-compose file before. How do I map 6001 to 80 within Dockerfile?
ports:
- 6001:80
Attempt 2
FROM mcr.microsoft.com/dotnet/core/sdk:2.2
WORKDIR /Customer
ENV DATABASE_HOST=database
ENV DATABASE_NAME=db
ENV DATABASE_USER=sa
ENV DATABASE_PASSWORD=Password
EXPOSE 80
COPY . .
CMD dotnet build
ENTRYPOINT ["dotnet", "Customer/bin/Release/netcoreapp2.2/Department.dll"]
Attempt 3
copied from main site.
Copied from here https://docs.docker.com/engine/examples/dotnetcore/
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
Did you mean to run dotnet SDK commands? Please install dotnet SDK
from: https://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
Here is a lazy and basic docker file. I added some comments and some helpful build/debug options, e.g: "RUN ls -al" to list the current directory. Just like a linux VM.
# step 1 - building you app with SDK as base image
FROM microsoft/dotnet:2.2-sdk AS build-env # call the environment build
WORKDIR /build # create a work dir
COPY . . # you don't need copy everything to build your app, but this is for simplisity
RUN ls -al # linux command to list dir content
RUN cd /Customer && dotnet publish -o out # actually building the app and publishing to /out dir
RUN cd /Customer && ls -al # navigate to the folder you copied and list dir
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS runtime # step 2, runtime env (slimmed down container)
WORKDIR /app # create workdir
COPY --from=build-env /<YOUR_BULD_PATH>/out ./ # copy from prev container build output
RUN ls -al # list again
ENTRYPOINT ["dotnet", "Department.dll", "--urls", "http://*:6001"] # example from .NET Core 2.2 webapi with port 6005, this might not be your case
Now to run the docker-compose, just point out the docker file like you have already done. But both docker/docker-compose should work just fine now. Ofcourse you need to tweak the docker file a bit, i dont know your app or folder structure.
And just a tip, if you want to run your docker file as stand alone, dont forget the args when you start it to map ports --> -p 6001:80
I need to access test result files in the host from the container. I know that I need to create a volume which maps between host and container, like below, but I get nothing written to the host.
docker run --rm -it -v <host_directory_path>:<container_path> imagename
Dockerfile:
FROM microsoft/dotnet:2.1-sdk AS builder
WORKDIR /app
COPY ./src/MyApplication.Program/MyApplication.Program.csproj ./src/MyApplication.Program/MyApplication.Program.csproj
COPY nuget.config ./
WORKDIR ./src/MyApplication.Program/
RUN dotnet restore
WORKDIR /app
COPY ./src ./src
WORKDIR ./src/MyApplication.Program/
RUN dotnet build MyApplication.Program.csproj -c Release
FROM builder as tester
WORKDIR /app
COPY ./test/MyApplication.UnitTests/MyApplication.UnitTests.csproj ./test/MyApplication.UnitTests/MyApplication.UnitTests.csproj
WORKDIR ./test/MyApplication.UnitTests/
RUN dotnet restore
WORKDIR /app
COPY ./test ./test
WORKDIR ./test/MyApplication.UnitTests/
RUN dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura
ENTRYPOINT ["dotnet", "reportgenerator", "-reports:coverage.cobertura.xml", "-targetdir:codecoveragereports", "-reportTypes:htmlInline"]
The command at the entry point is working correctly. It is writing the output to the MyApplication.UnitTests/codecoveragereports directory, but not to the host directory.
My docker run looks as follows:
docker run --rm -it -v /codecoveragereports:/app/test/MyApplication.UnitTests/codecoveragereports routethink.tests:latest
What could I be doing wrong?
Looks like a permission issue.
-v /codecoveragereports:/app/***/codecoveragereports is mounting a directory under the root / which is dangerous and you may not have the permission.
It's better to mount locally, like -v $PWD/codecoveragereports:/app/***/codecoveragereports, where $PWD is an environment variable equal to the current working directory.