SSD Nodes Learn Hosting plans →
கல்வி வழிகாட்டிகள் Matt Connorஆல் Matt Connor · புதுப்பிக்கப்பட்டது 2026-10-24

Docker Compose-ல் .env, env_file, environment வேறுபாடு

Docker Compose-ல் .env, env_file, environment ஆகிய மூன்றும் எவ்வாறு வேறுபடுகின்றன, ஒரே key வந்தால் எது முன்னுரிமை பெறும், secrets எங்கு வைக்க வேண்டும் என்பதைக் கற்கவும்.

env கோப்பு என்று மக்கள் அழைக்கும் மூன்று விஷயங்கள்

Docker Compose-ல் குழப்பத்தை ஏற்படுத்தும் வகையில் ஒரே மாதிரியான பெயர்களைக் கொண்ட மூன்று தனித்தனி வழிமுறைகள் உள்ளன. .env கோப்பு, Compose YAML-ஐ வாசித்து, எதையும் சரிபார்ப்பதற்கு அல்லது இயக்குவதற்கு முன்பாக, compose.yaml-க்குள் இருக்கும் ${VARIABLE} இடங்களை நிரப்புகிறது. env_file: பண்புக்கூறு (attribute), key/value ஜோடிகளைக் கொண்ட ஒரு கோப்பை container-ன் environment-க்குள் ஏற்றுகிறது. environment: பண்புக்கூறு, compose கோப்பிலேயே நேரடியாக எழுதப்பட்டு, container-க்கான மாறிகளை (variables) அமைக்கிறது. இவை ஒன்றிற்குப் பதிலாக மற்றொன்றைப் பயன்படுத்தக்கூடியவை அல்ல. ஒரே key-க்கு இவை இரண்டில் மதிப்புகள் அமைக்கப்பட்டால், ஆவணப்படுத்தப்பட்ட முன்னுரிமை வரிசையின்படி (precedence order) எது வெற்றி பெறும் என்பது தீர்மானிக்கப்படுகிறது.

இந்த வழிகாட்டி ஒவ்வொன்றும் எவ்வாறு செயல்படுகிறது என்பதைக் காட்டுகிறது, நீங்கள் இயக்கக்கூடிய ஒரு கட்டளையின் மூலம் முன்னுரிமையை நிரூபிக்கிறது, பின்னர் மிக முக்கியமான பகுதியை விளக்குகிறது: docker inspect-ஐ இயக்கக்கூடிய எவராலும் environment variables-ஐ வாசிக்க முடியும், எனவே கடவுச்சொற்களை (passwords) அவற்றில் வைக்கக்கூடாது. நீங்கள் compose கோப்புகளுக்குப் புதியவர் என்றால், VPS-ல் Docker Compose அடிப்படைகள் என்பதிலிருந்து தொடங்கி, பின்னர் உள்ளமைவு (configuration) குறித்து அறிய இங்கே திரும்பவும்.

.env கோப்பு compose கோப்பிற்கானது, container-க்கானது அல்ல

ஒரு கோப்பகத்தை (directory) உருவாக்கி அதில் இரண்டு கோப்புகளை இடவும்.

mkdir -p ~/envdemo && cd ~/envdemo
printf 'ALPINE_TAG=3.20\n' > .env
services:
  demo:
    image: alpine:${ALPINE_TAG}
    command: printenv ALPINE_TAG

இப்போது Compose எதை உண்மையில் பகுப்பாய்வு (parsed) செய்தது என்று கேட்கவும்.

docker compose config

