SSD Nodes Learn 🎉 VPS $5.50/மாதம் முதல்
கல்வி வழிகாட்டிகள் Matt Connorஆல் Matt Connor · புதுப்பிக்கப்பட்டது 2026-08-16

Docker Compose-ல் interactive shell-ஐப் பெறுவது எப்படி?

இயங்கும் Docker Compose service-க்குள் நுழைய docker compose exec கட்டளையைப் பயன்படுத்தவும். service இயங்கவில்லை என்றால் docker compose run --rm கட்டளையைப் பயன்படுத்தவும்.

docker compose exec மூலம் interactive shell-ஐப் பெறுதல்

docker compose exec web bash ஏற்கனவே இயங்கிக்கொண்டிருக்கும் web service-க்குள் ஒரு interactive shell-ஐத் திறக்கிறது. exec-க்கு அடுத்து வரும் பெயர் உங்கள் compose.yaml-ல் உள்ள service-ன் பெயராக இருக்க வேண்டும், container-ன் பெயராக இருக்கக்கூடாது. image-ல் bash இல்லையென்றால், அதற்குப் பதிலாக sh-ஐக் கேட்கவும்.

docker compose ps
docker compose exec web bash

முதலில் docker compose ps-ஐ இயக்கவும். இது running நிலையில் உள்ள web-ஐப் பட்டியலிட வேண்டும். அதன் பிறகு, இரண்டாவது கட்டளை உங்களை container-க்குள் ஒரு prompt-க்குக் கொண்டு செல்லும். exit அல்லது Ctrl-D-ஐ அழுத்தினால் நீங்கள் host-க்குத் திரும்பிவிடலாம். நீங்கள் வெளியேறிய பிறகும் service தொடர்ந்து இயங்கும், ஏனெனில் exec முதன்மை process-க்கு இணையாக இரண்டாவது process-ஐத் தொடங்கியுள்ளது. உங்கள் shell-ஐ மூடுவது PID 1-ஐ (process id 1) பாதிக்காது; அதுவே container-ஐ இயக்குவதற்காக உருவாக்கப்பட்ட process ஆகும்.

இது உள்ளே செல்வதற்கான இரண்டு வழிகளில் ஒன்றாகும். exec ஏற்கனவே இருக்கும் ஒரு container-உடன் இணைகிறது. docker compose run அதே service definition-லிருந்து ஒரு புதிய container-ஐ உருவாக்குகிறது. இந்த வழிகாட்டியில் உள்ள மற்ற அனைத்தும் இந்த ஒரு சிறிய வித்தியாசத்திலிருந்தே தொடங்குகின்றன.

Compose-ல் -it ஏன் விருப்பத்தேர்வாகவும், plain docker-ல் ஏன் கட்டாயமாகவும் உள்ளது

ஒரு session-ன் interactive தன்மையை இரண்டு flags கட்டுப்படுத்துகின்றன. -i என்பது stdin-ஐத் திறந்து வைத்திருக்கும், எனவே நீங்கள் தட்டச்சு செய்வது process-ஐச் சென்றடையும். -t என்பது TTY எனப்படும் pseudo terminal-ஐ ஒதுக்கும், இதன் மூலம் shell ஒரு prompt-ஐக் காட்டி, arrow keys-ஐக் கையாளும். Plain docker exec இயல்பாகவே இவை இரண்டையும் முடக்கி வைத்திருக்கும், இதனால்தான் நீங்கள் பார்த்த அனைத்து உதாரணங்களும் docker exec -it என்று எழுதப்பட்டுள்ளன. docker compose exec இவை இரண்டையும் உங்களுக்காகச் செயல்படுத்தும், எனவே docker compose exec -it web bash மற்றும் docker compose exec web bash ஆகிய இரண்டும் ஒரே வேலையைச் செய்கின்றன. Compose இப்போதும் -it-ஐ ஏற்றுக்கொள்கிறது, எனவே பழைய பழக்கவழக்கங்கள் தொடர்ந்து செயல்படும்.

TTY விடுபட்டிருப்பதை நீங்கள் சில நொடிகளிலேயே கவனிப்பீர்கள். Shell இயங்கும், ஆனால் அது prompt-ஐக் காட்டாது மற்றும் Ctrl-C கட்டளை process-ஐச் சென்றடையாது. இதற்கு நேர்மாறான சூழலில், அதாவது Compose ஒரு TTY-ஐ ஒதுக்கக்கூடாது என்று நீங்கள் கோர வேண்டியிருந்தால், அதற்குத் தனி flag உள்ளது; அது கீழே உள்ள பகுதியில் விளக்கப்பட்டுள்ளது.

