docker-compose: how to see file-changes instantly (when developing)

Philipp Wrann picture Philipp Wrann · Nov 28, 2017 · Viewed 14.6k times · Source

I am new to docker, so this may seem very basic to you, anyway - its freaking me out at the moment.

I decided to develop a new web-project ontop of containers, of course i thought about docker. After finishing the tutorial and reading some Dockerfiles and so on, i decided to go with docker-compose.

I want to have multiple compose-files, one for Development, one for Production and so on. Now i managed to orchestrate a basic php/mysql/redis application using 3 different services. The main application is php based and maintained in the project src. Mysql and Redis are simply configured with base images and do not require any business logic.

I can build the containers and bring them up with

build:

docker-compose -f compose-Development.yml build

up:

docker-compose -f compose-Development.yml up

Many files in the main application container are built by gulp (templates, css, etc) and code will exist in both javascript and php.

I noticed, that my app state does not change when i change my files. I would have to rebuild and restart my containers.

Having some experience with Vagrant, i would go for some kind of shared source during development. But how would i achieve that?

My application Dockerfile (for development) looks like this:

FROM webdevops/php-nginx:7.1
COPY ./ /app
COPY docker/etc/ /opt/docker/etc

# php config...
RUN ln -sf /opt/docker/etc/php/php.Development.ini /opt/docker/etc/php/php.ini

WORKDIR /app/
EXPOSE 80

The compose file:

version: "3"
services:

  app:
    build:
      context: .
      dockerfile: Dockerfile.Development
    links:
      - mysql
      - redis
    volumes:
      - ./data/fileadmin:/app/public/fileadmin
      - ./data/uploads:/app/public/uploads
    env_file:
      - docker/env/All.yml
      - docker/env/Development.yml
    ports:
      - "80:80"
    restart: always

  # Mysql Container
  mysql:
    build:
      context: docker/mysql/
      dockerfile: Dockerfile
    restart: always
    volumes:
      - mysql:/var/lib/mysql
    env_file:
      - docker/env/All.yml
      - docker/env/Development.yml

  # Cache Backend Container
  redis:
    build:
      context: docker/redis/
      dockerfile: Dockerfile
    ports:
      - "6379:6379"
    volumes:
      - redis:/data
    env_file:
      - docker/env/All.yml
      - docker/env/Development.yml
    restart: always

volumes:
  mysql:
  redis:

So far, i used some github repositories to copy chunks from. I know there might be other problems in my setup as well, for the moment the most blocking issue is the thing with the linked/copied source.

Kind regards, Philipp

Answer

TJ Biddle picture TJ Biddle · Nov 29, 2017

The idea of "Development/Production parity" confuses many on this front. This doesn't mean that you can simply have a single configuration and it will work across everything; it means you'll have much closer parity and that you can create an environment that resembles something very close to what you'll have in production.

What's wrong here is that currently you're building your image and it would be ready to ship out, it'd have your code, you have volumes set aside for uploads, etc. Awesome!

Unfortunately, this setup is not correct for development. If you want to be editing code on the fly - you need to attach your local working directory to the image as a volume as well. This would not be done in production; so it's very close - but not exactly the same setup.

Add the following in to the app service volumes section of your compose-file and you should be good to go:

- .:/app