5

I am trying to store nexus data in persistent volume. To do that I am using this compose yaml:

version: '3.5'

services:
  nexus:
    image: sonatype/nexus3
    volumes:
       - ./nexus-data:/nexus-data sonatype/nexus3
    ports:
      - "8081:8081"
    networks:
      - devops
    extra_hosts:
      - "my-proxy:my-proxy-address"
    restart: on-failure

networks:
  devops:
    name: devops
    driver: bridge

Before running docker-compose up I have created the nexus-data folder and gave required permissions to the uid/guid 200 as suggested here:

https://github.com/sonatype/docker-nexus3/blob/master/README.md#persistent-data.

root@master-node:~/docker# ll
total 16
drwxr-xr-x  3 root root 4096 Jan  8 13:37 ./
drwx------ 22 root root 4096 Jan  8 13:40 ../
-rw-r--r--  1 root root  319 Jan  8 13:36 docker-compose.yml
drwxr-xr-x  2  200  200 4096 Jan  8 13:37 nexus-data/

And here docker's volumes list before running compose file (it's empty):

root@master-node:~/docker# docker volume ls
DRIVER              VOLUME NAME

After docker-compose up command, docker created the volume as shown below:

root@master-node:~/docker# docker volume ls
DRIVER              VOLUME NAME
local               7b7b6517e5ed0e286a8fc7caef756141b5bbdb6e074ef93a657850da3dd78b2b
root@master-node:~/docker# docker volume inspect  7b7b6517e5ed0e286a8fc7caef756141b5bbdb6e074ef93a657850da3dd78b2b 
[
    {
        "CreatedAt": "2020-01-08T13:42:34+03:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/7b7b6517e5ed0e286a8fc7caef756141b5bbdb6e074ef93a657850da3dd78b2b/_data",
        "Name": "7b7b6517e5ed0e286a8fc7caef756141b5bbdb6e074ef93a657850da3dd78b2b",
        "Options": null,
        "Scope": "local"
    }
]
root@master-node:~/docker# ls /var/lib/docker/volumes/7b7b6517e5ed0e286a8fc7caef756141b5bbdb6e074ef93a657850da3dd78b2b/_data
admin.password  cache  db  elasticsearch  etc  generated-bundles  instances  javaprefs  karaf.pid  keystores  lock  log  orient  port  restore-from-backup  tmp

but the folder I specified in compose file (nexus-data) is still empty:

root@master-node:~/docker# ls nexus-data/
root@master-node:~/docker# 

So, what am I doing wrong here? Why isnexus-data empty and docker creating volume in another path?

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
kadir
  • 589
  • 1
  • 7
  • 29
  • 1
    There's a space in the container-side path in your `volumes:` directive; is that correct? – David Maze Jan 08 '20 at 11:11
  • 3
    Declare you volume like this `- ./nexus-data:/nexus-data`. – leopal Jan 08 '20 at 11:13
  • 3
    On official docs, there are using plain docker command `docker run -d -p 8081:8081 --name nexus -v nexus-data:/nexus-data sonatype/nexus3`. The volume part is `-v nexus-data:/nexus-data` but not `sonatype/nexus3` which is the image's name. – leopal Jan 08 '20 at 11:18
  • Thanks for your valuable comments, changing path to ./nexus-data:/nexus-data solved my problem. If you consider to write as an answer your comments I can accept it. @leopal – kadir Jan 08 '20 at 11:26
  • I used the guide from this blog post: https://medium.com/@ahmed24khaled/building-e2e-devops-pipeline-a0f7804390f7 and this repo: https://github.com/ahmed24khaled/DevOps-app/blob/develop/docker-compose.yml but it turns out that the guide has some problems. Updating path as ./nexus-data:/nexus-data solved my problem. – kadir Jan 08 '20 at 11:31

3 Answers3

8

You defined a volume instead of a bind mount, which is what you want. Read the documentation about it.

Basically, your configuration makes docker create a volume, which maps to a randomly created directory somewhere under /var/lib/docker/volumes.

If you want a specific directory that you control, you have to create a bind. That's the reason you don't have data on your chosen directory, as docker ignores it because it is not useful for a volume.

For it to work, set it like:

    volumes:
      - type: bind
        source: ./nexus-data
        target: /nexus-data

as explained in the compose documentation. (Also removed the image name from that configuration)

samthegolden
  • 1,366
  • 1
  • 10
  • 26
  • I downvote'd because OP's questions are "... what am I doing wrong here? Why is the nexus-data is empty and docker creating volume in another path?" none of which have been addressed in your answer. – masseyb Jan 08 '20 at 11:17
  • I used the guide from this blog post: https://medium.com/@ahmed24khaled/building-e2e-devops-pipeline-a0f7804390f7 and this repo: https://github.com/ahmed24khaled/DevOps-app/blob/develop/docker-compose.yml but it turns out that the guide has some problems. Updating path as ./nexus-data:/nexus-data solved my problem. – kadir Jan 08 '20 at 11:31
  • 1
    @samthegolden points for the lastest edit. Note: the [v3 short syntax](https://docs.docker.com/compose/compose-file/#short-syntax-3) `./path:/path` is of type `bind` (is equivalent to the explicit [long syntax](https://docs.docker.com/compose/compose-file/#long-syntax-3)). – masseyb Jan 08 '20 at 12:15
3

You've created a host volume, aka bind mount (which doesn't show in docker volume ls since it's not a named volume)B from ./nexus-data on the host to /nexus-data sonatype/nexus3 inside the container. This looks like a copy and paste error from a docker run command since you are adding the image name to the path being mounted inside the container. You should be able to exec into the container and see your files with:

docker exec ... ls "/nexus-data sonatype/nexus3"

You should remove the image name from the volume path to mount the typical location inside the container:

version: '3.5'

services:
  nexus:
    image: sonatype/nexus3
    volumes:
       - ./nexus-data:/nexus-data
    ports:
      - "8081:8081"
    networks:
      - devops
    extra_hosts:
      - "my-proxy:my-proxy-address"
    restart: on-failure

networks:
  devops:
    name: devops
    driver: bridge

The volume you did see was an anonymous volume. This would be from the image itself defining a volume that you did not include in your container spec. Inspecting the container using that volume would show where it's mounted, most likely at /nexus-data.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • Thank you, it seems the guide I have used had some problems. Updating the path solved my problem. – kadir Jan 08 '20 at 11:33
1

The below docker-compose.yaml works as expected:

version: '3.5'

services:
  nexus:
    image: sonatype/nexus3
    volumes:
       - ./nexus-data:/nexus-data
    ports:
      - "8081:8081"
    networks:
      - devops
    extra_hosts:
      - "my-proxy:my-proxy-address"
    restart: on-failure

networks:
  devops:
    name: devops
    driver: bridge

The trailing sonatype/nexus3 in your original docker-compose.yaml spec:

    ...
    volumes:
       - ./nexus-data:/nexus-data sonatype/nexus3
    ...

... throws docker off - the randomly named volume is created given the VOLUME instruction in the sonatype/nexus3 Dockerfile and is mounted to the running container hence why the intended locally mounted directory is empty.

masseyb
  • 3,745
  • 1
  • 17
  • 29