• Get application security done the right way! Detect, Protect, Monitor, Accelerate, and more…
  • Running commands inside a docker container is easier than you think.

    A docker container is an isolated environment that usually contains a single application with all required dependencies. Many times we need to run some commands inside a docker container. There are several ways in which we can execute a command inside a container and get the required output.

    Let’s see how we can do it.

    Using Interactive Shell

    We can directly access the shell of a container and execute our commands as with a normal Linux terminal. To get an interactive shell of a stopped (not in running state) container, you can use:

    $ docker run -it ubuntu bash
    [email protected]:/#

    As you can see, we landed directly inside a new Ubuntu container where we can run our commands. If a container is already running, you can use exec command as below.

    First, let’s find out the container ID.

    $ docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                      NAMES
    c2d969adde7a   nginx     "/docker-entrypoint.…"   2 hours ago   Up 2 hours   127.0.0.1:80->80/tcp       nginx
    0960560bc24b   mariadb   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   127.0.0.1:3306->3306/tcp   mariadb

    And, then get inside container ID c2d969adde7a

    $ docker exec -it c2d969adde7a bash 
    [email protected]:/#

    In the above output, you can observe that we started a bash session of nginx container which was in running state. Here we can execute any supported command and get the output.

    Note – your container may not have bash and if so, you can use sh.

    Ex:

    docker exec -it c2d969adde7a sh

    Direct Output

    Often we just need the output of one or two commands and do not require a full-blown interactive session for our task. You can run the required command inside a container and get its output directly without opening a new shell session using exec command without -it flag. Its syntax would be:

    $ docker exec <container-id or name> <command>

    Here’s an example:

    $ docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                      NAMES
    c2d969adde7a   nginx     "/docker-entrypoint.…"   2 hours ago   Up 2 hours   127.0.0.1:80->80/tcp       nginx
    0960560bc24b   mariadb   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   127.0.0.1:3306->3306/tcp   mariadb
    
    $ docker exec 0960560bc24b ps -ef | grep mysql
    mysql          1       0  0 13:35 ?        00:00:02 mysqld
    $

    We executed ps -ef | grep mysql command inside the running MariaDB container and got the output directly.

    Dockerfile Way

    This is not the exact way you can run commands inside a docker container though it may be helpful in development situations or for initial deployment debugging etc. We can use RUN command inside a Dockerfile. Here’s our sample Dockerfile:

    FROM nginx:latest
    RUN nginx -V

    It simply pulls the latest nginx image from the registry and then runs the nginx -V command to display the Nginx version when you build the image.

    $ docker build -t nginx-test .
    Sending build context to Docker daemon  2.048kB
    Step 1/2 : FROM nginx:latest
     ---> 7ce4f91ef623
    Step 2/2 : RUN nginx -V
     ---> Running in 43918bbbeaa5
    nginx version: nginx/1.19.9
    built by gcc 8.3.0 (Debian 8.3.0-6)
    built with OpenSSL 1.1.1d  10 Sep 2019
    TLS SNI support enabled
    configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.19.9/debian/debuild-base/nginx-1.19.9=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
    Removing intermediate container 43918bbbeaa5
     ---> d682277f2e50
    Successfully built d682277f2e50
    Successfully tagged nginx-test:latest
    $

    Observe the output of RUN command in the above snippet. The above snippet will be only displayed on the first build and consecutive builds will no-repeat the RUN command output. As a workaround, you can try --no-cache flag:

    $ docker build -t nginx-test . --no-cache

    The last method is not the best way but can be sometimes helpful for debugging etc.

    Summary

    Running command inside a docker container is simple and there are a few methods available to do it. It is a regular task of a Docker Administrator, so knowing these commands is useful.

    Next, learn some of the popular Docker commands.