Starting a Shell in the Docker Alpine Container

Starting a shell in the Docker Alpine container


ole@T:~$ docker run -it --rm alpine /bin/ash
(inside container) / #

Options used above:

  • /bin/ash is Ash (Almquist Shell) provided by BusyBox
  • --rm Automatically remove the container when it exits (docker run --help)
  • -i Interactive mode (Keep STDIN open even if not attached)
  • -t Allocate a pseudo-TTY

How do I run a Bash script in an Alpine Docker container?

Alpine comes with ash as the default shell instead of bash.

So you can

  1. Have a shebang defining /bin/bash as the first line of your sayhello.sh, so your file sayhello.sh will begin with bin/sh

    #!/bin/sh
  2. Install Bash in your Alpine image, as you seem to expect Bash is present, with such a line in your Dockerfile:

    RUN apk add --no-cache --upgrade bash

How to load shell aliases in an alpine docker container with start

By default docker start a non-login shell.
To read .profile file you need a login shell docker exec -it <container> ash -l.

To read /etc/profile (or another startup file) everytime, you've to set ENV variable.

Example Dockerfile

ARG PHPVERSION=7.4
FROM php:$PHPVERSION-fpm-alpine

ARG PHPVERSION=7.4
ENV PHPVERSION_ENV=$PHPVERSION

# copy composer from official image
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

#set $ENV
ENV ENV=/etc/profile
#copy aliases definition
COPY /assets/alias.sh /etc/profile.d/alias.sh


How to run a shell script on a Alpine Docker container on startup?

You should create a shell file to be copied inside a new container and then setup the container entrypoint as the shell script you created, synthax would be like

FROM <docker/alpine-image>
#.... somecode
USER root
COPY /localmachinelocation/entrypoint.sh /containerlocation/entrypoint.sh
RUN chmod 544 /var/www/webapp/entrypoint.sh
#.... somecode
CMD /containerlocation/entrypoint.sh

You could specify the user you need to run the script.
Chmod ensure the script would be runnable by the owner of the script, you could change it for security matters.

Let's say you have your script in /home/user/script.sh, you could do

FROM <docker/alpine-image>
USER root
COPY /home/user/script.sh /root/entrypoint.sh
RUN chmod 544 /var/www/webapp/entrypoint.sh
CMD /root/entrypoint.sh

Docker: How to use bash with an Alpine based docker image?

Alpine docker image doesn't have bash installed by default. You will need to add the following commands to get bash:

RUN apk update && apk add bash

If you're using Alpine 3.3+ then you can just do:

RUN apk add --no-cache bash

To keep the docker image size small. (Thanks to comment from @sprkysnrky)

If you just want to connect to the container and don't need bash, you can use:

docker run --rm -i -t alpine /bin/sh --login

Running a shell command on local files with Docker Alpine

The reason it's not working is because the use of double quotes to wrap the string means the variables (e.g. ${filename}) are interpolated outside of the Alpine shell. What you really want is to pass the string into the container inside single-quotes, so the interpolation happens within the container.

The following works to do the nested rename by using a single-quoted string, with double-quoted strings inside it (the opposite of what the question has):

docker run -v pwd:/tmp alpine /bin/sh -c 'find /tmp -name "*.dic" | while read filename; do mv ${filename} $(echo ${filename} | sed -e "s/\.dic$/\.dcm/"); done'

However, although this works, it's not the perfect solution. Another approach which retains the use of single-quotes within the executed command would be to wrap single quotes in double quotes and glue that into the strings, e.g. "'"'s/find/replace/g'"'". Whether the myriad extra quotes and lower legibility is worth it is a question for the reader. That would look something like this:

docker run -v pwd:/tmp alpine /bin/sh -c 'find /tmp -name '"'"'*.dic'"'"' | while read filename; do mv ${filename} $(echo ${filename} | sed -e '"'"'s/\.dic$/\.dcm/'"'"'); done'

TBH I generally get around this sort of wrangling by dropping the command into a script file and including that in the mount, as the script can be more easily shared/version controlled then.

Bash on alpine linux

The entrypoint is a GitLab Runner script. Change it to bash to get shell access:

$ docker run -it --entrypoint /bin/bash <image_name>

How do I get into a Docker container's shell?

docker attach will let you connect to your Docker container, but this isn't really the same thing as ssh. If your container is running a webserver, for example, docker attach will probably connect you to the stdout of the web server process. It won't necessarily give you a shell.

The docker exec command is probably what you are looking for; this will let you run arbitrary commands inside an existing container. For example:

docker exec -it <mycontainer> bash

Of course, whatever command you are running must exist in the container filesystem.

In the above command <mycontainer> is the name or ID of the target container. It doesn't matter whether or not you're using docker compose; just run docker ps and use either the ID (a hexadecimal string displayed in the first column) or the name (displayed in the final column). E.g., given:

$ docker ps
d2d4a89aaee9 larsks/mini-httpd "mini_httpd -d /cont 7 days ago Up 7 days web

I can run:

$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:3/64 scope link
valid_lft forever preferred_lft forever

I could accomplish the same thing by running:

$ docker exec -it d2d4a89aaee9 ip addr

Similarly, I could start a shell in the container;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$


Related Topics



Leave a reply



Submit