4

In docker-compose I was used to create volumes in this way:

volumes:
  - ./server:/home/app
  - /home/app/node_modules

in order to solve the problem of node_modules.

How could I approach the problem in kubernetes?

I've created the following config

  spec:
    containers:
    - env: []
      image: "image"
      volumeMounts:
      - mountPath: /home/app
        name: vol-app
      - mountPath: /home/app/node_modules
        name: vol-node-modules
      name: demo
    volumes:
    - name: vol-app
      hostPath:
        path: /Users/me/server
    - name: vol-node-modules
      emptyDir: {}

but it doesn't work. the node_modules is empty

Mazzy
  • 13,354
  • 43
  • 126
  • 207

2 Answers2

4

I just transitioned from Docker Swarm to Kubernetes and had the same question. The solution I settled on makes use of init containers (https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).

The general idea is that init containers allow you to copy the node_modules directory from your image into an empty volume, then mount that volume in your application's pod.

kind: Deployment
apiVersion: apps/v1
metadata:
  ...
spec:
  ...
  template:
    ...
    spec:
      initContainers:
        - name: frontend-clone
          image: YOUR_REGISTRY/YOUR_IMAGE
          command:
            - cp
            - -a
            - /app/node_modules/.
            - /node_modules/
          volumeMounts:
            - name: node-modules-volume
              mountPath: /node_modules
      containers:
        - name: frontend
          image: YOUR_REGISTRY/YOUR_IMAGE
          volumeMounts:
            - name: source-volume
              mountPath: /app
            - name: node-modules-volume
              mountPath: /app/node_modules
      volumes:
        - name: source-volume
          hostPath:
            path: /YOUR_HOST_CODE_DIRECTORY/frontend
        - name: node-modules-volume
          emptyDir: {}

Note that the command to copy the node_modules directory is cp -a /SOURCE/. /DEST/ and not the more common cp -r /SOURCE/* /DEST/. The asterisk in the latter command would be interpreted as a literal * instead of a logical * and it wouldn't match every file/directory as intended.

You can do whatever you want with an init container, even create the node_modules directory from a script at initialization (though it'd add a significant delay).

bfin
  • 511
  • 6
  • 11
  • Hi, thanks for this -- any idea how to work around `no kind "Deployment" is registered for version "apps/v1"`? – lol Apr 29 '18 at 04:30
  • @lol What version of k8s are you running? For >=1.9 use `apiVersion: apps/v1`, but in 1.8 it was `apiVersion: apps/v1beta2` and in 1.7 it was `apiVersion: apps/v1beta1`. https://kubernetes.io/docs/reference/workloads-18-19/ – bfin Apr 30 '18 at 10:58
0

the node_modules is empty

It's empty because you're using emptyDir volume:

An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. As the name says, it is initially empty.

Application should write data to it.

Slava Semushin
  • 14,904
  • 7
  • 53
  • 69