வெளியீடு image: alpine:3.20-ஐக் காட்டுகிறது. Compose கோப்பை ஏற்றும்போது interpolation நடந்ததால், placeholder நீங்கிவிட்டது. Compose, .env-ஐ project கோப்பகத்தில் தேடுகிறது: நீங்கள் --project-directory-ஐ அமைத்திருந்தால் அந்த கோப்பகம், இல்லையெனில் -f உடன் வழங்கப்பட்ட முதல் கோப்பின் கோப்பகம், அதுவும் இல்லையெனில் உங்கள் தற்போதைய கோப்பகம். இது YAML மதிப்புகளில் கண்டறியும் ${NAME} placeholders-ஐ மாற்றீடு செய்கிறது. Keys ஒருபோதும் interpolate செய்யப்படுவதில்லை, மேலும் இரட்டிப்பான $$ என்பது மாற்றீட்டிற்குப் பதிலாக ஒரு literal டாலர் குறியீட்டை உருவாக்குகிறது.

பிறகு service-ஐ இயக்கவும்.

docker compose run --rm demo

printenv ALPINE_TAG நிலை 1-உடன் வெளியேறுகிறது மற்றும் எதையும் அச்சிடுவதில்லை. அந்த variable container-க்குள் இல்லை. இதுவே மிகவும் பொதுவான தவறான புரிதல்: .env என்பது compose கோப்பை கட்டமைக்கிறது, process-ஐ அல்ல. POSTGRES_PASSWORD=hunter2 உள்ள ஒரு .env கோப்பு, compose கோப்பின் ஏதேனும் ஒரு பகுதி அதைக் குறிப்பிட்டால் ஒழிய, உங்கள் database-க்கு எதையும் செய்யாது.

${NAME:-default} என்பது variable அமைக்கப்படாதபோது அல்லது காலியாக இருக்கும்போது ஒரு fallback-ஐ வழங்குகிறது. ${NAME:?message} என்பது Compose தொடங்குவதைத் தடுத்து உங்கள் செய்தியை அச்சிடச் செய்கிறது; பாதுகாப்பான default மதிப்பு இல்லாத சூழலுக்கு இதுவே சரியான தேர்வாகும்.

env_file என்பது container-க்குள் மாறிகளை (variables) ஏற்றுகிறது

env_file: பண்புக்கூறு, அதன் உள்ளடக்கங்கள் container-ன் சூழல் மாறிகளாக (environment variables) மாறும் ஒன்று அல்லது அதற்கு மேற்பட்ட கோப்புகளைக் குறிப்பிடுகிறது.

printf 'GREETING=from_env_file\nAPP_MODE=production\n' > app.env
services:
  demo:
    image: alpine:3.20
    command: printenv GREETING
    env_file:
      - ./app.env
docker compose run --rm demo

இது from_env_file-ஐ அச்சிடுகிறது. கோப்பின் வடிவம் எளிய KEY=value வரிகளாகும், ஒரு வரிக்கு ஒன்று வீதம், # என்பது கருத்தைச் (comment) சேர்க்கத் தொடங்கும். இது shell அல்ல, இருப்பினும் Compose இதைச் சில shell போன்ற விதிகளுடன் பகுப்பாய்வு செய்கிறது. சுற்றியுள்ள மேற்கோள் குறிகள் (quotes) நீக்கப்படும், எனவே KEY="value" மற்றும் KEY=value ஆகிய இரண்டும் ஒரே முடிவைத் தரும். இரட்டை மேற்கோள் மற்றும் மேற்கோள் இல்லாத மதிப்புகளில் ${...} மாறிகள் மாற்றீடு செய்யப்படும், அதேசமயம் ஒற்றை மேற்கோள் மதிப்புகள் அப்படியே பயன்படுத்தப்படும். export முன்னொட்டு ஏற்றுக்கொள்ளப்படும், ஆனால் அது அவசியமில்லை. = குறியீட்டைச் சுற்றியுள்ள இடைவெளிகள் நீக்கப்படும். கவனிக்க வேண்டிய முக்கிய விஷயம் என்னவென்றால், வரியின் உள்ளே இருக்கும் கருத்துகள்: மேற்கோள் காட்டப்படாத மதிப்பில், ஒரு இடைவெளிக்குப் பிறகு # வந்தால் அது கருத்தைத் தொடங்குகிறது, எனவே #-ஐக் கொண்ட எந்த மதிப்பையும் மேற்கோள் குறிகளுக்குள் இடவும்.

