Search code examples
dockerdocker-composedockerfileduplicati

how to mount docker-compose command from host into docker-container


I would like to run docker-compose start and docker-compose stop within a docker-container. Equivalently one can simply try to run docker-compose --version successfully.

I've already managed to get docker --version run by simply add two lines (see below).

The container seems to use Ubuntu 18.04 LTS.

The docker-compose file looks as follows:

---
version: "2.1"
services:
  duplicati-2:
    image: ghcr.io/linuxserver/duplicati
    container_name: duplicati-2
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
      - CLI_ARGS= #optional
    volumes:
      - ./config:/config
      - /mnt/myBackups:/backups
      - /opt/docker:/source:ro
#---------------------------------------------------------------------
#---------- needed to run docker -------------------------------------
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/bin/docker

#---------------------------------------------------------------------
#------------what must stand down here to run docker-compose?---------
      - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose
      - /usr/bin/python3:/usr/bin/python3
#---------------------------------------------------------------------


    ports:
      - 8300:8200
    restart: unless-stopped

I've already found the requirements to generally run docker-compose --version here: https://docs.docker.com/compose/install/

I'm afraid of all needed dependencies and libs for python3 and so on. I don't want to pollute my docker-container with all of those libraries from the host machine when stupidly mount the whole /lib/* and /usr/bin directories from host.

So my question is: Which mounts do I have to add to my docker-compose file at minimal so that i can run docker-compose within the container?


Solution

  • If you want to run docker-compose from inside your container, you need to install it in your image's Dockerfile. There aren't really good shortcuts around this.

    FROM ubuntu:20.04
    RUN apt-get update \
     && DEBIAN_FRONTEND=noninteractive \
        apt-get install --assume-yes --no-install-recommends \
          docker-compose \
          docker.io
    

    In the particular case of Compose, it's a Python application with involved library dependencies, so you need the exact Python from the host and a hard-to-specify subset of the /usr/lib/python3 tree. (See for example this list of files from the Debian Buster docker-compose package.) More generally, bind-mounting binaries from the host into a container tends to not go well since applications can have things like shared-library dependencies or content in /usr/share that won't appear in the container.

    Also in the particular case of Compose, actually running this will be awkward, since you need to bind-mount the host directory containing the docker-compose.yml into the container to be able to use it. And in general, anything that has access to the host's Docker socket can pretty trivially root the entire host. I'd think hard as to whether there's another way to run your higher-level application that doesn't involve needing Compose inside a container.

    version: '3.8'
    services:
      compose:
        build: .
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - .:/compose
        working_dir: /compose
        environment:
          COMPOSE_PROJECT_NAME: current-directory-name
        command: /bin/true
      web:
        image: busybox
        command: httpd -f -h /www
        volumes:
          - .:/www
        ports:
          - 80:80
    
    # This will technically work
    docker-compose run compose \
      docker-compose up -d web