SSD Nodes Learn 🎉 VPS $5.50/నెల నుండి
మార్గదర్శకాలు Matt Connorద్వారా Matt Connor · అప్‌డేట్ చేయబడింది 2026-08-13

Ubuntu serverలో venv, pipx లేదా uv: ఏది ఎంచుకోవాలి?

Ubuntu 24.04లో pip install చేస్తే externally-managed-environment లోపం వస్తుంది. venv, pipx లేదా uvను install చేసేదాన్ని బట్టి ఎంచుకుని systemdను సరిగ్గా configure చేయండి.

తాజాగా ఏర్పాటు చేసిన Ubuntu serverలో pip install ఎందుకు విఫలమవుతుంది

Python venv, pipx, uv మధ్య ఎంపిక మీరు ఏమి install చేస్తున్నారనే ఒక ప్రశ్నపై ఆధారపడి ఉంటుంది. Application dependencies ను application స్వంత directoryలోని virtual environmentలో ఉంచాలి. పేరుతో టైప్ చేయాలనుకునే command-line tools ను pipxలో ఉంచాలి. uv ఈ రెండు పనులు చేస్తుంది. అదనంగా lockfileను అందిస్తుంది. అదే environmentను రెండో machineలో build చేయాల్సి వచ్చినప్పుడు ఇది ముఖ్యమవుతుంది. వీటిలో ఏదీ system Pythonలో install చేయదు. ప్రస్తుత Ubuntu server దాన్ని నేరుగా నిరాకరిస్తుంది.

Ubuntu 24.04లో sudo pip install requests ను run చేస్తే, ఒక్క file కూడా download చేయకముందే pip ఆగిపోతుంది.

error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip.

    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this behaviour by passing --break-system-packages.

ఇది PEP 668 (Python enhancement proposal 668, "externally managed environments") అమలు కావడం వల్ల జరుగుతుంది. Debian మరియు Ubuntu interpreter పక్కన /usr/lib/python3.12/EXTERNALLY-MANAGED వద్ద marker fileను ఉంచుతాయి. ఆ marker ఉన్న ఏ interpreterలోనూ pip రాయడానికి నిరాకరిస్తుంది.

ఈ నియమం sys.path order వల్ల అవసరం. apt librariesను /usr/lib/python3/dist-packagesలో install చేస్తుంది. system interpreterకు వ్యతిరేకంగా rootగా run చేసిన pip /usr/local/lib/python3.12/dist-packagesలో రాస్తుంది. Debian packaging ఆ directoryను search pathలో ముందుగా ఉంచుతుంది. python3 -c 'import sys; print(sys.path)' తో దాన్ని మీరే print చేసి orderను చూడండి. అందువల్ల pip రాసిన copy, apt install చేసిన copyను shadow చేస్తుంది. /usr/bin/python3 కింద run అయ్యే ఆ machineలోని ప్రతి programకు, distribution స్వంత toolsతో సహా, ఇదే వర్తిస్తుంది. cloud-init ఆ interpreter నుంచి requests, jinja2 మరియు PyYAMLను import చేస్తుంది. వీటిలో ఒకదాన్ని pipతో upgrade చేసి incompatible releaseకు చేరుకుంటే, మీరు తాకని ఏదో ఒకటి తదుపరి bootలో విఫలమవుతుంది. tracebackలో dependency chainలో ఉందని మీకు తెలియని package పేరు కనిపిస్తుంది. apt తన versionను ఇప్పటికీ installedగా నమోదు చేస్తుంది. అందువల్ల ఎలాంటి warning కనిపించదు. దాన్ని సరిచేయడానికి sudo apt reinstall python3-requests అవసరం.

దీనినుంచి వచ్చే నియమం సులభం. system Python distributionకు చెందుతుంది. అందులో install చేయకండి. దాని librariesను pipతో upgrade చేయకండి. సందేశం కనిపించకుండా చేయడానికి EXTERNALLY-MANAGED fileను delete చేయకండి. /usr/bin/python3 కు ఇవ్వాల్సిన ఏకైక పని virtual environmentsను build చేయడం.

