Docker Compose-ல் command மற்றும் entrypoint பயன்பாடு
Docker Compose-ல் ENTRYPOINT மற்றும் command எவ்வாறு செயல்படுகின்றன என்பதை அறியுங்கள். ENTRYPOINT அமைக்கும்போது ஏன் CMD நீக்கப்படுகிறது மற்றும் நான்கு முக்கிய மாற்றங்களை விளக்குகிறோம்.
Docker Compose command மற்றும் entrypoint: ஒரே விதி
Docker Compose-ல், entrypoint: என்பது இயங்கும் நிரலை அமைக்கிறது, command: என்பது அந்த நிரலுக்கு அனுப்பப்படும் வாதங்களை (arguments) அமைக்கிறது. Container-ன் process என்பது entrypoint பட்டியலுடன் command பட்டியலை இறுதியில் இணைத்து உருவாக்கப்படும் ஒன்றாகும். இந்தப் பக்கத்தில் உள்ள மற்ற அனைத்து செயல்பாடுகளும் இந்த ஒரே விதியிலிருந்தே பெறப்படுகின்றன.
இந்த இரண்டு keys-களும் இரண்டு Dockerfile அறிவுறுத்தல்களுக்கு இணையாகச் செயல்படுகின்றன. entrypoint: என்பது image-ன் ENTRYPOINT-ஐ மாற்றியமைக்கிறது. command: என்பது image-ன் CMD-ஐ மாற்றியமைக்கிறது. இவை ஒன்றையொன்று சார்ந்துள்ளன, இதில்தான் பயனர்கள் பெரும்பாலும் தடுமாறுகின்றனர்: entrypoint:-ஐ அமைப்பது, image-ன் CMD-ஐ நீக்கிவிடும். Compose விவரக்குறிப்பு இதை நேரடியாகக் குறிப்பிடுகிறது. entrypoint என்பது null அல்லாததாக இருந்தால், image-ல் உள்ள எந்தவொரு default command-ஐயும் Compose புறக்கணித்துவிடும்.
படத்தின் தற்போதைய அமைப்புகளைச் சரிபார்த்தல்
எந்தவொரு மாற்றத்தையும் (override) செய்வதற்கு முன்பு, அந்த image எதைக் கொண்டுள்ளது என்பதைப் பார்க்கவும்.
docker image inspect --format '{{json .Config.Entrypoint}}' postgres:16
docker image inspect --format '{{json .Config.Cmd}}' postgres:16உங்களுக்கு ["docker-entrypoint.sh"] மற்றும் ["postgres"] கிடைக்கின்றன, எனவே container docker-entrypoint.sh postgres-ஐ இயக்குகிறது. அந்த script முதல்முறை boot ஆகும்போது data directory-ஐ உருவாக்குகிறது, POSTGRES_* மாறிகளை (variables) வாசிக்கிறது, postgres பயனருக்கு உரிமைகளைக் குறைக்கிறது (drops privileges), இறுதியாக அதற்கு வழங்கப்பட்ட வாதங்களை (arguments) exec செய்கிறது. நீங்கள் எதை மாற்ற விரும்புகிறீர்கள் என்பதை அறிவதே முழு முடிவாகும். database-க்கு ஒரு flag-ஐ அனுப்ப, நீங்கள் command:-ஐ மாற்ற வேண்டும். நீங்கள் entrypoint:-ஐ மாற்றினால், அந்த setup செயல்முறை எதுவுமே இயங்காது.
நான்கு சேர்க்கைகள், ஒரு சிறிய படத்தில் காட்டப்பட்டுள்ளன
தொடங்கப்படும்போது அதற்கு வழங்கப்பட்ட argument பட்டியலை அச்சிடுவதை மட்டுமே பணியாகக் கொண்ட ஒரு image-ஐ உருவாக்கவும்.
FROM alpine:3.20
ENTRYPOINT ["/bin/echo", "ep"]
CMD ["cmd"]docker build -t argdemo .services:
demo:
image: argdemoஒவ்வொரு மாற்றத்திற்குப் பிறகும் docker compose up-ஐ இயக்கவும், அது பதிவு செய்யும் ஒற்றை வரியைப் படிக்கவும்.
- எந்த key-யும் அமைக்கப்படவில்லை. process
/bin/echo ep cmdஆக உள்ளது மற்றும் logep cmdஎன்பதைக் காட்டுகிறது. command: ["cmd2"]மட்டும். process/bin/echo ep cmd2ஆக உள்ளது. entrypoint மாற்றப்படாமல் உள்ளது, arguments மட்டுமே மாறியுள்ளன.entrypoint: ["/bin/echo", "ep2"]மட்டும். process/bin/echo ep2ஆக உள்ளது மற்றும் logep2என்பதைக் காட்டுகிறது. image-ல் இருந்தcmdநீக்கப்பட்டுவிட்டது, இது குறித்து எந்த எச்சரிக்கையும் இல்லை.- இரண்டு key-களும் அமைக்கப்பட்டுள்ளன. process
/bin/echo ep2 cmd2ஆக உள்ளது. முழு argument பட்டியலையும் நீங்கள் கட்டுப்படுத்தும் ஒரே சூழல் இதுதான்.
Entrypoint அமைக்கும்போது ஏன் image-ன் CMD நீக்கப்படுகிறது
ஒரு image-ன் CMD என்பது அந்த image-ன் ENTRYPOINT-க்கான இயல்புநிலை (default) வாதப் பட்டியலாக (argument list) எழுதப்படுகிறது. நீங்கள் entrypoint-ஐ மாற்றினால், அந்த வாதங்கள் தற்போது இயங்காத ஒரு நிரலுக்குச் சொந்தமானதாகிவிடும். எனவே, image-ஐ உருவாக்கியவர் திட்டமிடாத ஒரு command line-ஐ உருவாக்குவதற்குப் பதிலாக, Compose அந்த வாதங்களை நீக்கிவிடுகிறது. docker run --entrypoint-ம் இதேபோலவே செயல்படுகிறது, எனவே இது Docker-ன் செயல்பாடே தவிர, Compose-ன் குறைபாடு அல்ல.
இதன் விளைவு தெளிவாக உள்ளது. nginx:1.27 என்பது ENTRYPOINT ["/docker-entrypoint.sh"] மற்றும் CMD ["nginx", "-g", "daemon off;"] ஆகியவற்றை அறிவிக்கிறது. நீங்கள் entrypoint: /custom-init.sh-ஐ அமைத்தால், உங்கள் script காலியான வாதப் பட்டியலுடன் தொடங்கும். வழக்கமான exec "$@"-ல் முடியும் ஒரு script-க்கு exec செய்ய எதுவும் இருக்காது. எனவே exec எதையும் செய்யாது, script அதன் கடைசி வரியை அடையும், மேலும் container எந்த பிழைச் செய்தியும் இன்றி 0 என்ற code-உடன் வெளியேறும். வாதங்களை நீங்களே மீண்டும் சேர்க்கவும்:
services:
web:
image: nginx:1.27
entrypoint: /custom-init.sh
command: ["nginx", "-g", "daemon off;"]நீங்கள் நினைவில் கொள்ள வேண்டிய விதி: எப்போது நீங்கள் entrypoint:-ஐ அமைக்கிறீர்களோ, அதே மாற்றத்தின்போது command: என்னவாக இருக்க வேண்டும் என்பதையும் முடிவு செய்யுங்கள்.
Exec form மற்றும் shell form, மேலும் Compose எவ்வாறு வேறுபடுகிறது
Dockerfile இரண்டு வகையான syntax-களை ஏற்கிறது. CMD ["nginx", "-g", "daemon off;"] என்பது exec form: இதில் shell இன்றி binary நேரடியாக இயங்கும். CMD nginx -g "daemon off;" என்பது shell form: இதை Docker /bin/sh -c 'nginx -g "daemon off;"' என மாற்றியமைக்கும், எனவே முதலில் ஒரு shell இயங்கி, உங்கள் நிரல் அதன் child process-ஆக மாறும்.
Compose இந்த விதியைப் பின்பற்றுவதில்லை, இது பலரை ஆச்சரியப்படுத்துகிறது. command:-ல் உள்ள ஒரு string, வாதங்களாகப் (arguments) பிரிக்கப்பட்டு நேரடியாக இயக்கப்படும், எந்த ஒரு /bin/sh -c wrapper-ம் இருக்காது. Compose reference இதைத் தெளிவாகக் குறிப்பிடுகிறது: command புலம், image-ல் வரையறுக்கப்பட்ட SHELL சூழலுக்குள் இயங்காது. எனவே, உங்களுக்கு shell வசதிகள் தேவைப்பட்டால், நீங்களே ஒரு shell-ஐ அழைக்க வேண்டும்.
இதனால்தான் command: echo "hello $$HOSTNAME", hello $HOSTNAME என்ற உரையை அப்படியே அச்சிடுகிறது. எந்த shell-ம் அந்த string-ஐப் பார்க்காததால், எதுவும் விரிவுபடுத்தப்படவில்லை (expanded). உங்களுக்கு shell தேவைப்படும்போது, அதை வெளிப்படையாகக் கேட்கவும்:
services:
demo:
image: alpine:3.20
command: /bin/sh -c 'echo "hello $$HOSTNAME"'Signals, PID 1, மற்றும் ஒரு முறையான docker compose down
docker compose stop மற்றும் docker compose down ஆகியவை ஒவ்வொரு container-க்குள்ளும் உள்ள PID 1-க்கு SIGTERM-ஐ அனுப்பி, stop_grace_period-க்காகக் காத்திருந்து, பின் SIGKILL-ஐ அனுப்புகின்றன. இயல்பான grace period 10 வினாடிகள் ஆகும்.
Linux-ல் PID 1 என்பது சிறப்பு வாய்ந்தது. PID 1-க்கு வரும் signal-களுக்கு kernel இயல்பான நடவடிக்கைகளை எடுப்பதில்லை. எனவே, எந்தவொரு SIGTERM handler-ஐயும் கொண்டிராத ஒரு process, PID 1-ஆக இயங்கும்போது SIGTERM-ஐப் புறக்கணித்துவிடும். அது முழு grace period முடியும் வரை காத்திருந்து, பின் உடனடியாகக் கொல்லப்படும். இதனால் திறந்திருக்கும் இணைப்புகள் அல்லது முடிக்கப்படாத பரிவர்த்தனைகள் (uncommitted transactions) துண்டிக்கப்படும்.
உங்கள் program-க்கு முன்னால் ஒரு shell இருந்தால், இந்தச் சிக்கல் ஏற்பட அதிக வாய்ப்புள்ளது. ஏனெனில் shell தான் PID 1-ஆக இருக்கும், பெரும்பாலான shell-கள் தங்களுக்கு வரும் signal-களைத் தங்கள் child process-க்கு அனுப்புவதில்லை. சில shell-கள் -c string-ல் உள்ள இறுதி command-ஆகத் தங்களை மாற்றிக்கொள்ளும், எனவே சில நேரங்களில் உங்கள் program PID 1-ஐ அடையலாம். இது shell மற்றும் அந்த string-ஐப் பொறுத்தது, எனவே யூகிக்க வேண்டாம். அதைச் சரிபார்க்கவும்:
docker compose exec -T web cat /proc/1/cmdline | tr '\0' ' '; echoPID 1-ல் உங்கள் program-க்கு பதிலாக /bin/sh -c ... காட்டப்பட்டால், அதைச் சரிசெய்ய இரண்டு வழிகள் உள்ளன. Image-ல் exec form-ஐப் பயன்படுத்தவும் அல்லது shell-ஐ வைத்துக்கொண்டு exec மூலம் process-ஐ ஒப்படைக்கவும்:
services:
web:
image: myapp:1.4
command: /bin/sh -c 'exec myapp --config /etc/myapp.toml'exec என்பது shell process-ஐ உங்கள் program-ஆக மாற்றுகிறது (child process-ஐ உருவாக்குவதற்குப் பதிலாக). இதனால் உங்கள் program PID 1-ஐப் பெற்று, signal-களை நேரடியாகப் பெறும்.
சில program-கள் child process-களை உருவாக்கி அவற்றை முறையாக முடிப்பதில்லை (reap), இதனால் zombie process-கள் உருவாகின்றன. ஏனெனில் PID 1 தான் reaper-ஆகச் செயல்பட வேண்டும். Compose-ல் இதற்கென ஒரு வசதி உள்ளது:
services:
web:
image: myapp:1.4
init: true
stop_grace_period: 30sinit: true என்பது ஒரு சிறிய init process-ஐ PID 1-ஆக இயக்குகிறது. இது signal-களை உங்கள் process-க்கு அனுப்பி, child process-களை முறையாக முடிக்கும். stop_grace_period என்பது மெதுவான shutdown-க்கு கூடுதல் அவகாசம் அளிக்கிறது. உங்கள் program வேறு ஒரு signal-ஐ எதிர்பார்க்கிறது என்றால், stop_signal: SIGQUIT மூலம் Compose அனுப்பும் signal-ஐ மாற்றலாம். ஒரு image ஏற்கனவே எதைக் கேட்கிறது என்பதை docker image inspect --format '{{.Config.StopSignal}}' nginx:1.27 மூலம் சரிபார்க்கவும்.
ஒரு stack-ல் ஒவ்வொரு service-க்கும் docker compose down எப்போதும் பத்து வினாடிகள் எடுத்துக்கொள்கிறது என்றால், SIGTERM-ஐ எந்த process-ம் கையாளவில்லை என்று அர்த்தம். கருவி (tooling) மீது குற்றம் சாட்டுவதற்கு முன் அதைச் சரிசெய்யவும். ஒவ்வொன்றும் எதை நீக்குகிறது என்பதை அறிய docker compose down மற்றும் stop ஆகியவற்றுக்கு இடையேயான வேறுபாடு என்பதைப் பார்க்கவும்.
இதே exec மற்றும் shell இடையேயான வேறுபாடு மற்றொரு இடத்திலும் வெளிப்படுகிறது. test: ["CMD", "curl", "-f", "http://localhost/"] என எழுதப்பட்ட healthcheck நேரடியாக binary-ஐ இயக்குகிறது, அதேசமயம் test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"] ஒரு shell வழியாக இயக்குவதால் || என்பதற்குப் பொருள் கிடைக்கிறது. சரியாகத் தோல்வியடையும் Compose healthcheck-களை எழுதுதல் என்ற பகுதியில் இது குறித்து விரிவாகக் காணலாம்.
அதிகாரப்பூர்வ image-ல் ஒரு flag-ஐச் சேர்த்தல்
பெரும்பாலான வாசகர்கள் இதற்காகவே வந்துள்ளனர். உங்களுக்கு postgres-ல் ஒரு கூடுதல் flag தேவைப்படுகிறது, அதே சமயம் ஆரம்பகால initialization script-ஐ நீங்கள் மாற்றக்கூடாது.
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
command: postgres -c max_connections=200 -c shared_buffers=256MB
volumes:
pgdata:command: மட்டுமே மாற்றப்பட்டுள்ளதால், docker-entrypoint.sh தொடர்ந்து இயங்கும் மற்றும் நீங்கள் கொடுத்த கட்டளையை அதுவே செயல்படுத்தும். முடிவை ஊகிப்பதற்குப் பதிலாகச் சரிபார்க்கவும்:
docker compose up -d db
docker compose exec -T db psql -U postgres -c 'show max_connections;'வெளியீடு 200-ஐக் காட்ட வேண்டும். அது இன்னும் 100-ஐக் காட்டினால், docker compose config-ஐ இயக்கி, நீங்கள் எதிர்பார்க்கும் command இணைக்கப்பட்ட வெளியீட்டில் இருப்பதை உறுதிப்படுத்தவும். Compose கோப்புகளை இணைக்கும்போது, அவை command-ஐ அப்படியே மாற்றியமைக்கின்றன, அதற்குப் பின்னால் சேர்ப்பதில்லை. எனவே, command:-ஐ அமைக்கும் இரண்டாவது கோப்பு அமைதியாக முன்னுரிமை பெற்றுவிடும்.
மேலே உள்ள ${POSTGRES_PASSWORD}, container உருவாவதற்கு முன்பே, உங்கள் .env கோப்பிலிருந்து Compose மூலம் host-ல் விரிவாக்கப்படுகிறது. Compose-ல் Env கோப்புகள் மற்றும் secrets என்ற பகுதி அந்த மதிப்பை எங்கு பாதுகாப்பாக வைக்கலாம் என்பதை விளக்குகிறது.
docker compose run மூலம் ஒருமுறை மட்டும் இயங்கும் migration-ஐ இயக்குதல்
docker compose run ஆனது அதே service definition-லிருந்து ஒரு புதிய container-ஐ உருவாக்கி, நீங்கள் service பெயருக்குப் பின் குறிப்பிடும் கட்டளைக்கு ஏற்ப அதன் command-ஐ மாற்றியமைக்கிறது. Image-ன் entrypoint தொடர்ந்து இயங்குவதால், நீண்ட நேரம் இயங்கும் container-ஐப் போலவே இதுவும் சரியாகத் தயாராகிறது.
docker compose run --rm app python manage.py migrate--rmஆனது கட்டளை முடிந்ததும் container-ஐ நீக்கிவிடும். இதைப் பயன்படுத்தாவிட்டால், ஒவ்வொரு முறையும் இயக்கும்போதும் ஒரு stopped container எஞ்சியிருக்கும், அதைdocker compose ps -aமூலம் பார்க்கலாம்.- Ports வெளியிடப்படாது. ஒரு
runcontainer, நீங்கள்--service-ports-ஐச் சேர்த்தால் ஒழிய, service-ன்ports:-ஐப் புறக்கணிக்கும். எனவே, ஏற்கனவே இயங்கிக்கொண்டிருக்கும் service-உடன் இது மோதிக்கொள்ளாது. - Dependencies முதலில் தொடங்கும்.
depends_on-ல் உள்ளவை உங்கள் கட்டளைக்கு முன்பே இயங்கத் தொடங்கும்,--no-depsஇதைப் புறக்கணிக்கும். - Container-க்கு
myproject-app-run-9f2c1aபோன்ற ஒரு பெயர் உருவாக்கப்படும், எனவே இது service container-உடன் மோதிக்கொள்ளாது.
Entrypoint-ஐயும் மாற்ற, அதற்கென ஒரு flag உள்ளது:
docker compose run --rm --entrypoint /bin/sh app -c 'python manage.py migrate'இதன் விளைவாகக் கிடைக்கும் argument பட்டியல் /bin/sh -c 'python manage.py migrate' ஆகும், ஏனெனில் service பெயருக்குப் பின் உள்ள சொற்கள் இன்னும் கட்டளையாகவே கருதப்படுகின்றன. docker compose exec என்பது மற்றொரு கருவி, இது வித்தியாசமாகச் செயல்படுகிறது: இது ஏற்கனவே இயங்கிக்கொண்டிருக்கும் ஒரு container-க்குள் process-ஐ இயக்குகிறது, மேலும் இது entrypoint: மற்றும் command: ஆகிய இரண்டையும் முழுமையாகப் புறக்கணிக்கிறது. புதிய container தேவைப்படும் பணிக்கு run-ஐயும், இயங்கும் container-க்குள் பார்க்க exec-ஐயும் பயன்படுத்தவும். Compose கட்டளைகளின் சுருக்கக் குறிப்பு மற்ற subcommands-களை ஒப்பிட்டுப் பார்க்க உதவுகிறது.
எனது container ஏன் உடனடியாக வெளியேறுகிறது?
முதலில் exit code-ஐ சரிபார்க்கவும், ஏனெனில் இது காரணத்தை விரைவாகக் கண்டறிய உதவும்.
docker compose ps -a
docker compose logs appExit code 0 மற்றும் வெளியீடு ஏதுமில்லை. கட்டளை இயங்கி முடிந்துவிட்டது. இதற்கான பொதுவான காரணம், ஒரு entrypoint: மாற்றீடு, image-ன் CMD-ஐ நீக்கியதுதான். இதனால் entrypoint எந்த வாதங்களும் (arguments) இன்றி இயங்கியது, அதற்குச் செயல்பட எதுவும் இல்லை.
permission denied என முடியும் பிழை. image-க்குள் உள்ள script-க்கு executable bit இல்லை. பொதுவாக, repository-ல் உள்ள கோப்பில் இந்த bit அமைக்கப்படாததே இதற்குக் காரணம். build செய்யும்போது COPY --chmod=0755 entrypoint.sh /entrypoint.sh மூலம் இதை அமைக்கவும்.
image-ல் தெளிவாகத் தெரியும் ஒரு கோப்பிற்கு no such file or directory என முடியும் பிழை. அந்த script-ல் Windows line endings உள்ளன. அதன் முதல் வரி #!/bin/sh மற்றும் ஒரு carriage return byte-ஐக் கொண்டிருக்கும். எனவே, kernel அந்த byte-ஐ உள்ளடக்கிய பெயரைக் கொண்ட interpreter-ஐத் தேடும், அது கிடைக்காது. dos2unix entrypoint.sh-ஐ இயக்கவும், பின்னர் .gitattributes-ல் * text eol=lf-ஐச் சேர்க்கவும், அப்போதுதான் இது மீண்டும் வராது.
executable file not found in $PATH. command:-ல் குறிப்பிடப்பட்டுள்ள binary அந்த image-ல் இல்லை, அல்லது ஒரு உண்மையான program மட்டுமே இருக்க வேண்டிய இடத்தில் cd போன்ற shell built-in கட்டளையை நீங்கள் எழுதியுள்ளீர்கள்.
Entrypoint தோல்வியடையும் ஒரு image-க்குள் shell பெறுதல்
Entrypoint இயங்குவதற்கு முன்பே நின்றுவிட்டால், அதை ஆய்வு செய்ய கீழே உள்ளவாறு மாற்றவும்:
docker compose run --rm --entrypoint /bin/sh appஇது executable file not found in $PATH என்று திரும்ப அளித்தால், அந்த image-ல் shell இல்லை என்று பொருள். Distroless மற்றும் scratch அடிப்படையிலான image-களில் பெரும்பாலும் shell இருக்காது. Entrypoint-ஐத் தொடங்காமலேயே நீங்கள் filesystem-ஐ வெளியில் இருந்து பார்க்கலாம்:
docker create --name probe myapp:1.4
docker export probe | tar -tv | head -40
docker rm probeContainer தொடர்ந்து இயங்க வேண்டும், அப்போதுதான் நீங்கள் மீண்டும் மீண்டும் அதனுடன் இணைய முடியும் என்றால், அதை ஒருபோதும் முடியாத ஒரு process-ல் நிறுத்தவும். இதை நீங்கள் commit செய்யாத ஒரு override file-ல் சேர்க்கவும்:
services:
app:
entrypoint: ["tail", "-f", "/dev/null"]
command: []entrypoint:-ஐ அமைப்பதன் மூலம் ஏற்கனவே image-ன் CMD நீக்கப்பட்டுவிட்டதால், command: [] என்பது கட்டாயமில்லை. இருப்பினும், அதை எழுதுவது அந்த file-ஐப் பார்க்கும் அடுத்த நபருக்கு உங்கள் நோக்கத்தைத் தெளிவாக உணர்த்தும். அதை இயக்கி உள்ளே நுழையவும்:
docker compose -f compose.yaml -f compose.debug.yaml up -d app
docker compose exec app /bin/shஇப்போது உண்மையான entrypoint-ஐ நீங்களே நேரடியாக இயக்கி, அது எங்கே நிற்கிறது என்பதைக் கவனிக்கவும். அரை நொடியில் நின்றுபோன container-ல் பார்ப்பதற்குப் பதிலாக, உங்கள் terminal-லேயே பிழைச் செய்தியைப் பெற இது உதவும். நீங்கள் இன்னும் உங்கள் முதல் stack-ஐ உருவாக்கி வருகிறீர்கள் என்றால், VPS-ல் முதல் Compose stack என்ற பகுதி மேலே உள்ள அனைத்தும் சார்ந்திருக்கும் file layout-ஐ விளக்குகிறது.
FAQ
docker compose up செய்த பிறகு எனது container ஏன் உடனடியாக வெளியேறுகிறது?
வெளியேற்றக் குறியீட்டை (exit code) அறிய docker compose ps -a-ஐச் சரிபார்க்கவும். வெளியீடு ஏதுமின்றி 0 என்ற குறியீட்டுடன் வெளியேறினால், நீங்கள் அந்தச் சேவையில் entrypoint:-ஐ அமைத்திருக்கலாம். இது அந்த image-ன் CMD-ஐ நீக்கிவிடும், எனவே entrypoint காலியான வாதங்களுடன் (arguments) இயங்கி முடிந்துவிடும். command: மூலம் வாதங்களை மீண்டும் சேர்க்கவும். permission denied என்று முடியும் பிழை, entrypoint script-க்கு executable bit இல்லை என்பதைக் குறிக்கிறது. கோப்பு இருந்தும் no such file or directory என்று பிழை வந்தால், அந்த script-ல் Windows line endings உள்ளன என்று அர்த்தம்; இதனால் அதன் shebang வரியில் குறிப்பிடப்பட்டுள்ள interpreter-ஐ கணினியால் கண்டறிய முடியாது.
Compose-ல் entrypoint-ஐ அமைப்பது image-ன் CMD-ஐ நீக்கிவிடுமா?
ஆம். entrypoint காலியாக இல்லை என்றால், அந்த image-ல் அறிவிக்கப்பட்ட இயல்புநிலை கட்டளையை (default command) Compose புறக்கணித்துவிடும். இது ஆவணப்படுத்தப்பட்ட செயல்பாடு மற்றும் docker run --entrypoint-உடன் ஒத்துப்போகிறது. இதற்குக் காரணம், ஒரு image-ன் CMD என்பது அந்த image-ன் ENTRYPOINT-க்கான வாதங்களாக எழுதப்பட்டிருக்கும்; எனவே நீங்கள் entrypoint-ஐ மாற்றியவுடன், பழைய வாதங்கள் எதனுடனும் பொருந்தாது. புதிய entrypoint-க்கு வாதங்கள் தேவைப்பட்டால், அதே சேவையில் command:-ஐ அமைக்கவும்.
Compose command-ல் உள்ள string shell மூலம் இயக்கப்படுகிறதா?
இல்லை. Dockerfile CMD போலல்லாமல், Compose command:-ல் உள்ள string வாதங்களாகப் பிரிக்கப்பட்டு நேரடியாக இயக்கப்படும், அதற்கு /bin/sh -c wrapper இருக்காது. எனவே $VARIABLE என்பது container-க்குள் இருக்கும் shell-ஆல் விரிவாக்கம் (expand) செய்யப்படாது. உங்களுக்கு shell தேவைப்பட்டால், command: /bin/sh -c 'echo "hello $$HOSTNAME"'-ல் உள்ளவாறு நீங்களே அதை அழைக்கவும். இரட்டிப்பான $$ என்பது டாலர் குறியீட்டை escape செய்கிறது, இதனால் Compose அதை host-ல் விரிவாக்கம் செய்யாமல் அப்படியே container-க்கு அனுப்புகிறது.
ஒரு container-க்கு docker compose down ஏன் பத்து வினாடிகள் எடுத்துக்கொள்கிறது?
Compose ஆனது PID 1-க்கு SIGTERM-ஐ அனுப்பிவிட்டு, stop_grace_period (இயல்பாக 10 வினாடிகள்) வரை காத்திருந்து, பிறகு SIGKILL-ஐ அனுப்பும். Kernel ஆனது PID 1-க்கு இயல்புநிலை சிக்னல் செயல்பாடுகளைச் செய்யாது, எனவே SIGTERM handler இல்லாத நிரல் அந்த சிக்னலைப் புறக்கணித்துவிட்டு முழு நேரமும் காத்திருக்கும். docker compose exec -T app cat /proc/1/cmdline | tr '\0' ' ' மூலம் PID 1 உண்மையில் எது என்பதைக் கண்டறியவும். அது shell ஆக இருந்தால், image-ஐ exec வடிவத்திற்கு மாற்றவும் அல்லது shell string-க்குள் exec-ஐ எழுதவும். அந்தச் செயல்முறை (process) குழந்தைகளை (children) உருவாக்கி அவற்றை நீக்கவில்லை (reap) என்றால், அந்தச் சேவையில் init: true-ஐ அமைக்கவும்.