How can I copy a config file within a Dockerfile? - docker

I'm trying to install and configure nginx among other things, but I need to copy an entire config file. I tried simply adding it to the Dockerfile since it's just a few lines, but Dockerfile doesn't seem to have good support for multiline commands. I mean I need to copy my config file as is, I can't pollute it with 'sed', 'cat', or '\' on every line.
Some people suggested placing the config file in a public git repository, and I guess I can do that if it turns out there is no other way. But I don't like it at all because it doesn't make sense. I don't want to have and manage version control repositories for these files (let alone make them public), I just want to copy/paste them. They are very simple!
Any ideas?

You should use the ADD instruction in your Dockerfile to copy the config file into the container.

Related

docker build context and sensitive data

The title of this question might suggest that it has already been answered, but trust me, I searched intensively here on SO :-)
As I understand it when building a docker-image the current folder will be packaged up and sent to the docker-deamon as the build-context. From this build-context the docker-image is build by "ADD"ing or "COPY"ing files and "RUN"ning the commands in the Dockerfile.
And furthermore: In case I have sensitive configuration-files in the folder of the DockerFile, these files will be sent to the docker-deamon as part of the build-context.
Now my question:
Lets say I did not use any COPY or ADD in my Dockerfile... will these configuration files be included somewhere in the docker-image? I ran a bash inside the image and could not find the configuration-files, but maybe they are still somewhere in the deeper layers of the image?
Basically my question is: Will the context of the build be stored in the image?
Only things you explicitly COPY or ADD to the image will be present there. It's common to have lines like COPY . . which will copy the entire context into the image, so it's up to you to check that you're not copying in things you don't want to have persisted and published.
It still is probably a good idea to keep these files from being sent to the Docker daemon at all. If you know which files have this information, you can add them to a .dockerignore file (syntax similar to .gitignore and similar files). There are other ways to more tightly control what's in the build context (by making a shadow install tree that has only the context content) but that's a relatively unusual setup.
As you said only COPY, ADD and RUN operations create layers, and therefore, only those operations add something to the image.
The build context is only the directory with the resources those operations (specifically COPY and ADD) will have access to while building the image. But it's not anything like a "base layer".
In fact, you said you ran bash and double checked that nothing sensitive was there. Another way to make sure about this is by checking the layers of the image. To do so, docker history --no-trunc <image>

Create docker directory structure based on local directory structure

I'm trying to write a Dockerfile. From a directory structure such as:
something/Keep1
something/Keep2
something/... # lots of other files
otherthing/Keep1
otherthing/Keep2
otherthing/...
I would like my dockerfile to import the Keep1 and Keep2 files, without the rest of the files / folders.
Ideally, this would be a simple COPY or ADD command, but I can't seem to get that to work - e.g. COPY */Keep1 ./ only shows a single Keep1, in the current directory, presumably the last one copied.
I could import the whole folder structure and delete anything that isn't Keep1 or Keep2 - but I don't know how this will affect my storage space - presumably all the files will still exist in the layer files?
(Probably not important, but for context, what I'm actually trying to do is import Gemfile and Gemfile.lock files so that I can run bundler from the project folders during docker's build phase and save spin-up time. The Dockerfile bridges several ruby projects that need to co-exist within the same container - but I don't want to hardcode those folder names)

How can I add an xml configuration file to a docker image via a Dockerfile?

I built a .jar file that accesses an .xml file
I add this jar file to docker via a Dockerfile
But how do I add this xml file to the docker image?
According to the Dockerfile best practices, the COPY command is preferred on the ADD command:
Although ADD and COPY are functionally similar, generally speaking, COPY is preferred.
recommended reading for your task:
The "ADD or COPY" section in the Dockerfile best practices.
Docker Tip #2: The Difference between COPY and ADD in a Dockerfile
ADD test-harness.xml test-harness.xml
This basically adds the .xml file to the Docker image and makes it accessible to the jar file which was added in a similar way.

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 do I name the .bowerrc file?

This MEAN-stack tutorial describes using Bower to install AngularJS in your public folder. One of the steps describes creating a file called ".bowerrc" in your test-app folder. However, Windows won't let you create a file without a name. How do I accomplish this on a Windows system?
on the command line (make sure to cd into your working directory), issue this command:
touch .bowerrc
This will also work for other files common to webdev like .htaccess and .gitignore
Note: If you haven't installed git bash for windows, you may not have support for the touch command. In that case (as mentioned in one of the comments here), the easiest way to accomplish this is via the cli with:
echo "" > .bowerrc
To create a file that starts with a "." in Windows, you just need to add a trailing ".".
So, simply name your file ".bowerrc." instead of ".bowerrc".
See https://superuser.com/questions/64471/create-rename-a-file-folder-that-begins-with-a-dot-in-windows for more information and more detailed solution if this doesn't work for you.
Another way to accomplish this is through Notepad++.
Create the file in Notepad++
Set the encoding to "Encoding in ANSI" (click "Encoding" in the menu bar)
Save the file as .bowerrc (change the "Save as type:" to . which is one list item up from *.txt)
Simply rename the file you created:
C:\project> ren bowerrc .bowerrc

Resources