venv vs pipx vs uv: నిర్ణయ నియమం

మీరు ఇటీవలి కాలంలో ఎక్కువగా చదివిన సాధనం ఆధారంగా కాకుండా, మీరు ఏమి install చేస్తున్నారో ఆధారంగా ఎంచుకోండి.

  • మీరు serviceగా deploy చేసి run చేసే application, ఉదాహరణకు Django లేదా Flask project: ఆ application directory లోపల ఒక virtual environment (venv).
  • మీ PATH లో అందుబాటులో ఉండాలని కోరుకునే command-line tool, ఉదాహరణకు ansible లేదా httpie: pipx. ఇది ప్రతి toolకు ప్రత్యేక private environmentను, అలాగే PATH లో ఒక linkను అందిస్తుంది.
  • lockfile, వేగవంతమైన installs లేదా distribution ship చేయని Python version అవసరమైన project: uv. ఇది సాధారణ venvతో పాటు ఒక uv.lock fileను సృష్టిస్తుంది.
  • మీ codeకు కాకుండా distribution toolకు అవసరమైన library: sudo apt install python3-<name>. system interpreterకు ఏదైనా జోడించడానికి support చేయబడిన ఏకైక మార్గం ఇదే.

pipx మరియు uv tool install ఒకే పని చేస్తాయి. అందువల్ల ఇప్పటికే uv ఉన్న boxలో pipxను కూడా install చేయాల్సిన అవసరం లేదు. మీరు ఎంచుకున్న web framework దీనిపై ఎలాంటి మార్పు చేయదు: VPSలో Django మరియు Flask లో requirements.txt లోకి ఏది చేరుతుందో మాత్రమే మారుతుంది; దాని చుట్టూ ఉన్న environment ఎలా నిర్మించబడుతుందో మారదు. దిగువ ఉదాహరణలన్నీ Ubuntu 24.04 మరియు దాని Python 3.12ను ఉపయోగిస్తాయి. మీ version భిన్నంగా ఉంటే pathsలోని versionను సరిచేయండి.

ప్రతి అప్లికేషన్ కోసం venv సృష్టించండి

Ubuntu venv module ను base Python package నుంచి వేరుగా ఉంచుతుంది. అందువల్ల minimal image లో మొదటి ప్రయత్నం విఫలమైతే, ఏది missing అయిందో స్పష్టంగా తెలిపే message కనిపిస్తుంది.

The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt install python3.12-venv

దాన్ని install చేసి, code ను స్వంతం చేసుకునే user తో environment ను సృష్టించండి.

sudo apt update
sudo apt install -y python3-venv
sudo install -d -o deploy -g deploy -m 755 /srv/myapp
sudo -u deploy python3 -m venv /srv/myapp/.venv
sudo -u deploy /srv/myapp/.venv/bin/pip install -r /srv/myapp/requirements.txt

అక్కడ లేనివి గమనించండి: source లేదు, activate కూడా లేదు. /srv/myapp/.venv/bin/pip ఆ environment లో install అవుతుంది. దీనికి కారణం binary ఉన్న స్థానం; మీరు shell లో export చేసిన ఏదీ కారణం కాదు. ముందుకు వెళ్లే ముందు దీన్ని నిర్ధారించండి.

/srv/myapp/.venv/bin/python -c 'import sys; print(sys.prefix)'

ఇది /srv/myapp/.venv ను output చేస్తుంది. /usr కనిపిస్తే, మీరు system interpreter ను ఉపయోగిస్తున్నారు. మీ packages మీరు ఉద్దేశించని ప్రదేశంలో install అయ్యాయి.

