I don't understand the syntax of the docker-compose-file.
First of all
version: '3'
services:
bla:
command: /bin/bash
stdin_open: true
#tty: true
container_name: docker-gulp-template
#restart: always
build: .
ports:
- '80:3000'
volumes:
- ".:/usr/src/html/bla-source"
volumes:
volumes-xyz:
If I execute it with
docker-compose up
It does create a container with the name
docker-gulp-template_bla
But that sounds illogical to me, though. Shouldn't the container be called this way:
bla_docker-gulp-template ?
Why was it solved like this? Does any of you have an example?
And another point:
volumes:
- ".:/usr/src/html/bla-source"
volumes:
volumes-xyz:
Why do I need the second volumes command and how does docker know that the first volume path belongs to the other volumes name?
Thanks in advance
You don't need the volume section.
A volume can be a named volume, created under the top level volumes section, like
volumes:
volumes-xyz:
and mounted under a service with
volumes:
- "volumes-xyz:/usr/src/html/bla-source"
Named volumes are managed by docker (/var/lib/docker/volumes/ on Linux).
Volume can also be anonymous by
volumes:
- "/usr/src/html/bla-source"
- ".:/usr/src/html/bla-source", on the other hand, creates a "bind mount". It's very similar to volume but you can choose its path to create a two-way mapping between your container and the host.
Related
I am currently learning Docker. I am stucked at the idea of volumes. I assume that they made to store the data whenever we restart the container etc., but i do not understand what happens if we don't provide the ":" for the source:target.
Example:
- "/usr/src/my-app/frontend/node_modules"
- "/usr/src/my-app/backend/node_modules"
What do we store inside the container if we use volumes like above?
The whole docker-compose
version: '3'
services:
nginx:
image: nginx
container_name: nginx
ports:
- 80:80
restart: always
volumes:
- "./nginx/default.conf:/etc/nginx/conf.d/default.conf"
backend:
build:
dockerfile: Dockerfile.dev
context: ./backend
container_name: backend
volumes:
- "/usr/src/my-app/backend/node_modules"
- "./backend:/usr/src/my-app/backend"
frontend:
build:
dockerfile: Dockerfile.dev
context: ./frontend
container_name: frontend
environment:
CHOKIDAR_USEPOLLING: "true"
volumes:
- "/usr/src/my-app/frontend/node_modules"
- "./frontend:/usr/src/my-app/frontend"
It is an anonymous volume. It is managed by docker like a named volume, but it doesn't have a real name, only a GUID. Likewise, it's similar to the one you get when you use the VOLUME instruction in your Dockerfile without mounting a named volume or bind mount to that path when running the container.
See this for example (emphasis mine):
-v or --volume: Consists of three fields, separated by colon characters (:). The fields must be in the correct order, and the meaning of each field is not immediately obvious.
In the case of named volumes, the first field is the name of the volume, and is unique on a given host machine. For anonymous volumes, the first field is omitted.
https://docs.docker.com/storage/volumes/#choose-the--v-or---mount-flag
As long as you keep the container and only restart it, the same volume will be used. If you delete the container / create a new container, it will use a new volume.
I am using docker to run prometheus, grafana and node exporter. I am trying to use named volumes and I am having some issues with that. My docker-compose code is:
version: "3.7"
volumes:
grafana_ini:
prometheus_data:
grafana_data:
dashboards_data:
services:
grafana:
build: ./grafana
volumes:
- grafana_ini:/etc/grafana/grafana.ini
- grafana_data:/etc/grafana/provisioning/datasources/datasource.yml
- dashboards_data:/etc/grafana/provisioning/dashboards
- ./dashboards/linux_dashboard.json:/etc/grafana/provisioning/dashboards/linux_dashboard.json
ports:
- 3000:3000
links:
- prometheus
prometheus:
build: ./prometheus
volumes:
- prometheus_data:/etc/prometheus/prometheus.yml
ports:
- 9090:9090
node-exporter:
image: prom/node-exporter:latest
container_name: node_exporter
restart: unless-stopped
expose:
- 9100
and my dockerfile for grafana is:
FROM grafana/grafana:latest
COPY ./Ini/grafana.ini /etc/grafana/grafana.ini
COPY datasource.yml /etc/grafana/provisioning/datasources/datasource.yml
COPY ./dashboards/dashboard.yml /etc/grafana/provisioning/dashboards
COPY ./dashboards/server/linux_dashboard.json /etc/grafana/provisioning/dashboards
COPY ./dashboards/server/windows_dashboard.json /etc/grafana/provisioning/dashboards
EXPOSE 3000:3000
and I am getting this error while building it
ERROR: for 2022_grafana_1 Cannot create container for service grafana: source /var/lib/docker/overlay2/4ac5b487fd7fd52491b250c4afaa433801420cd907ac4a70ddb4589fdb99368b/merged/etc/grafana/grafana.ini is not directory
ERROR: for grafana Cannot create container for service grafana: source /var/lib/docker/overlay2/4ac5b487fd7fd52491b250c4afaa433801420cd907ac4a70ddb4589fdb99368b/merged/etc/grafana/grafana.ini is not directory
Can anybody please help me.
It looks like there are some problems with the volume configuration in your Grafana container:
First, I think this was simply a typo in your question:
- grafana_ini:/etc/grafana/grafana.inianticipated location in container
I suspect that you were actually intending this:
- grafana_ini:/etc/grafana/grafana.ini
Which doesn't make any sense: grafana.ini is a file, but a volume is
a directory. Docker won't allow you to mount a directory on top of a
file, hence the error:
ERROR: .../etc/grafana/grafana.ini is not directory
You have the same problem with the grafana_data volume, which you're
attempting to mount on top of datasource.yml:
- grafana_data:/etc/grafana/provisioning/datasources/datasource.yml
I think you may be approaching this configuration in the wrong way;
you may want to read through these documents:
https://grafana.com/docs/grafana/latest/installation/docker/
https://grafana.com/docs/grafana/latest/administration/configure-docker/
https://grafana.com/docs/grafana/latest/administration/provisioning/
It is possible to configure Grafana (and Prometheus!) using only bind
mounts and environment variables (this includes installing plugin,
data sources, and dashboards), so you don't need to build your own
custom images.
Unrelated to this particular problem, there are some other things in
your docker-compose.yml that are worth changing. You should no
longer be using the links directive...
links:
- prometheus
...because Docker maintains DNS for you automatically; your containers
can refer to each other by name with no additional configuration.
I got docker compose:
version: '2'
services:
elasticsearch:
image: 'elasticsearch:7.9.1'
environment:
- discovery.type=single-node
ports:
- '9200:9200'
- '9300:9300'
volumes:
- /var/lib/docker/volumes/elastic_search_volume:/usr/share/elasticsearch/data:rw
When I run:
docker volume ls
I see no results. How to list unnamed volumes?
docker volume ls as you've shown it will list all of the volumes that exist.
However, in the docker-compose.yml file you show, you're not creating a named or anonymous volume. Instead, you're creating a bind mount to connect a host directory to the container filesystem space. These aren't considered "volumes" in a technical Docker sense, and a docker volume command won't show or manipulate those.
Reaching directly into /var/lib/docker usually isn't a best practice. It's better to ask Docker Compose to manage the named volume for you:
version: '2'
services:
elasticsearch:
volumes:
# No absolute host path, just the volume name
- elastic_search_volume:/usr/share/elasticsearch/data:rw
volumes:
elastic_search_volume:
# Without this line, Compose will create the volume for you.
# With this line, Compose expects it to already exist; you may
# need to manually `docker volume create elastic_search_volume`.
# external: true
What is the meaning of {} in volume definition?
For example
version: '2'
volumes:
dataelasticsearch: {}
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3
volumes:
- ./dataelasticsearch:/usr/share/elasticsearch/data
It's just an empty mapping. It just means that no extra options were given to the named volume.
From the tests I have done, this is no different from leaving it blank like:
volumes:
dataelasticsearch:
The docker-compose docs do not give any more insights into this.
One more thing: you are defining a named volume at the top but then you are binding a mounted volume in the service:
volumes:
- ./dataelasticsearch:/usr/share/elasticsearch/data
Here ./dataelasticsearch basically creates a folder in your local directory which is mounted as a volume. If you want this feature, you do not need the named volume at all.
I'm trying to create a docker-compose.yml file that contains a --volumes-from instruction. Does anyone know the syntax?
I have been looking online for some time now, and it appears that the --volumes-from command is only available as a docker command. I hope I'm wrong.
Aug. 2022:
brandt points out in the comments to the updated docker-compose documentation.
Note August 2017: with docker-compose version 3, regarding volumes:
The top-level volumes key defines a named volume and references it from each service’s volumes list.
This replaces volumes_from in earlier versions of the Compose file format. See Use volumes and Volume Plugins for general information on volumes.
Example:
version: "3.2"
services:
web:
image: nginx:alpine
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data"
volumes:
mydata:
dbdata:
This example shows a named volume (mydata) being used by the web service, and a bind mount defined for a single service (first path under db service volumes).
The db service also uses a named volume called dbdata (second path under db service volumes), but defines it using the old string format for mounting a named volume.
Named volumes must be listed under the top-level volumes key, as shown.
February 2016:
The docs/compose-file.md mentions:
Mount all of the volumes from another service or container, optionally specifying read-only access(ro) or read-write(rw).
(If no access level is specified, then read-write will be used.)
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw
For instance (from this issue or this one)
version: "2"
services:
...
db:
image: mongo:3.0.8
volumes_from:
- dbdata
networks:
- back
links:
- dbdata
dbdata:
image: busybox
volumes:
- /data/db