image-ல் bash இல்லாதபோது என்ன செய்வது

Alpine அடிப்படையிலான image-ல் bash-ஐக் கோரும்போது exec இவ்வாறு தோல்வியடையும்:

OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown

அந்தச் செய்தி ஒரு exec சிக்கல் அல்ல. நீங்கள் கோரிய binary அந்த image-ல் இல்லை என்று அது கூறுகிறது. Alpine-ல் BusyBox உள்ளது, இது ash-ஐ /bin/sh ஆக வழங்குகிறது, ஆனால் bash இதில் இல்லை. எனவே sh-ஐக் கோரவும்:

docker compose exec web sh

Debian மற்றும் Ubuntu அடிப்படையிலான image-கள், -slim tags உட்பட, bash-ஐக் கொண்டுள்ளன. bash உங்களுக்கு command history மற்றும் சிறந்த completion வசதியைத் தருகிறது. எனவே முதலில் bash-ஐ முயற்சி செய்து, தோல்வியுற்றால் sh-க்கு மாறவும். sh கிட்டத்தட்ட அனைத்து பொதுவான image-களிலும் இருக்கும்.

சில image-களில் shell-லே இருக்காது. Distroless image-கள் மற்றும் FROM scratch மூலம் உருவாக்கப்பட்ட image-கள், application binary மற்றும் அதன் libraries-ஐ மட்டுமே கொண்டிருக்கும். இது வேண்டுமென்றே செய்யப்படுகிறது, ஏனெனில் இல்லாத shell-ஐ உங்களை எதிர்த்துப் பயன்படுத்த முடியாது. அவற்றில், sh அதே செய்தியுடன் தோல்வியடையும், முயற்சி செய்ய வேறு வழியில்லை. இரண்டு அணுகுமுறைகள் வேலை செய்யும். Google-ன் distroless image-கள் :debug tags-ஐ வெளியிடுகின்றன, அவை BusyBox shell-ஐச் சேர்க்கின்றன, எனவே தற்காலிகமாக tag-ஐ மாற்றினால் நீங்கள் உள்ளே நுழையலாம். அல்லது target-ன் namespaces-க்குள் ஒரு தனி container-ஐத் தொடங்கவும்:

CID=$(docker compose ps -q web)
docker run --rm -it --network "container:$CID" --pid "container:$CID" nicolaka/netshoot

இப்போது உங்களிடம் netshoot-ன் கருவிகள் application-ன் network-ஐச் சுட்டிக்காட்டுகின்றன, எனவே curl localhost:8080 மற்றும் ss -lntp நீங்கள் உள்ளே இருப்பது போலவே செயல்படும். நீங்கள் பார்க்கும் filesystem netshoot-க்குச் சொந்தமானது, app-க்கு அல்ல. process namespace பகிரப்படுவதால், நீங்கள் root-ஆக இருக்கும்போது ls /proc/1/root/ target-ன் சொந்தக் கோப்புகளை அணுகும்.

Service இயங்காதபோது docker compose run --rm பயன்படுத்தவும்

exec கட்டளைக்கு இயங்கிக்கொண்டிருக்கும் container தேவை. நிறுத்தப்பட்ட service-ஐக் குறிப்பிட்டால் அது இயங்காது:

service "web" is not running

இது உங்களுக்காக எதையும் தொடங்காது. docker compose run கட்டளை அதைச் செய்யும்:

docker compose run --rm web bash

run கட்டளையானது web service வரையறையிலிருந்து புதிய container-ஐ உருவாக்குகிறது. இது அதே image, environment, volumes மற்றும் networks-ஐப் பயன்படுத்துகிறது, மேலும் service-ன் command-க்கு பதிலாக நீங்கள் உள்ளிட்ட command-ஐ மாற்றுகிறது. --rm நீங்கள் வெளியேறும்போது அந்த container-ஐ நீக்கிவிடும். --rm-ஐத் தவிர்த்தால், மீதமுள்ளவை myproject-web-run-4f1c2b போன்ற பெயர்களில் சேரும், இவற்றை docker compose ps -a மூலம் பார்க்கலாம், ஆனால் இவை தானாக நீங்காது.