env_file பாதை விடுபட்டிருந்தால் அது பிழையாகக் கருதப்பட்டு, Compose இயக்கம் நிறுத்தப்படும். கோப்பு இல்லாமல் இருப்பது இயல்பானது என்றால், அதை விருப்பத்தேர்வாக (optional) மாற்றவும்:

    env_file:
      - path: ./app.env
        required: false

environment மாறிகளை inline-ஆக அமைத்தல்

services:
  demo:
    image: alpine:3.20
    command: printenv GREETING
    environment:
      GREETING: from_environment

இரண்டு வகையான syntaxes ஏற்றுக்கொள்ளப்படுகின்றன: மேலே உள்ள mapping வடிவம் மற்றும் - GREETING=from_environment-ஐப் பயன்படுத்தும் list வடிவம். இவை இரண்டும் ஒரே மாதிரியாகவே செயல்படுகின்றன. இவை இரண்டிற்கும் ஒரு கூடுதல் வசதி உண்டு: மதிப்பு இல்லாத ஒரு key, நீங்கள் docker compose-ஐ இயக்கும் shell-லிருந்து அந்த மாறியை அப்படியே பெற்றுக்கொள்ளும். List வடிவத்தில் இது ஒரு வெற்று - GREETING ஆகும், mapping வடிவத்தில் இது colon-க்கு பின் எதுவுமில்லாத GREETING: ஆகும்.

    environment:
      - GREETING
GREETING=from_my_shell docker compose run --rm demo

இது from_my_shell-ஐ அச்சிடும். Shell-ல் GREETING-ஐ அமைக்காமல் இதை இயக்கினால், Compose எதையும் அமைக்காது, எந்த எச்சரிக்கையும் தராது. இத்தகைய அமைதியான pass-through தோல்விகளைப் பற்றித் தெரிந்துகொள்வது அவசியம்; ஏனெனில், காலியான password மாறியுடன் தொடங்கும் ஒரு service பெரும்பாலும் வெற்றிகரமாகத் தொடங்கிவிடும், ஆனால் பாதுகாப்பற்ற நிலையில் (wide open) இருக்கும்.

எது முன்னுரிமை பெறும்

Docker precedence வரிசையை அதிக முன்னுரிமையிலிருந்து குறைந்த முன்னுரிமை வரை ஆவணப்படுத்துகிறது: command line-ல் வழங்கப்படும் docker compose run -e, அதன் பிறகு shell அல்லது env file-லிருந்து value interpolation செய்யப்படும் environment அல்லது env_file, அதன் பிறகு compose file-ல் உள்ள சாதாரண environment, அடுத்து env_file, இறுதியாக image-க்குள் முன்கூட்டியே சேர்க்கப்பட்ட ENV directive.

தினசரி பயன்பாட்டிற்கான சுருக்கமான விதி: environment:, env_file:-ஐ விட முன்னுரிமை பெறும். command line-ல் வழங்கப்படும் -e, இரண்டையும் விட முன்னுரிமை பெறும். இதை ஒரே file-ல் நிரூபிக்கலாம்.

services:
  demo:
    image: alpine:3.20
    command: printenv GREETING
    env_file:
      - ./app.env
    environment:
      GREETING: from_environment
docker compose run --rm demo
docker compose run --rm -e GREETING=from_cli demo printenv GREETING

முதல் command from_environment-ஐ வெளியிடுகிறது. அதாவது environment:, app.env-ல் உள்ள value-ஐ override செய்துள்ளது. இரண்டாவது command from_cli-ஐ வெளியிடுகிறது. compose file-ல் உள்ள எந்த அமைப்பும் command line value-ஐ override செய்யாது.

