version: '3'
services:
nginx:
image: nginxtest
container_name: nginxtest-container
volumes:
- "$PWD:/apps"
ports:
- "80:80"
Above is my compose file.
I have created dummy file in that directory. If I want to ignore or exclude changes made in one file and all other files should be reflecting the change as it is, how to do that.
Let's say you want to mount $PWD but want to exclude $PWD/template, you can use this.
version: '3'
services:
nginx:
image: nginx
container_name: nginxtest-container
volumes:
- "/apps/template"
- "$PWD:/apps"
ports:
- "80:80"
/apps/template creates a separate space. Anything in $PWD/template will not be mirrored in the container, anything in /apps/template will also not be reflected on the host.
Related
Is a very simple question I guess, but I could not find an answer.
This is my docker-compose.yml
version: '3'
services:
db:
volumes:
- db:/var/lib/mysql
volumes:
db:
nextcloud:
The question is, I want to specify the value of "db" or "nextcloud" in "volumes", and reference them in "Services".like this
services:
db:
volumes:
- db:/var/lib/mysql
nextcloud:
volumes:
- nextcloud:/var/www/html
volumes:
db: /home/roj/DataDisk/nextcloud-insecure/db
nextcloud: /home/roj/DataDisk/nextcloud-insecure/disk
but I got problemERROR: In file './docker-compose.yml', volume 'db' must be a mapping not a string.
how can i fix it ?
The top-level volumes section is not meant to specify mounts but volume driver configuration (see official documention on that matter). ie. this is incorrect
volumes:
db: /home/roj/DataDisk/nextcloud-insecure/db # incorrect
nextcloud: /home/roj/DataDisk/nextcloud-insecure/disk # incorrect
If you want to mount host directories to you container, you must specify it in the volumes section of your services, eg.
services:
db:
volumes:
- /home/roj/DataDisk/nextcloud-insecure/db:/var/lib/mysql
nextcloud:
volumes:
- /home/roj/DataDisk/nextcloud-insecure/disk:/var/www/html
See official documentation on services volumes for more information on that.
Your syntax in the outer volumes instruction is incorrect.
If you want to mount to a docker-managed volume, do this:
services:
test:
image: alpine
volumes:
- db:/app
volumes:
db:
If you want to mount to a local path, do this (you can replace the dot in .:/app with any other local path, like: /home/you:/server/path):
services:
test:
image: alpine
volumes:
- .:/app
If it starts with a dot or a slash, it will be treated as a path, otherwise, as a docker-managed named volume.
These are the common usage patterns, but you can read more about volumes in compose for some additional information.
I am trying to learn docker by reading the official documentation. I am on the task of Use Compose to develop locally. Trying to compose mongodb but I got an error
The Compose file './docker-compose.dev.yml' is invalid because:
Unsupported config option for services.volumes: 'mongodb'
here is docker-compose.dev.yml file:
version: '3.8'
services:
notes:
build:
context: .
ports:
- 8080:8080
- 9229:9229
environment:
- SERVER_PORT=8080
- DATABASE_CONNECTIONSTRING=mongodb://mongo:27017/notes
volumes:
- ./:/code
command: npm run debug
mongo:
image: mongo:4.2.8
ports:
- 27017:27017
volumes:
- mongodb:/data/db
- mongodb_config:/data/configdb
volumes:
mongodb:
mongodb_config:
How can I make it work?
That's a small mistake on your part, the volumes section of the docker-compose.yaml file is related to all services and not one in particular, because of how yaml files are formatted the indentation level matters a lot, in your example you didn't use the volumes parameter, instead you defined a service called volumes and services don't have a parameter called mongodb.
You have to simply decrease the identation level on the last 3 lines and it will work just fine.
version: '3.8'
services:
mongo:
image: mongo:4.2.8
ports:
- 27017:27017
volumes:
- mongodb:/data/db
- mongodb_config:/data/configdb
volumes:
mongodb:
mongodb_config:
Is it possible to "import" or link a docker-compose file into another docker-compose file?
Suppose I have two files:
# docker-compose-1.yml
services:
A:
# config
B:
# config
# docker-compose-2.yml
services:
C:
# config
import: docker-compose-1.yml
By running docker-compose -f docker-compose-2.yml up, I would like to start containers A, B (specified in the imported file) and C. Is this possible, without having to link both files with the -f parameter?
By extending
It's possible to extend or use multiple docker-compose files and their services and link them in just one file. You can take a look at this link to understand how is the other usages of multiple compose files. But you can't include the file yet without linking related files together as you mentioned.
Here, I defined a common-services.yaml:
version: '2'
services:
nginx_a:
image: nginx:latest
container_name: nginx
ports:
- 81:80
- 1443:443
And then, I created a docker-compose.yml and included the common-services.yml file and its own service as well.
services:
nginx:
extends:
file: common-services.yml
service: nginx_a
nginx_b:
image: nginx:latest
container_name: nginx_b
volumes:
ports:
- 82:80
- 2443:443
By .env technique
And if you want to avoid chaining usage of multiple files, there is also a technique with .env files. I will rewrite the previous example with .env technique.
COMPOSE_PATH_SEPARATOR=:
COMPOSE_FILE=common-services.yml:docker-compose.yml
Let's add another service as an example in the common-services.yml
version: '2'
services:
ngin_a:
image: nginx:latest
container_name: nginx_a
ports:
- 81:80
- 1443:443
redis_c:
image: redis:latest
container_name: redis_c
ports:
- 6381:6380
And finally, load all of them in the docker-compose file without even mention to those services.
version: '2'
services:
nginx_b:
image: nginx:latest
container_name: nginx_b
ports:
- 82:80
- 2443:443
env_file:
- .env
In the end, you will have three running services.
I already have a docker-compose.yml file like this:
version: "3.1"
services:
memcached:
image: memcached:alpine
container_name: dl-memcached
redis:
image: redis:alpine
container_name: dl-redis
mysql:
image: mysql:5.7.21
container_name: dl-mysql
restart: unless-stopped
working_dir: /application
environment:
- MYSQL_DATABASE=dldl
- MYSQL_USER=docker
- MYSQL_PASSWORD=docker
- MYSQL_ROOT_PASSWORD=docker
volumes:
- ./../:/application
ports:
- "8007:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: dl-phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=dl-mysql
- PMA_PORT=3306
- MYSQL_USER=docker
- MYSQL_PASSWORD=docker
- MYSQL_ROOT_PASSWORD=docker
restart: always
ports:
- 8002:80
volumes:
- /application
links:
- mysql
elasticsearch:
build: phpdocker/elasticsearch
container_name: dl-es
volumes:
- ./phpdocker/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
ports:
- "8003:9200"
webserver:
image: nginx:alpine
container_name: dl-webserver
working_dir: /application
volumes:
- ./../:/application:delegated
- ./phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
- ./logs:/var/log/nginx:delegated
ports:
- "9003:80"
php-fpm:
build: phpdocker/php-fpm
container_name: dl-php-fpm
working_dir: /application
volumes:
- ./../:/application:delegated
- ./phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/7.2/fpm/conf.d/99-overrides.ini
- ./../docker/php-fpm/certs/store_stock/:/usr/local/share/ca-certificates/
- ./logs:/var/log:delegated # nginx logs
- /application/var/cache
environment:
XDEBUG_CONFIG: remote_host=host.docker.internal
PHP_IDE_CONFIG: "serverName=dl"
node:
build:
dockerfile: dl/phpdocker/node/Dockerfile
context: ./../
container_name: dl-node
working_dir: /application
ports:
- "8008:3000"
volumes:
- ./../:/application:cached
tty: true
My goal is to have 2 isolate environments working at the same time in the same server with the same docker-compose file? I wonder if it's possible?
I want to be able to stop and update one env. while the other one is still running and getting the traffic.
Maybe I need another approach in my case?
There are a couple of problems with what you're trying to do. If your goal is to put things behind a load balancer, I think that rather than trying to start multiple instances of your project, a better solution would be to use the scaling features available to docker-compose. In particular, if your goal is to put some services behind a load balancer, you probably don't want multiple instances of things like your database.
If you combine this with a dynamic front-end proxy like Traefik, you can make the configuration largely automatic.
Consider a very simple example consisting of a backend container running a simple webserver and a traefik frontend:
---
version: "3"
services:
webserver:
build:
context: web
labels:
traefik.enable: true
traefik.port: 80
traefik.frontend.rule: "PathPrefix:/"
frontend:
image: traefik
command:
- --api
- --docker
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
ports:
- "80:80"
- "127.0.0.1:8080:8080"
If I start it like this, I get a single backend and a single frontend:
docker-compose up
But I can also ask docker-compose to scale out the backend:
docker-compose up --scale webserver=3
In this case, I get a single frontend and three backend servers. Traefik will automatically discover the backends and will round-robin connections between them. You can download this example and try it out.
Caveats
There are a few aspects of your configuration that would need to change in order to make this work (and in fact, you would need to change them even if you were to create multiple instances of your project as you have proposed in your question).
Conflicting paths
Take for example the configuration of your webserver container:
volumes:
- ./logs:/var/log/nginx:delegated
If you start two instances of this service, both containers will mount ./logs on /var/log/nginx. If they both attempt to write to /var/log/nginx/access.log, you're going to have problems.
The easiest solution here is to avoid bind mounts for things like log directories (and any other directories to which you will be writing), and instead use named docker volumes.
Hardcoding container names
In some places, you are hardcoding the container name, like this:
mysql:
image: mysql:5.7.21
container_name: dl-mysql
This will cause problems if you attempt to start multiple instances of this project or multiple instances of the mysql container. Don't statically set the container name.
Deprecated links syntax
Your configuration is using the deprecated links syntax:
links:
- mysql
Don't do that. In modern docker, containers on the same network can simply refer to each other by name. In other words, if your compose configuration has:
mysql:
image: mysql:5.7.21
restart: unless-stopped
working_dir: /application
environment:
- MYSQL_DATABASE=dldl
- MYSQL_USER=docker
- MYSQL_PASSWORD=docker
- MYSQL_ROOT_PASSWORD=docker
volumes:
- ./../:/application
ports:
- "8007:3306"
Other containers in your compose stack can simply use the hostname mysql to refer to this service.
You won't be able to run same compose file on a host without changing the port mappings because that will cause port conflict. I'd recommend creating a base compose file and using extends to override port mappings for different environments.
Hi I have been trying to make my following docker(based on moodle) compose file work
version: '2'
services:
mysql:
image: "mysql/mysql-server"
container_name: moodle-db
restart: always
env_file: .env
volumes:
- ./moodle-db:/var/lib/mysql:z
apache:
image: my-moodle-image:latest
container_name: moodle
restart: always
env_file: .env
ports:
- "8080:80"
depends_on:
- mysql
volumes:
- ./moodledata:/var/www/moodledata:z
#- ./themes:/var/www/theme
And it works as long as the commented line remains like that.
/var/www/theme has some files, but when mounting the folders goes empty instead of propagaiting the files to the file system.
can anyone point out, the why?
Thanks in advance
Tringing to base myself of https://docs.docker.com/engine/admin/volumes/#good-use-cases-for-tmpfs-mounts, in the following text:
If the container’s image contains data at the mount point, this data will be propagated into the bind mount or volume.