run கட்டளையின் இரண்டு செயல்பாடுகள் பயனர்களை ஆச்சரியப்படுத்தும். நீங்கள் --service-ports-ஐச் சேர்த்தால் ஒழிய, இது service-ன் ports-ஐ publish செய்யாது; இது திட்டமிட்டே செய்யப்படுகிறது: முதல் container ஏற்கனவே host port 8080-ஐப் பயன்படுத்திக்கொண்டிருக்கும்போது, இரண்டாவது container அதே port-ஐப் பயன்படுத்த முயன்றால் bind: address already in use பிழை ஏற்படும். மேலும், உங்கள் shell தோன்றுவதற்கு முன்பே depends_on-ன் கீழ் பட்டியலிடப்பட்டுள்ள அனைத்தையும் இது தொடங்கும், எனவே ஒரு சிறிய சோதனையைச் செய்யும்போதுகூட database மற்றும் cache தொடங்கப்படலாம். --no-deps இதைப் தவிர்க்க உதவும்.

run கட்டளை image-ன் ENTRYPOINT வழியாகச் செல்லும், ஆனால் exec அவ்வாறு செய்யாது. exec உங்கள் command-ஐ ஏற்கனவே உள்ள container-ல் நேரடியாகத் தொடங்கும், எனவே entrypoint script-க்கு அது தெரியாது. run கட்டளையின் கீழ், உங்கள் bash அந்த script-க்கான arguments-ஆகச் செல்லும். பல அதிகாரப்பூர்வமான images தங்கள் entrypoint-ஐ exec "$@" உடன் முடிக்கும், எனவே அது நேரடியாகச் சென்று உங்களுக்கு shell கிடைக்கும். அதற்குப் பதிலாகத் தனது சொந்த arguments-ஐப் புரிந்துகொள்ளும் script வேறுவிதமாகச் செயல்படும், அப்போது அந்த ஒரு run-க்கு மட்டும் நீங்கள் entrypoint-ஐ மாற்றலாம்:

docker compose run --rm --entrypoint sh web

exec-ல் வேலை செய்யும் ஒரு command run-ல் வித்தியாசமாகச் செயல்படுவதற்கு இதுவே பொதுவான காரணம். command மற்றும் entrypoint-க்கு இடையிலான வேறுபாடு ஒவ்வொரு முறையும் நீங்கள் image configuration-ன் எந்தப் பகுதியை மாற்றுகிறீர்கள் என்பதை விளக்குகிறது.

exec அல்லது run: எதைத் தேர்ந்தெடுப்பது

  • exec கட்டளைக்கு இயங்கிக்கொண்டிருக்கும் container தேவை. run கட்டளைக்கு அது தேவையில்லை, மேலும் run கட்டளை dependencies-ஐத் தொடங்கக்கூடும்.
  • exec தற்போதைய process list மற்றும் கோப்புகளைக் காட்டும்; application தொடங்கிய பிறகு மாற்றப்பட்ட கோப்புகளும் இதில் அடங்கும். run கட்டளை image-ன் புதிய நகலை எடுக்கும், எனவே அதில் முந்தைய மாற்றங்கள் இருக்காது.
  • exec கட்டளை entrypoint-ஐத் தவிர்க்கும். run கட்டளை அதை இயக்கும்.
  • நீங்கள் --rm-ஐப் பயன்படுத்தாவிட்டால், run கட்டளை ஒரு container-ஐ விட்டுச் செல்லும்.

நடந்துகொண்டிருக்கும் நிகழ்வுகளைப் பார்க்க exec-ஐப் பயன்படுத்தவும். ஒரே மாதிரியான சூழலில் தற்காலிகமாக ஒரு கட்டளையை இயக்க, ஒருமுறை மட்டும் செய்யும் migration பணிகளுக்கு, அல்லது உண்மையான service exec செய்வதற்கு முன்பே நின்றுவிடும் சூழலில் run --rm-ஐப் பயன்படுத்தவும்.

பயனுள்ள exec flags: user, working directory மற்றும் replicas

பெரும்பாலான images ஒரு non-root user-க்கு மாறிவிடும், எனவே உங்கள் exec shell-க்குள் ஒரு diagnostic tool-ஐ நிறுவுவது இத்துடன் நின்றுவிடும்:

E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)

