GitLab CI/CD pipeline using Docker image fails with error: shell not found

Written by - 0 comments

Published on - Listed in Docker Linux Containers Git


While I was working on a GitLab pipeline for automatic RPM package building, I came across an error "shell not found" on a job with a specific Docker image.

Image rockylinux:9: Shell not found

The job defines a specific Docker image (rockylinux:9) and executes some commands within the "script" context:

build-job-el9:
  stage: build
  image: rockylinux:9
  variables:
    OS: "el9"
  tags:
    - linux
  script:
    - cat /etc/os-release
[...]

But once the pipeline was started on a GitLab runner, the job "build-job-el9" failed:

Executing "step_script" stage of the job script 00:01
Using docker image sha256:eeea865f4111bd48e16801554f44adf2db2fa4cb87a98ff7470d6de6be49fc15 for rockylinux:9 with digest rockylinux@sha256:b07e21a7bbcecbae55b9153317d333d4d50808bf5dc0859db0180b6fbd7afb3d ...
shell not found
Cleaning up project directory and file based variables 00:00
ERROR: Job failed: exit code 1

GitLab pipeline job failed

The error message here is "shell not found" - which is not a clear error message but hints that no $SHELL is around?

Same job works with rockylinux:8 image

To test the behaviour on another image, the same pipeline job works fine with a different Docker image (rockylinux:8):

build-job-el8:
  stage: build
  image: rockylinux:8
  variables:
    OS: "el8"
  tags:
    - linux
  script:
    - cat /etc/os-release
[...]

When the pipeline ran and started the rockylinux:8 container, the command(s) from the script context were executed without an error:

Executing "step_script" stage of the job script 00:56
Using docker image sha256:4e97feadb2763684b6477e6c8c34d5e9750f9d1a24f5eac82a07a66f82200611 for rockylinux:8 with digest rockylinux@sha256:20cfffabbe5fe1ff6643741bde0afdea23a2e525639b2fbf97c5820ecad11871 ...
$ cat /etc/os-release
NAME="Rocky Linux"
VERSION="8.8 (Green Obsidian)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="8.8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Rocky Linux 8.8 (Green Obsidian)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:8:GA"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
SUPPORT_END="2029-05-31"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-8"
ROCKY_SUPPORT_PRODUCT_VERSION="8.8"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.8"

As I was unable to find a difference between /bin/sh inside the different container images, the difference is most likely "what" is started by default when the image is started as a container. This can be overridden by defining the image entrypoint inside .gitlab-ci.yaml.

Use image entrypoint to launch a Shell

Whenever a (Docker|Application) container is started, the container starts the command defined as ENTRYPOINT in the image's Dockerfile. GitLab allows to overwrite this and describes it in the documentation:


To override the entrypoint of a Docker image, define an empty entrypoint in the .gitlab-ci.yml file, so the runner does not start a useless shell layer.
For Docker 17.06 and later, the entrypoint can be set to an empty value.
For Docker 17.03 and earlier, the entrypoint can be set to /bin/sh -c, /bin/bash -c, or an equivalent shell available in the image.
The syntax of image:entrypoint is similar to Dockerfile ENTRYPOINT

Let's adjust the el9 job in .gitlab-ci.yaml:

build-job-el9:
  stage: build
  image:
    name: rockylinux:9
    entrypoint: [ '/bin/bash', '-c' ]

  variables:
    OS: "el9"
  tags:
    - linux
  script:
    - cat /etc/os-release
[...]

The "image" context now contains two fields: "name" and "entrypoint". The name obviously defines the Docker image to pull and use for this job. The entrypoint tells the image what process or command to launch.

Prior to that change, only the image name was used directly under "image:" (which is an alias for image->name:).

After this change, the pipeline job "build-job-el9" was able to execute commands within the launched RockyLinux 9 container:

Executing "step_script" stage of the job script 00:06
Using docker image sha256:eeea865f4111bd48e16801554f44adf2db2fa4cb87a98ff7470d6de6be49fc15 for rockylinux:9 with digest rockylinux@sha256:3387f6adc2fcdba59b9ff07acb955b4dbb610d3d93f7c68182107c1d25fac39c ...
$ cat /etc/os-release
NAME="Rocky Linux"
VERSION="9.2 (Blue Onyx)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.2"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Rocky Linux 9.2 (Blue Onyx)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:9::baseos"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
SUPPORT_END="2032-05-31"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9"
ROCKY_SUPPORT_PRODUCT_VERSION="9.2"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.2"

The entrypoint workaround was only necessary on the rockylinux:9 image. On the other two images (centos:7 and rockylinux:8) this was not needed for executing the build jobs.

GitLab pipeline jobs successful


Add a comment

Show form to leave a comment

Comments (newest first)

No comments yet.

RSS feed

Blog Tags:

  AWS   Android   Ansible   Apache   Apple   Atlassian   BSD   Backup   Bash   Bluecoat   CMS   Chef   Cloud   Coding   Consul   Containers   CouchDB   DB   DNS   Database   Databases   Docker   ELK   Elasticsearch   Filebeat   FreeBSD   Galera   Git   GlusterFS   Grafana   Graphics   HAProxy   HTML   Hacks   Hardware   Icinga   Influx   Internet   Java   KVM   Kibana   Kodi   Kubernetes   LVM   LXC   Linux   Logstash   Mac   Macintosh   Mail   MariaDB   Minio   MongoDB   Monitoring   Multimedia   MySQL   NFS   Nagios   Network   Nginx   OSSEC   OTRS   Office   PGSQL   PHP   Perl   Personal   PostgreSQL   Postgres   PowerDNS   Proxmox   Proxy   Python   Rancher   Rant   Redis   Roundcube   SSL   Samba   Seafile   Security   Shell   SmartOS   Solaris   Surveillance   Systemd   TLS   Tomcat   Ubuntu   Unix   VMWare   VMware   Varnish   Virtualization   Windows   Wireless   Wordpress   Wyse   ZFS   Zoneminder