instruction: Create a Dockerfile for Node.js with production best practices
output: ```dockerfile
  From Message
  ---- ------ ---- ---- -------
  Normal Scheduled 57s default-scheduler Successfully assigned default/liveness-exec to node01
  Normal Pulling 55s kubelet, node01 Pulling image "registry.k8s.io/busybox:1.27.2"
  Normal Pulled 53s kubelet, node01 Successfully pulled image "registry.k8s.io/busybox:1.27.2"
  Normal Created 53s kubelet, node01 Created container liveness
  Normal Started 53s kubelet, node01 Started container liveness
  Warning Unhealthy 10s (x3 over 20s) kubelet, node01 Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal Killing 10s kubelet, node01 Container liveness failed liveness probe, will be restarted
  Wait another 30 seconds, and verify that the container has been restarted:kubectl get pod liveness-exec
  The output shows that RESTARTS has been incremented. Note that the RESTARTS counter
  increments as soon as a failed container comes back to the running state:NAME READY STATUS RESTARTS AGE
  liveness-exec 1/1 Running 1 1m
  Define a liveness HTTP requestAnother kind of liveness probe uses an HTTP GET request. Here is the configuration
  file for a Pod that runs a container based on the registry.k8s.io/e2e-test-images/agnhost image.pods/probe/http-liveness.yaml
  apiVersion: v1
  kind: Pod
  metadata:
   labels:
   test: liveness
   name: liveness-http
  spec:
   containers:
   - name: liveness
   image: registry.k8s.io/e2e-test-images/agnhost:2.40
   args:
   - liveness
   livenessProbe:
   httpGet:
   path: /healthz
   port: 8080
   httpHeaders:
   - name: Custom-Header
   value: Awesome
   initialDelaySeconds: 3
   periodSeconds: 3
  In the configuration file, you can see that the Pod has a single container.
  The periodSeconds field specifies that the kubelet should perform a liveness
  probe every 3 seconds. The initialDelaySeconds field tells the kubelet that it
  should wait 3 seconds before performing the first probe. To perform a probe, the
  kubelet sends an HTTP GET request to the server that is running in the container
  and listening on port 8080. If the handler for the server's /healthz path
  returns a success code, the kubelet considers the container to be alive and
  healthy. If the handler returns a failure code, the kubelet kills the container
  and restarts it.Any code greater than or equal to 200 and less than 400 indicates success. Any
  other code indicates failure.You can see the source code for the server in
  server.go.For the first 10 seconds that the container is alive, the /healthz handler
  returns a status of 200. After that, the handler returns a status of 500.http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
   duration := time.Now().Sub(started)
   if duration.Seconds() > 10 {
   w.WriteHeader(500)
   w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
   } else {
   w.WriteHeader(200)
   w.Write([]byte("ok"))
   }
  })
  The kubelet starts performing health checks 3 seconds after the container starts.
  So the first couple of health checks will succeed. But after 10 seconds, the health
  checks will fail, and the kubelet will kill and restart the container.To try the HTTP liveness check, create a Pod:kubectl apply -f https://k8s.io/examples/pods/probe/http-liveness.yaml
  After 10 seconds, view Pod events to verify that liveness probes have failed and
  the container has been restarted:kubectl describe pod liveness-http
  In releases after v1.13, local HTTP proxy environment variable settings do not
  affect the HTTP liveness probe.Define a TCP liveness probeA third type of liveness probe uses a TCP socket. With this configuration, the
  kubelet will attempt to open a socket to your container on the specified port.
  If it can establish a connection, the container is considered healthy, if it
  can't it is considered a failure.pods/probe/tcp-liveness-readiness.yaml
  apiVersion: v1
  kind: Pod
  metadata:
   name: goproxy
   labels:
   app: goproxy
  spec:
   containers:
   - name: goproxy
   image: registry.k8s.io/goproxy:0.1
   ports:
   - containerPort: 8080
   readinessProbe:
   tcpSocket:
   port: 8080
   initialDelaySeconds: 15
   periodSeconds: 10
   livenessProbe:
   tcpSocket:
   port: 8080
   initialDelaySeconds: 15
   periodSeconds: 10
  As you can see, configuration for a TCP check is quite similar to an HTTP check.
  This example uses both readiness and liveness probes. The kubelet will run the
  first liveness probe 15 seconds after the container starts. This will attempt to
  connect to the goproxy container on port 8080. If the liveness probe fails,
  the container will be restarted. The kubelet will continue to run this check
  every 10 seconds.In addition to the liveness probe, this configuration includes a readiness
  probe. The kubelet will run the first readiness probe 15 seconds after the
  container starts. Similar to the liveness probe, this will attempt to connect to
  the goproxy container on port 8080. If the probe succeeds, the Pod will be
  marked as ready and will receive traffic
  ```
  
  ## Production Considerations
  
  ### Security Best Practices
  
  1. **Use non-root user**
  ```dockerfile
  # Create non-root user
  RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
  USER nodejs
  ```
  
  2. **Scan for vulnerabilities**
  ```bash
  # Scan container image
  docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image <image_name>
  ```
  
  3. **Apply security policies**
  ```yaml
  apiVersion: v1
  kind: Pod
  spec:
    securityContext:
      runAsNonRoot: true
      runAsUser: 1001
      fsGroup: 1001
    containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
          - ALL
  ```
  
  ### Performance Optimization
  
  1. **Resource management**
  ```yaml
  resources:
    requests:
      memory: "128Mi"
      cpu: "100m"
    limits:
      memory: "256Mi"
      cpu: "200m"
  ```
  
  2. **Horizontal Pod Autoscaling**
  ```yaml
  apiVersion: autoscaling/v2
  kind: HorizontalPodAutoscaler
  metadata:
    name: app-hpa
  spec:
    scaleTargetRef:
      apiVersion: apps/v1
      kind: Deployment
      name: my-app
    minReplicas: 3
    maxReplicas: 10
    metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
  ```
  
  ### Backup and Disaster Recovery
  
  1. **Data backup strategy**
  ```bash
  # Automated backup script
  kubectl create job --from=cronjob/backup-job backup-manual-$(date +%Y%m%d-%H%M%S)
  ```
  
  2. **Multi-region deployment**
  ```yaml
  # Anti-affinity rules
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - my-app
          topologyKey: kubernetes.io/zone
  ```