-u root அதே container-க்குள் உங்களுக்கு root shell-ஐ வழங்குகிறது:

docker compose exec -u root web sh

-w /srv/app அந்த command-க்கு மட்டும் working directory-ஐ அமைக்கும். -e KEY=value உங்கள் session-க்கு மட்டும் ஒரு environment variable-ஐ சேர்க்கும், இது service-க்கு பொருந்தாது. ஒரு service ஒன்றுக்கு மேற்பட்ட replica-க்களை இயக்கும்போது, --index 2 எந்த container-க்குள் நீங்கள் நுழைய வேண்டும் என்பதைத் தீர்மானிக்கிறது. mounted directory-ல் உள்ள file ownership-ஐ நீங்கள் சரிபார்க்கிறீர்கள் என்றால், container images-ல் PUID மற்றும் PGID என்ற பகுதி, user names அல்லாமல் ஏன் numeric id-கள் மட்டுமே அங்கு யார் எழுதலாம் என்பதைத் தீர்மானிக்கின்றன என்பதை விளக்குகிறது.

Database container-க்குள் psql அல்லது mysql shell-ஐப் பெறுதல்

Client ஏற்கனவே database image-க்குள் இருப்பதால், host-ல் தனியாக client தேவையில்லை; port-ஐயும் publish செய்ய வேண்டிய அவசியமில்லை:

docker compose exec db psql -U postgres -d app
docker compose exec db mariadb -u root -p

Postgres images-ல் psql இருக்கும், MySQL images-ல் mysql இருக்கும், மற்றும் MariaDB images-ல் mariadb இருக்கும். Container-க்குள் இருந்தே இணைப்பு ஏற்படுத்தப்படுவதால், compose file-ல் எந்த database port-ம் publish செய்யப்படாதபோதும் இது வேலை செய்யும். இதுவே பாதுகாப்பான முறையாகும்: நீங்கள் publish செய்யாத port-ஐ இணையத்தில் உள்ள எவராலும் அணுக முடியாது.

ஒரு சிறிய தவறு பலரது நேரத்தை வீணடிக்கும். Docker கட்டளையைப் பார்ப்பதற்கு முன்பே, உங்கள் shell host-ல் உள்ள variables-ஐ விரிவுபடுத்திவிடும். எனவே, அந்த variable container-க்குள் மட்டுமே இருந்தால், -U "$POSTGRES_USER" ஒரு காலியான string-ஐயே அனுப்பும். Single quotes-ஐப் பயன்படுத்தி, container-க்குள் இருக்கும் shell-ஐ இயக்கினால் மட்டுமே அது சரியான இடத்தில் விரிவுபடுத்தப்படும்:

docker compose exec db sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB"'

இங்கே கட்டளை ஏதுமின்றி docker compose run --rm db-ஐப் பயன்படுத்த வேண்டாம். அது அதே data volume-ஐக் கொண்டு இரண்டாவது Postgres server-ஐத் தொடங்க முயலும், ஆனால் அது தொடங்க மறுத்துவிடும்:

FATAL:  lock file "postmaster.pid" already exists

Lock file அதன் வேலையைச் சரியாகச் செய்கிறது. ஏனெனில், ஒரே data directory-யில் இரண்டு server-கள் எழுதினால் தரவுகள் சிதைந்துவிடும் (corrupt). Database இயங்கிக்கொண்டிருக்கும்போது, இயங்கும் container-க்குள் நுழைய exec-ஐப் பயன்படுத்தவும். Database-ஐ Compose-ல் வைப்பதா என்பது தனிப்பட்ட முடிவு. Docker-ல் அல்லது host-ல் database-ஐ இயக்குவது குறித்த ஒப்பீடு இதற்கான தீர்மானத்தை எடுக்க உதவும்.

தொடக்கத்தில் கன்சோல் தேவைப்படும் சேவைகள்: stdin_open மற்றும் tty

exec மற்றும் run கட்டளைகள் நீங்கள் கைமுறையாகத் திறக்கும் ஷெல்களைக் கையாளுகின்றன. ஒரு சேவையின் முதன்மைச் செயல்முறை (main process) இயல்பிலேயே ஊடாடும் (interactive) தன்மையைக் கொண்டிருந்தால், compose கோப்பில் இரண்டு விசைகள் (keys) தேவைப்படும்:

services:
  console:
    image: python:3.12-slim
    command: python
    stdin_open: true
    tty: true

