How to set up .dockerignore with Laravel Sail? - docker

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

Related

Dockerfile its not copying all files

I'm trying to run a discord.py bot on a docker container. But when I'm running the container, docker says that I'm "missing a module". The Dockerfile its not copying all the files/folders from the source code.
This is my directory:
These are the contents of my docker-compose.yml:
version: '3'
services:
bot:
build: .
restart: always
volumes:
- ./.env:/usr/src/app/.env
This is my Dockerfile:
FROM python:bullseye
WORKDIR /usr/app/src
COPY bot bot
CMD ["python", "-m", "bot"]
When I run # sudo docker compose up It fails with the following log:
Checking the docker image files, it seems like its copying all the contents inside of the bot folder, but its not copying the folder itself.
The code works fine if I run it outside of the container, so is not related to this discord bot code.
How can I fix this?
This is my first docker container I'm new really with this.
The correct syntax should be:
COPY bot bot/
By design, COPY always copies the contents of the directory if the source is a directory, and by adding the trailing / to the destination you tell docker that the destination is a directory, so it will create it for you if needed.
See the full documentation.

docker compose not finding my files

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.

Move docker setup into folder

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

How to set the "current" directory of a Dockerfile with Docker Compose?

I have the following project structure:
.
..
project/
docker/cli/Dockerfile
docker-compose.yml
In docker-compose.yml I have the following configuration:
cli:
build: docker/cli
And somewhere in my Dockerfile:
COPY . /app
Now the problem is that when I do docker-compose build cli docker copies the contents of docker/cli/ in /app in my image. Which makes sense because that is the relative path to my docker/cli/Dockerfile. Is there a way however to tell in my docker-compose.yml config that the path should be different (namely the root dir of my project where the actual project files are)?
You can use the context attribute of a build instruction inside the docker-compose file.
version: '2'
services:
cli:
build:
context: .
dockerfile: docker/cli/Dockerfile
This should work as desired. The context is what is sent to the docker daemon for build. You will also want a .dockerignore file in your project directory though, to ensure only what you need is sent.

Docker VOLUME for different users

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

Resources