Resolved: Hot reloading in a Laravel + Vue project running with docker-compose not working

Question:

For the last few hours I have been trying to implement hot reloading with browserSync but I have not found a way to do that. The browser does not refresh automatically, I still have to refresh manually to see the changes in my Vue components. Here is my configuration:
docker-compose.yml
version: '3.7'
services:
  app:
    build:
      context: .
      dockerfile: .docker/Dockerfile
    container_name: app
    image: digitalocean.com/php
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./.docker/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network
  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: always
    tty: true
    ports:
      - "80:80"
      - "443"
    volumes:
      - ./:/var/www
      - ./.docker/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network
  mongo:
    image: mongo
    restart: always
    container_name: mongodb
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root
    networks:
      - app-network
  mongo-express:
    image: mongo-express
    container_name: mongoexpress
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: root
    networks:
      - app-network

#Docker Networks
networks:
  app-network:
    driver: bridge
Dockerfile
FROM php:8.1.2-fpm

COPY composer.lock composer.json /var/www/

WORKDIR /var/www

# Install dependencies
RUN apt-get update && apt-get install -y \
    libzip-dev \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl \
    libcurl4-openssl-dev \
    pkg-config \
    libssl-dev \
    software-properties-common \
    npm \
    && docker-php-ext-configure gd \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install mysqli \
    && docker-php-ext-install zip \
    && docker-php-source delete

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

RUN pecl install mongodb
RUN echo "extension=mongodb.so" >> /usr/local/etc/php/php.ini

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Install nodejs and npm
ENV NODE_VERSION=16.13.2
RUN apt install -y curl
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
RUN node --version
RUN npm --version

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory contents
COPY . /var/www

# Copy existing application directory permissions
COPY --chown=www:www . /var/www

# Change current user to www
USER www

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
webpack.mix.js
mix.js('resources/js/app.js', 'public/js');
mix.browserSync({
    host: 'localhost',
    proxy: 'app',
    port: 80,
    open: false,
});
I also added this line at the end of the <body> in my app.blade.php (main view, contains the <div id="app"> ):
<script src="{{mix('js/app.js')}}"></script>
Im running npm run hot inside the app container using docker exec -it app /bin/bash.
Can anyone help me out? Maybe browser sync is not really needed and there is another (better) way to have hot reloading?

Answer:

I finally found a way to make it work. Here’s what I did
Expose port 3000 in my app container:
  app:
    build:
      context: .
      dockerfile: .docker/Dockerfile
    container_name: app
    image: digitalocean.com/php
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./.docker/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network
    ports:
      - "3000:3000"
I also exposed the port from the Dockerfile:
...
COPY --chown=www:www . /var/www

# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000 

EXPOSE 3000 //here 
CMD ["php-fpm"]
webpack.mix.js:
mix.js('resources/js/app.js', 'public/js').vue();
mix.browserSync({ 
    host: "localhost", 
    proxy: 'webserver', //here 
    open: false, 
});
That’s it. npm run watch and go to localhost:3000

If you have better answer, please add a comment about this, thank you!