உங்கள் config பயன்படுத்தப்படாதது போல் container செயல்பட்டால், ஊகிக்க வேண்டாம். docker compose config முழுமையாகத் தீர்மானிக்கப்பட்ட file-ஐ வெளியிடும். docker compose config --environment, Compose பயன்படுத்தும் interpolation variables-ஐ வெளியிடும். “எனது env file புறக்கணிக்கப்படுகிறது” என்ற பெரும்பாலான பிரச்சினைகளில், ஒரே value இரண்டு வெவ்வேறு நிலைகளில் அமைக்கப்பட்டிருக்கும்.

Environment variables ஏன் கசிகின்றன

environment:-ல் ஒரு கடவுச்சொல்லை அமைக்கும்போது, அது container-ன் configuration கோப்பில் சேமிக்கப்படுகிறது. docker குழுவில் உள்ள எந்தவொரு பயனரும் இதைப் பார்க்க முடியும்.

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 வடிவில் காட்டுகிறது. மேலும் மூன்று பாதைகள் இதே மதிப்பை வெளிப்படுத்துகின்றன. docker compose config கட்டளையானது அதை terminal-ல் அச்சிடுகிறது; இதன் மூலமே அது தவறுதலாக support forum-களில் பகிரப்படுகிறது. ஒரு process-ன் parent, மாற்று environment-ஐ வேண்டுமென்றே உருவாக்காத வரை, child processes அந்த variable-ஐ இயல்பாகவே பெற்றுக்கொள்கின்றன. PID 1-ன் அதே பயனர் உரிமையுடன் இயங்கும் ஒரு process அல்லது CAP_SYS_PTRACE உரிமையைக் கொண்ட ஒரு process, /proc/1/environ கோப்பிலிருந்து அந்த மதிப்பை வாசிக்க முடியும். root பயனராக அனைத்தும் இயங்கும் ஒரு container-ல், ஒவ்வொரு process-ம் இதைச் செய்ய முடியும். ஒரு application unprivileged பயனராக இயங்கி, PID 1 root-ஆக இயங்கினால், அந்த கோப்பை அணுகும்போது permission error ஏற்படும்; இருப்பினும் அந்த application-ன் சொந்த environment-ல் அந்த variable இருக்கும். மேலும், application crash handlers வழக்கமாக முழு environment-ஐயும் ஒரு log கோப்பிலோ அல்லது error report-லோ பதிவேற்றிவிடும்.

docker குழுவில் உறுப்பினராக இருப்பது என்பது host-ல் root உரிமையைப் பெறுவதற்குச் சமம். எனவே, இதை ஒரு பாதுகாப்பு எல்லையாகக் கருத முடியாது. VPS-ல் குறைந்தபட்ச உரிமை கொண்ட பயனர் கணக்குகள் குறித்த வழிகாட்டி, பகிரப்பட்ட கணினிகளில் ஏன் இந்தக் குழுவை கட்டுப்படுத்த வேண்டும் என்பதை விளக்குகிறது.

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.txt

Secret, container-க்குள் /run/secrets/db_password என்ற path-ல் mount செய்யப்படுகிறது. Slash-க்கு அடுத்துள்ள பெயர், மேல் நிலை secrets: block-ல் உள்ள secret name ஆகும்.

_FILE suffix என்பது postgres, mysql மற்றும் mariadb உள்ளிட்ட Docker Official Images பயன்படுத்தும் ஒரு convention ஆகும். அவற்றின் entrypoint scripts, VARNAME_FILE இருப்பதைச் சரிபார்த்து, file-ஐப் படித்து, அதன் உள்ளடக்கத்தைப் பயன்படுத்தும். இது Docker feature அல்ல. எனவே, image இதைச் செயல்படுத்தும் இடங்களில் மட்டுமே இது வேலை செய்யும். SOMETHING_FILE மதிக்கப்படும் என்று கருதுவதற்கு முன், image documentation-ஐச் சரிபார்க்கவும். இதை ஆதரிக்காத applications, startup நேரத்தில் file-ஐத் தாங்களே படிக்கலாம். அல்லது path-ஐ pass செய்து, உங்கள் சொந்த entrypoint மூலம் அதைச் செயல்படுத்தலாம்.

