docker-compose project root reference - docker

I have a docker-compose.yml file at the root of my project, and within that project there are several modules in sub-directories.
I find that I can issue docker-compose commands from anywhere within the project root and these work, compose seems to search backwards until it finds the docker-compose file. This is useful.
However, it does not locate the .env file in the project root, it seems to want to find the file in the current folder so docker-compose up commands don't work and I imagine volume mounts that reference folders relative to the docker-compose file may not work either.
How can I change my docker-compose file to such that these references refer to the a location relative to the docker-compose.yml file itself?

Related

Using Docker COPY to copy files to container without keeping directory structure

Starting to use Docker here.
Right now im facing an issue with my project, where I need to copy multiple files from multiple directories to the docker image on start up.
Here is my current code
FROM heroiclabs/nakama:3.11.0
COPY src/*.lua /nakama/data/modules
COPY src/database/*.lua /nakama/data/modules
COPY src/managers/*.lua /nakama/data/modules
COPY src/modules/*.lua /nakama/data/modules
COPY local.yml /nakama/data
What is happening so far is that docker copies only the main.lua file from the starting directory, it either dont copy the remaining ones or copy them with the current data structure.
How can I actually copy it in order to get the lua files from database, manages and modules into the same root directory as main.lua?
To add to this, I get this error on the Nakama console that indicates that a file searched by main.lua module its not found.
{"level":"fatal","ts":"2022-04-28T21:19:51.163Z","caller":"main.go:154","msg":"Failed initializing runtime modules","error":"/nakama/data/modules/src/main.lua:2: module economyManager not found:\n\tno field package.preload['economyManager']\n\tno cached module 'economyManager', \nstack traceback:\n\t[G]: in function 'require'\n\t/nakama/data/modules/src/main.lua:2: in main chunk\n\t[G]: ?"}
So far so good, the / at the end of each COPY line did not do the trick.
Edit:
This is the full directory structure:
src
-database
--luascripts.lua
-managers
--luascripts.lua
-modules
--luascripts.lua
-main.lua
intellisense
-nakama.lua
local.yml
dorckerfile
docker-compose.yml
This helps better illustrate the error. As you can se on the log, docker its copying src directory over to nakama/data/modules, what I aim to do is to copy ONLY the content from src, but not the src directory.
Same can be said for other directories to a lesser degree, my aim is to not carry over directory structure to the destination path
Your command seems to be right, just add a trailing / to the destination docker image's path.
For example,
COPY *.lua /nakama/data/modules/
The error was on the docker-compose file, I was double mounting a volume and that was causing errors on the whole COPY operation.

Docker File Location for Asp.Net core

I am running Docker in Windows, using Linux containers.
I have an asp.net core hello-world app that writes a text file:
var path = Path.Combine(
Directory.GetCurrentDirectory(), "text.txt");
System.IO.File.WriteAllText(path, "text");
Directory.GetCurrentDirectory() comes back as "/app"
In my docker-compose I map /app to /usr/xxxxx
volumes:
- /app:/usr/xxxxx
My question is: Where on my Windows file system is the /usr/xxxxx ? I want to back it up so that it stays after containers are removed.
Volumes (actually bind-mounts) use the format host-path:container-path.
It looks like you put it in the wrong order in the docker-compose file.
Also, as there is no folder called /usr/xxx on windows, just use a path that exists instead.
For example, you can create a directory called "backup" inside the directory with the docker-compose file, and then modify the docker-compose file like so
volumes:
- "./backup:/app"
In the standard Dockerfile that Visual Studio generates, your application dll's are copied into /app. Therefore, it might be a bad choice to use /app. I'm actually not sure what happens if the bind-mount directory already exists with different data inside the container. But you could just write the file to another directory and use that instead.

Running container can't find the file that it has created to /home/user/ directory

I hope you are having a great day!
I'm new to docker. I think my problem is related to docker's directory tree
My app writes to a file to /home/user directory and then after some time reads that file again.
I got this error from my app.
[error] a.a.OneForOneStrategy - /home/user/bkjw_eqvfohygvkaxoxc-small.jpg
java.nio.file.NoSuchFileException: /home/user/bkjw_eqvfohygvkaxoxc-small.jpg
My dockerized app is unable to create the file and read. I'm thinking that the Docker considers the directory /home/user/ as a absolute directory of host.
I thought that the container would write to /home/user directory within the container's directory tree.
So the question is :
How can I specify the path to write the file inside the containers directory tree?
Your understanding about the directory tree is correct. Application running inside a docker container would write to /home/user/ in the container's directory tree.
Your issue seems to be with permissions, your java application probably doesn't have the rights to write to /home/user/ within the container. Either you should change the ownership/rights of the directory you're wanting to write in, or a simple solution I did in such case was to create the directory I wanted to write in, within the java code.
like:
// Create volume directories explicitly so that they are created with correct owner
Files.createDirectories(Paths.get(dirPath));
You can set dirPath String to something like /home/user/mydir IF your requirement is not to write in /home/user/ specifically.

Why is my dockerfile not copying directories

in my dockerfile I have these two lines:
ADD /ansible/inventory /etc/ansible/hosts
ADD /ansible/. /ansiblerepo
The first line works, as I can run the container and see my hosts file has been populated with all the ips from my inventory file.
The second line doesn't appear to be working though. I'm just trying to copy all the files/subdirectories of ansible and copy them over to the ansiblerepo directory inside the new container.
There are no errors while building the image, but again ansiblerepo is just an empty directory and nothing has copied over to it. I assume I'm just missing a back slash or something.
Docker ADD and COPY commands work relative to the build directly, and only for files in that directory that weren't excluded with a .dockerignore file. The reason for this is that builds actually run on the docker host, which may be a remote machine. The first step of a docker build . is to package up all the files in the directory (in this case .) and send them to the host to run your build. Any absolute paths you provide are interpreted as relative to the build directory and anything you reference that wasn't sent to the server will be interpreted as a missing file.
The solution is to copy /ansible to your build directory (typically the same folder as your Dockerfile).
Make sure that in your ".dockerignore" file, it does not excluded everything. usually, dockerignore file has these lines
*
!obj\Docker\publish\*
!obj\Docker\empty\
this means that everything is ignored except publish and empty folders.
Removing trailing /. from source directory should fix the ADD command.
On a related note, Docker Best Practices suggest using COPY over ADD if you don't need the URL download feature.

How to map all containing folders using volume path docker

I'm new to Docker so let me know whether I should be doing something completely different, but here goes..
I'd like to create a volume within an nginx container which maps all sites-enabled configuration files to the location on the container. The catch is, these files are scattered across multiple folders which can be named at random. But wait! I can tell you for certain that the .conf file will always be in a specific folder only 1 level deep (because that's how I prefer the layout to be). Here's a basic layout explaining what I mean:
- images/
- nginx/
- docker-compose.yml
- sites/
- site_a/
- vhost/
site_a.conf
- site_b/
- vhost/
site_b.conf
I have tried to do this when declaring the volumes for nginx:
- ../sites/*/vhost/:/etc/nginx/sites-enabled
Yet I get the following error:
ERROR: for nginx Cannot start service nginx: mkdir /c/Users/Yates/Documents/docker/sites/*: protocol error
I kind of get the error, yet I can't find anything telling me how accomplish what I eventually want. Any help would be much appreciated.
Pretty sure you can't do this.
What you could do is symlink copy all the .conf files into a single directory on the host and use that as your volume mount point. Or just mount the sites/ root directory.
This is a conceptional question and your concept is very fragile and will lead to issues most probably.
What you are doing wrong is:
the configuration for the httpd server is kept inside the sites data/configuration structure or at least its nested inside
You are trying to configure a dynamic amount of 'services' sites using a static+nested folder. You are mixing up "configuration" and data. Try to put your configuration into something like consul/etcd/zookeeper and generate configuration usint tiller ( confd/consul-template)
If you to force it, you can:
Way a)
Mount the volume holding the sites folder in nginx, read only ( however this volume is called )
Then you runn an entrypoint script in the nginx container, some find expression to traverse your "sites" folder, find any site, use the vhost folder and create a symlink from there to /etc/nginx/sites-enabled
You need to also think about deletions, so pick a good namespaces for the symlinks, like mysite.automated.conf and before the entrypoint creates the symlinks, you run rm /etc/nginx/sites-enabled/*automated.conf to flush the potentially outdated/deleted ones. You can do it the update way also, but thats for more complicated..
way b)
If you can, change the structure of sites in general, extrac all "vhosts" into one folder, lets say you will have
sites/vhosts/*.sites.conf
sites/data/siteA/
sites/data/siteA/
and then mount the volume read-only on nginx and symlink sites/vhosts to /etc/nginx/site-enabled ( the folder itself )

Resources