I have a simple application that uses github.com/go-sql-driver/mysql to connect to a MySQL database and execute simple queries. This all works fine on my local machine, however when I try to build it using docker build I get the following output:
[+] Building 4.1s (9/10)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 104B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/golang:onbuild 1.3s
=> [auth] library/golang:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 5.63kB 0.0s
=> CACHED [1/2] FROM docker.io/library/golang:onbuild#sha256:c0ec19d49014d604e4f62266afd490016b11ceec103f0b7ef44 0.0s
=> [2/2] COPY . /go/src/app 0.1s
=> [3/2] RUN go-wrapper download 2.0s
=> ERROR [4/2] RUN go-wrapper install 0.6s
------
> [4/2] RUN go-wrapper install:
#8 0.465 + exec go install -v
#8 0.535 github.com/joho/godotenv
#8 0.536 github.com/go-sql-driver/mysql
#8 0.581 # github.com/go-sql-driver/mysql
#8 0.581 ../github.com/go-sql-driver/mysql/driver.go:88: undefined: driver.Connector
#8 0.581 ../github.com/go-sql-driver/mysql/driver.go:99: undefined: driver.Connector
#8 0.581 ../github.com/go-sql-driver/mysql/nulltime.go:36: undefined: sql.NullTime
------
executor failed running [/bin/sh -c go-wrapper install]: exit code: 2
My go version is up to date and I am using the following dockerfile:
FROM golang:onbuild
To my knowledge this should go get all the packages it requires. I've also tried it this way:
FROM golang:onbuild
RUN go get "github.com/go-sql-driver/mysql"
This had the same output.
Note that in my code I import the package like this:
import _ "github.com/go-sql-driver/mysql"
I also use other packages from github, these seem to work fine.
The Docker community has generally been steering away from the Dockerfile ONBUILD directive, since it makes it very confusing what will actually happen in derived images (see the various comments around "is that really the entire Dockerfile?"). If you search Docker Hub for the golang:onbuild image you'll discover that this is Go 1.7 or 1.8; Go modules were introduced in Go 1.11.
You'll need to update to a newer base image, and that means writing out the Dockerfile steps by hand. For a typical Go application this would look like
FROM golang:1.18 AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY ./ ./
RUN go build -o myapp .
FROM ubuntu:20.04
COPY --from=build /app/myapp /usr/local/bin
CMD ["myapp"]
(In the final stage you may need to RUN apt-get update && apt-get install ... a MySQL client library or other tools.)
I am trying to build a vue app docker image but I keep getting this error
Module not found: Error: Can't resolve './src/main.js' in '/app'
I am using the a multi-stage dockerfile
FROM node:15.4 as build
WORKDIR /app
COPY ./frontend/package.json .
RUN npm install
COPY . .
RUN npm run build
FROM nginx:1.19
COPY ./frontend/nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/dist /usr/share/nginx/html
Here's the script section of the package.json file
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
This is a detailed log of the build process
[+] Building 26.9s (14/16)
=> [internal] load build definition from frontend.dockerfile 0.0s
=> => transferring dockerfile: 293B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 34B 0.0s
=> [internal] load metadata for docker.io/library/nginx:1.19 2.5s
=> [internal] load metadata for docker.io/library/node:15.4 2.4s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [auth] library/nginx:pull token for registry-1.docker.io 0.0s
=> [build 1/6] FROM docker.io/library/node:15.4#sha256:a76eb778d162f8fd96138d9ca7dbd14b8916c201775a97d2f2aa22e9f13eb105 0.0s
=> [stage-1 1/3] FROM docker.io/library/nginx:1.19#sha256:df13abe416e37eb3db4722840dd479b00ba193ac6606e7902331dcea50f4f1f2 0.0s
=> [internal] load build context 8.5s
=> => transferring context: 166.03MB 8.4s
=> CACHED [build 2/6] WORKDIR /app 0.0s
=> CACHED [build 3/6] COPY ./frontend/package.json . 0.0s
=> CACHED [build 4/6] RUN npm install 0.0s
=> [build 5/6] COPY . . 7.4s
=> ERROR [build 6/6] RUN npm run build 8.3s
------
> [build 6/6] RUN npm run build:
#14 2.913
#14 2.913 > frontend#0.1.0 build
#14 2.913 > vue-cli-service build
#14 2.913
#14 4.668 All browser targets in the browserslist configuration have supported ES module.
I move the frontend folder from the project to stand alone and I am able to build the image and run a container based on it successfully.
What could possibly be wrong here?
I try to give you some help. First of all I assume your nginx.conf file is located in the upper nginx folder. I see two in your repo. If this is the case you are copying one layer to deep. I suggest to change your file as follows with this order:
FROM node:alpine as build
WORKDIR /app
COPY ./package*.json ./
RUN npm install
COPY "frontend/target/dist" ./
FROM nginx:alpine as production
COPY ./frontend/nginx/nginx.conf /etc/nginx/conf.d/nginx.conf
RUN rm -rf /usr/share/nginx/html/*
COPY --from=build /app /usr/share/nginx/html
What I changed was the layer of the folders you are trying to add and the asterix (*) in package.json. If you are defining a frontend before, you are also searching it in the copied part, which is not existing in the nginx image. Also as you see you only need /app instead of /app/dist. Additional your /etc... config path was wrongly referenced. Give it a shot now. It should work like this with the given information I had.
Add in your .dockerignore file only those lines:
node_modules
dist
I am trying to create a docker image for a svelte application. The svelte application I am using is just the svelte template with TypeScript initiated. I have made no changes to the application itself, my only goal is to serve the svelte application using Docker. I am using yarn berry (v2) as my package manager and rollupjs for the build process. This is my first question so please let me know if something is missing.
I am expecting the image to be built, but when the build process reaches the "yarn build" command, it never completes. It doesn't crash either, but it never completes the build step either. It seems to hang at the bundling step:
=> => # src/main.ts → public/build/bundle.js...
The build command from package.json:
"build": "rollup -c"
My Dockerfile was initially taken from here: https://sveltesociety.dev/recipes/publishing-and-deploying/dockerize-a-svelte-app/. However, I had to make some changes to it for yarn v2 and I found the following stack thread: Using Yarn 2 (Berry) for packaging application in a Docker image. Adding some modifications form that question left me with the following Dockerfile:
WORKDIR /app
COPY package.json ./
RUN yarn set version berry
COPY .yarn ./.yarn
COPY yarn.lock .yarnrc.yml ./
RUN yarn plugin import workspace-tools
RUN yarn workspaces focus -A --production
COPY . ./
RUN yarn build # This is where it gets stuck
FROM nginx:1.19-alpine
COPY --from=build /app/public /usr/share/nginx/html
I run the command docker build -t svelte-image . to build and this is the output I get:
[+] Building 572.6s (16/18)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 34B 0.0s
=> [internal] load metadata for docker.io/library/nginx:1.19-alpine 1.2s
=> [internal] load metadata for docker.io/library/node:12 1.1s
=> CACHED [stage-1 1/2] FROM docker.io/library/nginx:1.19-alpine#sha256:07ab71a2c8e4ecb19a5a5abcfb3a4f175946c001c8af288b1aa766d67b0 0.0s
=> CACHED [build 1/6] FROM docker.io/library/node:12#sha256:cc4adb82efc04b74b9f96326e682ad04be2df84d23e40609802eb6d6c207abde 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 69.58kB 0.0s
=> CACHED [stage-1 2/3] RUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf 0.0s
=> CACHED [build 2/10] WORKDIR /app 0.0s
=> CACHED [build 3/10] COPY package.json ./ 0.0s
=> CACHED [build 4/10] RUN yarn set version berry 0.0s
=> [build 5/10] COPY .yarn ./.yarn 0.2s
=> [build 6/10] COPY yarn.lock .yarnrc.yml ./ 0.0s
=> [build 7/10] RUN yarn plugin import workspace-tools 1.5s
=> [build 8/10] RUN yarn workspaces focus -A --production 0.5s
=> [build 9/10] COPY . ./ 0.1s
=> [build 10/10] RUN yarn build 568.9s
=> => # src/main.ts → public/build/bundle.js... # -> Never completes
I have been trying to figure out why the build hangs, but I am unable to find the source of error. It works just fine when building locally with yarn build. Does anyone have any clue as to why it hangs in the bundling process?
I did not figure out what was wrong, but I managed to build the docker image and run it successfully. Here is the working Dockerfile:
FROM node:16 AS build
WORKDIR /app
COPY package.json ./
RUN yarn set version berry
COPY .yarn ./.yarn #
COPY yarn.lock .yarnrc.yml ./
RUN yarn install
# These two lines are from the original example. It did not work to use this,
# but I leave it here to highlight the difference
## RUN yarn plugin import workspace-tools
## RUN yarn workspaces focus -A --production
COPY . ./
RUN yarn build
FROM nginx:1.19-alpine
COPY --from=build /app/public /usr/share/nginx/html
I am new to Docker, and this issue has me completely stumped. None of the online solutions are working for me, so any help would be appreciated.
So I am trying to build a docker image for a .NET 5.0 web application that also references a class library project. This is for a Linux container on a Windows machine, and Docker Desktop has been set to 'Linux containers'.
This is my directory structure-
I have my solution file here:
D:\Repo\HostServer-v2\HostServer\HostServer.sln
The main web application project is located here (also contains the Dockerfile):
D:\Repo\HostServer-v2\HostServer\HostServer\HostServer.csproj
The class library project is located here:
D:\Repo\HostServer-v2\HostServer\QuicktronWrapper.csproj
Visual studio created the following Dockerfile in D:\Repo\HostServer-v2\HostServer\HostServer\
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["HostServer/HostServer.csproj", "HostServer/"]
COPY ["QuicktronWrapper/QuicktronWrapper.csproj", "QuicktronWrapper/"]
RUN dotnet restore "HostServer/HostServer.csproj"
COPY . .
WORKDIR "/src/HostServer"
RUN dotnet build "HostServer.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HostServer.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HostServer.dll"]
and a .dockerignore has been created here:
D:\Repo\HostServer-v2\HostServer
I know that all projects should be in the same build conext for Docker, so I run the following command from D:\Repo\HostServer-v2\HostServer
docker build -f D:\Repo\HostServer-v2\HostServer\HostServer -t hostserver .
But I get the following error:
[+] Building 0.0s (2/2) FINISHED
=> [internal] load build definition from HostServer 0.0s
=> => transferring dockerfile: 20.52kB 0.0s
=> CANCELED [internal] load .dockerignore 0.0s
=> => transferring context: 0.0s
failed to solve with frontend dockerfile.v0: failed to read dockerfile: read /var/lib/docker/tmp/buildkit-mount468265171/HostServer: is a directory
PS D:\Repo\HostServer-v2\HostServer>
I know it has something to do with the Dockerfile.
Please help.
The problem has shown in the error "HostServer: is a directory". It requires a file, not a directory. You can refer to this
Please try to run the command by providing explicitly a Dockerfile name docker build -f HostServer\Dockerfile -t hostserver . from the directory D:\Repo\HostServer-v2\HostServer as you did.
Inside of my Dockerfiles I would like to COPY a file into my image if it exists, the requirements.txt file for pip seems like a good candidate but how would this be achieved?
COPY (requirements.txt if test -e requirements.txt; fi) /destination
...
RUN if test -e requirements.txt; then pip install -r requirements.txt; fi
or
if test -e requirements.txt; then
COPY requiements.txt /destination;
fi
RUN if test -e requirements.txt; then pip install -r requirements.txt; fi
Here is a simple workaround:
COPY foo file-which-may-exist* /target
Make sure foo exists, since COPY needs at least one valid source.
If file-which-may-exist is present, it will also be copied.
NOTE:
You should take care to ensure that your wildcard doesn't pick up other files which you don't intend to copy. To be more careful, you could use file-which-may-exist? instead (? matches just a single character).
Or even better, use a character class like this to ensure that only one file can be matched:
COPY foo file-which-may-exis[t] /target
As stated by this comment, Santhosh Hirekerur's answer still copies the file, to achieve a true conditional copy, you can use this method.
ARG BUILD_ENV=copy
FROM alpine as build_copy
ONBUILD COPY file /file
FROM alpine as build_no_copy
ONBUILD RUN echo "I don't copy"
FROM build_${BUILD_ENV}
# other stuff
The ONBUILD instructions ensures that the file is only copied if the "branch" is selected by the BUILD_ENV. Set this var using a little script before calling docker build
This isn't currently supported (as I suspect it would lead to a non-reproducible image, since the same Dockerfile would copy or not the file, depending on its existence).
This is still requested, in issue 13045, using wildcards: "COPY foo/* bar/" not work if no file in foo" (May 2015).
It won't be implemented for now (July 2015) in Docker, but another build tool like bocker could support this.
2021:
COPY source/. /source/ works for me (i.e. copies directory when empty or not, as in "Copy directory into docker build no matter if empty or not - fails on "COPY failed: no source files were specified"")
2022
Here is my suggestion:
# syntax=docker/dockerfile:1.2
RUN --mount=type=bind,source=jars,target=/build/jars \
find /build/jars -type f -name '*.jar' -maxdepth 1 -print0 \
| xargs -0 --no-run-if-empty --replace=source cp --force source >"${INSTALL_PATH}/modules/"
That works around:
COPY jars/*.jar "${INSTALL_PATH}/modules/"
But copies no *.jar if none is found, without throwing an error.
I think I came up with a valid workaround with this Dockerfile
FROM alpine
COPy always_exist_on_host.txt .
COPY *sometimes_exist_on_host.txt .
The always_exist_on_host.txt file will always be copied to the image and the build won't fail to COPY the sometimes_exist_on_host.txt file when it doesn't exist. Furthermore, it will COPY the sometimes_exist_on_host.txt file when it does exist.
For example:
.
├── Dockerfile
└── always_exist_on_host.txt
build succeeds
docker build . -t copy-when-exists --no-cache
[+] Building 1.0s (7/7) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 36B 0.0s
=> [internal] load metadata for docker.io/library/alpine:latest 1.0s
=> [internal] load build context 0.0s
=> => transferring context: 43B 0.0s
=> CACHED [1/2] FROM docker.io/library/alpine#sha256:c0e9560cda118f9ec63ddefb4a173a2b2a0347082d7dff7dc14272e7841a5b5a 0.0s
=> [2/2] COPY always_exist_on_host.txt *sometimes_exist_on_host.txt . 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:e7d02c6d977f43500dbc1c99d31e0a0100bb2a6e5301d8cd46a19390368f4899 0.0s
.
├── Dockerfile
├── always_exist_on_host.txt
└── sometimes_exist_on_host.txt
build still succeeds
docker build . -t copy-when-exists --no-cache
[+] Building 1.0s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 36B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/alpine:latest 0.9s
=> [internal] load build context 0.0s
=> => transferring context: 91B 0.0s
=> CACHED [1/2] FROM docker.io/library/alpine#sha256:c0e9560cda118f9ec63ddefb4a173a2b2a0347082d7dff7dc14272e7841a5b5a 0.0s
=> [2/2] COPY always_exist_on_host.txt *sometimes_exist_on_host.txt . 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:4c88e2ffa77ebf6869af3c7ca2a0cfb9461979461fc3ae133709080b5abee8ff 0.0s
=> => naming to docker.io/library/copy-when-exists 0.0s
Work around Solution
I had requirement on copy FOLDER to server based on ENV Variables. I took the empty server image. created required deployment folder structure at in local folder. then added below line to DockerFile copy the folder to container. In last line added entry point to execute init file.sh before docker start the server.
#below lines added to integrate testing framework
RUN mkdir /mnt/conf_folder
ADD install /mnt/conf_folder/install
ADD install_test /mnt/conf_folder/install_test
ADD custom-init.sh /usr/local/bin/custom-init.sh
ENTRYPOINT ["/usr/local/bin/custom-init.sh"]
Then create the custom-init.sh file in local with script something like below
#!/bin/bash
if [ "${BUILD_EVN}" = "TEST" ]; then
cp -avr /mnt/conf_folder/install_test/* /mnt/wso2das-3.1.0/
else
cp -avr /mnt/conf_folder/install/* /mnt/wso2das-3.1.0/
fi;
In docker-compose file below lines.
environment:
- BUILD_EVN=TEST
These changes copy folder to container during docker build. when we execute docker-compose up it copy or deploy the actual required folder to server before server starts.
Copy all files to a throwaway dir, hand pick the one you want, discard the rest.
COPY . /throwaway
RUN cp /throwaway/requirements.txt . || echo 'requirements.txt does not exist'
RUN rm -rf /throwaway
You can achieve something similar using build stages, which relies on the same solution, using cp to conditionally copy. By using a build stage, your final image will not include all the content from the initial COPY.
FROM alpine as copy_stage
COPY . .
RUN mkdir /dir_for_maybe_requirements_file
RUN cp requirements.txt /dir_for_maybe_requirements_file &>- || true
FROM alpine
# Must copy a file which exists, so copy a directory with maybe one file
COPY --from=copy_stage /dir_for_maybe_requirements_file /
RUN cp /dir_for_maybe_requirements_file/* . &>- || true
CMD sh
Tried the other ideas, but none met our requirement. The idea is to create base nginx image for child static web applications. For security, optimization, and standardization reasons, the base image must be able to RUN commands on directories added by child images. The base image does not control which directories are added by child images. Assumption is child images will COPY resources somewhere under COMMON_DEST_ROOT.
This approach is a hack, but the idea is base image will support COPY instruction for 1 to N directories added by child image. ARG PLACEHOLDER_FILE and ENV UNPROVIDED_DEST are used to satisfy <src> and <dest> requirements for any COPY instruction not needed.
#
# base-image:01
#
FROM nginx:1.17.3-alpine
ENV UNPROVIDED_DEST=/unprovided
ENV COMMON_DEST_ROOT=/usr/share/nginx/html
ONBUILD ARG PLACEHOLDER_FILE
ONBUILD ARG SRC_1
ONBUILD ARG DEST_1
ONBUILD ARG SRC_2
ONBUILD ARG DEST_2
ONBUILD ENV SRC_1=${SRC_1:-PLACEHOLDER_FILE}
ONBUILD ENV DEST_1=${DEST_1:-${UNPROVIDED_DEST}}
ONBUILD ENV SRC_2=${SRC_2:-PLACEHOLDER_FILE}
ONBUILD ENV DEST_2=${DEST_2:-${UNPROVIDED_DEST}}
ONBUILD COPY ${SRC_1} ${DEST_1}
ONBUILD COPY ${SRC_2} ${DEST_2}
ONBUILD RUN sh -x \
#
# perform operations on COMMON_DEST_ROOT
#
&& chown -R limited:limited ${COMMON_DEST_ROOT} \
#
# remove the unprovided dest
#
&& rm -rf ${UNPROVIDED_DEST}
#
# child image
#
ARG PLACEHOLDER_FILE=dummy_placeholder.txt
ARG SRC_1=app/html
ARG DEST_1=/usr/share/nginx/html/myapp
FROM base-image:01
This solution has obvious shortcomings like the dummy PLACEHOLDER_FILE and hard-coded number of COPY instructions that are supported. Also there is no way to get rid of the ENV variables that are used in the COPY instruction.
I have other workarounds for the same. The idea is to touch the file in the build context and use the copy statement inside the Dockerfile. If the file exists it will just create an empty file and the docker build will not fail. If there is already a file it will just change the time stamp.
touch requirements.txt
and for Dockerfile
FROM python:3.9
COPY requirements.txt .