venv తో తరువాత ఏమి చేయవచ్చో రెండు లక్షణాలు నిర్ణయిస్తాయి. venv ను మరో ప్రదేశానికి మార్చలేరు. కారణం, bin/ లోని ప్రతి script లో absolute shebang line ఉంటుంది: head -1 /srv/myapp/.venv/bin/pip, #!/srv/myapp/.venv/bin/python ను చదువుతుంది. Parent directory పేరు మార్చితే, ఆ scripts bad interpreter: No such file or directory తో విఫలమవుతాయి. venv ను సృష్టించిన interpreter ను కూడా అది స్థిరంగా ఉపయోగిస్తుంది. ఇది /srv/myapp/.venv/pyvenv.cfg లోని home line గా నమోదు అవుతుంది. bin/python3 ఆ binary కు symlink గా ఉంటుంది. Release ను upgrade చేసినప్పుడు python3.12 లేకపోతే, symlink కు target ఉండదు. అప్పుడు service ప్రారంభంలో No such file or directory తో ఆగిపోతుంది. రెండు సందర్భాల్లోనూ పరిష్కారం ఒకటే: venv ను delete చేసి, requirements.txt నుంచి కొత్తదాన్ని సృష్టించండి. Rebuild చేయడానికి కొన్ని seconds మాత్రమే పడుతుంది. ఒక machine నుంచి మరో machine కు venv ను ఎప్పుడూ copy చేయవద్దు.

venv ఎక్కడ ఉండాలి, దాని యజమాని ఎవరు

దాన్ని /srv/myapp/.venv వద్ద ఉన్న code పక్కన ఉంచండి. ప్రతి application కు ఒక venv మాత్రమే ఉపయోగించండి. అప్పుడు deployment ఒకే directoryగా ఉంటుంది. systemd unit కు ఎప్పటికీ మారని path లభిస్తుంది. ఒకే shared dependency upgrade వల్ల రెండు applications ఒకదానినొకటి ఎప్పుడూ ప్రభావితం చేయలేవు. మీ web server files ను నేరుగా publish చేసే ప్రదేశంలో venv ను ఉంచవద్దు. అందులో dependencies మరియు తరచుగా configuration కూడా ఉంటాయి.

Ownership పై అర నిమిషం కేటాయించండి. code మరియు environment కు deploy user ను owner గా ఉంచండి. service account కు read మరియు execute access మాత్రమే ఇవ్వండి.

sudo adduser --system --group --no-create-home myapp
sudo chown -R deploy:myapp /srv/myapp
sudo chmod -R o-rwx /srv/myapp

ఇప్పుడు service తన dependencies ను import చేయగలదు. కానీ వాటిని తిరిగి రాయలదు. అందువల్ల web application లోని code execution bug disk పై ఉన్న library ని నిశ్శబ్దంగా మార్చి, restart తర్వాత కూడా కొనసాగించలదు. ఇదే విధానాన్ని మిగిలిన machine కు ఎలా వర్తింపజేయాలో least-privilege users గా services ను నడపడం లో వివరించాం.

కమాండ్-లైన్ సాధనాల కోసం pipx

pipx లైబ్రరీలను కాదు, అప్లికేషన్లను ఇన్‌స్టాల్ చేస్తుంది. ప్రతి సాధనానికి ~/.local/share/pipx/venvs/<name> కింద ప్రత్యేక environment లభిస్తుంది. ఆ సాధనం యొక్క executables ~/.local/bin లోకి link చేయబడతాయి. అందువల్ల ఒకే లైబ్రరీకి వేర్వేరు versions అవసరమైన రెండు సాధనాల మధ్య ఘర్షణ ఉండదు.

sudo apt update
sudo apt install -y pipx
pipx ensurepath
pipx install httpie

