I have a docker-compose setup something like:
/
- sources/
- docker-compose.yml
- Dockerfile
- .dockerignore
- many more files
The Dockerfile contains instructions including a COPY command of the sources.
Because of all the different tools, including multiple docker setups, I'd like to organise it a bit, by either moving all files to a folder:
/
- sources/
- docker/
- many more files
or leaving just the docker-compose.yml file outside of this folder:
/
- sources/
- docker/
- many more files
I'd like to do this because:
It cleans up the project folder
I currently have multiple docker setups in the project folder, moving them to seperate folders allows for a more clear and/or precise setup (e.g. multiple dockerignore files)
Currently I am running into some issues which do make sense, such as:
COPY failed: Forbidden path outside the build context: ../sources/
Is it possible to achieve this setup? Thanks!
Inside the Dockerfile, you cannot access files that are outside the build context. In your case the build context is the directory containing the Dockerfile.
You can change the build context inside the composefile.
Below is an example where the composefile is at the root and Dockerfile is under docker folder:
version: '3'
services:
test:
build:
context: .
dockerfile: docker/Dockerfile
In this case, inside the Dockerfile the file paths should be set relative to the context.
COPY sources sources
For dockerignore:
As specified in the docs for .dockerignore file:
Before the docker CLI sends the context to the docker daemon, it looks for a file named .dockerignore in the root directory of the context
Thus you need to add the dockerignore file to the root of the context.
You can't use that within the Dockerfile however you should be able to make it work using a .env file and pulling it in from there.
https://docs.docker.com/compose/env-file/
You could try something like:
.env
SOURCE_PATH=../sources/
Dockerfile
COPY ${SOURCE_PATH}/myfile /some/destination
Related
After Laravel Sail install, I published the Laravel Sail docker files to my project following the official docs. The directory is at {project root}/docker/8.1. This directory is also the one specified as build context in the docker-compose.yml file. I added a .dockerignore file in that directory with the following content:
**/.devcontainer
**/.git
**/.vscode
**/docker
[...]
When I terminal into the laravel container, the directories and files in my .dockerignore have been copied over despite [internal] load .dockerignore log statement on sail build. sail build is basically an alias for docker compose build.
How can I set-up my .dockerignore for it to be applied on container build?
As a side-note, I don't really understand how the project source files are copied over to the container, as the Dockerfile does not seem to contain COPY or ADD instructions wrt these.
I have looked on this site for answers and on the web without success. I also went through the laravel/sail github issues.
Any input would be greatly appreciated.
By default, the project files are copied over to the container using a volume. This is why the .dockerignore file is ignored. I decided to replace the volume by a COPY command in the Dockerfile:
COPY --chown=$WWWUSER:$WWWGROUP . /var/www/html/
I had to change the docker-compose.yml build directive as follow:
build:
context: .
dockerfile: ./docker/8.1/Dockerfile
args:
WWWUSER: "${WWWUSER}"
WWWGROUP: "${WWWGROUP}"
I adjusted relative paths to local files in the Dockerfile.
I placed the .dockerignore in the project root and it is now taken into account as expected.
replace dockerfile: ./docker/8.1 with context: ./vendor/laravel/sail/runtimes/8.1 in the docker-compose.yml file
I've just installed docker and I'm following the ‘[Getting started tutorial][1]’
[1]: http://localhost/tutorial/our-application/ which is packaged within the Docker install. At the beginning of the tutorial it says...
In order to build the application, we need to use a Dockerfile. A
Dockerfile is simply a text-based script of instructions that is used
to create a container image. Create a file named Dockerfile with the
following contents.....
So far so good, but before issuing the 'Build' command it doesn't specify where I'm supposed to put/save the dockerfile??
You can save your Dockerfile anywhere. You can specify the path to your Dockerfile when running docker build by using flag --file.
A basic Docker folder structure would look something like this:
myapp/
- src/
- Dockerfile
- docker-compose.yml (optional: If you want to use docker-compose)
And the folder structure if you are using multiple services using docker-compose would be:
myapp/
- app1/
- src/
- Dockerfile
- app2/
- src/
- Dockerfile
- docker-compose.yml
But, in these case, you cannot access the files outside the folder containing Dockerfile. In those cases, as mentioned by #Nguyễn you can use a --file flag along with docker build.
I'd like to compose a service while keeping the file structure of my project neat. But Docker appears to have issues with paths outside the build context. I'm creating a package and would like to keep all Docker related stuff in a folder under the project root. But I can't find a way to reference the project files from docker-compose and Dockerfile. When creating the containers files from the project must be copied.
Here's my current project structure:
root/
docker/
docker-compose.yml
Dockerfile
docker_resource.txt
config
src/
project-files.whatever
root-files.txt
Now if I $cd docker and $docker-compose up, there are two possibilities that I've tried. Either my Dockerfile copies the files with COPY .. /path/in/container or the compose file has build instructions like:
x-build: &my-build
context: ..
dockerfile: docker/Dockerfile
The first approach doesn't work. Apparently Dockerfile cannot reference anything outside the build context. The second approach appears to work, but only after I edit my copy command from docker_resource.txt to docker/docker_resource.txt. Ideally I'd like to retain the ability to docker build from ./docker and keep the things clean - not having to worry about the composing context in the Dockerfile. Is this possible?
Minimally I'm after a way to have docker related files in an arbitrary folder and to be able to specify the build context in the compose file without additional changes.
You need to treat src/project-files.whatever like a self-sufficient minimal build. I would put a Dockerfile inside src. It should be treated as part of the project, and should be specific to it. You would still need to edit your copy command though.
root/
docker/
docker-compose.yml
docker_resource.txt
config
src/
project-files.whatever
Dockerfile
root-files.txt
You want to separate your compose and Dockerfile and resources anyway. Depending on what is inside docker_resourceyou may want to move it into src. Think the image as the program itself, with no configuration. I suggest putting resource / config stuff in a volume so that you wouldn't have to rebuild from scratch with every change.
Another way to do it is to put Dockerfile one level above and allow your root to be the build context. Your structure would be something like this in that case:
/root
Dockerfile
docker-compose.yml
docker_resource.txt
config
src/
project-files.whatever
root-Files/
root-files.txt
Not sure if you like that.
Docker is telling me it cant find the specified file. Is my context wrong? My folder structure is as follows.
root
- docker
- docker-compose-service.yml
- service
- DockerFile
Nuget.config
Inside my docker-compose-service.yml file I have
build:
context: .
dockerfile: ../service/DockerFile
I run from the root folder the following command
docker-compose -f docker/docker-compose-service.yml up --build
It can find the Dockerfile as it runs the code but fails on a line inside the dockerFile which is
COPY NuGet.config .
The error is
failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder408021827/NuGet.config: no such file or directory
What am I doing wrong? I played around with the context and dockerFile location but then it couldn't find the DockerFile
Hmm so if I run the command from the docker folder and change the docker-compose-service.yml file to be
context: ../
dockerfile: service/DockerFile
That seems to work
Usually, from what I can see in projects, context's are build in a different way. You should reorganize your project like this:
root
- docker-compose.yml
- service
- Dockerfile
- Nuget.config
The build in the compose file would look like this afterwards:
build: ./service
And you run it like:
docker-compose up --build
The path specified in your docker file sets the context as the parent folder of the compose file.
In order to make it work, you need to either:
Change the context to .
Change the path to NuGet.config to also contain the current folder name: root/NuGet.config
I would recommend the first approach as from your question I don't see any reason you would want to refer to the parent folder.
I'm using docker and docker-compose for building my app. There are two developers now for the project hosted on github.
Our project structure is:
sup
dockerfiles
dev
build
.profile
Dockerfile
docker-compose.yml
Now we have ./dockerfiles/dev/docker-compose.yml like this:
app:
container_name: sup-dev
build: ./build
and ./dockerfiles/dev/build/Dockerfile:
FROM sup:dev
# docker-compose tries to find .profile relative to build dir:
# ./dockerfiles/dev/build
COPY .profile /var/www/
We run container like so:
docker-compose up -d
Everything works fine, but due to different OS we have our code in different places: /home/aliance/www/project for me and /home/user/other/path/project for the second developer. So I can not just add volume instruction into Dockerfile.
Now we solve this problem in this wrong way:
- I am using lsyncd with my personal config to transfer files into the container
- While the second one uses volume instruction into Dockerfile but not commited it.
May be you know how can I write an unified Dockerfile for docker-compose to volume out code into app container from different paths?
The file paths on the host shouldn't matter. Why do you need absolute paths?
You can use paths that are relative to the docker-compose.yml so they should be the same for both developers.
The VOLUME instructions in the Dockerfile are always relative to the build context, so if you want, you can use something like this:
app:
container_name: sup-dev
build: ..
dockerfile: build/Dockerfile
That way the build context for the Dockerfile will be the project root.
Maybe you should keep your Dockerfile at the root of your project. Then you could add an instruction in the Dockerfile:
COPY ./ /usr/src/app/
or (not recommended in prod)
VOLUME /usr/src/app
+ (option while running the container as I don't know docker-compose)
-v /path/to/your/code:/usr/src/app