stdin_open: true என்பது docker run -i மற்றும் tty: true என்பது docker run -t ஆகும். இவை இல்லையென்றால், கொள்கலன் (container) தொடங்கி உடனடியாக 0 என்ற குறியீட்டுடன் வெளியேறிவிடும், மேலும் docker compose ps -a ஆனது Exited (0) என்பதைக் காட்டும். எந்தப் பிழையும் ஏற்படவில்லை. stdin-ல் முனையம் (terminal) இல்லாதபோது, python உடனடியாக கோப்பின் முடிவை (end of file) வாசித்துவிட்டு இயல்பாகவே வெளியேறிவிடும்; இது யாரும் தட்டச்சு செய்யாத நிரலுக்குச் சரியான செயல்பாடாகும்.

இரண்டு விசைகளும் அமைக்கப்பட்ட பிறகு, இயங்கும் செயல்முறையுடன் இணைக்க:

docker attach $(docker compose ps -q console)

Ctrl-P மற்றும் Ctrl-Q ஆகியவற்றை அழுத்தி வெளியேறவும்; இது செயல்முறையைத் தொடர்ந்து இயங்க வைக்கும். கொள்கலனில் TTY மற்றும் stdin ஆகிய இரண்டும் திறந்திருக்கும்போது மட்டுமே இந்த வரிசைமுறை வேலை செய்யும். அதற்குப் பதிலாக Ctrl-C அழுத்தினால், அது PID 1-க்கு ஒரு interrupt-ஐ அனுப்பி சேவையை நிறுத்திவிடும்.

சாதாரண சேவைகளுக்கு இந்த இரண்டு விசைகளையும் பயன்படுத்த வேண்டாம். ஒரு இணைய சேவையகம் (web server) ஒருபோதும் stdin-ஐ வாசிப்பதில்லை. மேலும், tty: true அமைப்பானது பல நிரல்களை வண்ண வெளியீடு (colour output) மற்றும் வரி இடையகத்திற்கு (line buffering) மாற்றும், ஏனெனில் ஒரு நபர் அதைப் பார்க்கிறார் என்று அவை கருதும்; இது docker compose logs-ஐ எஸ்கேப் குறியீடுகளால் (escape codes) நிரப்பிவிடும்.

cron மற்றும் CI-ல் scripted exec ஏன் தோல்வியடைகிறது: -T flag-ன் அவசியம்

உங்கள் terminal-ல் சரியாக இயங்கும் ஒரு exec கட்டளை, cron job அல்லது continuous integration (CI) runner-க்குள் இயங்கும்போது தோல்வியடையும்:

the input device is not a TTY

Compose இயல்பாகவே ஒரு pseudo terminal-ஐக் கோருகிறது, ஆனால் cron அந்த job-க்கு எந்த terminal-ஐயும் வழங்குவதில்லை. எனவே, உங்கள் கட்டளை இயங்குவதற்கு முன்பே இந்த கோரிக்கை தோல்வியடைகிறது. -T அந்த கோரிக்கையை முடக்குகிறது:

0 3 * * * docker compose -f /srv/app/compose.yaml exec -T db pg_dump -U postgres -Fc app > /srv/backups/app.dump

-T இரண்டாவது காரணத்திற்காகவும் முக்கியமானது. ஒரு TTY, வெளியேறும் byte stream-ஐ மாற்றியமைக்கும். எனவே, அதன் வழியாகச் செல்லும் ஒரு compressed dump சிதைந்துவிடும். redirected அல்லது piped output தேவைப்படும் எந்தவொரு கட்டளைக்கும் -T அவசியம்.

cron குறித்த மேலும் இரண்டு விவரங்கள். -f-ஐ ஒரு absolute path-உடன் பயன்படுத்தவும். ஏனெனில், cron அந்த job-ஐ home directory-லிருந்து இயக்குகிறது, அங்கு compose file இருக்காது. இதனால் Compose no configuration file provided: not found பிழையுடன் நின்றுவிடும். மேலும், exec தான் இயக்கிய கட்டளையின் exit code-ஐயே திருப்பித் தரும். எனவே, தோல்வியடையும் ஒரு pg_dump, வெறும் காலி backup-ஐ உருவாக்கிவிட்டு வெற்றியைப் பதிவு செய்வதற்குப் பதிலாக, set -e-ன் கீழ் உங்கள் script-ஐத் தோல்வியடையச் செய்யும். அன்றாடம் பயன்படுத்தும் பிற கட்டளைகள் Compose கட்டளைகளின் cheat sheet-ல் தொகுக்கப்பட்டுள்ளன; அவற்றை உங்கள் script-களுக்கு அருகில் வைத்திருப்பது பயனுள்ளது.