Shell startup file ను సవరించడం ద్వారా pipx ensurepath, ~/.local/bin ను PATH కు జోడిస్తుంది. మీరు ఇప్పటికే ఉపయోగిస్తున్న shell ను ఇది మార్చదు. అందువల్ల install చేసిన వెంటనే http: command not found కనిపిస్తే, సాధారణంగా మీరు ఇంకా logout చేసి మళ్లీ login కాలేదని అర్థం. Ubuntu యొక్క default ~/.profile, login సమయంలో ఆ directory ఇప్పటికే ఉన్నప్పుడు మాత్రమే ~/.local/bin ను జోడిస్తుంది. అందుకే కొత్త account లో ఈ సమస్య ఒక్కసారి మాత్రమే కనిపిస్తుంది. తరువాత మళ్లీ కనిపించదు.

pipx కు library ను ఇస్తే అది నిరాకరిస్తుంది. సందేశం ఇలా ప్రారంభమవుతుంది:

No apps associated with package requests or its dependencies.

ఇది తప్పు సాధనాన్ని ఉపయోగిస్తున్నారని pipx తెలియజేస్తోంది. Libraries ను application యొక్క venv లో ఉంచాలి.

Serverలో ముఖ్యమైన విషయం location. సాధారణ pipx install ప్రతిదాన్ని ఒక user యొక్క home directory కింద ఉంచుతుంది. myapp గా నడిచే systemd unit దాన్ని చూడలేడు. root cron job కూడా దాన్ని చూడలేడు. sudo కూడా దాన్ని కనుగొనదు. కారణం, /etc/sudoers లోని secure_path, PATH ను fixed list తో భర్తీ చేస్తుంది. మొత్తం machineలో అందుబాటులో ఉండాల్సిన సాధనం అయితే దాన్ని globally install చేయాలి.

sudo pipx install --global ansible
sudo pipx ensurepath --global

--global flag environments ను /opt/pipx లో ఉంచుతుంది. Executables ను /usr/local/bin లోకి link చేస్తుంది. ఈ directory default PATH లోనూ, secure_path లోపల కూడా ఉంటుంది. ముందుగా pipx --version తో మీ version ను తనిఖీ చేయండి. Ubuntu 24.04 లో pipx 1.4.3 package అవుతుంది. ఇది --global కంటే పాతది. పాత pipx, unrecognized arguments: --global తో సమాధానం ఇస్తుంది. ఆ versionలో documented directories రెండింటినీ మీరే సెట్ చేయాలి:

sudo env PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin pipx install ansible
command -v ansible

command -v ansible, /usr/local/bin/ansible ను print చేయాలి. అది /home కింద ఉన్న path ను print చేస్తే, సాధనం ఒకే user account లోకి వెళ్లింది. ఏ service కూడా దాన్ని కనుగొనదు.

lockfile కావాలనుకున్నప్పుడు uv

uv అనేది Astral అందించే ఒకే binary. ఇది pip, venv మరియు pip-tools చేసే పనులను కవర్ చేస్తుంది. అవసరమైతే interpreters ను కూడా download చేయగలదు. చిన్న VPSలో కూడా దాని వేగం స్పష్టంగా కనిపిస్తుంది. ఇది నిజమైన lockfile ను రాస్తుంది.

Official installer uv మరియు uvx ను ~/.local/bin లో ఉంచుతుంది:

curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version

Serverలో script ను shellకు pipe చేయడానికి ముందు కొంత జాగ్రత్త అవసరం. URLలో version ను నిర్దిష్టంగా pin చేసి, run చేయడానికి ముందు file ను చదవండి:

curl -LsSf https://astral.sh/uv/0.12.3/install.sh -o uv-install.sh
less uv-install.sh
sh uv-install.sh

pipx ఇప్పటికే ఉంటే pipx install uv కూడా పనిచేస్తుంది. uv అనేది స్వతంత్రంగా పనిచేసే ఒకే binary. దానికి స్వంతంగా Python dependency అవసరం లేదు. అందువల్ల దాన్ని /usr/local/bin లోకి copy చేయడం ద్వారా serverలోని ప్రతి userకు అందించవచ్చు.

pyproject.toml ఉన్న project కోసం workflowలో నాలుగు commands ఉంటాయి. వాటిలో చివరి command మాత్రమే serverపై run అవుతుంది.

