1"use strict";(self.webpackChunkcommunity_charts_github_io=self.webpackChunkcommunity_charts_github_io||[]).push([["1472"],{19959(e,n,r){r.r(n),r.d(n,{metadata:()=>i,default:()=>h,frontMatter:()=>a,contentTitle:()=>o,toc:()=>c,assets:()=>l});var i=JSON.parse('{"id":"charts/pypiserver/configuration","title":"PyPI Server Configuration","description":"Learn how to configure PyPI Server chart with custom values, environment variables, and deployment options","source":"@site/docs/charts/pypiserver/configuration.md","sourceDirName":"charts/pypiserver","slug":"/charts/pypiserver/configuration","permalink":"/docs/charts/pypiserver/configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/community-charts/community-charts.github.io/tree/main/docs/charts/pypiserver/configuration.md","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"id":"configuration","title":"PyPI Server Configuration","sidebar_label":"Configuration","sidebar_position":2,"description":"Learn how to configure PyPI Server chart with custom values, environment variables, and deployment options","keywords":["pypiserver configuration","helm values","kubernetes deployment","python package server"]},"sidebar":"guideSidebar","previous":{"title":"Usage","permalink":"/docs/charts/pypiserver/usage"},"next":{"title":"Storage","permalink":"/docs/charts/pypiserver/storage"}}'),t=r(74848),s=r(28453);let a={id:"configuration",title:"PyPI Server Configuration",sidebar_label:"Configuration",sidebar_position:2,description:"Learn how to configure PyPI Server chart with custom values, environment variables, and deployment options",keywords:["pypiserver configuration","helm values","kubernetes deployment","python package server"]},o="Configuration",l={},c=[{value:"Basic Configuration",id:"basic-configuration",level:2},{value:"Image Configuration",id:"image-configuration",level:3},{value:"Replica Configuration",id:"replica-configuration",level:3},{value:"Service Configuration",id:"service-configuration",level:3},{value:"PyPI Server Arguments",id:"pypi-server-arguments",level:2},{value:"Common PyPI Server Arguments",id:"common-pypi-server-arguments",level:3},{value:"Ingress Configuration",id:"ingress-configuration",level:2},{value:"Resource Management",id:"resource-management",level:2},{value:"Security Configuration",id:"security-configuration",level:2},{value:"Pod Security Context",id:"pod-security-context",level:3},{value:"Container Security Context",id:"container-security-context",level:3},{value:"Health Checks",id:"health-checks",level:2},{value:"Deployment Strategy",id:"deployment-strategy",level:2},{value:"Node Scheduling",id:"node-scheduling",level:2},{value:"Node Selector",id:"node-selector",level:3},{value:"Affinity Rules",id:"affinity-rules",level:3},{value:"Tolerations",id:"tolerations",level:3},{value:"Service Account",id:"service-account",level:2},{value:"Complete Example",id:"complete-example",level:2},{value:"Environment Variables",id:"environment-variables",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){let n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,t.jsxs)(n.p,{children:["This page covers all configuration options available for the PyPI Server Helm chart. You can customize the deployment by creating a custom ",(0,t.jsx)(n.code,{children:"values.yaml"})," file or passing values directly to the Helm command."]}),"\n",(0,t.jsx)(n.h2,{id:"basic-configuration",children:"Basic Configuration"}),"\n",(0,t.jsx)(n.h3,{id:"image-configuration",children:"Image Configuration"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'image:\n repository: pypiserver/pypiserver\n tag: "" # Uses chart appVersion by default\n pullPolicy: IfNotPresent\n'})}),"\n",(0,t.jsx)(n.h3,{id:"replica-configuration",children:"Replica Configuration"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"replicaCount: 1\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"PyPI Server is designed to be lightweight and typically runs as a single instance. For high availability, consider using multiple replicas with proper volume sharing."})}),"\n",(0,t.jsx)(n.h3,{id:"service-configuration",children:"Service Configuration"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"service:\n t
1ype: ClusterIP\n port: 8080\n name: http\n annotations: {}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"pypi-server-arguments",children:"PyPI Server Arguments"}),"\n",(0,t.jsx)(n.p,{children:"The chart allows you to customize PyPI Server startup arguments:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'podArgs:\n - "run"\n - "-a"\n - "."\n - "-P"\n - "."\n - "--overwrite"\n'})}),"\n",(0,t.jsx)(n.h3,{id:"common-pypi-server-arguments",children:"Common PyPI Server Arguments"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Argument"}),(0,t.jsx)(n.th,{children:"Description"}),(0,t.jsx)(n.th,{children:"Example"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"-a, --authenticate"})}),(0,t.jsx)(n.td,{children:"Comma-separated list of package names that require authentication"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'-a "my-package,private-package"'})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"-P, --passwords"})}),(0,t.jsx)(n.td,{children:"Path to password file"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'-P "/data/.htpasswd"'})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"--overwrite"})}),(0,t.jsx)(n.td,{children:"Allow overwriting existing packages"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"--overwrite"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"--fallback-url"})}),(0,t.jsx)(n.td,{children:"Fallback URL for packages not found locally"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'--fallback-url "https://pypi.org/simple/"'})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"--server"})}),(0,t.jsx)(n.td,{children:"Server method (auto, cherrypy, paste, twisted, gunicorn, gevent, tornado, waitress)"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'--server "gunicorn"'})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"--port"})}),(0,t.jsx)(n.td,{children:"Port to listen on"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'--port "8080"'})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"--interface"})}),(0,t.jsx)(n.td,{children:"Interface to bind to"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'--interface "0.0.0.0"'})})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"ingress-configuration",children:"Ingress Configuration"}),"\n",(0,t.jsx)(n.p,{children:"Enable and configure ingress for external access:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ingress:\n enabled: true\n className: nginx\n annotations:\n kubernetes.io/ingress.class: nginx\n cert-manager.io/cluster-issuer: letsencrypt-prod\n hosts:\n - host: pypi.yourdomain.com\n paths:\n - path: /\n pathType: Prefix\n tls:\n - secretName: pypi-tls\n hosts:\n - pypi.yourdomain.com\n"})}),"\n",(0,t.jsx)(n.h2,{id:"resource-management",children:"Resource Management"}),"\n",(0,t.jsx)(n.p,{children:"Configure resource limits and requests:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"resources:\n limits:\n cpu: 500m\n memory: 2Gi\n requests:\n cpu: 200m\n memory: 1Gi\n"})}),"\n",(0,t.jsx)(n.h2,{id:"security-configuration",children:"Security Configuration"}),"\n",(0,t.jsx)(n.h3,{id:"pod-security-context",children:"Pod Security Context"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"podSecurityContext:\n runAsUser: 1000\n runAsGroup: 3000\n fsGroup: 2000\n fsGroupChangePolicy: OnRootMismatch\n"})}),"\n",(0,t.jsx)(n.h3,{id:"container-security-context",children:"Container Security Context"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"securityContext:\n runAsNonRoot: true\n runAsUser: 1000\n readOnlyRootFilesystem: true\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n"})}),"\n",(0,t.jsx)(n.h2,{id:"health-checks",children:"Health Checks"}),"\n",(0,t.jsx)(n.p,{children:"Configure liveness and readiness probes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"livenessProbe:\n httpGet:\n path: /health\n port: http\n initialDelaySeconds: 30\n periodSeconds: 10\n timeoutSeconds: 5\n failureThreshold: 3\n\nreadinessProbe:\n httpGet:\n path: /health\n port: http\n initialDelaySeconds: 5\n periodSeconds: 5\n timeoutSeconds: 3\n failureThreshold: 3\n"})}),"\n",(0,t.jsx)(n.h2,{id:"deployment-strategy",children:"Deployment Strategy"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'strategy:\n type: Recreate\n # Alternative: RollingUpdate\n # rollingUpdate:\n # maxSurge: "100%"\
1n # maxUnavailable: 0\n'})}),"\n",(0,t.jsx)(n.h2,{id:"node-scheduling",children:"Node Scheduling"}),"\n",(0,t.jsx)(n.h3,{id:"node-selector",children:"Node Selector"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'nodeSelector:\n kubernetes.io/os: linux\n node-role.kubernetes.io/worker: "true"\n'})}),"\n",(0,t.jsx)(n.h3,{id:"affinity-rules",children:"Affinity Rules"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"affinity:\n podAntiAffinity:\n preferredDuringSchedulingIgnoredDuringExecution:\n - weight: 100\n podAffinityTerm:\n labelSelector:\n matchExpressions:\n - key: app.kubernetes.io/name\n operator: In\n values:\n - pypiserver\n topologyKey: kubernetes.io/hostname\n"})}),"\n",(0,t.jsx)(n.h3,{id:"tolerations",children:"Tolerations"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'tolerations:\n - key: "dedicated"\n operator: "Equal"\n value: "pypiserver"\n effect: "NoSchedule"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"service-account",children:"Service Account"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'serviceAccount:\n create: true\n automount: true\n annotations: {}\n name: ""\n'})}),"\n",(0,t.jsx)(n.h2,{id:"complete-example",children:"Complete Example"}),"\n",(0,t.jsx)(n.p,{children:"Here's a complete example of a production-ready configuration:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'# values.yaml\nreplicaCount: 1\n\nimage:\n repository: pypiserver/pypiserver\n tag: ""\n pullPolicy: IfNotPresent\n\nservice:\n type: ClusterIP\n port: 8080\n name: http\n\ningress:\n enabled: true\n className: nginx\n annotations:\n kubernetes.io/ingress.class: nginx\n cert-manager.io/cluster-issuer: letsencrypt-prod\n hosts:\n - host: pypi.yourdomain.com\n paths:\n - path: /\n pathType: Prefix\n tls:\n - secretName: pypi-tls\n hosts:\n - pypi.yourdomain.com\n\npodArgs:\n - "run"\n - "-a"\n - "."\n - "-P"\n - "/data/.htpasswd"\n - "--overwrite"\n - "--fallback-url"\n - "https://pypi.org/simple/"\n\nresources:\n limits:\n cpu: 500m\n memory: 2Gi\n requests:\n cpu: 200m\n memory: 1Gi\n\nsecurityContext:\n runAsNonRoot: true\n runAsUser: 1000\n readOnlyRootFilesystem: true\n allowPrivilegeEscalation: false\n\npodSecurityContext:\n runAsUser: 1000\n runAsGroup: 3000\n fsGroup: 2000\n\nvolumes:\n - name: packages\n persistentVolumeClaim:\n claimName: pypi-packages-pvc\n - name: auth\n secret:\n secretName: pypi-auth\n\nvolumeMounts:\n - name: packages\n mountPath: "/data/packages"\n - name: auth\n mountPath: "/data/.htpasswd"\n subPath: ".htpasswd"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"environment-variables",children:"Environment Variables"}),"\n",(0,t.jsx)(n.p,{children:"The chart automatically sets the following environment variables:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"PYPISERVER_PORT"}),": Set to the service port (default: 8080)"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["You can add custom environment variables using the ",(0,t.jsx)(n.code,{children:"env"})," section in the deployment template or by modifying the chart."]}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn about ",(0,t.jsx)(n.a,{href:"/docs/charts/pypiserver/storage",children:"storage configuration"})," for persistent package storage"]}),"\n",(0,t.jsxs)(n.li,{children:["Explore ",(0,t.jsx)(n.a,{href:"/docs/charts/pypiserver/advanced-configuration",children:"advanced configuration"})," options"]}),"\n",(0,t.jsxs)(n.li,{children:["Check ",(0,t.jsx)(n.a,{href:"/docs/charts/pypiserver/troubleshooting",children:"troubleshooting"})," for common issues"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"/docs/charts/pypiserver/usage",children:"usage guide"})," for deployment examples"]}),"\n"]})]})}function h(e={}){let{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453(e,n,r){r.d(n,{R:()=>a,x:()=>o});var i=r(96540);let t={},s=i.createContext(t);function a(e){let n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.