instruction: Create a Dockerfile for Python with production best practices
output: ```dockerfile
  from failed Jobs is not lost inadvertently.
  Backoff limit per index
  
  FEATURE STATE: Kubernetes v1.29 [beta]
  
  Note:You can only configure the backoff limit per index for an Indexed Job, if you
  have the JobBackoffLimitPerIndex feature gate
  enabled in your cluster.
  When you run an indexed Job, you can choose to handle retries
  for pod failures independently for each index. To do so, set the
  .spec.backoffLimitPerIndex to specify the maximal number of pod failures
  per index.
  When the per-index backoff limit is exceeded for an index, Kubernetes considers the index as failed and adds it to the
  .status.failedIndexes field. The succeeded indexes, those with a successfully
  executed pods, are recorded in the .status.completedIndexes field, regardless of whether you set
  the backoffLimitPerIndex field.
  Note that a failing index does not interrupt execution of other indexes.
  Once all indexes finish for a Job where you specified a backoff limit per index,
  if at least one of those indexes did fail, the Job controller marks the overall
  Job as failed, by setting the Failed condition in the status. The Job gets
  marked as failed even if some, potentially nearly all, of the indexes were
  processed successfully.
  You can additionally limit the maximal number of indexes marked failed by
  setting the .spec.maxFailedIndexes field.
  When the number of failed indexes exceeds the maxFailedIndexes field, the
  Job controller triggers termination of all remaining running Pods for that Job.
  Once all pods are terminated, the entire Job is marked failed by the Job
  controller, by setting the Failed condition in the Job status.
  Here is an example manifest for a Job that defines a backoffLimitPerIndex:
  
  /controllers/job-backoff-limit-per-index-example.yaml
  
  apiVersion: batch/v1
  kind: Job
  metadata:
   name: job-backoff-limit-per-index-example
  spec:
   completions: 10
   parallelism: 3
   completionMode: Indexed # required for the feature
   backoffLimitPerIndex: 1 # maximal number of failures per index
   maxFailedIndexes: 5 # maximal number of failed indexes before terminating the Job execution
   template:
   spec:
   restartPolicy: Never # required for the feature
   containers:
   - name: example
   image: python
   command: # The jobs fails as there is at least one failed index
   # (all even indexes fail in here), yet all indexes
   # are executed as maxFailedIndexes is not exceeded.
   - python3
   - -c
   - |
   import os, sys
   print("Hello world")
   if int(os.environ.get("JOB_COMPLETION_INDEX")) % 2 == 0:
   sys.exit(1)
  
  In the example above, the Job controller allows for one restart for each
  of the indexes. When the total number of failed indexes exceeds 5, then
  the entire Job is terminated.
  Once the job is finished, the Job status looks as follows:
  kubectl get -o yaml job job-backoff-limit-per-index-example
   status:
   completedIndexes: 1,3,5,7,9
   failedIndexes: 0,2,4,6,8
   succeeded: 5 # 1 succeeded pod for each of 5 succeeded indexes
   failed: 10 # 2 failed pods (1 retry) for each of 5 failed indexes
   conditions:
   - message: Job has failed indexes
   reason: FailedIndexes
   status: "True"
   type: Failed
  Additionally, you may want to use the per-index backoff along with a
  pod failure policy. When using
  per-index backoff, there is a new FailIndex action available which allows you to
  avoid unnecessary retries within an index.
  Pod failure policy
  
  FEATURE STATE: Kubernetes v1.26 [beta]
  
  Note:You can only configure a Pod failure policy for a Job if you have the
  JobPodFailurePolicy feature gate
  enabled in your cluster. Additionally, it is recommended
  to enable the PodDisruptionConditions feature gate in order to be able to detect and handle
  Pod disruption conditions in the Pod failure policy (see also:
  Pod disruption conditions).
  Both feature gates are available in Kubernetes 1.30.
  A Pod failure policy, defined with the .spec.podFailurePolicy field, enables
  your cluster to handle Pod failures based on the container exit codes and the
  Pod conditions.
  In some situations, you may want to have a better control when handling Pod
  failures than the control provided by the Pod backoff failure policy,
  which is based on the Job's .spec.backoffLimit. These are some examples of use cases:
  
  To optimize costs of running workloads by avoiding unnecessary Pod restarts,
  you can terminate a Job as soon as one of its Pods fails with an exit code
  indicating a software bug.
  To guarantee that your Job finishes even if there are disruptions, you can
  ignore Pod failures caused by disruptions (such as preemption,
  API-initiated eviction
  or taint-based eviction) so
  that they don't count towards the .spec.backoffLimit limit of retries.
  
  You can configure a Pod failure policy, in the .spec.podFailurePolicy field,
  to meet the above use cases. This policy can handle Pod failures based on the
  container exit codes and the Pod conditions.
  Here is a manifest for a Job that defines a podFailurePolicy:
  
  /controllers/job-pod-failure-policy-example.yaml
  
  apiVersion: batch/v1
  kind: Job
  metadata:
   name: job-pod-failure-policy-example
  spec:
   completions: 12
   parallelism: 3
   template:
   spec:
   restartPolicy: Never
   containers:
   - name: main
   image: docker.io/library/bash:5
   command: ["bash"] # example command simulating a bug which triggers the FailJob action
   args:
   - -c
   - echo "Hello world!" && sleep 5 && exit 42
   backoffLimit: 6
   podFailurePolicy:
   rules:
   - action: FailJob
   onExitCodes:
   containerName: main # optional
   operator: In # one of: In, NotIn
   values: [42]
   - action: Ignore # one of: Ignore, FailJob, Count
   onPodConditions:
   - type: DisruptionTarget # indicates Pod disruption
  
  In the example above, the first rule of the Pod failure policy specifies that
  the Job should be marked failed if the main container fails with the 42 exit
  code. The following are the rules for the main container specifically:
  
  an exit code of 0 means that the container succeeded
  an exit code of 42 means that the entire Job failed
  any other exit code represents that the container failed, and hence the entire
  Pod. The Pod will be re-created if the total number of restarts is
  below backoffLimit. If the backoffLimit is reached the entire Job failed.
  
  Note:Because the Pod template specifies a restartPolicy: Never,
  the kubelet does not restart the main container in that particular Pod.
  The second rule of the Pod failure policy, specifying the Ignore action for
  failed Pods with condition DisruptionTarget excludes Pod disruptions
  ```