uv init myapp
uv add flask gunicorn
uv lock
uv sync --frozen --no-dev

uv lock, ఖచ్చితంగా resolve చేసిన versions ను కలిగి ఉన్న cross-platform lockfile అయిన uv.lock ను రాస్తుంది. దాన్ని code పక్కన commit చేయాలి. దానికి సరిపడేలా project rootలో .venv ను uv sync build చేస్తుంది. Serverపై ముఖ్యమైన flag --frozen. Documentation ప్రకారం, lockfile తాజాగా ఉందో లేదో తనిఖీ చేయకుండా, lockfileలోని versionsనే ప్రామాణిక ఆధారంగా ఉపయోగించమని ఇది సూచిస్తుంది. Deploymentకు ఇదే కావాలి. --no-dev development dependency groupను చేర్చదు.

ఇప్పటికే ఉన్న requirements.txt projectకు conversion అవసరం లేదు, ఎందుకంటే uv pip భాషను అర్థం చేసుకుంటుంది:

uv venv /srv/myapp/.venv
uv pip install --python /srv/myapp/.venv/bin/python -r /srv/myapp/requirements.txt

దీని ఫలితంగా సాధారణ virtual environment ఏర్పడుతుంది. .venv/bin/python, python3 -m venv దాన్ని build చేసినట్లే పనిచేస్తుంది. అందువల్ల ఈ guideలోని తరువాతి దశల్లో ఎలాంటి మార్పు అవసరం లేదు.

Serverలో uvను ఉపయోగించే ముందు దాని defaultలో ఒక విషయం తెలుసుకోవాలి. దాని python-preference setting defaultగా managed కు సెట్ అయి ఉంటుంది. Documentation ప్రకారం, systemలో ఇప్పటికే ఉన్న interpreters కంటే “uv ద్వారా download చేసి install చేసిన వాటిని” ఎంచుకోవడం దీని అర్థం. కాబట్టి కేవలం 3.12 ఉన్న serverలో uv venv --python 3.13 run చేస్తే, అది విఫలమవకుండా 3.13ను ~/.local/share/uv/python లోకి download చేస్తుంది. Laptopలో ఇది సౌకర్యవంతంగా ఉంటుంది. Serverలో మాత్రం ఇది అనుకోని ఫలితాన్ని ఇస్తుంది. ఎందుకంటే ఇప్పుడు మీ service home directoryలో ఉన్న interpreterపై ఆధారపడుతుంది. దాన్ని apt upgrade ఎప్పటికీ patch చేయదు. Distribution అందించే interpreter కావాలంటే python-preference ను only-system కు, uv.toml లో సెట్ చేయండి. Environment project rootకు బదులుగా వేరే ప్రదేశంలో కావాలంటే, project virtual environment కోసం ఉపయోగించాల్సిన directoryని UV_PROJECT_ENVIRONMENT నిర్దేశిస్తుంది.

venv interpreter ను activate పై కాకుండా systemd కు సూచించండి

ఇక్కడే ఎక్కువ Python deployments విఫలమవుతాయి. దీనికి కారణం activate ఏమి చేస్తుందో అర్థం చేసుకోవడంలో ఉన్న పొరపాటు.

bin/activate ఒక shell script. ఇది venv కు చెందిన bin directory ను PATH ముందు ఉంచుతుంది, VIRTUAL_ENV ను సెట్ చేస్తుంది, పాత విలువలను సేవ్ చేసి deactivate వాటిని పునరుద్ధరించగలిగేలా చేస్తుంది, అలాగే మీ prompt ను మార్చుతుంది. Interpreter స్వయంగా చదివే ఏ విషయం కూడా ఇందులో ఉండదు. Prompt వద్ద python టైప్ చేసే వ్యక్తికి activation ఒక సౌకర్యం మాత్రమే.

