Syntax of docker-compose version 3 and above - docker

This might be a completely lame question, but I was going through the different directive examples of docker-compose and a thought came to my mind.
Is there a syntax or a code-book that specifies the spacing syntax of the spacing that is written in docker-compose.yml? Different examples online show different spacing.
I know that tab is not allowed in docker-compose.yml, but for the spacing part, which of the below stands correct -
docker-compose.yml : Here the spacing is 2 spaces each, for the services, directives and their values (given using -)
version: "3.2"
services:
myservice:
image: mysql:5.5
container_name: contDEV
ports:
- target: 18530
published: 3306
volumes:
- type: bind
source: /app
target: /var
environment:
- MYSQL_USER=unpush
- MYSQL_PASSWORD=push
networks:
- cloud-nw
networks:
cloud-nw:
docker-compose.yml : Here the spacing is 2 spaces each, for the services and directives but their values (given using -) are written without space.
version: "3.2"
services:
myservice:
image: mysql:5.5
container_name: contDEV
ports:
- 18530:3306
volumes:
- type: bind
source: /app
target: /var
environment:
- MYSQL_USER=unpush
- MYSQL_PASSWORD=push
networks:
- cloud-nw
networks:
cloud-nw:
docker-compose.yml : Here the spacing is 4 spaces each, for the services and directives but their values (given using -) are written without space.
version: "3.2"
services:
myservice:
image: mysql:5.5
container_name: contDEV
ports:
- 18530:3306
volumes:
- type: bind
source: /app
target: /var
environment:
- MYSQL_USER=unpush
- MYSQL_PASSWORD=push
networks:
- cloud-nw
networks:
cloud-nw:

Related

docker-compose force services to create seperate containers even when images are the same

I have 2 services which use the same image:, what can i do, to force docker-compose to generate 2 seperate containers?
Thanks!
EDIT:
Full docker-compose:
version: "3.5"
services:
database:
container_name: proj-database
env_file: ../orm/.env.${PROJ_ENV}
image: postgres
restart: always
ports:
- 5432:5432
networks:
- proj
api:
image: golang:1.17
container_name: proj-api
env_file: ../cryptoModuleAPI/.env.${PROJ_ENV}
restart: always
build: ../cryptoModuleAPI/
links:
- database:database
ports:
- 8080:8080
volumes:
- ../cryptoModuleAPI:/proj/api
- ../orm:/proj/orm
networks:
- proj
admin:
image: golang:1.17
container_name: proj-admin
env_file: ../admin/.env.${PROJ_ENV}
restart: always
build: ../admin/
links:
- database:database
ports:
- 8081:8081
volumes:
- ../admin:/proj/admin
- ../orm:/proj/orm
networks:
- proj
networks:
proj:
external:
name: proj
I just run with docker-compose up
You misunderstand how the build and image directives work when used together.
Paraphrasing the docs,
https://docs.docker.com/compose/compose-file/compose-file-v3/#build
If you specify image as well as build, then Compose names the built image with the value of the image directive.
Compose is going to build two images, both named the same thing. Only one will survive. I'm surprised your app spins up at all!
Provide a different name for the image directive of each service, or leave it out entirely.

docker-compose yaml.parser.ParserError

With the following docker-compose.yml I always get a syntax error I can't explain (I don't see the difference in lines 2 and 3 between the two docker-compose.ymls)
---
version: '2'
services:
app-module:
container_name: app-module:
env_file: ./app-module:.env
image: registry.x/app/app-module:latest
network_mode: "bridge"
ports:
- "30303:30303"
volumes:
- type: volume
source: node-volume
target: /datadir
- ./data:/data
- ./log:/log
Error message:
ERROR: yaml.parser.ParserError: while parsing a block mapping
in "./docker-compose.yml", line 2, column 1
expected <block end>, but found '<block mapping start>'
in "./docker-compose.yml", line 3, column 3
I don't see any syntax differences to other working files.
That's the working docker-compose.yml I used as the inspiration of my file:
---
version: '2'
services:
app-node:
container_name: app-node
env_file: ./app-node.env
image: registry.x/group/app-node:latest
network_mode: "bridge"
ports:
- "7990:7990"
- "7999:7999"
volumes:
- ./data:/data
- ./log:/log
Proof:
$ docker-compose config
services:
app-node:
container_name: app-node
environment: {}
image: registry.x/group/app-node:latest
network_mode: bridge
ports:
- 7990:7990/tcp
- 7999:7999/tcp
volumes:
- ...app-node/Test/data:/data:rw
- ...app-node/Test/log:/log:rw
version: '2.0'
Spaces matter in YAML. You have two spaces before services: that are not supposed to be there. You're telling YAML that services is in version but version already has a value.
It's the difference between:
foo: bar
in_foo: bar
which will not work because in_foo is in foo, and:
foo: bar
not_in_foo: bar
that will work because not_in_bar is not in foo.
Alternatively, this would be valid syntax (but then docker-compose will fail because it expects a string in version):
version:
services:
foo: bar

