Search code examples
reactjsdockerkubernetesminikubeskaffold

Erratic and slow behavior with create-react-app and Skaffold kubernetes


I have Skaffold working well with local development server and database deployments. I'm trying to get working on the create-react-app front-end, but the behavior is incredibly slow and erratic.

Issues

The main problems are the following:

  1. It takes upwards of five minutes from running skaffold dev --port-forward --tail for it finally start spinning up. Running just a docker build takes less than 30 seconds.
  2. When it finally starts spinning up, it just sits on Starting the development server... for another two minutes.
  3. Then, nine times out of ten, I get the following errors after several minutes (there are three because that is how many replicas there are): enter image description here

    One out of ten times, it will actually go into the Compiled Successfully! You can now view in the browser. It never does launch in Chrome though.

  4. Changes to JS in create-react-app are never reflected in new browser. You have to stop and run Skaffold again. Skaffold does say Syncing 1 files for <image>... Watching for changes..., but nothing changes even after a refresh.

What I've tried

  1. I've really simplified what I'm trying to do to make it easier to sort this out, so I'm using just an OOTB create-react-app application. The behavior is the same regardless.
  2. minikube delete and minikube start several times (did this because even the server deployment started acting erratically after trying create-react-app)

Code and Steps to Reproduce

I'm on macOS Mojave (10.14.6) using Docker for Mac, Kubernetes (v1.16.0), minikube (v1.4.0), Skaffold (v0.39.0), and create-react-app. I'll have to skip the installation process for all of these since it is fairly lengthy, so the following steps assume you have this already setup.

  1. Make a project directory:

    mkdir project

  2. Make a Kubernetes manifest directory and move into it:

    mkdir k8s && cd k8s

  3. Make a client-deployment.yaml and add the following:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: client-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          component: web
      template:
        metadata:
          labels:
            component: web
        spec:
          containers:
            - name: client
              image: testapp/client
              ports:
                - containerPort: 3000
    
  4. Make a client-cluster-ip-service.yaml and add the following:

    apiVersion: v1
    kind: Service
    metadata:
      name: client-cluster-ip-service
    spec:
      type: ClusterIP
      selector:
        component: web
      ports:
        - port: 3000
          targetPort: 3000
    
  5. Move back into the parent:

    cd ..

  6. Create a skaffold.yaml and add the following:

    apiVersion: skaffold/v1beta15
    kind: Config
    build:
      local:
        push: false
      artifacts:
        - image: testapp/client
          context: web
          docker:
            dockerfile: Dockerfile.dev
          sync:
            manual:
              - src: "**/*.js"
                dest: .
              - src: "**/*.html"
                dest: .
              - src: "**/*.css"
                dest: .
    deploy:
      kubectl:
        manifests:
          - k8s/client-deployment.yaml
          - k8s/client-cluster-ip-service.yaml
    portForward:
      - resourceType: service
        resourceName: client-cluster-ip-service
        port: 3000
        localPort: 3000
    
  7. Start a new create-react-app project:

    npx create-react-app test-app

  8. Change into the directory:

    cd test-app

  9. Create a Dockerfile.dev and add the following:

    FROM node:alpine
    
    WORKDIR '/app'
    EXPOSE 3000
    CMD ["npm", "run", "start"]
    
    COPY package* ./
    RUN npm install
    COPY . .
    
  10. Create a .dockerignore file and add the following:

    node_modules
    *.swp
    
  11. Go back into the parent directory:

    cd ..

  12. Make sure minikube is running:

    minikube start

  13. Run the skaffold.yaml:

    skaffold dev --port-forward --tail

This is what produces the issues for me.


Solution

  • Ok. Disregard. Started with one replica and it worked fine. Two worked fine. Three worked if skaffold was already running, but not from a fresh skaffold dev --port-forward --tail.

    skaffold ssh and then did a top. Was running out of RAM... well was at 86% utilization. Increased it from the default 2GB to 8GB and now it works fine.

    First deleted the VM with minikube delete and then created a new one with minikube start --memory='8g'. All good now.