Environment ను వాస్తవంగా ఎంచుకునేది మీరు execute చేసే interpreter file. /srv/myapp/.venv/bin/python ప్రారంభమైనప్పుడు, Python యొక్క site module executable ఉన్న directory లో మరియు దాని ఒక స్థాయి పైన pyvenv.cfg file కోసం చూస్తుంది. /srv/myapp/.venv/pyvenv.cfg దొరికితే sys.prefix ను venv కు సెట్ చేస్తుంది. దాంతో ఆ venv కు చెందిన site-packages, sys.path లో చేరుతుంది. మొత్తం mechanism ఇదే. దీనికి environment variable లేదా shell అవసరం లేదు.

అందువల్ల ఈ unit ఎప్పటికీ ప్రారంభం కాదు:

[Service]
ExecStart=source /srv/myapp/.venv/bin/activate && gunicorn app:app
myapp.service: Failed to locate executable source: No such file or directory
myapp.service: Failed at step EXEC spawning source: No such file or directory
myapp.service: Main process exited, code=exited, status=203/EXEC

ExecStart అనేది shell command line కాదు. systemd program ను నేరుగా execute చేస్తుంది. కాబట్టి source builtin అందుబాటులో ఉండదు, && ను literal argument గా పంపిస్తుంది, ఏదీ expand కాదు.

ఈ unit ప్రారంభమై, తరువాత ఆగిపోతుంది:

[Service]
ExecStart=/usr/bin/python3 /srv/myapp/app.py
ModuleNotFoundError: No module named 'flask'

/usr/bin/python3 system interpreter. దాని sys.path లో మీ venv ఎప్పుడూ ఉండలేదు. మీ SSH session లో అదే command పనిచేసింది, ఎందుకంటే అక్కడ మీరు venv ను activate చేశారు. అందువల్ల shell python3 ను PATH ద్వారా resolve చేసి, బదులుగా .venv/bin/python3 ను ఉపయోగించింది.

Command ను /bin/bash -c 'source ... && gunicorn ...' లో wrap చేస్తే పనిచేస్తుంది. అయితే దీనివల్ల systemd మరియు మీ process మధ్య అవసరం లేని shell చేరుతుంది. ఒక absolute path సరిపోతుంది:

[Unit]
Description=myapp web service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/srv/myapp
Environment=PYTHONUNBUFFERED=1
Environment=PATH=/srv/myapp/.venv/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/srv/myapp/.venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 app:app
Restart=on-failure
RestartSec=5
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp
journalctl -u myapp -n 50 --no-pager

systemctl status myapp మీ gunicorn process కు చెందిన Main PID తో active (running) ను report చేయాలి. వేరే ఫలితం వస్తే journal ను పరిశీలించండి.

Environment=PATH= line ExecStart కోసం కాదు. అది ఇప్పటికే పూర్తి path ను కలిగి ఉంది. మీ application ప్రారంభించే processes కోసం అది అవసరం. Service కు systemd నుంచి చిన్న default PATH లభిస్తుంది. అందువల్ల subprocess.run(["ffmpeg", ...]) ను పిలిచే Python code లేదా venv నుంచి console script ను shell ద్వారా ప్రారంభించే management command అవసరమైనదాన్ని కనుగొనదు. venv కు చెందిన bin directory ను మొదట ఉంచడం, service నిజంగా ఉపయోగించే activate లోని ఒక భాగం. Unit కు వాస్తవంగా అందిన విలువను systemctl show -p Environment myapp తో పరిశీలించండి.

ఇదే నియమం scheduled work కు కూడా వర్తిస్తుంది. cron jobs ను /usr/bin:/bin యొక్క PATH తో నడుపుతుంది. కాబట్టి python3 /srv/myapp/cleanup.py ను కలిగి ఉన్న crontab line system interpreter ను నడిపిస్తుంది. తెల్లవారుజామున మూడు గంటలకు ModuleNotFoundError తో విఫలమవుతుంది. ఆ error ను ఎవరూ చదవని local mail spool కు పంపిస్తుంది. అక్కడ కూడా absolute venv path ను రాయండి. ఆ output ను journal లోకి పంపించి, చివరి run యొక్క record కావాలంటే, systemd service మరియు timer జత అదే ExecStart line ను ఉపయోగిస్తుంది.

