Dockerfile: SHELL în Docker

Dockerfile Docker 1.12+

Schimbă shell-ul folosit de forma „shell” a instrucțiunilor RUN, CMD și ENTRYPOINT (implicit /bin/sh -c pe Linux).

Sintaxă comandă
SHELL ["executabil", "parametri"]

Ce face Dockerfile: SHELL

Când scrii RUN apt-get update (forma shell, fără paranteze drepte), Docker rulează de fapt /bin/sh -c "apt-get update" pe Linux și cmd /S /C pe Windows. SHELL schimbă acest shell pentru instrucțiunile care urmează; poate apărea de mai multe ori în același Dockerfile.

Cel mai des este folosită pentru bash cu -o pipefail: implicit, într-o comandă cu pipe (curl ... | tar ...), doar ultima comandă decide dacă pasul reușește, deci o descărcare eșuată poate trece neobservată. Pe Windows, SHELL permite folosirea PowerShell. Instrucțiunea acceptă doar forma JSON.

Parametri

Parametru Descriere
SHELL ["/bin/bash", "-o", "pipefail", "-c"] Bash, cu oprire la eroare în orice comandă dintr-un pipe.
SHELL ["/bin/sh", "-c"] Revine la shell-ul implicit pe Linux.
SHELL ["powershell", "-Command"] PowerShell, pe imagini Windows.
RUN ["executabil", "arg"] Forma exec: nu folosește shell-ul deloc, deci nici SHELL.

Exemple

Exemplul 1: Pipe-uri sigure cu bash și pipefail

Scriptul de instalare se descarcă și se dă direct lui bash. Fără pipefail, dacă curl eșuează, bash primește un text gol, iese cu cod 0, iar pasul pare reușit.

FROM debian:12-slim
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \
    && rm -rf /var/lib/apt/lists/*
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN curl -fsSL https://exemplu.ro/instaleaza.sh | bash

Exemplul 2: Build-ul se oprește la descărcarea eșuată

Cu SHELL de mai sus, o adresă greșită oprește build-ul chiar la acest pas, cu codul de ieșire al lui curl (22).

docker build -t unealta .

Ieșire în terminal

curl: (22) The requested URL returned error: 404
ERROR: failed to solve: process "/bin/bash -o pipefail -c curl -fsSL https://exemplu.ro/instaleaza.sh | bash" did not complete successfully: exit code: 22

Greșeli frecvente

  • Scrierea în forma shell (SHELL /bin/bash -c): SHELL acceptă numai forma JSON, cu ghilimele duble.
  • Folosirea bash pe imagini Alpine sau distroless care nu îl conțin: instalează-l întâi (apk add bash) sau rămâi la /bin/sh.

Comenzi înrudite

  • Dockerfile: USER: Stabilește utilizatorul (și grupul) cu care rulează instrucțiunile următoare și procesul principal al containerului.
  • Dockerfile: STOPSIGNAL: Alege semnalul trimis procesului principal la docker stop (implicit SIGTERM), pentru o oprire curată a aplicației.