I have a pretty standard docker-compose.yml and I need to edit the password of the database programmatically.
Since its a YAML file, I thought it would be simple to edit and dump the content. So far I tried the PyYAML and it just mess the docker-compose file and I don't know why.
Loading and dumping the same content, it breaks the structure.
Content of the docker-compose.yml:
version: '2'
services:
web:
container_name: xxx
ports:
- "80:80"
volumes:
- .:/xxx
depends_on:
- mysql
build: .
mysql:
ports:
- "32768:32768"
- "3306:3306"
container_name: xxx-mysql
restart: always
image: mariadb:latest
environment:
MYSQL_ROOT_PASSWORD: 'thiswillbechangeonsetupscript'
MYSQL_DATABASE: 'xxxdb'
volumes:
- ./database:/var/lib/mysql
ports:
- "3306:3306"
This is how I'm loading and dumping the content:
import yaml
with open("docker-compose.yml", 'r') as ymlfile:
docker_config = yaml.load(ymlfile)
with open("docker-compose.yml", 'w') as newconf:
yaml.dump(docker_config, newconf)
And this is how the file is saved.
services:
mysql:
container_name: xxx-mysql
environment: {MYSQL_DATABASE: xxxdb, MYSQL_ROOT_PASSWORD: thiswillbechangeonsetupscript}
image: mariadb:latest
ports: ['3306:3306']
restart: always
volumes: ['./database:/var/lib/mysql']
web:
build: .
container_name: xxx
depends_on: [mysql]
ports: ['80:80']
volumes: ['.:/xxx']
version: '2'
Is there any better way to do this?! What I'm missing?
You need to add default_flow_style=False
when you write the yaml:
import yaml
with open("docker-compose.yml", 'r') as ymlfile:
docker_config = yaml.load(ymlfile)
with open("docker-compose_new.yml", 'w') as newconf:
yaml.dump(docker_config, newconf, default_flow_style=False)
Then you will get the following as output which, except using alphabetic order to write the lines, is similar to your input:
services:
mysql:
container_name: xxx-mysql
environment:
MYSQL_DATABASE: xxxdb
MYSQL_ROOT_PASSWORD: thiswillbechangeonsetupscript
image: mariadb:latest
ports:
- 3306:3306
restart: always
volumes:
- ./database:/var/lib/mysql
web:
build: .
container_name: xxx
depends_on:
- mysql
ports:
- 80:80
volumes:
- .:/xxx
version: '2'
Please note that, in your original docker-compose.yaml
you are declaring the ports
variable twice, so yaml parser will only consider the last variable. To fix that, remove the following lines:
ports:
- "3306:3306"
Then, running the write operation as explained above gives the following ouput:
services:
mysql:
container_name: xxx-mysql
environment:
MYSQL_DATABASE: xxxdb
MYSQL_ROOT_PASSWORD: thiswillbechangeonsetupscript
image: mariadb:latest
ports:
- 32768:32768
- 3306:3306
restart: always
volumes:
- ./database:/var/lib/mysql
web:
build: .
container_name: xxx
depends_on:
- mysql
ports:
- 80:80
volumes:
- .:/xxx
version: '2'