How to run livereload with gulp within a docker co

2019-03-13 09:19发布

问题:

I created a docker container to run tasks with gulp. All tasks are running, the problem is I can't enable livrereload in Chrome although I exposed the 35729 port in my container.

Here is the Dockerfile :

FROM ubuntu:latest
MAINTAINER jiboulex

EXPOSE 80 8080 3000 35729

RUN apt-get update
RUN apt-get install curl -y
RUN apt-get install software-properties-common -y
RUN add-apt-repository ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get install nodejs -y
RUN curl -L https://www.npmjs.com/install.sh | sh
RUN npm install --global gulp -y

# overwrite this with 'CMD []' in a dependent Dockerfile
CMD ["/bin/bash"]

I create the image with the following command :

docker build -t gulp_image .

I create a container :

docker run --name=gulp_container -i -t  --rm  -v /var/www/my_app:/var/www/my_app:rw gulp_image bash

then in my container

cd /var/www/my_app
gulp

Here is my Gulpfile.js

var gulp = require('gulp'),
livereload = require('gulp-livereload'),
exec = require('child_process').exec;
gulp.task('js', function() {
gulp.src([
    './src/js/*.js'
]).pipe(livereload());
});
gulp.task('watch', function(){
var onChange = function (event) {
    console.log('File '+event.path+' has been '+event.type);
};
livereload.listen();
gulp.watch([
    './src/js/*.js'
], ['js'])
    .on('change', onChange);
});
gulp.task('default', ['watch', 'js']);

When I edit a js file, I can see in my container that the files are processed but when I try to enable live reload in my browser (Chrome), I got the following message : "Could not connect to LiveReload server.."

Anyone got a clue about what I missed or didn't do ? Thanks for reading !

回答1:

Exposing ports in a container does not imply that the ports will be opened on the docker host. You should be using the docker run -p option. The documentation says:

-p=[] : Publish a container᾿s port or a range of ports to the host

format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort

Both hostPort and containerPort can be specified as a range of ports.

When specifying ranges for both, the number of container ports in the range must match the number > of host ports in the range. (e.g., -p 1234-1236:1234-1236/tcp) (use 'docker port' to see the actual mapping)

Since you tried the -p containerPort form, the actual port opened on your host (Linux mint) was randomly chosen by docker when you run the docker run command. To figure out what port was chosen, you have to use the docker port command.

Since this is not convenient, you should use the -p hostPort:containerPort form, and specify that hostPort is 35729. (I also assume you expect ports 80, 8080 and 3000 to be accessible in the same manner)

The command to run your container would then be:

docker run --name=gulp_container -i -t --rm \
    -v /var/www/my_app:/var/www/my_app:rw \
    -p 35729:35729 \
    -p 80:80 \
    -p 8080:8080 \
    -p 3000:3000 \
    gulp_image bash

An easier way to deal with ports is to run your docker container in host networking mode. In this mode, any port opened on the container is in fact opened on the host network interface (they are actually both sharing the same interface).

You would then start your container with:

docker run --name=gulp_container -i -t --rm \
    -v /var/www/my_app:/var/www/my_app:rw \
    --net=host \ 
    gulp_image bash