இயங்கும் container-க்குள் இருந்து சரிபார்க்கவும்:

docker compose exec db cat /run/secrets/db_password
docker compose exec db printenv POSTGRES_PASSWORD

முதல் command password-ஐ print செய்யும். இரண்டாவது command எதையும் print செய்யாது, ஏனெனில் அந்த மதிப்பு environment-க்குள் சென்றதே இல்லை. இதுவே இதன் நோக்கம்: இந்த container-ல் docker inspect பாதுகாப்பான path-ஐ மட்டும் காட்டும்.

Host-ல் உள்ள source file-ஐ பாதுகாக்கவும். ஏனெனில் secret-ன் privacy, அதற்குப் பின்னால் உள்ள file-ன் பாதுகாப்பைப் பொறுத்ததே:

chmod 600 db_password.txt

VPS-ல் நடைமுறைக்கு ஏற்ற நடுநிலை அணுகுமுறை

பல 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.env

install -m 600 ஏற்கனவே சரியான mode அமைக்கப்பட்ட நிலையில் file-ஐ உருவாக்குகிறது. எனவே, அது அனைவராலும் படிக்கக்கூடியதாக இருக்கும் இடைவெளி ஏற்படாது. அந்த file-க்கு root உரிமையாளராக இருக்கும். ஆகவே, அந்த machine-ல் உள்ள non-root user அதை படிக்க முடியாது. ஆனால் docker இயக்கக்கூடிய எவரும் container-லிருந்து அந்த value-ஐ இன்னும் படிக்க முடியும். *.env மற்றும் .env ஆகியவற்றை .gitignore-ல் சேர்க்கவும். அதற்குப் பதிலாக, key names மற்றும் காலியான values கொண்ட app.env.example-ஐ commit செய்யவும். Commit செய்யப்பட்ட password ஏற்கனவே மாற்றப்பட வேண்டிய password ஆகும்.

ஒரு value-ஐ rotate செய்வது service-ஐ restart செய்வதாகும். Container process தொடங்கும்போது environment variables ஒருமுறை மட்டுமே படிக்கப்படுகின்றன. எனவே, file-ஐத் திருத்துவது மட்டும் எந்த மாற்றத்தையும் ஏற்படுத்தாது. docker compose up -d --force-recreate db இயக்கிய பிறகே மாற்றம் அமலாகும். இதே pattern VPS-ல் HTTPS பின்னால் n8n அமைத்தல் guide-லும் பயன்படுத்தப்படுகிறது. அங்கு encryption key compose file-க்கு வெளியே வைக்கப்படுகிறது.

ஒவ்வொரு environment-க்கும் configuration-ஐ பிரித்தல்

Compose, project directory-லிருந்து இயல்பாக .env-ஐ படிக்கும். --env-file மூலம் அதை வேறு இடத்தைக் குறிப்பிடுமாறு அமைக்கலாம்.

docker compose --env-file .env.staging config

பல files வரிசைப்படி படிக்கப்படும். பின்னர் வரும் files, முன்னர் வந்த files-ன் மதிப்புகளை override செய்யும். Secret அல்லாத default values-ஐ commit செய்யப்பட்ட file-ல் வைத்திருக்கவும். Secrets உள்ள file server-ஐ விட்டு வெளியே செல்லாதபடி பாதுகாக்கவும். இதே விதி env_file:-க்கும் பொருந்தும். ஒரே key பலமுறை இருந்தால், பட்டியலில் கடைசியாக உள்ள file-ன் மதிப்பே பயன்படுத்தப்படும்.

FAQ

