skip to Main Content

I have a symfony project with docker and I would like to setup webpack-dev-server for hot reloading. I have a basic knowledge about docker, but I probably not know how it works deeply. In my php container I have yarn installed. My docker-compose file looks like:

version: '3.8'

networks:
  nginx-php8-mysql8-node:

services:

  nginx:
    build:
      context: docker/nginx
      dockerfile: Dockerfile
    image: nginx:1.21-alpine
    container_name: nginx-container
    ports:
      - "8080:8080"
      - "443:443"
    volumes:
      - ./app:${PROJECT_ROOT}
      - ./app/public:${PROJECT_ROOT}/public
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./docker/nginx/conf/default_template.conf:/etc/nginx/conf.d/default.template
      - ./certs:/etc/nginx/certs
      - ./log/nginx:/var/log/nginx
    env_file:
      - .env
    depends_on:
      - php8
    command: /bin/bash -c "envsubst '$$NGINX_HOST $$PROJECT_ROOT'
      < /etc/nginx/conf.d/default.template
      > /etc/nginx/conf.d/default.conf
      && exec nginx -g 'daemon off;'"
    networks:
      - nginx-php8-mysql8-node

  php8:
    build:
      context: ./docker/php
      args:
        PHP_VERSION: ${PHP_VERSION}
        PROJECT_ROOT: ${PROJECT_ROOT}
    container_name: php8-container
    env_file:
      - .env
    volumes:
      - ./app:${PROJECT_ROOT}:rw,cached
      - ./certs:/etc/certs
    depends_on:
      - mysql
    networks:
      - nginx-php8-mysql8-node

  mysql:
    image: mysql:8.0
    container_name: mysql8-container
    command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    restart: always
    volumes:
      - ./data:/var/lib/mysql
    env_file:
      - .env
    ports:
      - "33061:3306"
    networks:
      - nginx-php8-mysql8-node

If I get into the container with @docker exec -it php8-container bash and try to run webpack-dev-server I see Connection failed to ws://foo.test:8080/ws and Disconnected errors only. I tried to set host to 0.0.0.0 in the webpack configuration, and all the things I found, but never had a working configuration. Also, I have to set writeToDisk to true, or there isn’t any connecting attempt.

 .configureDevServerOptions(options => {
        options.allowedHosts = 'all';
        options.host         = '0.0.0.0';

        options.devMiddleware = {
            writeToDisk:true
        };
   });

However if I add another container to my docker-compose file like this, it works as expected.

node:
    build:
      context: docker/webpack
      dockerfile: Dockerfile
    container_name: node-container
    working_dir: "${PROJECT_ROOT}"
    env_file:
      - .env
    volumes:
      - ./app:${PROJECT_ROOT}:rw
      - ./certs:/etc/certs
    command: yarn encore dev-server --host 0.0.0.0 --hot --port 9000
    ports:
      - "9000:9000"
    depends_on:
      - php8
    networks:
      - nginx-php8-mysql8-node

So my question is, what’s the difference, and why can’t I just run the dev-server without a separate container? Is there a way to make it work that way or I must edit my docker configuration?

2

Answers


  1. I don’t see any webpack dev server starting logic in the php8 container, how do you start it? The difference is obviously you’ve exposed your ports for the nginx in the network therefore allowing to connection from browser to pass through nginx.

    Login or Signup to reply.
  2. in your case you just have to install node in your php container and also expose port 9000 if you want use this one like you did for the node container.

    for php8 container you have set
    context: ./docker/php
    so lets edit the docker-file associated
    there is multiple way to install node on another image than official one, but here is what i use myself :

    1. adding NODE_VERSION argument in your .env and in your php8 docker-compose
    php8:
        build:
          context: ./docker/php
          args:
            PHP_VERSION: ${PHP_VERSION}
            PROJECT_ROOT: ${PROJECT_ROOT}
            NODE_VERSION: ${NODE_VERSION} <------ here
        container_name: php8-container
        ports:                          <----- opening port
          - "9000:9000"
        env_file:
          - .env
        volumes:
          - ./app:${PROJECT_ROOT}:rw,cached
          - ./certs:/etc/certs
        depends_on:
          - mysql
        networks:
          - nginx-php8-mysql8-node
    
    1. install node in php container via the dockerfile
      in ./docker/php

    add the following

    ARG NODE_VERSION=""   <---- put this on the top
    
    FROM node:$NODE_VERSION AS selectednode  <---- put this after your ARG declarations
    
    
    FROM php:.....      <------- you should have something similar in your dockerfile
    
    
    # then copy the following under the from PHP....
    COPY --from=selectednode /usr/local/lib/node_modules /usr/local/lib/node_modules
    COPY --from=selectednode /usr/local/bin/node /usr/local/bin/node
    RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm
    
    
    1. dont forget to set your node version somewhere in your .env
      ex:
    NODE_VERSION=16.14.2 
    

    to check if everything work, rebuild your docker-compose, and the following command should work :

    docker-compose exec php8 node -v
    

    now you have 2 options for launching the dev-server

    1. via executing the command manualy with the exec
    docker-compose exec php8 npm run dev-server
    

    note that you will have to execute this command everytime after you start or restart your container, and that’s not really cool

    1. on adding an entrypoint to make the command executing on startup of container
      explaining how to setup a entry point will unnecessary increase the lenght of this post, its almost consist on adding the "npm run dev-server" on container start.

    but i strongly advise you to keep using a independent container for using dev-server for node as it let you have access to log from it easier, and make the container restart if in any case node would crash

    its a good practice to have ONE container for EACH SERVICES you could need.

    and not ONE container who contain EVERY SERVICES.

    in that case the day you want to upgrade to PHP "12" you could simply update your php dockerfile without have "any" conflict if the way you install node inside it, isnt working anymore.

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