I have a repository with a directory structure like this
.
├── Dockerfile
├── README.md
├── frontend/
├── backend/
├── docs/
├── examples/
└── build/
The dockerfile is a simple ADD with no entrypoint:
FROM python:3.6-slim
WORKDIR /app
# Copy and install requirements.txt first for caching
ADD . /app
RUN pip install --no-cache-dir --trusted-host pypi.python.org -r backend/requirements.txt
EXPOSE 8200
WORKDIR /app/backend
My issue is that after docker build -t myimage ., the build folder is missing from the image.
I just ran an ls when verifying the image contents with docker run -it myimage /bin/bash, and the build folder is missing!
.
├── frontend/
├── backend/
├── docs/
├── examples/
Does anyone know why? How can I add modify my Dockerfile to add this folder into my image? All resources online say that ADD . <dest> should duplicate my current directory tree inside the image, but the build folder is missing...
Missed that there's a .dockerignore file in the repo that contains this folder. Whooooops, thank you #David Maze.
Related
I have a hard time dockerizing a web app with following structure:
├── Dockerfile
├── file1.txt
├── file2.txt
├── file3.txt
├── go.mod
└── src
├── go
│ ├── handlers
│ │ └── handlers.go
│ ├── main.go
│ └── parsetext
│ └── parsetext.go
└── resources
├── static
│ └── style.css
└── templates
├── index.html
└── result.html
I have tried multiple ways to build an image and none of them were successful so far. Here are some of them.
FROM golang:1.19
WORKDIR /app
COPY go.mod ./
COPY *.go ./
RUN go build -o /app
EXPOSE 8080
CMD [ "/app" ]
FROM golang:1.19
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY src/go/main.go app/src/go
COPY src/go/handlers/*.go app/src/go/handlers
COPY src/go/parsetext/*.go app/src/go/parsetext
COPY src/resources/static/*.css app/src/resources/static
COPY src/resources/templates/*.html app/src/resources/templates
RUN go build -o /app
EXPOSE 8080
CMD [ "/app" ]
I would truly appreciate any help with this
I found two issues in your Dockerfile:
COPY *.go ./:
It only copies *.go files in the current directory. I think you want to copy the whole directory like this: COPY src/go ./src/go
RUN go build -o /app:
The specified build artifact /app conflicts with the directory created by WORKDIR /app. And I think that you should specify the package to build. I believe the correct one should be: RUN go build -o theapp ./src/go (change to artifact name theapp to whatever you like).
Here is the one that may work for you. And multi-stage build is recommended.
# =============== build stage ===============
FROM golang:1.19 as build
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY src/go ./src/go
RUN go build -o theapp ./src/go
# =============== final stage ===============
FROM debian:bullseye AS final
WORKDIR /app
EXPOSE 8080
COPY --from=build /app/theapp ./
# Make sure the resources folder is copied to the correct place that your app expected.
COPY src/resources ./resources
CMD [ "/app/theapp" ]
I built a small Golang application and I want to run it on a Docker container.
I wrote the following Dockerfile:
# syntax=docker/dockerfile:1
FROM golang:1.16-alpine
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY ./* .
RUN go env -w GO111MODULE=on
RUN go build -o /docker-gs-ping
EXPOSE 8080
CMD [ "/docker-gs-ping" ]
However, when I run the command:
docker build --tag docker-gs-ping .
I get the errors:
#16 0.560 found packages controllers (controller.go) and repositories (csv_file_repository.go) in /app
#16 0.560 main.go:4:2: package MyExercise/controllers is not in GOROOT (/usr/local/go/src/MyExercise/controllers)
I want to mention that the package controllers exists in my working directory and all files associated with this directory are placed in MyExercise/controllers folder.
Do you know how to resolve this error?
Edit:
This is the directory tree:
.
├── Dockerfile
├── REDAME
├── controllers
│ └── controller.go
├── go.mod
├── go.sum
├── logging
│ └── logger.go
├── main.go
├── models
│ └── location.go
├── output.log
├── repositories
│ ├── csv_file_repository.go
│ ├── csv_file_repository_builder.go
│ ├── csv_file_repository_builder_test.go
│ ├── csv_file_repository_test.go
│ ├── repository_builder_interface.go
│ ├── repository_interface.go
│ └── resources
│ └── ip_address_list.txt
└── services
├── ip_location_service.go
├── ip_location_service_test.go
├── rate_limiter_service.go
├── rate_limiter_service_interface.go
├── rate_limiter_service_test.go
└── time_service.go
import section in main.go:
import (
"MyExercise/controllers"
"MyExercise/logging"
"MyExercise/repositories"
"MyExercise/services"
"errors"
"github.com/gin-gonic/gin"
"os"
"strconv"
"sync"
)
Do go mod vendor in your app directory. Documentaion.
For build the container docker build -t app:v1 .
Dockerfile
FROM golang:1.16-alpine
WORKDIR /app/
ADD . .
RUN go build -o /app/main
EXPOSE 5055
CMD [ "/app/main" ]
There is actually an issue with your Dockerfile.
COPY ./* .
does not actually do what you think. It will copy all files recursively in a flat structure to the /app directory.
Modify your Dockerfile to something like:
# syntax=docker/dockerfile:1
FROM golang:1.16-alpine
WORKDIR /app
ADD . /app
RUN go mod download
RUN go env -w GO111MODULE=on
RUN go build -o /docker-gs-ping
EXPOSE 8080
CMD [ "/docker-gs-ping" ]
Basically, remove all of the COPY directives and replace with a single ADD directive
Dockerfile and build context file tree, the core-site.xml file's relative path IS conf/etc/hadoop
.
├── Dockerfile
└── conf
├── etc
│ └── hadoop
│ └── core-site.xml
└── xxx.conf
Dockerfile(very simple) as below
FROM alpine:latest
RUN mkdir -p /data
WORKDIR /data
COPY conf/* /data/
After docker build -t any/any:any ., the COPY layer's file list as below. Intermediate path etc/ of file core-site.xml lost. Where the etc/ gone ?
data/
data/xxx.conf
data/hadoop/
data/hadoop/.wh..wh..opq
data/hadoop/core-site.xml
Remove the * so you just have COPY conf /data
The COPY command treats the copying of files and directories a bit differently. Your COPY statement expands to
COPY conf/etc /data/
COPY conf/xxx.conf /data/
The first statement actually copies the contents of conf/etc into the /data directory on the container.
Have a Dockerfile to build releases for an Elixir/Phoenix application...The tree directory structure is as follows, where the Dockerfile (which has a dependency on this other Dockerfile) is in the "infra" subfolder and needs access to all the files one level above "infra".
.
├── README.md
├── assets
│ ├── css
│ ├── js
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
├── lib
├── infra
│ ├── Dockerfile
│ ├── config.yaml
│ ├── deployment.yaml
The Dockerfile looks like:
# https://github.com/bitwalker/alpine-elixir
FROM bitwalker/alpine-elixir:latest
# Set exposed ports
EXPOSE 4000
ENV PORT=4000
ENV MIX_ENV=prod
ENV APP_HOME /app
ENV APP_VERSION=0.0.1
COPY ./ ${HOME}
WORKDIR ${HOME}
RUN mix deps.get
RUN mix compile
RUN MIX_ENV=${MIX_ENV} mix distillery.release
RUN echo $HOME
COPY ${HOME}/_build/${MIX_ENV}/rel/my_app/releases/${APP_VERSION}/my_app.tar.gz .
RUN tar -xzvf my_app.tar.gz
USER default
CMD ./bin/my_app foreground
The command "mix distillery.release" is what builds the my_app.tar.gz file in the path indicated by the COPY command.
I invoke the docker build as follows in the top-level directory (the parent directory of "infra"):
docker build -t my_app:local -f infra/Dockerfile .
I basically then get an error with COPY:
Step 13/16 : COPY ${HOME}/_build/${MIX_ENV}/rel/my_app/releases/${APP_VERSION}/my_app.tar.gz .
COPY failed: stat /var/lib/docker/tmp/docker-builder246562111/opt/app/_build/prod/rel/my_app/releases/0.0.1/my_app.tar.gz: no such file or directory
I understand that the COPY command depends on the "build context" but I thought that by issuing the "docker build" in the parent directory of infra meant I had the appropriate context set for the COPY, but clearly that doesn't seem to be the case. Is there a way to have a Dockerfile one level below the parent directory that contains all the files needed to build an Elixir/Phoenix "release" (the my_app.tar.gz and associated files created via the command mix distillery.release)? What bits am I missing?
So I have a tree that looks like this:
.
├── README.md
├── dataloader
│ ├── Dockerfile
...
│ ├── log.py
│ ├── logo.py
│ ├── processors
...
│ └── tests
├── datastore
│ ├── datastore.py
and the Dockerfile inside the dataloader application looks like this:
FROM python:3.7
WORKDIR /var/dsys-2uid-dataloader
COPY assertions/ ./assertions/
COPY events/ ./events/
COPY processors/ ./processors/
COPY requirements.txt ./
<*>COPY datastore/ ./datastore/
COPY *.py ./
RUN pip3 install -r requirements.txt
ENTRYPOINT ["python", "dataloader.py"]
the line with the asterisk doesn't work since the datastore folder is in the parent of the Dockerfile. What can be done? I need this Dockerfile to be correct because it's going to be used as the image in the kubernetes deployment.
You can't access a file outside of your build context, but you can "trick" docker to be in a different build context.
Just run docker build -t foo -f dataloader/Dockerfile . from the root directory (where you have the README and the dirs)
$ tree
.
├── bar
│ └── wii
└── foo
└── Dockerfile
2 directories, 2 files
$ cat foo/Dockerfile
FROM ubuntu
COPY bar/wii .
$ docker build -t test -f foo/Dockerfile .
Sending build context to Docker daemon 3.584kB
Step 1/2 : FROM ubuntu
---> cf0f3ca922e0
Step 2/2 : COPY bar/wii .
---> c3ff3f652b4d
Successfully built c3ff3f652b4d
Successfully tagged test:latest