I have a fully functioning live reload server for my php projects using Gulp and BrowserSync:
gulpfile.js
const { watch, series } = require('gulp');
const browserSync = require('browser-sync');
const connect = require("gulp-connect-php");
function connectPHP (cb) {
connect.server({
base: "/public",
hostname: "localhost",
port: 4000
});
cb()
}
function serve (cb) {
browserSync.init({
proxy: "http://localhost:4000"
});
watch("*.html").on("change", browserSync.reload)
watch("*.php").on("change", browserSync.reload)
};
exports.default = series(connectPHP, serve);
This works just fine in localhost but now I want to dockerize it because I want to reuse this little project in combination with whatever php project I happen to be working at the moment.
This is my Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN mkdir public
RUN npm install gulp-cli -g
RUN npm install
VOLUME /public
CMD [ "gulp" ]
EXPOSE 3000
EXPOSE 3001
EXPOSE 4000
And this is the relevant part in my docker-compose.yml for this service:
sync:
depends_on:
- db
ports:
- 3000:3000
- 3001:3001
- 4000:4000
volumes:
- .:/app/public
However when I run the docker container and make a curl request to http://localhost:3000
I get:
* Host localhost:3000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:3000...
* Connected to localhost (::1) port 3000
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/8.9.0
> Accept: */*
>
* Request completely sent off
And curls just hangs.
When I request http://localhost:3001
I do get an actual response (I can access the control panel if I open this in the browser), this is why I think the issue is not BrowserSync:
* Host localhost:3001 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:3001...
* Connected to localhost (::1) port 3001
> GET / HTTP/1.1
> Host: localhost:3001
> User-Agent: curl/8.9.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Encoding: gzip
< Date: Thu, 25 Jul 2024 22:51:34 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Transfer-Encoding: chunked
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell curl to output it to your terminal
Warning: anyway, or consider "--output <FILE>" to save to a file.
* client returned ERROR on write of 16384 bytes
* Failed reading the chunked-encoded stream
* closing connection #0
And finally when I make a request to http://localhost:4000
I get:
* Host localhost:4000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:4000...
* Connected to localhost (::1) port 4000
> GET / HTTP/1.1
> Host: localhost:4000
> User-Agent: curl/8.9.0
> Accept: */*
>
* Request completely sent off
* Recv failure: Connection reset by peer
* closing connection #0
curl: (56) Recv failure: Connection reset by peer
After some googling I learned that is not recommended to run two servers in the same container although it is possible. However for project this small separating gulp-connect-php
server and BrowserSync server in different containers is overkill I think.
So, how can I make this work with just one container?
PD: I know that to have live reload for php files you don’t really need gulp-connect-php
and in fact if I remove this package and just use BrowserSync then this whole issue disappears, but the thing is BrowserSync requires the body
tag to be present in the file to be able to reload it, and I don’t want to wrap all my php files in body
tags.