Docker ఈ నిర్ణయాన్ని భర్తీ చేస్తుందా?

ఒక container కు దాని స్వంత filesystem ఉంటుంది. అందువల్ల ప్రశ్న తొలగిపోదు; దాని రూపం మాత్రమే మారుతుంది. python:3.12-slim వంటి official image లో Python ఇప్పటికే /usr/local లో నిర్మించబడి ఉంటుంది. దానిలో EXTERNALLY-MANAGED marker ఉండదు. కాబట్టి packages జోడించడానికి root గా pip install ఉపయోగించడం ఉద్దేశించిన విధానమే, మరియు venv వల్ల పెద్దగా ప్రయోజనం ఉండదు. బదులుగా FROM ubuntu:24.04 build చేయండి. అప్పుడు image లోపల మళ్లీ externally-managed-environment సమస్యను ఎదుర్కొంటారు. Host పై ఉన్న కారణమే ఇక్కడ కూడా ఉంటుంది: ఇది distribution కు చెందిన interpreter, దానిలో distribution marker file ఉంటుంది.

అయినా అనేక images venv ను ఉపయోగిస్తాయి, ఎందుకంటే అది multi-stage build ను సులభం చేస్తుంది. Builder stage /opt/venv లో install చేస్తుంది. Runtime stage ఆ ఒక్క directory ని copy చేసి compilers ను అక్కడే వదిలేస్తుంది. Activate సమస్య కూడా దానితో పాటు వస్తుంది. RUN source /opt/venv/bin/activate line ఆ build layer యొక్క shell పై మాత్రమే ప్రభావం చూపుతుంది. కాబట్టి runtime సమయంలో container system interpreter తో ప్రారంభమై ModuleNotFoundError ను చూపిస్తుంది. ENV PATH="/opt/venv/bin:$PATH" ను సెట్ చేయండి, లేదా CMD కు absolute path /opt/venv/bin/gunicorn ను ఇవ్వండి. ఇది systemd లోని సమస్యతో సమానమైన bug, కానీ వేరే file లో ఉంటుంది.

కాబట్టి container interpreter ప్రశ్నను భర్తీ చేస్తుంది, ఎందుకంటే image interpreter ను మరియు దాని కింద ఉన్న ప్రతిదాన్ని నిర్దిష్టంగా నిర్ణయిస్తుంది. కానీ version pinning ప్రశ్నను భర్తీ చేయదు. Unpinned requirements.txt నుంచి build చేసిన image వచ్చే నెలలో వేర్వేరు versions ను resolve చేయవచ్చు. అంటే image tag reproducible అయినప్పటికీ, దాన్ని రూపొందించిన build reproducible కాదు. uv.lock వంటి lockfile లేదా పూర్తిగా pinned requirements file ఈ అంతరాన్ని మూసివేస్తుంది; container ఉపయోగించినా లేకపోయినా ఇదే వర్తిస్తుంది. ఒక VPS పై systemd కింద ఒకే అప్లికేషన్ నడుస్తున్నప్పుడు, container సాధారణంగా ఇదే నిర్ణయాన్ని Dockerfile లోకి మాత్రమే తరలిస్తుంది. ఎందుకంటే systemd ఇప్పటికే విఫలమైన process ను restart చేసి, దాని output ను journal లో capture చేస్తుంది. VPS పై Docker నడపడం మీరు deploy చేసేది built image నే కావాలనుకున్నప్పుడు ఉపయోగకరంగా ఉంటుంది.

FAQ

నేను --break-system-packages తో pip install ఉపయోగించవచ్చా?

