skip to Main Content

I already have a docker-compose.yml file like this:

version: "3.1"

services:

memcached:
  image: memcached:alpine
  container_name: dl-memcached

redis:
  image: redis:alpine
  container_name: dl-redis

mysql:
  image: mysql:5.7.21
  container_name: dl-mysql
  restart: unless-stopped
  working_dir: /application
  environment:
    - MYSQL_DATABASE=dldl
    - MYSQL_USER=docker
    - MYSQL_PASSWORD=docker
    - MYSQL_ROOT_PASSWORD=docker
  volumes:
    - ./../:/application
  ports:
    - "8007:3306"

phpmyadmin:
  image: phpmyadmin/phpmyadmin
  container_name: dl-phpmyadmin
  environment:
    - PMA_ARBITRARY=1
    - PMA_HOST=dl-mysql
    - PMA_PORT=3306
    - MYSQL_USER=docker
    - MYSQL_PASSWORD=docker
    - MYSQL_ROOT_PASSWORD=docker
  restart: always
  ports:
    - 8002:80
  volumes:
    - /application
  links:
    - mysql

elasticsearch:
  build: phpdocker/elasticsearch
  container_name: dl-es
  volumes:
    - ./phpdocker/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
  ports:
    - "8003:9200"

webserver:
  image: nginx:alpine
  container_name: dl-webserver
  working_dir: /application
  volumes:
      - ./../:/application:delegated
      - ./phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./logs:/var/log/nginx:delegated
  ports:
   - "9003:80"

php-fpm:
  build: phpdocker/php-fpm
  container_name: dl-php-fpm
  working_dir: /application
  volumes:
    - ./../:/application:delegated
    - ./phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/7.2/fpm/conf.d/99-overrides.ini
    - ./../docker/php-fpm/certs/store_stock/:/usr/local/share/ca-certificates/
    - ./logs:/var/log:delegated # nginx logs
    - /application/var/cache 
  environment:
    XDEBUG_CONFIG: remote_host=host.docker.internal
    PHP_IDE_CONFIG: "serverName=dl"

node:
  build:
    dockerfile: dl/phpdocker/node/Dockerfile
    context: ./../
  container_name: dl-node
  working_dir: /application
  ports:
    - "8008:3000"
  volumes:
    - ./../:/application:cached
  tty: true

My goal is to have 2 isolate environments working at the same time in the same server with the same docker-compose file? I wonder if it’s possible?

I want to be able to stop and update one env. while the other one is still running and getting the traffic.

Maybe I need another approach in my case?

2

Answers


  1. You won’t be able to run same compose file on a host without changing the port mappings because that will cause port conflict. I’d recommend creating a base compose file and using extends to override port mappings for different environments.

    Login or Signup to reply.
  2. There are a couple of problems with what you’re trying to do. If your goal is to put things behind a load balancer, I think that rather than trying to start multiple instances of your project, a better solution would be to use the scaling features available to docker-compose. In particular, if your goal is to put some services behind a load balancer, you probably don’t want multiple instances of things like your database.

    If you combine this with a dynamic front-end proxy like Traefik, you can make the configuration largely automatic.

    Consider a very simple example consisting of a backend container running a simple webserver and a traefik frontend:

    ---
    version: "3"
    
    services:
    
      webserver:
        build:
          context: web
        labels:
          traefik.enable: true
          traefik.port: 80
          traefik.frontend.rule: "PathPrefix:/"
    
      frontend:
        image: traefik
        command:
          - --api
          - --docker
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
        ports:
          - "80:80"
          - "127.0.0.1:8080:8080"
    

    If I start it like this, I get a single backend and a single frontend:

    docker-compose up
    

    But I can also ask docker-compose to scale out the backend:

    docker-compose up --scale webserver=3
    

    In this case, I get a single frontend and three backend servers. Traefik will automatically discover the backends and will round-robin connections between them. You can download this example and try it out.

    Caveats

    There are a few aspects of your configuration that would need to change in order to make this work (and in fact, you would need to change them even if you were to create multiple instances of your project as you have proposed in your question).

    Conflicting paths

    Take for example the configuration of your webserver container:

    volumes:
        - ./logs:/var/log/nginx:delegated
    

    If you start two instances of this service, both containers will mount ./logs on /var/log/nginx. If they both attempt to write to /var/log/nginx/access.log, you’re going to have problems.

    The easiest solution here is to avoid bind mounts for things like log directories (and any other directories to which you will be writing), and instead use named docker volumes.

    Hardcoding container names

    In some places, you are hardcoding the container name, like this:

    mysql:
      image: mysql:5.7.21
      container_name: dl-mysql
    

    This will cause problems if you attempt to start multiple instances of this project or multiple instances of the mysql container. Don’t statically set the container name.

    Deprecated links syntax

    Your configuration is using the deprecated links syntax:

    links:
      - mysql
    

    Don’t do that. In modern docker, containers on the same network can simply refer to each other by name. In other words, if your compose configuration has:

    mysql:
      image: mysql:5.7.21
      restart: unless-stopped
      working_dir: /application
      environment:
        - MYSQL_DATABASE=dldl
        - MYSQL_USER=docker
        - MYSQL_PASSWORD=docker
        - MYSQL_ROOT_PASSWORD=docker
      volumes:
        - ./../:/application
      ports:
        - "8007:3306"
    

    Other containers in your compose stack can simply use the hostname mysql to refer to this service.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search