container-க்குள் நீங்கள் செய்யும் மாற்றங்கள் ஏன் மறைந்துவிடுகின்றன

நீங்கள் exec மூலம் ஒரு கருவியை நிறுவி, ஒரு config கோப்பைத் திருத்தி, சிக்கலைச் சரிசெய்கிறீர்கள். ஒரு வாரம் கழித்து அந்தத் திருத்தம் மறைந்துவிடுகிறது. இது container-ன் writable layer வடிவமைக்கப்பட்ட விதம் ஆகும். image tag அல்லது service definition-ல் ஏதேனும் மாற்றம் செய்த பிறகு docker compose up -d கட்டளையை இயக்கினால், அது பழைய container-ஐ அழித்துவிட்டு, image-லிருந்து புதிய ஒன்றை உருவாக்கும். அப்போது நீங்கள் கைகளால் செய்த அனைத்து மாற்றங்களும் பழைய container-உடன் சேர்ந்து அழிந்துவிடும்.

docker compose restart இதற்கு மாறுபட்டது. இது அதே container-ஐ நிறுத்தி மீண்டும் தொடங்கும், எனவே நீங்கள் செய்த மாற்றங்கள் அழியாமல் இருக்கும். இதனால்தான், ஒரு கையேடு திருத்தம் வாரக்கணக்கில் நீடிப்பது போலத் தோன்றி, பின்னர் தொடர்பில்லாத ஒரு update-ன் போது திடீரென மறைந்துவிடுகிறது. Named volumes மற்றும் bind mounts ஆகிய இரண்டும் இந்த இரண்டு செயல்பாடுகளையும் தாண்டி நீடிக்கும். ஏனெனில் அவற்றின் தரவு container-க்கு வெளியே சேமிக்கப்படுகிறது. நீங்கள் பாதுகாக்க விரும்பும் தரவுகளுக்கு எதைத் தேர்ந்தெடுக்க வேண்டும் என்பதை bind mounts and named volumes விளக்குகிறது.

எனவே, exec shell-ஐ வாசிப்பதற்கும் சோதிப்பதற்கும் மட்டுமே பயன்படுத்துங்கள். திருத்தம் என்னவென்று தெரிந்தவுடன், அது அழியாத இடத்தில் அதைச் செய்யுங்கள்: ஒரு package-ஐ Dockerfile-லும், ஒரு அமைப்பை compose கோப்பிலும் எழுதுங்கள். பின்னர் மாற்றங்களைச் செயல்படுத்த docker compose up -d கட்டளையைப் பயன்படுத்துங்கள். புதிய container-ல் அந்த மாற்றம் சரியாக உள்ளதா என்பதை மீண்டும் ஒரு exec மூலம் உறுதிப்படுத்திக் கொள்ளுங்கள்.

FAQ

docker compose exec மற்றும் docker compose run ஆகியவற்றுக்கு இடையே உள்ள வேறுபாடு என்ன?

exec என்பது ஏற்கனவே இயங்கிக்கொண்டிருக்கும் ஒரு container-க்குள், முதன்மை process-க்கு இணையாக ஒரு கட்டளையை இயக்குகிறது; இது image-ன் entrypoint-ஐத் தவிர்க்கிறது. run என்பது அதே image, environment, volumes மற்றும் networks-ஐப் பயன்படுத்தி, அதே service definition-லிருந்து ஒரு புதிய container-ஐ உருவாக்குகிறது; இது உங்கள் கட்டளையை entrypoint வழியாக அனுப்பி, முதலில் depends_on services-ஐத் தொடங்குகிறது. மேலும், நீங்கள் --service-ports-ஐச் சேர்க்காத வரை, run கட்டளை service-ன் ports-ஐ வெளியிடாது. இயங்கிக்கொண்டிருக்கும் service-ஐ ஆய்வு செய்ய exec-ஐப் பயன்படுத்தவும். service நிறுத்தப்பட்டிருக்கும்போது அல்லது அதைத் தொந்தரவு செய்ய விரும்பாதபோது run --rm-ஐப் பயன்படுத்தவும்.

