Запускать команды внутри контейнера проще, чем вы думаете.
Контейнер Docker – это изолированная среда, которая обычно содержит одно приложение со всеми необходимыми зависимостями.
Зачастую нам необходимо запустить некоторые команды внутри контейнера.
Есть несколько способов, которыми мы можем выполнить команду внутри контейнера и получить требуемый результат.
Далее мы покажем, как это сделать.
Использование интерактивного шелла
Мы можем напрямую обращаться к оболочке контейнера и выполнять наши команды, как в обычном терминале Linux.
Чтобы получить интерактивную оболочку остановленного (не в рабочем состоянии) контейнера, вы можете использовать:
$ 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
Затем зайдем в контейнер с идентификатором c2d969adde7a
$ docker exec -it c2d969adde7a bash
root@c2d969adde7a:/#
В приведенном выше выводе вы можете заметить, что мы запустили сеанс bash контейнера nginx, который находился в рабочем состоянии.
Здесь мы можем выполнить любую поддерживаемую команду и получить результат.
Обратите внимание: в вашем контейнере может не быть bash, и если это так, вы можете использовать sh.
Зачастую нам просто нужен вывод одной или двух команд и не требуется полноценный интерактивный сеанс для нашей задачи.
Вы можете запустить требуемую команду внутри контейнера и получить ее вывод напрямую, не открывая новый сеанс оболочки, используя команду exec без флага -it.
Cинтаксис будет таким:
$ 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
$
Мы выполнили ps -ef | grep mysql внутри работающего контейнера MariaDB и получила результат напрямую.
Использование Dockerfile
Это не совсем тот способ, которым вы можете запускать команды внутри контейнера, хотя он может быть полезен в ситуациях разработки или для начальной отладки развертывания и т.д.
Мы можем использовать команду RUN внутри Dockerfile.
Вот наш пример Dockerfile:
FROM nginx:latest
RUN nginx -V
Данный метод просто извлекает последний образ nginx из реджестри, а затем запускает команду nginx -V, чтобы отобразить версию Nginx при создании образа.
$ 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
$
Обратите внимание на вывод команды RUN в приведенном выше фрагменте.
Приведенный выше фрагмент будет отображаться только при первой сборке, а последующие сборки не будут повторять вывод команды RUN.
В качестве обходного пути вы можете попробовать флаг –no-cache:
Последний метод не самый лучший, но иногда может быть полезен для отладки и т.д.
Заключение
Выполнить команду внутри контейнера просто, и есть несколько доступных методов.
Это обычная задача администратора Docker, поэтому полезно знать эти команды.
См. также:
- 🐳 Как узнать IP-адрес Docker контейнера
- 🐳 Как проверить установленные сетевые подключения внутри Docker?