I recently came across this and was wondering what &django means
version: '2'
services:
django: &django
I can't see anything in the docs related to this.
These are a YAML feature called anchors, and are not particular to Docker Compose. I would suggest you have a look at below URL for more details
https://learnxinyminutes.com/docs/yaml/
Follow the section EXTRA YAML FEATURES
YAML also has a handy feature called 'anchors', which let you easily duplicate
content across your document. Both of these keys will have the same value:
anchored_content: &anchor_name This string will appear as the value of two keys.
other_anchor: *anchor_name
Anchors can be used to duplicate/inherit properties
base: &base
name: Everyone has same name
foo: &foo
<<: *base
age: 10
bar: &bar
<<: *base
age: 20
To complement Tarun's answer, & identifies an anchor and * is an alias referring back to the anchor. It is described as the following in the YAML specification:
In the representation graph, a node may appear in more than one
collection. When serializing such data, the first occurrence of the
node is identified by an anchor. Each subsequent occurrence is
serialized as an alias node which refers back to this anchor.
Sidenote:
For those who want to start using anchors in your docker-compose files, there is more powerful way to make re-usable anchors by using docker-compose YAML extension fields.
version: "3.4"
# x-docker-data is an extension and when docker-compose
# parses the YAML, it will not do anything with it
x-docker-data: &docker-file-info
build:
context: .
dockerfile: Dockerfile
services:
some_service_a:
<<: *docker-file-info
restart: on-failure
ports:
- 8080:9090
some_service_b:
<<: *docker-file-info
restart: on-failure
ports:
- 8080:9595
Related
I'm dockerizing a bunch of windows apps in Windows Containers.
All my apps require the same mappings, here's a short snippet of my config:
version: '3.9'
services:
shell0:
build:
target: myimage
context: .
image: 'salimfadhley/myimage:latest'
entrypoint: c:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe
working_dir: "c:\\"
volumes:
- type: "bind"
source: "x:"
target: "x:"
volumes: # THIS BIT DOESN'T WORK!
xdrive:
source: "x:"
"xdrive" is a network drive share used by all of my applications. Every single process needs access do "xdrve", that's why I'm bind-mounting this into each service.
I'm doing this by repeating the configuration for every single service in this Docker Compose file. There's going to be quite a few of them. It's going to make my docker-compose file very repetitive.
Is there a way to define the "xdrive" just once, for example in the global "volumes" section? I'd like to be able to do something like this per-service:
...service
volumes:
- xdrive: "x:"
Can it be done? What is the syntax to define a bind-mount globally?
You can solve this with YAML syntax:
version: "3.5"
services:
one:
image: busybox
command: ls /foo
volumes:
- &volume-foo
type: bind
source: .
target: /foo
two:
image: busybox
command: ls /foo
volumes:
- *volume-foo
&volume-foo is an anchor, *volume-foo is an alias. An alias repeats what's been declared after the corresponding anchor, in this case a single object of the array. After parsing it will look like this:
version: "3.5"
services:
one:
image: busybox
command: "ls /foo"
volumes:
-
source: "."
target: /foo
type: bind
two:
image: busybox
command: "ls /foo"
volumes:
-
source: "."
target: /foo
type: bind
While I'm configuring my yaml it shows the error below:
version:'3.9'
services:
Web:
image:nginx
database:
image:redis
ERROR: yaml.scanner.ScannerError: mapping values are not allowed here
in ".\docker-compose.yml", line 2, column 9
YAML requires a space after mapping keys:
version: '3.9'
services:
Web:
image: nginx
database:
image: redis
If that space is missing, YAML reads version:'3.9' as single scalar that continues on the next line. On the next line, there is space after the :, but you are now in a multiline scalar, and multiline scalars do not allow implicit mapping keys. This is what the error message is trying to tell you.
You also need to fix the indentation to have a proper docker compose file:
version:'3.9'
services:
Web:
image: nginx
database:
image: redis
I'm using docker-compose to manage a multi container application. 1 of those containers needs access to the contents of a directory on the host.
This seems simple according to the various sources of documentation on docker and docker-compose but I'm struggling to get it working.
event_processor:
environment:
- COMPOSE_CONVERT_WINDOWS_PATHS=1
build: ./Docker/event_processor
ports:
- "15672:15672"
entrypoint: python -u /src/event_processor/event_processor.py
networks:
- app_network
volumes:
- C/path/to/interesting/directory:/interesting_directory"
Running this I get the error message:
ERROR: Named volume
"C/path/to/interesting/directory:/interesting_directory:rw" is used in
service "event_processor" but no declaration was found in the
volumes section.
I understand from the docs that a top level declaration is only necessary if data is to be shared between containers
which isn't the case here.
The docs for docker-compose I linked above have an example which seems to do exactly what I need:
version: "3.2"
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
networks:
webnet:
volumes:
mydata:
However when I try, I get errors about the syntax:
ERROR: The Compose file '.\docker-compose.yaml' is invalid because:
services.audio_event_processor.volumes contains an invalid type, it
should be a string
So I tried to play along:
volumes:
- type: "bind"
source: "C/path/to/interesting/directory"
target: "/interesting_directory"
ERROR: The Compose file '.\docker-compose.yaml' is invalid because:
services.audio_event_processor.volumes contains an invalid type, it should be a string
So again the same error.
I tried the following too:
volumes:
- type=bind, source=C/path/to/interesting/directory,destination=/interesting_directory
No error, but attaching to the running container, I see the following two folders;
type=bind, source=C
So it seems that I am able to create a number of volumes with 1 string (though the forward slashes are cutting the string in this case) but I am not mapping it to the host directory.
I've read the docs but I think I'm missing something.
Can someone post an example of mounting a a windows directory from a host to a linux container so that the existing contents of the windows dir is available from the container?
OK so there were multiple issues here:
1.
I had
version: '3'
at the top of my docker-compose.yml. The long syntax described here wasn't implemented until 3.4 so I stopped receiving the bizarre syntax error when I updated this to:
version: '3.6'
2.
I use my my docker account on 2 windows PCs. Following a hint from another stackoverflow post, I reset Docker to the factory settings. I had to give docker the computer username and password with the notice that this was necessary to access the contents of the local filesystem - at this point I remembered doing this on another PC so I'm not sure whether the credentials were correct on this on. With the correct credentials for the current PC, I was able to bind-mount the volume with the expected results as follows:
version: '3.6'
event_processor:
environment:
- COMPOSE_CONVERT_WINDOWS_PATHS=1
build: ./Docker/event_processor
ports:
- "15672:15672"
entrypoint: python -u /src/event_processor/event_processor.py
networks:
- app_network
volumes:
- type: bind
source: c:/path/to/interesting/directory
target: /interesting_directory
Now it works as expected. I'm not sure if it was the factory reset or the updated credentials that fixed it. I'll find out tomorrow when I use another PC and update.
I am trying to define a reusable block in a docker-compose.yml file in a way that the reusable block definition itself is NOT included in the final (evaluated) YAML.
I know how to define a reusable block with this syntax:
services:
default: &default
image: some/image
dashboard:
<<: *default
command: run dashboard
ports: ["3000:3000"]
But, the above also creates an entry named default under services, which I would like to avoid. In other words, I need the final YAML result to only include dashboard under the services property.
Is this possible with YAML? I was unable to find any reference that discusses this structure clearly enough.
Intuitively, I have tried some variations of the below, but it also did not work.
services:
&default:
image: some/image
dashboard:
<<: *default
command: run dashboard
ports: ["3000:3000"]
This is not possible in YAML 1.2 (or any former version). The reasoning behind this is that YAML has been designed to be a serialization language, not a configuration language.
The Anchor/Alias construct is nice for serializing cyclic data structures. It was never intended to be used for declaring variables that will be used in multiple places. So currently, the only way to create a reusable structure which can be used in multiple places it to define the structure at the first place where it is used. For example:
services:
dashboard:
<<: &default
image: some/image
command: run dashboard
ports: ["3000:3000"]
some_other_service:
<<: *default
other_props: ...
Also, be aware that the merge key << is not part of the YAML spec and only defined as additional feature for YAML 1.1. It is not defined for YAML 1.2 and will be explicitly deprecated for upcoming YAML 1.3.
We (as in: the people currently working on YAML 1.3) are aware of this missing feature and plan to provide a better solution with YAML 1.3.
Docker Compose file format 3.4 adds support for extension fields: top-level keys starting with x- that are ignored by Docker Compose and the Docker engine.
For example:
version: '3.4'
x-default: &default
image: some/image
services:
dashboard:
<<: *default
command: run dashboard
ports: ["3000:3000"]
Source: “Don’t Repeat Yourself with Anchors, Aliases and Extensions in Docker Compose Files” by King Chung Huang https://link.medium.com/N5DFdiC3F0
Here is my docker-compose.yml file:
version:'2':
services:
redis:
image: redis
environment:
- HOST='localhost'
- PORT=6379
ports:
-"0.0.0.0:${PORT}:6379"
I get this error on running docker-compose up:
ERROR: The Compose file './docker-compose.yml' is invalid because:
Invalid service name 'services' - only [a-zA-Z0-9\._\-] characters are allowed
Unsupported config option for services: 'redis'
There are multiple problems with your file. The one causing the syntax error is that you have an extra colon on the first line:
version:'2':
that way you define a scalar string key version:'2' with value of null. Since you are therefore not defining the version of the docker compose file, the rest of the file (which is version 2 oriented) fails. This is best resolved by adding a space after version:
In addition your ports definition is incorrect, the value for that should be a sequence/list, and you again specify a scalar string -"0.0.0.0:${PORT}:6379" because there is no space after the initial dash.
Change your docker_compose.yaml file to:
version: '2'
# ^ no colon here
# ^ space here
services:
redis:
image: redis
environment:
- HOST='localhost'
- PORT=6379
ports:
- "0.0.0.0:${PORT}:6379"
# ^ extra space here
just remove last character ":" into string version:'2':
after it docker-compose.yml must be like
version:'2'
services:
redis:
image: redis
environment:
- HOST='localhost'
- PORT=6379
ports:
-"0.0.0.0:${PORT}:6379"