I am basically trying to run an react js app which is mainly composed of 3 services namely postgres db, API server and UI frontend(served using nginx).Currently the app works as expected in the development mode using docker-compose but when i tried to run this in the production using kubernetes,I was not able to access the api server of the app(CONNECTION REFUSED).
I already tried running the command npm install within the api server container.
Dockerfile for API server image
FROM node:12.4.0-alpine
RUN mkdir -p usr/src/app
WORKDIR /usr/src/app
COPY package.json package.json
RUN npm install sequelize-cli nodemon -g
RUN npm install && npm cache clean --force
WORKDIR /usr/src/app
COPY . .
WORKDIR /usr/src/app
EXPOSE 8000
CMD [ "npm","start" ]
package.json of API server
{
"name": "wootz-backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node_modules/.bin/nodemon index.js",
"migrate": "node_modules/.bin/sequelize db:migrate --config config/config.json"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"nodemon": "^1.19.1",
"pg": "^7.11.0",
"sequelize": "^5.8.7",
"sequelize-cli": "^5.4.0"
}
}
API persistant volume one yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: api-initdb-pv-volume
labels:
type: local
app: api
spec:
storageClassName: manual
capacity:
storage: 1Mi
accessModes:
- ReadOnlyMany
hostPath:
path: "/home/vignesh/page designer kubernetes yamls/api"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: api-initdb-pv-claim-one
labels:
app: api
spec:
storageClassName: manual
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1Mi
API persistant volume two yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: api-initdb-pv-volume-2
labels:
type: local
app: api
spec:
storageClassName: manual
capacity:
storage: 1Mi
accessModes:
- ReadOnlyMany
hostPath:
path: "/home/vignesh/page designer kubernetes yamls/api"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: api-initdb-pv-claim-two
labels:
app: api
spec:
storageClassName: manual
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1Mi
APIserver.yaml
apiVersion: v1
kind: Service
metadata:
name: apiserver
labels:
app: apiserver
spec:
ports:
- name: apiport
port: 8000
targetPort: 8000
selector:
app: apiserver
tier: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: apiserver
labels:
app: apiserver
spec:
selector:
matchLabels:
app: apiserver
tier: backend
strategy:
type: Recreate
template:
metadata:
labels:
app: apiserver
tier: backend
spec:
containers:
- image: suji165475/vignesh:apifinal
name: apiserver
env:
- name: POSTGRES_PASSWORD
value: password
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_DB
value: wootz
ports:
- containerPort: 8000
name: myport
volumeMounts:
- name: api-persistent-storage-one
mountPath: /usr/src/app
- name: api-persistent-storage-two
mountPath: /usr/src/app/node_modules
volumes:
- name: api-persistent-storage-one
persistentVolumeClaim:
claimName: api-initdb-pv-claim-one
- name: api-persistent-storage-two
persistentVolumeClaim:
claimName: api-initdb-pv-claim-two
When I tried to run the command npm run migrate inside the api server container I got an error saying-
/usr/src/app # npm run migrate
wootz-backend@1.0.0 migrate /usr/src/app sequelize db:migrate --config config/config.json
Unable to resolve sequelize package in /usr/src/app ERR! code ELIFECYCLE ERR! errno 1 ERR! wootz-backend@1.0.0 migrate:
sequelize db:migrate --config > config/config.json
ERR! Exit status 1 ERR! ERR! Failed at the wootz-backend@1.0.0 migrate script.
I also tried running the command npm install --save sequelize in the api container but this time I got a different error saying-
WARN checkPermissions Missing write access to /usr/src/app/node_modules/pg WARN pg-pool@2.0.6 requires a peer of pg@>5.0 but none is installed. You must > install peer dependencies yourself. WARN wootz-backend@1.0.0 No description WARN wootz-backend@1.0.0 No repository field.
ERR! path /usr/src/app/node_modules/pg ERR! code ENOENT ERR! errno -2 ERR! syscall access ERR! enoent ENOENT: no such file or directory, access > > '/usr/src/app/node_modules/pg' ERR! enoent This is related to npm not being able to find a file. ERR! enoent
NOTE: This problem happens only when I run it using kubernetes and not in development mode using docker-compose.Therefore it can't be a problem with the app itself.
Your application should be built into the Docker image you’re deploying.
There’s a “pattern” of mounting your local source code on top of the Docker image to do local development. This pattern just does not work in Kubernetes. You cannot do “live” development on a deployed Kubernetes pod.
Fortunately, fixing this cuts down your Kubernetes YAML by about two thirds. You need to just outright delete both PersistentVolume
s and PersistentVolumeClaim
s, and the volumes:
and volumeMounts:
in the deployment spec.
When you make changes to your application, you need to docker build
a new image and somehow cause the deployment to restart. The “best” way is to use a different image tag and change the tag in the deployment object, which will cause it to do a rolling restart of pods, and can be cleanly rolled back to the old image if there’s a critical problem with the new code.
(There are two technical problems with this pattern in Kubernetes. The first is that you don’t directly control which node a pod will run on, so you have to manually copy your source code on to every node; that very much misses the point of Kubernetes. The second is that a plain docker run
will populate an empty volume mounted over an image path with the content from the image, but Kubernetes will not, so the “trick” of using an anonymous volume to use the node_modules
tree from the image [now it contains Very Important Application Data and Docker will never update it again] doesn’t actually work; you’ll just get empty node_modules
.)