Unsupported config option for services.volumes

Trying to setup docker for the first time and I'm running into a problem with volumes. I feel pretty confident that the spacing and formatting in the .yml is correct at this point.
I've tried versions 3, 3.1, 3.2, 3.3 and 3.4. All are getting the same error message (below)
Unsupported config option for services.volumes: 'db2_prod'
version: '3'
services:
liberty:
image: liberty:${liberty_tag}
ports:
- "${liberty_ip}:9080:9080"
- "${liberty_ip}:9443:9443"
restart: always
apache:
image: webapp:${apache_tag}
ports:
- "${apache_ip}:80:80"
- "${apache_ip}:443:443"
restart: always
db2:
image: db2:${db2_tag}
ports:
- "${db2_ip}:50000:50000"
stdin_open: true
tty: true
restart: always
volumes:
- db2_prod:/database/stagg3
volumes:
db2_prod:
volumes needs to be at the same indentation with services i.e
services:
#...
volumes:
db2_prod:
version: '3.7'
services:
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- 8000:8000
depends_on:
- db
db:
image: postgres:11
volumes:
- postgres_data:/var/lib/postgresql/data/
volumes:
postgres_data:
observe that version, services and volumes have same indent level. Moreover use spacebar for indentation, use of tab may create problem.

Docker-Compose file has yaml.scanner.ScannerError but i don´t see anything

when i try to compose i get shown this:
yaml.scanner.ScannerError: mapping values are not allowed here
in "./docker-compose.yml", line 6, column 15
my docker-compose.yml:
version: '2'
services:
fhem:
restart:always
expose:
- "8083"
- "7072"
ports:
- "8083:8083"
- "7072:7072"
build: fhem
privileged: true
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
....
can´t see any wrong syntax at all
You're missing a space after the colon following restart (per #bartimar), and your device line isn't indented correctly, since you're using 4 space indent.
version: '2'
services:
fhem:
restart: always
expose:
- "8083"
- "7072"
ports:
- "8083:8083"
- "7072:7072"
build: fhem
privileged: true
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"

docker-compose v3 share the same volume mount locations between multiple containers

Previously I used volumes_from to mount multiple volume locations to multiple containers, like so:
app:
image: mageinferno/magento2-nginx:1.11-1
links:
- phpfpm
volumes_from:
- appdata
ports:
- 8000:80
phpfpm:
image: mageinferno/magento2-php:7.0-fpm-1
links:
- db
volumes_from:
- appdata
appdata:
image: tianon/true
volumes:
- /var/www/html
- ~/.composer:/var/www/.composer
- ./html/app/code:/var/www/html/app/code
- ./html/app/design:/var/www/html/app/design
However, in docker-compose version 3 when using native volume mounts, volumes_from is not available, which leads me to do something like this:
version: "3"
services:
app:
image: mageinferno/magento2-nginx:1.11-1
links:
- phpfpm
volumes:
- appdata:/var/www/html
- ~/.composer:/var/www/.composer
- ./html/app/code:/var/www/html/app/code
- ./html/app/design:/var/www/html/app/design
ports:
- 8000:80
phpfpm:
image: mageinferno/magento2-php:7.0-fpm-1
links:
- db
volumes:
- appdata:/var/www/html
- ~/.composer:/var/www/.composer
- ./html/app/code:/var/www/html/app/code
- ./html/app/design:/var/www/html/app/design
Is there any way I can reference the same group of volume mounts to multiple services, without defining them twice?
YAML supports "anchors" for re-using bits: (From https://learnxinyminutes.com/docs/yaml/)
# 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
Here is a docker-compose version 3 example where an anchor is used for the environment variables.
The values are set the first time they are used, and then referenced in any additional services that use the same environment variables.
Note the use of &environment in setting the anchor, and *environment in referencing it.
version: '3'
services:
ui:
build:
context: ./ui
ports:
- 80:80
- 8080:8080
networks:
- cluster-net
environment: &environment
A_VAR: 'first-var'
ANOTHER_VAR: 'second-var'
api:
build:
context: ./api
networks:
- cluster-net
environment: *environment
networks:
cluster-net:
driver: bridge

Resources