Reputation: 390
I have a functional fullstack application running through docker-compose. Works like a charm. Only problem is that the team has to rebuild the entire application to reflect changes. That means bringing the entire thing down with docker-compose down
.
I'm looking for help to update the file(s) below to allow for either hot reloads OR simply enable browser refreshes to pickup UI changes
NOTES:
Any help would be greatly appreciated :)
package.json
{
"name": "politicore",
"version": "1.0.1",
"description": "Redacted",
"repository": "Redacted",
"author": "Redacted",
"license": "LicenseRef-LICENSE.MD",
"private": true,
"engines": {
"node": "10.16.3",
"yarn": "YARN NO LONGER USED - use npm instead."
},
"scripts": {
"dev": "docker-compose up",
"dev-force": "docker-compose up --build --force-recreate",
"dev-force-d": "docker-compose up --build --force-recreate -d",
"prod-up": "docker-compose -f docker-compose-prod.yml up",
"prod-up-force": "docker-compose -f docker-compose-prod.yml up --build --force-recreate",
"prod-up-force-d": "docker-compose -f docker-compose-prod.yml up --build --force-recreate -d",
"dev-down": "docker-compose down",
"dev-down-remove": "docker-compose down --remove-orphans",
"prod-down": "docker-compose down",
"prod-down-remove": "docker-compose down --remove-orphans"
}
}
nginx dev config file
server {
listen 80;
listen 443;
server_name MyUrl.com www.MyUrl.com;
server_tokens off;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-Permitted-Cross-Domain-Policies master-only;
add_header Referrer-Policy same-origin;
add_header Expect-CT 'max-age=60';
add_header Feature-Policy "accelerometer none; ambient-light-sensor none; battery none; camera none; gyroscope none;";
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /graphql {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_pass http://api:5000;
proxy_redirect default;
}
}
docker-compose dev file
version: '3.6'
services:
api:
build:
context: ./services/api
dockerfile: Dockerfile-dev
restart: always
volumes:
- './services/api:/usr/src/app'
- '/usr/src/app/node_modules'
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
env_file:
- common/.env
client:
build:
context: ./services/client
dockerfile: Dockerfile-dev
restart: always
volumes:
- './services/client:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- 80:80
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
depends_on:
- api
stdin_open: true
Client Service dockerfile
FROM node:10 as builder
WORKDIR /usr/src/app
COPY package.json /usr/src/app/package.json
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
COPY nginx/dev.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
API dockerfile (dev & prod)
FROM node:10
WORKDIR /usr/src/app
COPY package.json /usr/src/app/package.json
RUN npm install
CMD ["npm", "start"]
Filetree Picture
Upvotes: 4
Views: 5927
Reputation: 575
As I understand it, your nginx file defines 2 areas to serve: location /
and location /graphql
.
The first (location /
) is serving up static files from /usr/share/nginx/html
inside the container. Those files are created during your docker build. Since those are produced in a multi-stage docker build, you will need to change your strategy up. Here are several options that may help guide you.
One option is to build local and mount a volume.
npm run build
on your box (perhaps even with a filewatcher to perform builds any time *.js files change- ./build:/usr/share/nginx/html
to list of volumes for client
serviceThe trade-off here is that you have to forego a fully dockerized build (if that's something that matters heavily to you and your team).
Utilize a hot-reloading node server for local development and build a docker image for production environments. It's hard to tell from the files whether the client is react, angular, vuejs, etc., but typically they have a pattern from running local dev servers.
The trade-off here is that you run locally differently than running in production.
Combine nginx and nodejs into one docker image with hot reloading inside.
client
of your app src files)npm run build
inside the container every time a file changes in that mounted volumeThe trade-off here is that you may have more than 1 process running in a docker container (a big no-no).
A variation of option 3 where you run 2 docker containers.
client_build
volumes:
- client_build:
docker-compose
with 2 volumes
- ./services/client:/usr/src/app
- client_build:/usr/src/app/build
client
service: - client_build:/usr/share/nginx/html
Upvotes: 2