I am moving our web application to docker-compose deployment (Django, DRF, AngularJS).
Docker looks solid now and things are going well.
I want to:
I've managed to use environment variables and docker-compose secrets read from the Django settings.py
file and it works. The downside is that environment variables are limited to simple strings and can pose some escape challenges when sending Python lists, dictionaries etc. We also have to define and maintain a lot of environment variables since our web app is installed in many place and it's highly configurable.
On frontend side (AngularJS) we have two constants.js
files and the nginx conf.
I've used a CMD ["/start.sh"]
in Dockerfile and have some sed
commands.
But this looks really hackish and it also means that we have to define and maintain quite a few environment variables.
Are Docker volumes a good idea to use for these configuration files?
Does such thing as "volume file" actually exist (mentioned here) or is it actually a bind mount? And bind mounts are less recommendable since they depend on the file system and file path on the host.
Volumes documentation briefly mentions files: "path where the file or directory are mounted in the container", but does not go into greater detail.
Our web app has simple configuration files now:
settings.py
site\contants.js
admin\constants.js
and:
I want to avoid moving those files to dedicated directories that can be mounted.
Can you show me a sample docker-compose.yml with single file volumes (not bind mounts).
Thank you
In Windows containers, configs are all mounted into C:\ProgramData\Docker\configs and symbolic links are created to the desired location, which defaults to C:\<config-name> . You can set the ownership ( uid and gid ) for the config, using either the numerical ID or the name of the user or group.
yml when building a multi-container Docker application. The docker-compose. yml file lets you define a set of related services to be deployed as a composed application with deployment commands. It also configures its dependency relations and runtime configuration.
If you can't use environment variables then you should use a bind mount. If you use a named volume you can't access single files and you can't directly edit the config files.
A named volume is always an entire directory, and can't be directly accessed from the host. There is no such thing as a "volume file" (your linked question is entirely about bind mounts, some using named-volume syntax) and there is no way to mount a single file out of a named volume.
Newer Docker has a couple of different syntaxes for bind mounts (in Compose, the short and long volumes:
service configuration, or creating a type: bind
named volume). These are all basically equivalent, and many of the answers in the question you link to involve making a named volume simulate a bind mount.
Docker Compose supports relative paths, so there is much less of a concern around host paths for bind mounts being non-portable across systems. A basic fragment of a docker-compose.yml
file could include:
services:
app:
build: django
volumes:
- ./config/django-settings.py:/app/settings.py
In this example I'd suggest a (deploy-time) config
directory that contains the configuration files, but that's an arbitrary choice; if you want to bind-mount ./django/settings.py
from the application source tree over what's in the image to be able to directly edit it, that's a valid choice too. You can check this tree into source control, and it will still work regardless of where it's checked out.
If you're using a base image with the full GNU tool set (Ubuntu, not Alpine) then your container entrypoint script can also use envsubst as a very lightweight templating tool (it replaces $VARIABLE
references with the equivalent environment variable), which will help you support the "many options" case but not the "dict-type options" case.
In general I'd recommend bind mounts for two cases and maybe a third: for config files (where the operator needs to directly edit them), for log files (where the operator needs to directly read them) and maybe for persistent data storage (where your existing backup solution will work unmodified; but not on MacOS where it's very slow). Named volumes can be a good match for the persistent-data case and better match what you would use in a clustered environment (Swarm, Kubernetes) but can't be directly accessed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With