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 )
Related
I have a question about the .dockerignore workflow which I wasn't really able to understand while browsing through the documentation and different internet topics.
Have the following folder structure:
home
|
|- folder_1
|- folder_2
Inside my dockerfile I want to copy the contents of home directory, so I use
COPY ./ /home
Inside .dockerignore I have:
*
!folder_1
!folder_3
I am referring to a non-existent folder - folder_3, which is supposed to be copied, right?
I ran it and it looks like there's no problem with that, thus .dockerignore somehow manages this situation.
If I tried to do the same thing without using .dockerignore, targeting a non-existent directory I would get an error.
If anybody can please clear this workflow, or if a duplicate, please attach some information so I can educate myself.
Thanks in advance!
First of all, .dockerignore works like .gitignore. Inside these files you set the rules on the basis of which files should be added, and which should not.
In your scenario you COPY the whole home directory which consists of folder_1 and folder_2. Your .dockerignore file sets the following rules:
* # ignore all files/directories
!folder_1 # do not ignore folder_1
!folder_3 # do not ignore folder_3
Regardless of whether there is a folder_1 or folder_3 in your local home directory or not, it won't show you any errors, because it just tries to find particular files/directories that are inside .dockerignore. If it finds this file/directory, it applies the rules. If it doesn't find this file/directory, it doesn't do anything with it.
Hope that's a little bit more clear now.
You'll occasionally see reference to a Docker build context. The build has two steps:
The docker build client application creates a tar file of its directory parameter, and sends it in an HTTP request to the Docker daemon.
The Docker daemon unpacks the tar file, finds the Dockerfile in it, and runs it using the file content it was given.
.dockerignore only affects the first step: it keeps docker build from sending the Docker daemon particular files. The .dockerignore file doesn't require there to be a folder_3 directory, it just says that if there is one it shouldn't be excluded. The second step on the Docker daemon side doesn't use .dockerignore at all, and when you COPY . /somewhere it copies the entire build context; that is, whatever was sent in the API request.
There are a couple of practical consequences of this workflow. If you have a very large local directory it can take time to send it to the Docker daemon, and the Docker daemon keeps a duplicate copy of it during the build, so it's often worthwhile to .dockerignore your .git directory and a build tree. This setup is also how docker build works with a Docker daemon on a different system or in a VM, and it's why if you try to COPY a file by name that doesn't exist (COPY folder_3 somewhere) you get an error message referencing a Docker-internal path.
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.
Hi I have multiple folders that I wish to mount. this is the scenario:
On my host:
path\to\mount\HostFolder\folder_*
On my container:
\path\to\mount\ContainerFolder\
* is a number
I want to mount all folder_* to ContainerFolder\
ContainerFolder already have some folders inside so I must not mount HostFolder to ContainerFolder to save them.
I wish to use regex but volume keyword doesn't seems to support it, any suggestions how to manage that?
My only idea right now is script to write for me the docker-compose.
My suggestion would be to seriously reconsider the assumption that you need the current directory structure. (Of course, this may be impossible, I know.)
If you can change the directory structure at all, you can try restructuring the folders like this:
ContainerFolder
folders
folder_1
folder_2
In this way, you can mount the HostFolder into a subdirectory of ContainerFolder without overwriting the contents of ContainerFolder itself.
I want to run an already existing app on docker. The app interacts with some files on a folder. So i am trying to hook up a volume.
Here is the docker-compose:
test:
container_name: test
volumes:
- C:\test\:\test\
build: .
When i hook into the docker image i can see that the folder is created on the root folder. Now i need to write the correct path to that folder into the application settings.
Before it was something like this:
"test": {
"Path": "C:\\test\\"
}
But i dont know how to get the absolute path of my folder from inside docker, so my app can understand where to search for it.
Thank you
EDIT: it looks like the problem was on my side: the way i defined the volumes created a folder with the name "\test\" ... doing C:\test:/test/ instead did the trick
If you’re building your own Docker image, you control the filesystem layout entirely. For Linux-based images it’s common to follow the FHS standard (I think the standard MySQL image stores its data in /var/lib/mysql) but it’s also common enough to just store data in subdirectories of the root directory (/data or /config or what not).
If you have a setup like this, your image should pick a path. If the only thing in the configuration is the location of that directory, it’s fine to hard-code it in the image. However you document your image (even if it’s just a standard docker-compose.yml file) mention that you have this fixed path; it doesn’t need to match the host path (if any) on any particular system.
How to make dockerfile and .conf file are not accessible direct
through url
Look this url
http://localhost/dockerfile
http://localhost/nginx.conf
If I Open this url this files are downloadable which should be not. How can i prevent this?
You can use a .dockerignore file to avoid sending files to your container. See docs here for things like your Dockerfile.
To exclude config files and others that you need in your container from being served, you would do this via your web server config. E.g., for nginx:
location ~ (\.conf$|Dockerfile) {
return 403;
}
As a best practice, you might want to structure your project so the Dockerfile root isn't the same as your web root, similar as to how would (should) structure a non-Dockerized app.