instruction: Create a Dockerfile for Node.js with production best practices
output: ```dockerfile
  from the one used by
  /var/lib/, format the filesystem and mount it into /var/lib/docker.
  Make sure to add this mount to /etc/fstab to make it permanent.Edit /etc/docker/daemon.json. If it doesn't yet exist, create it. Assuming
  that the file was empty, add the following contents.
  
  {
   "storage-driver": "overlay2"
  }Docker doesn't start if the daemon.json file contains invalid JSON.Start Docker.
  
  $ sudo systemctl start docker
  Verify that the daemon is using the overlay2 storage driver.
  Use the docker info command and look for Storage Driver and
  Backing filesystem.
  
  $ docker info
  
  Containers: 0
  Images: 0
  Storage Driver: overlay2
   Backing Filesystem: xfs
   Supports d_type: true
   Native Overlay Diff: true
  <...>
  Docker is now using the overlay2 storage driver and has automatically
  created the overlay mount with the required lowerdir, upperdir, merged,
  and workdir constructs.Continue reading for details about how OverlayFS works within your Docker
  containers, as well as performance advice and information about limitations of
  its compatibility with different backing filesystems.How the overlay2 driver worksOverlayFS layers two directories on a single Linux host and presents them as
  a single directory. These directories are called layers, and the unification
  process is referred to as a union mount. OverlayFS refers to the lower directory
  as lowerdir and the upper directory as upperdir. The unified view is exposed
  through its own directory called merged.The overlay2 driver natively supports up to 128 lower OverlayFS layers. This
  capability provides better performance for layer-related Docker commands such
  as docker build and docker commit, and consumes fewer inodes on the backing
  filesystem.Image and container layers on-diskAfter downloading a five-layer image using docker pull ubuntu, you can see
  six directories under /var/lib/docker/overlay2.
  WarningDon't directly manipulate any files or directories within
  /var/lib/docker/. These files and directories are managed by Docker.
  
  $ ls -l /var/lib/docker/overlay2
  
  total 24
  drwx------ 5 root root 4096 Jun 20 07:36 223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
  drwx------ 3 root root 4096 Jun 20 07:36 3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b
  drwx------ 5 root root 4096 Jun 20 07:36 4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1
  drwx------ 5 root root 4096 Jun 20 07:36 e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5
  drwx------ 5 root root 4096 Jun 20 07:36 eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed
  drwx------ 2 root root 4096 Jun 20 07:36 l
  The new l (lowercase L) directory contains shortened layer identifiers as
  symbolic links. These identifiers are used to avoid hitting the page size
  limitation on arguments to the mount command.
  
  $ ls -l /var/lib/docker/overlay2/l
  
  total 20
  lrwxrwxrwx 1 root root 72 Jun 20 07:36 6Y5IM2XC7TSNIJZZFLJCS6I4I4 -> ../3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff
  lrwxrwxrwx 1 root root 72 Jun 20 07:36 B3WWEFKBG3PLLV737KZFIASSW7 -> ../4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1/diff
  lrwxrwxrwx 1 root root 72 Jun 20 07:36 JEYMODZYFCZFYSDABYXD5MF6YO -> ../eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed/diff
  lrwxrwxrwx 1 root root 72 Jun 20 07:36 NFYKDW6APBCCUCTOUSYDH4DXAT -> ../223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff
  lrwxrwxrwx 1 root root 72 Jun 20 07:36 UL2MW33MSE3Q5VYIKBRN4ZAGQP -> ../e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5/diff
  The lowest layer contains a file called link, which contains the name of the
  shortened identifier, and a directory called diff which contains the
  layer's contents.
  
  $ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/
  
  diff link
  
  $ cat /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/link
  
  6Y5IM2XC7TSNIJZZFLJCS6I4I4
  
  $ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff
  
  bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
  The second-lowest layer, and each higher layer, contain a file called lower,
  which denotes its parent, and a directory called diff which contains its
  contents. It also contains a merged directory, which contains the unified
  contents of its parent layer and itself, and a work directory which is used
  internally by OverlayFS.
  
  $ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
  
  diff link lower merged work
  
  $ cat /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/lower
  
  l/6Y5IM2XC7TSNIJZZFLJCS6I4I4
  
  $ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff/
  
  etc sbin usr var
  To view the mounts which exist when you use the overlay storage driver with
  Docker, use the mount command. The output below is truncated for readability.
  
  $ mount | grep overlay
  
  overlay on /var/lib/docker/overlay2/9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/merged
  type overlay (rw,relatime,
  lowerdir=l/DJA75GUWHWG7EWICFYX54FIOVT:l/B3WWEFKBG3PLLV737KZFIASSW7:l/JEYMODZYFCZFYSDABYXD5MF6YO:l/UL2MW33MSE3Q5VYIKBRN4ZAGQP:l/NFYKDW6APBCCUCTOUSYDH4DXAT:l/6Y5IM2XC7TSNIJZZFLJCS6I4I4,
  upperdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/diff,
  workdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/work)
  The rw on the second line shows that the overlay mount is read-write.The following diagram shows how a Docker image and a Docker container are
  layered. The image layer is the lowerdir and the container layer is the
  upperdir. If the image has multiple layers, multiple lowerdir directories
  are used. The unified view is exposed through a directory called merged which
  is effectively the containers mount point.
  Where the image layer and the container layer contain the same files, the
  container layer (upperdir) takes precedence and obscures the existence of the
  same files in the image layer.To create a container, the overlay2 driver combines the directory representing
  the image's top layer plus a new directory for the container. The image's
  layers are the lowerdirs in the overlay and are read-only. The new directory for
  the container is the upperdir and is writable.Image and container layers on-diskThe following docker pull command shows a Docker host downloading a Docker
  image comprising five layers.
  
  $ docker pull ubuntu
  
  Using default tag: latest
  latest: Pulling
  ```
  
  ## 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
  ```