instruction: Create a Dockerfile for Python with production best practices
output: ```dockerfile
  from the subset of indexes specified in the succeededIndexes reaches the succeededCount,
  the job controller marks the Job as succeeded.
  
  Note that when you specify multiple rules in the .spec.successPolicy.rules,
  the job controller evaluates the rules in order. Once the Job meets a rule, the job controller ignores remaining rules.
  Here is a manifest for a Job with successPolicy:
  
  /controllers/job-success-policy.yaml
  
  apiVersion: batch/v1
  kind: Job
  metadata:
   name: job-success
  spec:
   parallelism: 10
   completions: 10
   completionMode: Indexed # Required for the success policy
   successPolicy:
   rules:
   - succeededIndexes: 0,2-3
   succeededCount: 1
   template:
   spec:
   containers:
   - name: main
   image: python
   command: # Provided that at least one of the Pods with 0, 2, and 3 indexes has succeeded,
   # the overall Job is a success.
   - python3
   - -c
   - |
   import os, sys
   if os.environ.get("JOB_COMPLETION_INDEX") == "2":
   sys.exit(0)
   else:
   sys.exit(1)
   restartPolicy: Never
  
  In the example above, both succeededIndexes and succeededCount have been specified.
  Therefore, the job controller will mark the Job as succeeded and terminate the lingering Pods
  when either of the specified indexes, 0, 2, or 3, succeed.
  The Job that meets the success policy gets the SuccessCriteriaMet condition.
  After the removal of the lingering Pods is issued, the Job gets the Complete condition.
  Note that the succeededIndexes is represented as intervals separated by a hyphen.
  The number are listed in represented by the first and last element of the series, separated by a hyphen.
  Note:When you specify both a success policy and some terminating policies such as .spec.backoffLimit and .spec.podFailurePolicy,
  once the Job meets either policy, the job controller respects the terminating policy and ignores the success policy.
  Job termination and cleanup
  When a Job completes, no more Pods are created, but the Pods are usually not deleted either.
  Keeping them around allows you to still view the logs of completed pods to check for errors, warnings, or other diagnostic output.
  The job object also remains after it is completed so that you can view its status. It is up to the user to delete
  old jobs after noting their status. Delete the job with kubectl (e.g. kubectl delete jobs/pi or kubectl delete -f ./job.yaml).
  When you delete the job using kubectl, all the pods it created are deleted too.
  By default, a Job will run uninterrupted unless a Pod fails (restartPolicy=Never)
  or a Container exits in error (restartPolicy=OnFailure), at which point the Job defers to the
  .spec.backoffLimit described above. Once .spec.backoffLimit has been reached the Job will
  be marked as failed and any running Pods will be terminated.
  Another way to terminate a Job is by setting an active deadline.
  Do this by setting the .spec.activeDeadlineSeconds field of the Job to a number of seconds.
  The activeDeadlineSeconds applies to the duration of the job, no matter how many Pods are created.
  Once a Job reaches activeDeadlineSeconds, all of its running Pods are terminated and the Job status
  will become type: Failed with reason: DeadlineExceeded.
  Note that a Job's .spec.activeDeadlineSeconds takes precedence over its .spec.backoffLimit.
  Therefore, a Job that is retrying one or more failed Pods will not deploy additional Pods once
  it reaches the time limit specified by activeDeadlineSeconds, even if the backoffLimit is not yet reached.
  Example:
  apiVersion: batch/v1
  kind: Job
  metadata:
   name: pi-with-timeout
  spec:
   backoffLimit: 5
   activeDeadlineSeconds: 100
   template:
   spec:
   containers:
   - name: pi
   image: perl:5.34.0
   command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
   restartPolicy: Never
  Note that both the Job spec and the Pod template spec
  within the Job have an activeDeadlineSeconds field. Ensure that you set this field at the proper level.
  Keep in mind that the restartPolicy applies to the Pod, and not to the Job itself:
  there is no automatic Job restart once the Job status is type: Failed.
  That is, the Job termination mechanisms activated with .spec.activeDeadlineSeconds
  and .spec.backoffLimit result in a permanent Job failure that requires manual intervention to resolve.
  Clean up finished jobs automatically
  Finished Jobs are usually no longer needed in the system. Keeping them around in
  the system will put pressure on the API server. If the Jobs are managed directly
  by a higher level controller, such as
  CronJobs, the Jobs can be
  cleaned up by CronJobs based on the specified capacity-based cleanup policy.
  TTL mechanism for finished Jobs
  
  FEATURE STATE: Kubernetes v1.23 [stable]
  
  Another way to clean up finished Jobs (either Complete or Failed)
  automatically is to use a TTL mechanism provided by a
  TTL controller for
  finished resources, by specifying the .spec.ttlSecondsAfterFinished field of
  the Job.
  When the TTL controller cleans up the Job, it will delete the Job cascadingly,
  i.e. delete its dependent objects, such as Pods, together with the Job. Note
  that when the Job is deleted, its lifecycle guarantees, such as finalizers, will
  be honored.
  For example:
  apiVersion: batch/v1
  kind: Job
  metadata:
   name: pi-with-ttl
  spec:
   ttlSecondsAfterFinished: 100
   template:
   spec:
   containers:
   - name: pi
   image: perl:5.34.0
   command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
   restartPolicy: Never
  The Job pi-with-ttl will be eligible to be automatically deleted, 100
  seconds after it finishes.
  If the field is set to 0, the Job will be eligible to be automatically deleted
  immediately after it finishes. If the field is unset, this Job won't be cleaned
  up by the TTL controller after it finishes.
  Note:It is recommended to set ttlSecondsAfterFinished field because unmanaged jobs
  (Jobs that you created directly, and not indirectly through other workload APIs
  such as CronJob) have a default deletion
  policy of orphanDependents causing Pods created by an unmanaged Job to be left around
  after that Job is fully deleted.
  Even though the control plane eventually
  garbage collects
  the Pods
  ```