docker compose exec ஏன் service இயங்கவில்லை என்று காட்டுகிறது?

exec ஏற்கனவே உள்ள ஒரு container-உடன் இணைகிறது, புதியதை உருவாக்க முடியாது. எனவே, நிறுத்தப்பட்ட அல்லது செயலிழந்த service service "web" is not running பிழையைக் கொடுக்கும். docker compose ps -a-ஐச் சரிபார்க்கவும்; இது Exited (1) போன்ற நிலையில் உள்ள, வெளியேறிய container-களைப் பட்டியலிடும். அது ஏன் நின்றது என்பதைக் கண்டறிய docker compose logs web-ஐப் படிக்கவும். எப்படியாவது ஒரு shell-ஐப் பெற, docker compose run --rm --entrypoint sh web-ஐ இயக்கவும். இது பழுதடைந்த start கட்டளையை இயக்காமல், அதே service definition-லிருந்து ஒரு புதிய container-ஐ உருவாக்கும்.

image-ல் bash இல்லை என்றால், shell-ஐ எப்படித் திறப்பது?

docker compose exec web bash கட்டளை exec: "bash": executable file not found in $PATH பிழையுடன் தோல்வியடைந்தால், அந்த image-ல் bash இல்லை என்று அர்த்தம். Alpine-ஐ அடிப்படையாகக் கொண்ட எதற்கும் இது பொதுவானது. docker compose exec web sh-ஐப் பயன்படுத்தவும், ஏனெனில் BusyBox /bin/sh-ஐ வழங்குகிறது. Distroless மற்றும் scratch images-ல் shell-களே இருக்காது, எனவே எந்த exec கட்டளையும் வேலை செய்யாது. அந்த image-ன் வெளியீட்டாளர் வழங்கினால், அதன் :debug tag-க்கு மாறவும். அல்லது docker compose ps -q web-லிருந்து பெறப்பட்ட $CID-ஐப் பயன்படுத்தி, docker run --rm -it --network "container:$CID" --pid "container:$CID" nicolaka/netshoot மூலம் target-ன் namespaces-ல் ஒரு debug container-ஐத் தொடங்கவும்.

cron-ல் எனது exec கட்டளை ஏன் "the input device is not a TTY" என்று தோல்வியடைகிறது?

docker compose exec இயல்பாகவே ஒரு pseudo terminal-ஐக் கோருகிறது, ஆனால் cron எதையும் வழங்குவதில்லை. எனவே உங்கள் கட்டளை இயங்குவதற்கு முன்பே கோரிக்கை தோல்வியடைகிறது. அதை அணைக்க -T-ஐச் சேர்க்கவும்: docker compose exec -T db pg_dump -U postgres app. திசைதிருப்பப்பட்ட (redirected) அல்லது piped output-களுக்கும் -T-ஐப் பயன்படுத்தவும், ஏனெனில் TTY byte stream-ஐ மாற்றி binary dump-ஐப் பாதிக்கும். cron-ல், உங்கள் compose கோப்பிற்கான முழுமையான பாதையுடன் (absolute path) -f-ஐயும் அனுப்பவும், இல்லையெனில் Compose no configuration file provided: not found பிழையுடன் வெளியேறும்.

exec மூலம் container-க்குள் நான் செய்யும் மாற்றங்கள் restart-க்குப் பிறகும் இருக்குமா?

அவை docker compose restart-க்குப் பிறகு நீடிக்கும், ஏனெனில் அது அதே container-ஐ மீண்டும் பயன்படுத்துகிறது. image அல்லது configuration மாற்றத்திற்குப் பிறகு docker compose up -d செய்யும்போது அவை அழிந்துவிடும், ஏனெனில் அது image-லிருந்து container-ஐ மீண்டும் உருவாக்கி, அதன் writable layer-ஐ நீக்கிவிடும். named volumes அல்லது bind mounts-ல் எழுதப்பட்ட தரவு, container-க்கு வெளியே இருப்பதால், இவை இரண்டிற்கும் பிறகும் நீடிக்கும். கண்டறியும் மாற்றங்களை (diagnostic changes) exec மூலம் செய்யவும், பின்னர் நிரந்தரமான மாற்றங்களை Dockerfile அல்லது compose கோப்பில் சேர்க்கவும்.