Docker Compose-ல் .env, env_file, environment வேறுபாடு
Docker Compose-ல் .env, env_file, environment ஆகியவை எப்படி வேறுபடுகின்றன, எந்த value முன்னுரிமை பெறுகிறது, secrets-ஐ எங்கு வைக்க வேண்டும் என்பதை அறிக.
மக்கள் env file என்று அழைக்கும் 3 தனித்தனி விஷயங்கள்
Docker Compose ஒரே மாதிரியாகத் தோன்றும் பெயர்களைக் கொண்ட 3 தனித்தனி mechanisms-ஐ வழங்குகிறது. .env file, Compose அந்த file-ஐ parse செய்வதற்கும் முன்பே, compose.yaml file-இல் உள்ள ${VARIABLE} placeholders-ஐ நிரப்புகிறது. env_file: attribute, key/value pairs கொண்ட file-ஐ container-ன் environment-இல் load செய்கிறது. environment: attribute, compose file-இல் நேரடியாக எழுதப்பட்ட variables-ஐ container-இல் அமைக்கிறது. இவை ஒன்றுக்கொன்று மாற்றாகப் பயன்படுத்த முடியாது. இரண்டில் ஒரே key அமைக்கப்பட்டால், எது வெற்றி பெறும் என்பது ஆவணப்படுத்தப்பட்ட precedence order மூலம் நிர்ணயிக்கப்படுகிறது.
இந்த வழிகாட்டி ஒவ்வொன்றும் எவ்வாறு செயல்படுகிறது என்பதை காட்டுகிறது. இயக்கக்கூடிய command மூலம் precedence-ஐ உறுதிப்படுத்துகிறது. அதன் பிறகு மிகவும் முக்கியமான விஷயத்தை விளக்குகிறது: docker inspect-ஐ இயக்கக்கூடிய எவரும் environment variables-ஐ படிக்க முடியும். எனவே passwords-ஐ அவற்றில் வைக்கக்கூடாது. compose files பற்றிய அடிப்படைகளை நீங்கள் முதன்முறையாகக் கற்கிறீர்கள் என்றால், VPS-இல் Docker Compose அடிப்படைகள் என்பதை முதலில் படித்துவிட்டு, configuration-க்காக இங்கு திரும்பவும்.
.env கோப்பு compose கோப்புக்கானது; container-க்கானது அல்ல
ஒரு directory-ஐ உருவாக்கி, அதில் இரண்டு கோப்புகளை வைக்கவும்.
mkdir -p ~/envdemo && cd ~/envdemo
printf 'ALPINE_TAG=3.20\n' > .envservices:
demo:
image: alpine:${ALPINE_TAG}
command: printenv ALPINE_TAGஇப்போது Compose உண்மையில் எதை parse செய்தது என்பதைப் பார்க்கவும்.
docker compose configவெளியீடு image: alpine:3.20 என்பதைக் காட்டுகிறது. Placeholder மறைந்துவிட்டது, ஏனெனில் interpolation parse நேரத்தில் நடந்தது. Compose, compose கோப்பைக் கொண்ட project directory-யில் .env-ஐத் தேடி, அது காணும் ஒவ்வொரு ${NAME}-ஐயும் மாற்றுகிறது.
பிறகு service-ஐ இயக்கவும்.
docker compose run --rm demoprintenv ALPINE_TAG status 1 உடன் நிறுத்தப்பட்டு, எதையும் அச்சிடாது. அந்த variable container-க்குள் இல்லை. இதுவே அதிகம் ஏற்படும் தவறான புரிதல்: .env compose கோப்பை மட்டுமே configure செய்தது; process-ஐ அல்ல. POSTGRES_PASSWORD=hunter2-ஐக் கொண்ட .env கோப்பு மட்டும் இருந்தால், compose கோப்பின் ஏதேனும் பகுதி அதைக் குறிப்பிடாவிட்டால், உங்கள் database-க்கு அது எந்த விளைவையும் ஏற்படுத்தாது.
variable unset அல்லது empty ஆக இருக்கும்போது ${NAME:-default} fallback மதிப்பை வழங்குகிறது. ${NAME:?message} Compose-ஐ start ஆக மறுத்து, நீங்கள் வழங்கிய செய்தியை அச்சிடச் செய்கிறது. பாதுகாப்பான default மதிப்பு இல்லாத value-க்கு இதுவே சரியான தேர்வு.
env_file மாறிகளை container-க்குள் ஏற்றுகிறது
env_file: attribute-ல் ஒன்று அல்லது அதற்கு மேற்பட்ட files குறிப்பிடப்படுகின்றன. அவற்றின் contents container environment variables-ஆக மாறும்.
printf 'GREETING=from_env_file\nAPP_MODE=production\n' > app.envservices:
demo:
image: alpine:3.20
command: printenv GREETING
env_file:
- ./app.envdocker compose run --rm demoஇது from_env_file-ஐ அச்சிடும். File format என்பது ஒவ்வொரு வரியிலும் ஒரு plain KEY=value line ஆகும். # அந்த வரியில் comment தொடங்குவதை குறிக்கும். இது shell format அல்ல. பெரும்பாலான சந்தர்ப்பங்களில் quotes value-ன் ஒரு பகுதியாகவே வைக்கப்படும். export prefixes தேவையில்லை. = sign-ஐச் சுற்றி spaces இட வேண்டாம். இல்லையெனில் KEY = value, value-ன் தொடக்கத்தில் leading space உடன், KEY என்ற பெயருடைய variable-ஐ உருவாக்கும்.
env_file path கிடைக்கவில்லை என்றால் அது error ஆகும், மேலும் Compose நிறுத்தப்படும். அந்த file இல்லாமல் இருப்பது ஏற்றுக்கொள்ளத்தக்கதாக இருந்தால், அதை optional எனக் குறிக்கவும்:
env_file:
- path: ./app.env
required: falseenvironment sets variables inline
services:
demo:
image: alpine:3.20
command: printenv GREETING
environment:
GREETING: from_environment2 syntaxகள் ஏற்கப்படுகின்றன: மேலே காட்டிய mapping வடிவமும், - GREETING=from_environment-ஐ பயன்படுத்தும் list வடிவமும். இரண்டும் ஒரே விதமாகச் செயல்படுகின்றன. list வடிவத்தில் ஒரு கூடுதல் வசதி உள்ளது: மதிப்பு இல்லாத bare key, நீங்கள் docker compose இயக்கிய shell-இலிருந்து அந்த variable-ஐ அப்படியே pass through செய்கிறது.
environment:
- GREETINGGREETING=from_my_shell docker compose run --rm demoஇது from_my_shell-ஐ அச்சிடும். shell-இல் GREETING-ஐ set செய்யாமல் இதை இயக்கினால், Compose எதையும் set செய்யாது; எந்த warning-மும் காட்டாது. இவ்வாறு அமைதியாக ஏற்படும் pass-through தோல்விகளை அறிந்திருப்பது முக்கியம். காரணம், காலியான password variable-உடன் தொடங்கும் service பெரும்பாலும் வெற்றிகரமாகத் தொடங்கி, அணுகல் கட்டுப்பாடின்றி திறந்துவிடும்.
எது முன்னுரிமை பெறுகிறது
Docker முன்னுரிமை வரிசையை அதிக முன்னுரிமையிலிருந்து குறைந்த முன்னுரிமை வரை ஆவணப்படுத்துகிறது: கட்டளை வரியில் உள்ள docker compose run -e, அதன் பிறகு shell அல்லது env file இலிருந்து value பெறப்படும் environment அல்லது env_file, அதன் பிறகு compose file-ல் உள்ள சாதாரண environment, அதன்பிறகு env_file, இறுதியாக image-ல் உட்பொதிக்கப்பட்ட ENV directive.
தினசரி பயன்பாட்டிற்கான சுருக்கமான விதி: environment:, env_file:-ஐ விட முன்னுரிமை பெறுகிறது. கட்டளை வரியில் உள்ள -e, இவை இரண்டையும் விட முன்னுரிமை பெறுகிறது. இதை ஒரே file-ல் நிரூபிக்கலாம்.
services:
demo:
image: alpine:3.20
command: printenv GREETING
env_file:
- ./app.env
environment:
GREETING: from_environmentdocker compose run --rm demo
docker compose run --rm -e GREETING=from_cli demo printenv GREETINGமுதல் command from_environment-ஐ அச்சிடுகிறது. அதனால் environment:, app.env-ல் இருந்த value-ஐ மாற்றியுள்ளது. இரண்டாவது command from_cli-ஐ அச்சிடுகிறது. compose file-ல் உள்ள எதுவும் கட்டளை வரியில் வழங்கிய value-ஐ மாற்றாது.
உங்கள் config செயல்படுத்தப்படாதது போல container செயல்பட்டால், ஊகிக்க வேண்டாம். docker compose config முழுமையாகத் தீர்மானிக்கப்பட்ட file-ஐ அச்சிடுகிறது. docker compose config --environment, Compose பயன்படுத்தும் interpolation variables-ஐ அச்சிடுகிறது. “எனது env file புறக்கணிக்கப்படுகிறது” என்ற பெரும்பாலான reports-க்கு காரணம், ஒரே value இரண்டு வெவ்வேறு நிலைகளில் அமைக்கப்பட்டிருப்பதே ஆகும்.
சூழல் மாறிகள் கசியும் காரணம்
environment: இல் கடவுச்சொல்லை அமைத்தால், அது container-ன் disk-இல் உள்ள configuration-ல் சேமிக்கப்படும். docker குழுவில் உள்ள எந்த user-க்கும் அதை பார்க்க முடியும்.
docker compose run -d --name leaky -e DB_PASSWORD=hunter2 demo sleep 300
docker inspect leaky --format '{{json .Config.Env}}'வெளியீட்டில் "DB_PASSWORD=hunter2" plain text-ஆக உள்ளது. அதே மதிப்பை வெளிப்படுத்தும் மேலும் 3 paths உள்ளன. docker compose config அதை terminal-க்கு அச்சிடும். அதனால் அது support forum-ல் paste செய்யப்படும். container-க்குள் இயங்கும் எந்த process-மும் /proc/1/environ-ஐ படிக்க முடியும். ஒவ்வொரு child process-மும் அந்த variable-ஐ inherit செய்யும். மேலும், application crash handlers வழக்கமாக முழு environment-ஐ log அல்லது error report-ல் dump செய்யும்.
docker குழுவில் உறுப்பினராக இருப்பது host-ல் root அணுகலைப் பெறுவதற்கு இணையானது. எனவே, இதை நம்பகமான privilege boundary-ஆகக் கருத முடியாது. பகிரப்பட்ட server-ல் அந்தக் குழுவுக்கான அணுகலைக் கட்டுப்படுத்த வேண்டிய காரணத்தை VPS-ல் குறைந்த privilege கொண்ட user accounts பற்றிய வழிகாட்டி விளக்குகிறது.
Compose secrets மதிப்பை ஒரு file-ல் வைத்திருக்கும்
Compose file அடிப்படையிலான secrets-ஐ ஆதரிக்கிறது. மதிப்பு environment-க்கு நேரடியாக வழங்கப்படுவதற்குப் பதிலாக, container-க்குள் ஒரு file ஆக mount செய்யப்படுகிறது.
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txtsecret container-க்குள் /run/secrets/db_password இல் mount செய்யப்படுகிறது. slash-க்கு பிறகு வரும் பெயர், மேல் நிலை secrets: block-இலுள்ள secret பெயராகும்.
_FILE suffix என்பது postgres, mysql மற்றும் mariadb உள்ளிட்ட Docker Official Images பயன்படுத்தும் ஒரு convention ஆகும். அந்த entrypoint scripts VARNAME_FILE இருப்பதைச் சரிபார்த்து, file-ஐ வாசித்து, அதன் உள்ளடக்கத்தைப் பயன்படுத்துகின்றன. இது Docker feature அல்ல. எனவே, image இதை implement செய்த இடங்களில் மட்டுமே இது செயல்படும். SOMETHING_FILE மதிக்கப்படும் என்று கருதுவதற்கு முன், image documentation-ஐச் சரிபார்க்கவும். இதை ஆதரிக்காத applications, startup நேரத்தில் file-ஐத் தாங்களே வாசிக்கக்கூடும். அல்லது path-ஐ வழங்கி, உங்கள் சொந்த entrypoint அதைச் செயல்படுத்தலாம்.
இயங்கும் container-க்குள் இருந்து சரிபார்க்கவும்:
docker compose exec db cat /run/secrets/db_password
docker compose exec db printenv POSTGRES_PASSWORDமுதல் command password-ஐ அச்சிடும். இரண்டாவது எதையும் அச்சிடாது, ஏனெனில் அந்த மதிப்பு environment-க்குள் சென்றதில்லை. இதுவே இதன் நோக்கம்: இந்த container-இல் உள்ள docker inspect பயனற்ற path-ஐ மட்டும் காட்டுகிறது.
host-இல் உள்ள source file-ஐப் பாதுகாக்கவும். ஏனெனில் secret-ன் தனியுரிமை, அதன் பின்னால் உள்ள file-ன் தனியுரிமைக்கு மட்டுமே சமம்:
chmod 600 db_password.txtVPS-இல் நடைமுறைக்கு ஏற்ற சமநிலை
பல self hosted images _FILE variables-ஐ ஆதரிப்பதில்லை. எனவே environment variables மட்டுமே பயன்படுத்தக்கூடிய வழியாக இருக்கும். ஒரே administrator நிர்வகிக்கும் VPS-இல், உங்கள் project directory-யில் அனைவரும் படிக்கக்கூடிய file-ல் values இருப்பதைத் தடுத்து, அவற்றை git-க்கு வெளியே வைத்திருப்பதே நடைமுறை இலக்காகும்.
sudo install -o root -g root -m 600 /dev/null /etc/myapp/app.env
sudo nano /etc/myapp/app.env env_file:
- /etc/myapp/app.envinstall -m 600 file-ஐ உருவாக்கும்போதே mode-ஐ அமைக்கிறது. எனவே அது அனைவராலும் படிக்கக்கூடியதாக இருக்கும் இடைக்கால நிலை ஏற்படாது. அதற்கு root உரிமையாளர் என்பதால், அந்த server-இல் root அல்லாத user அதைப் படிக்க முடியாது. ஆனால் docker இயக்கக்கூடிய எவரும் container-இலிருந்து value-ஐப் படிக்க முடியும். *.env மற்றும் .env ஆகியவற்றை .gitignore-இல் சேர்த்து, அதற்குப் பதிலாக key names-ஐ empty values-உடன் கொண்ட app.env.example-ஐ commit செய்யுங்கள். commit செய்யப்பட்ட password மாற்றப்பட வேண்டும்.
ஒரு value-ஐ மாற்றியமைப்பது service-ஐ restart செய்வதைக் குறிக்கும். container process தொடங்கும்போது environment variables ஒருமுறை மட்டுமே வாசிக்கப்படுகின்றன. எனவே file-ஐத் திருத்திய பிறகு docker compose up -d --force-recreate db இயக்கும் வரை எந்த மாற்றமும் ஏற்படாது. இது VPS-இல் HTTPS-க்குப் பின்னால் n8n வழிகாட்டியிலும் பயன்படுத்தப்படும் அதே முறையாகும். அங்கு encryption key compose file-க்கு வெளியே வைக்கப்படுகிறது.
ஒவ்வொரு environment-க்கும் தனித்தனியாக configuration பிரித்தல்
Compose இயல்பாக project directory-யிலிருந்து .env-ஐப் படிக்கும். அதை வேறு இடத்தைக் குறிக்க --env-file-ஐப் பயன்படுத்தவும்.
docker compose --env-file .env.staging configபல files வரிசைப்படி படிக்கப்படுகின்றன. பின்னர் வரும் files, முன்னர் வந்த files-ஐ override செய்கின்றன. secret அல்லாத defaults-ஐ commit செய்யப்பட்ட file-ல் வைத்திருக்கவும். secrets-ஐ server-ஐ விட்டு ஒருபோதும் வெளியேறாத file-ல் வைத்திருக்கவும். env_file:-க்கும் இதே விதி பொருந்தும். ஒரே key பலமுறை இருந்தால், பட்டியலில் கடைசியாக உள்ள file-ன் மதிப்பு பயன்படுத்தப்படும்.
FAQ
எனது .env கோப்பு container-க்குள் ஏன் புறக்கணிக்கப்படுகிறது?
அது புறக்கணிக்கப்படவில்லை. .env கோப்பு compose file-இல் உள்ள ${NAME} placeholders-ஐ மட்டுமே மாற்றுகிறது. அது container-க்குள் variables-ஐ ஒருபோதும் அமைக்காது. மதிப்பை container-க்குள் கொண்டு வர, environment: { KEY: "${NAME}" }-ஐ குறிப்பிடவும் அல்லது அதற்குப் பதிலாக env_file: ./that-file.env-ஐப் பயன்படுத்தவும்.
environment, env_file-ஐ override செய்கிறதா, அல்லது மாறாக நடக்கிறதா?
environment: முன்னுரிமை பெறுகிறது. Docker-ன் ஆவணப்படுத்தப்பட்ட வரிசையில் environment attribute, env_file attribute-ஐ விட மேலாக உள்ளது. இரண்டும் command line-இல் உள்ள docker compose run -e-க்கு கீழே உள்ளன. ஒரே key இரு இடங்களிலும் அமைக்கப்பட்டால், env_file-இல் உள்ள மதிப்பு அமைதியாகப் பயன்படுத்தப்படாது.
Compose பயன்படுத்தும் இறுதி மதிப்பை எவ்வாறு பார்க்கலாம்?
முழுமையாகத் தீர்க்கப்பட்ட compose file-ஐ, அனைத்து interpolation-உம் பயன்படுத்தப்பட்ட நிலையில் அச்சிட docker compose config-ஐ இயக்கவும். ஏற்கனவே இயங்கும் container-க்கு, அதன் process பெற்ற துல்லியமான மதிப்புகளை docker inspect <container> --format '{{json .Config.Env}}' காட்டும்.
Compose secrets குறியாக்கம் செய்யப்படுமா?
இல்லை. file based secret, /run/secrets/<name>-இல் plain file ஆக container-க்குள் mount செய்யப்படுகிறது. source file host disk-இல் குறியாக்கமின்றி உள்ளது. இதன் பயன் encryption அல்ல, scope ஆகும்: அந்த மதிப்பு container environment-க்கு வெளியிலும், docker inspect output-க்கு வெளியிலும், environment-ஐ அச்சிடும் crash dumps-க்கு வெளியிலும் இருக்கும்.
env file-ல் quotes மற்றும் spaces-ஐப் பயன்படுத்தலாமா?
KEY=value with spaces-ஐப் பயன்படுத்தி quotes-ஐ விடுங்கள். Compose, அந்த வரியின் மீதமுள்ள முழுப் பகுதியையும் மதிப்பாகக் கருதும். எனவே quotes பொதுவாக மதிப்பில் literal characters ஆகச் சேர்ந்து விடும். =-ஐச் சுற்றி spaces-ஐ ஒருபோதும் இடாதீர்கள். அப்படிச் செய்தால் key-யில் trailing space சேரும், மேலும் எதுவும் அதனுடன் பொருந்தாது.