నిరంతరం నడవాల్సిన server పై అలా చేయకండి. ఆ flag తన పేరు సూచించినట్లే పనిచేస్తుంది: రక్షణను తొలగించి, pip ను /usr/local/lib/python3.12/dist-packages లోకి రాయడానికి అనుమతిస్తుంది. ఇది sys.path లోని apt directory కంటే ముందుంటుంది. ఆ తర్వాత /usr/bin/python3 కింద నడిచే ప్రతి system script కు మీ version distribution version ను మించిపోతుంది. apt మాత్రం తన version install అయిందనే భావిస్తుంది. అందువల్ల ఏదైనా విఫలమయ్యే వరకు ఈ విరుద్ధతను ఏదీ గుర్తించదు. ప్రతి సారి మొదటి నుంచి rebuild చేసే container image లో ఈ నష్టం ఆ image కే పరిమితం అవుతుంది. కాబట్టి అక్కడ ఈ పద్ధతిని సమర్థించవచ్చు. మీరు నిర్వహించే machine పై venv సృష్టించండి. దానికి ఒకే command చాలు.

server పై virtual environment ఎక్కడ ఉండాలి?

అప్లికేషన్‌కు చెందిన directory లోనే, /srv/myapp/.venv గా ఉంచండి. దాని యాజమాన్యం deploy user కు ఇవ్వండి. service account కు read మరియు execute access మాత్రమే ఉండాలి. ప్రతి అప్లికేషన్‌కు ఒక venv ఉంచండి. Shared venv వాడితే మొదటి అప్లికేషన్‌కు చేసిన upgrade రెండవ అప్లికేషన్‌ను విఫలమయ్యేలా చేయవచ్చు. venv సృష్టించిన తర్వాత దాన్ని తరలించవద్దు లేదా copy చేయవద్దు. దాని bin/ directory లోని ప్రతి script తన shebang line లో ఆ absolute path ను కలిగి ఉంటుంది. అందువల్ల తరలించిన venv bad interpreter: No such file or directory తో విఫలమవుతుంది. దాన్ని తొలగించి, బదులుగా requirements.txt నుంచి మళ్లీ build చేయండి.

నా systemd service ModuleNotFoundError తో ఎందుకు విఫలమవుతోంది?

ఆ unit venv కు చెందిన interpreter ను కాకుండా వేరే interpreter ను execute చేస్తోంది. systemctl cat myapp ను run చేసి, ExecStart ను చదవండి. అది absolute path ద్వారా /srv/myapp/.venv/bin/python ను లేదా అదే bin/ directory నుంచి వచ్చిన console script ను సూచించాలి. Unit file లో activate ను source చేయడం పనిచేయదు. ఎందుకంటే ExecStart shell కాదు. systemd Failed to locate executable source ను status=203/EXEC తో report చేస్తుంది. మీ code ప్రారంభించే ఏ subprocess అయినా venv లోని tools ను కనుగొనేలా Environment=PATH=/srv/myapp/.venv/bin:/usr/local/bin:/usr/bin:/bin ను జోడించండి.

venv మరియు pip కు బదులుగా uv ఉపయోగించాలా?

మీకు lockfile కావాలనుకున్నప్పుడు, install సమయం ఇబ్బంది కలిగించేంత ఎక్కువగా ఉన్నప్పుడు లేదా మీ distribution విడుదల చేయని Python version అవసరమైనప్పుడు uv ఉపయోగించండి. ఇది సాధారణ venv ను సృష్టిస్తుంది. కాబట్టి systemd unit మరియు file layout మారవు. uv sync --frozen lockfile లో నమోదు చేసిన వాటినే ఖచ్చితంగా install చేస్తుంది. ఒకే అప్లికేషన్ pinned requirements.txt తో git నుంచి deploy అవుతూ, install కొన్ని seconds లో పూర్తయితే python3 -m venv ఇప్పటికే సరిపోతుంది. అదనంగా server పై update చేయాల్సిన ఒక binary తగ్గుతుంది.

#python#venv#pipx#uv#deployment