container-க்குள் எனது .env file ஏன் புறக்கணிக்கப்படுகிறது?

அது புறக்கணிக்கப்படுவதில்லை. .env file, compose file-ல் உள்ள ${NAME} placeholders-ஐ மாற்றீடு செய்கிறது, மேலும் இது COMPOSE_PROJECT_NAME அல்லது COMPOSE_FILE போன்ற Compose-ன் சொந்த மாறிகளையும் (variables) அமைக்க உதவும். இது container-க்குள் மாறிகளை ஒருபோதும் அமைப்பதில்லை. ஒரு மதிப்பை container-க்குள் கொண்டுவர, அதை இவ்வாறு குறிப்பிடவும்: environment: { KEY: "${NAME}" }, அல்லது அதற்கு பதிலாக env_file: ./that-file.env-ஐப் பயன்படுத்தவும்.

environment, env_file-ஐ விட முன்னுரிமை பெறுமா அல்லது அதற்கு மாறாகவா?

environment: வெற்றி பெறும். Docker-ன் ஆவணப்படுத்தப்பட்ட வரிசைப்படி, environment பண்புக்கூறு (attribute), env_file பண்புக்கூறுக்கு மேலாக உள்ளது, மேலும் இவை இரண்டும் command line-ல் உள்ள docker compose run -e-க்கு கீழே உள்ளன. ஒரு key இரண்டு இடங்களிலும் அமைக்கப்பட்டிருந்தால், env_file-ல் உள்ள மதிப்பு எவ்வித அறிவிப்பும் இன்றி பயன்படுத்தப்படாமல் போகும்.

Compose பயன்படுத்தும் இறுதி மதிப்பை நான் எவ்வாறு பார்ப்பது?

அனைத்து interpolation-களும் செய்யப்பட்ட முழுமையான compose file-ஐ அச்சிட docker compose config-ஐ இயக்கவும். ஏற்கனவே இயங்கிக்கொண்டிருக்கும் ஒரு container-க்கு, அதன் process எதைப் பெற்றது என்பதைத் துல்லியமாக அறிய docker inspect <container> --format '{{json .Config.Env}}'-ஐப் பயன்படுத்தவும்.

Compose secrets குறியாக்கம் (encrypted) செய்யப்படுமா?

இல்லை. File அடிப்படையிலான secret, /run/secrets/<name> என்ற இடத்தில் ஒரு plain file-ஆக container-க்குள் mount செய்யப்படுகிறது, மேலும் source file host disk-ல் குறியாக்கம் செய்யப்படாமல் இருக்கும். இதன் பயன் குறியாக்கம் அல்ல, மாறாக அதன் வரம்பு (scope) ஆகும்: இந்த மதிப்பு container environment-க்கு வெளியிலும், docker inspect வெளியீட்டிற்கு வெளியிலும், environment-ஐ அச்சிடும் crash dumps-க்கு வெளியிலும் இருக்கும்.

env file-ல் quotes மற்றும் spaces-ஐ நான் பயன்படுத்தலாமா?

ஆம். Compose சுற்றியுள்ள quotes-ஐ நீக்கிவிடும், எனவே KEY="value with spaces" மற்றும் KEY=value with spaces ஆகிய இரண்டுமே value with spaces என்ற முடிவையே தரும். மதிப்பில் interpolation செய்யக்கூடாத $ இருக்கும்போது single quotes-ஐப் பயன்படுத்தவும், மேலும் #-ஐக் கொண்ட எந்தவொரு மதிப்பையும் quote செய்யவும், ஏனெனில் quote செய்யப்படாவிட்டால் அது ஒரு comment-ஆகத் தொடங்கும். =-ஐச் சுற்றியுள்ள spaces நீக்கப்படும், எனவே KEY = value என்பது KEY-ஐயே அமைக்கும்.

இந்தக் கட்டுரை பயனுள்ளதாக இருந்ததா?