What is the difference between docker-machine and docker-compose?

User picture User · Jul 27, 2016 · Viewed 18k times · Source

I think I don't get it. First, I created docker-machine:

$ docker-machine create -d virtualbox dev
$ eval $(docker-machine env dev)

Then I wrote Dockerfile and docker-compose.yml:

FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/


version: '2'
services:
  db:
    image: postgres
  web:
    build: .
    restart: always
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

Finally, I built and started the image:

$ docker-compose build --no-cache
$ docker-compose start

I checked ip of my virtual machine

$ docker-machine ip dev

and successfully opened the site in my browser. But when I made some changes in my code - nothing happened. So I logged to the "dev" machine:

$ docker-machine ssh dev

and I didn't find my code! So I logged to the docker "web" image:

$ docker exec -it project_web_1 bash

and there was a code, but unchanged.

What is the docker-machine for? What is the sense? Why docker doesn't syncing files after changes? It looks like docker + docker-machine + docker-compose are pain in the a...s for local development :-)

Thanks.

Answer

AlexChaffee picture AlexChaffee · Jul 28, 2016

Docker is the command-line tool that uses containerization to manage multiple images and containers and volumes and such -- a container is basically a lightweight virtual machine. See https://docs.docker.com/ for extensive documentation.

Until recently Docker didn't run on native Mac or Windows OS, so another tool was created, Docker-Machine, which creates a virtual machine (using yet another tool, e.g. Oracle VirtualBox), runs Docker on that VM, and helps coordinate between the host OS and the Docker VM.

Since Docker isn't running on your actual host OS, docker-machine needs to deal with IP addresses and ports and volumes and such. And its settings are saved in environment variables, which means you have to run commands like this every time you open a new shell:

eval $(docker-machine env default)
docker-machine ip default

Docker-Compose is essentially a higher-level scripting interface on top of Docker itself, making it easier (ostensibly) to manage launching several containers simultaneously. Its config file (docker-compose.yml) is confusing since some of its settings are passed down to the lower-level docker process, and some are used only at the higher level.

I agree that it's a mess; my advice is to start with a single Dockerfile and get it running either with docker-machine or with the new beta native Mac/Windows Docker, and ignore docker-compose until you feel more comfortable with the lower-level tools.