Como vimos na seção anterior, o Docker é uma importante ferramenta e possui uma gama de comandos para a criação de imagens e manipulação de contêineres. Para informações detalhadas das diversas opções pode-se utilizar o comando docker --help ou até mesmo consultar a documentação on-line disponível em https://docs.docker.com/.
Nesta seção falaremos um pouco mais sobre o registry público do Docker, denominado Docker Hub. Sugerimos fortemente que você crie uma conta no Docker Hub e gere um Token de Acesso que irá permitir a você armazenar imagens no Docker Hub, conforme veremos a seguir. Uma vez logado em sua conta, a criação do token de acesso pode ser feita no menu "Account Settings/Security", conforme ilustrado na tela a seguir.
Ao gerar o Token de Acesso, copie e cole o número gerado pois ele será necessário em cada nova conexão ao Docker Hub realizada via linha de comando quando se desejar armazenar uma imagem no registry público do Docker.
Registrando nova imagem no Docker Hub
Por exemplo, na Seção 1.5, construímos uma imagem, denominada python:sample que ficou armazenada no registry local. Para isso, utilizamos o comando abaixo:
$ docker build -t python:sample .
Se desejarmos que essa imagem possa ser compartilhada via Hub Docker, inicialmente, precisamos mudar o seu nome de modo a incluir, prescendendo o mesmo, o DOCKER_ID do usuário do Hub Docker. No exemplo aqui apresentado, esse DOCKER_ID é aurimrv. como pode ser observado na figura acima. Desse modo, o comando de construção a ser utilizado será:
$ docker build -t aurimrv/python:sample .
Sending build context to Docker daemon 4.096kB
Step 1/6 : FROM python:3
---> ee2a4300ffa2
Step 2/6 : WORKDIR /usr/src/app
---> Using cache
---> c311c48f19db
Step 3/6 : COPY requirements.txt ./
---> Using cache
---> ea7e1c3c6991
Step 4/6 : RUN pip install --no-cache-dir -r requirements.txt
---> Using cache
---> ca94e718b78b
Step 5/6 : COPY . .
---> Using cache
---> 4fec572aaf81
Step 6/6 : CMD [ "python", "./script.py" ]
---> Using cache
---> 9862ce240bbe
Successfully built 9862ce240bbe
Successfully tagged aurimrv/python:sample
Observa-se no final da execução (linha 21) que a imagem passou a ser rotulada como aurimrv/python:sample.
Ao final desse processo temos uma imagem denominada aurimrv/python:sample, criada e armazenada localmente. Agora vamos enviá-la para o Docker Hub. Para isso você precisa saber o seu DOCKER_ID e o seu DOCKER_TOKEN. Ambos serão utilizados no processo. Ao ser solicitada a Password, simplesmente copie e cole o seu token de acesso de desenvolvedor gerado na plataforma Docker Hub.
$ docker login -u aurimrv
Password:
WARNING! Your password will be stored unencrypted in /home/auri/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
Em seguida, o comando docker push permite submeter uma nova imagem para o registry do Docker Hub, conforme ilustrado abaixo:
$ docker push aurimrv/python:sample
The push refers to repository [docker.io/aurimrv/python]
8f87ebb3c106: Pushed
9efb950a790c: Pushed
e8900ae5a74c: Pushed
9be204ecae2e: Pushed
50ba39281905: Mounted from library/python
c4dbdfaeca5a: Mounted from library/python
a221bc56b147: Mounted from library/python
7ed1d87a050a: Mounted from library/python
3ffc178e6d86: Mounted from library/python
327e42081bbe: Mounted from library/python
6e632f416458: Mounted from library/python
e019be289189: Mounted from library/python
c9a63110150b: Mounted from library/python
sample: digest: sha256:49a87389f8af762b96318c71942e1ccd9bd3a59203870a93a1452d65aae66972 size: 3050
Ao consultar a respectiva conta no Docker Hub, observa-se que essa imagem aparece disponível para ser utilizada por qualquer outro usuário. A figura a seguir ilustra a presença dessa imagem.
Consultando por imagens existentes
Como apresentado acima, o Docker Hub é um grande repositório de imagens que estão disponíveis para serem utilizadas para uso direto ou como base para o desenvolvimento de novas imagens como fizemos no exemplo apresento. Pelo campo de busca do Docker Hub você pode pesquisar por imagens de interesse. A tela a seguir, por exemplo, ilustra a pesquisa feita por Python.
Como pode ser observao, existe uma grande variedade de imagens contento Python no nome em alguma parte da descrição de uma imagem, basta localizar a desejada e utilizar. No nosso exemplo, utilizamos a imagem oficial do Python com a Tag 3.8.
Existe também a opção de procurar por imagens utilizando-se o comando docker search via linha de comando. Por exemplo a busca realizada acima no Docker Hub via linha de comando ficaria conforme abaixo:
$ docker search python
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
python Python is an interpreted, interactive, objec… 7217 [OK]
continuumio/anaconda3 Powerful and flexible python distribution 596 [OK]
pypy PyPy is a fast, compliant alternative implem… 314 [OK]
continuumio/anaconda Powerful and flexible python distribution 219 [OK]
circleci/python Python is an interpreted, interactive, objec… 48
hylang Hy is a Lisp dialect that translates express… 43 [OK]
amazon/aws-lambda-python AWS Lambda base images for Python 41
bitnami/python Bitnami Python Docker Image 17 [OK]
google/guestbook-python-redis A simple guestbook example written in Python… 4
cimg/python 3
appdynamics/python-agent-init AppDynamics Repository for Python agent inst… 0
okteto/python-fastapi 0
pachyderm/python-build 0
ibmcom/python-sybase-ppc64le Docker image for python-sybase-ppc64le 0
ibmcom/python-memcached-ppc64le Docker image for python-memcached-ppc64le 0
bitnami/python-snapshot 0
ibmcom/python-dropbox-ppc64le Docker image for python-dropbox-ppc64leDocke… 0
ibmcom/python-glanceclient-ppc64le Docker image for python-glanceclient-ppc64le 0
ibmcom/python-ceilometerclient-ppc64le Docker image for python-ceilometerclient-ppc… 0
ibmcom/pythonfutures-ppc64le Docker image for pythonfutures-ppc64le 0
okteto/python 0
mirantis/python-operations-api https://mirantis.jira.com/browse/IT-40189 0 [OK]
pachyderm/python-evaluate 0
okteto/python-job-launcher 0
ibmcom/python-semver-ppc64le Docker image for python-semver-ppc64leDocker… 0
Entretanto, certamente a documentação encontrada no Docker Hub referente as imagens é mais detalhada e merece ser lida para viabilizar a correta utilização das mesmas.
Executando a imagem registrada
Para executar a imagem registrada utiliza-se o comando docker run mas, agora, passando o nome da imagem registrada remotamente.
$ docker run --rm aurimrv/python:sample
Basic Image Operations With the Python Pillow Library
Read the full article at https://realpython.com/image-processing-with-the-
Parando a execução de um contêiner
Suponha que tenha se iniciado a execução de um contêiner contendo uma instância do Apache Tomcat. Por exemplo, o comando abaixo colocaria tal contêiner em execução.
$ docker run --rm tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
5492f66d2700: Already exists
540ff8c0841d: Already exists
a0bf850a0df0: Already exists
d751dc38ae51: Already exists
21fd8f6c2501: Pull complete
3585e93a38a5: Pull complete
fca7cf2735d1: Pull complete
4f339b93865d: Pull complete
39442253360c: Pull complete
89db664184b6: Pull complete
Digest: sha256:09d1da454a73d526264e62f71c63beb62c189a3438606269a2298c0a943b2726
Status: Downloaded newer image for tomcat:latest
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
26-Mar-2022 04:36:13.972 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/10.0.18
26-Mar-2022 04:36:13.974 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Mar 9 2022 14:30:15 UTC
26-Mar-2022 04:36:13.975 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 10.0.18.0
26-Mar-2022 04:36:13.975 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
26-Mar-2022 04:36:13.975 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 5.4.0-105-generic
26-Mar-2022 04:36:13.975 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
26-Mar-2022 04:36:13.975 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/local/openjdk-11
26-Mar-2022 04:36:13.975 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 11.0.14.1+1
26-Mar-2022 04:36:13.975 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation
26-Mar-2022 04:36:13.976 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat
26-Mar-2022 04:36:13.976 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat
26-Mar-2022 04:36:13.984 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
26-Mar-2022 04:36:13.984 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
26-Mar-2022 04:36:13.984 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
26-Mar-2022 04:36:13.984 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
26-Mar-2022 04:36:13.985 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
26-Mar-2022 04:36:13.985 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
26-Mar-2022 04:36:13.985 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
26-Mar-2022 04:36:13.985 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
26-Mar-2022 04:36:13.985 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
26-Mar-2022 04:36:13.985 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
26-Mar-2022 04:36:13.985 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
26-Mar-2022 04:36:13.986 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
26-Mar-2022 04:36:13.986 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
26-Mar-2022 04:36:13.986 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
26-Mar-2022 04:36:13.991 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded Apache Tomcat Native library [1.2.31] using APR version [1.7.0].
26-Mar-2022 04:36:13.991 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true].
26-Mar-2022 04:36:13.993 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1k 25 Mar 2021]
26-Mar-2022 04:36:14.258 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
26-Mar-2022 04:36:14.278 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [442] milliseconds
26-Mar-2022 04:36:14.318 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
26-Mar-2022 04:36:14.318 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.0.18]
26-Mar-2022 04:36:14.325 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
26-Mar-2022 04:36:14.334 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [55] milliseconds
No caso específico desse contêiner, como o Tomcat permanece em execução, o prompt não é liberado. É possível, inclusive, conectar nessa instância do Tomcat e verificar que o mesmo está em execução no endereço. Entretanto, da forma como o comando docker run foi executado acima, para se conectar à instância do Tomcat em execução no contêiner é necessário se saber o endereço IP que o contêiner está utilizando. Para isso pode-se utilizar o comando docker ps para se obter o ID ou nome do contêiner e, em seguida, o docker inspect para obter informações sobre o status da execução do contêiner, incluíndo o endereço IP utilizado.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e579c1e6c9d0 tomcat "catalina.sh run" 4 minutes ago Up 4 minutes 8080/tcp laughing_bhaskara
Por exemplo, o comando acima identificou que o ID do contêiner é e579c1e6c9d0 e seu nome é laughing_bhaskara. Utilizando qualquer desses identificadores podemos inspecionar o contêiner com o comando abaixo:
Observa-se pelo comando acima que o endereço IP utilizado pelo contêiner é o 172.17.0.2. Desse modo, é possível se conectar a essa instância do Tomcat utilizando-se o endereço: http://172.17.0.2:8080/ que irá produzir como saída um erro 404 uma vez que no contêiner não há qualquer aplicação instalada.
Para parar o contêiner é necessário abrir um outro prompt de comando e executar os comandos docker ps para se decobrir o ID ou nome do contêiner e, em seguida, o comando docker stop com a identificação do contêiner que se deseja interromper a execução.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e579c1e6c9d0 tomcat "catalina.sh run" 4 minutes ago Up 4 minutes 8080/tcp laughing_bhaskara
$ docker stop e579c1e6c9d0
e579c1e6c9d0
Redirecionamento de portas
No caso do Tomcat e outros serviços que fazem uso de portas, o docker run oferece um parâmetro que permite realizar o mapeamento de portas utilizadas no contêiner para portas na máquina hospedeira, executando os contêineres. Por exemplo, considerando o exemplo do Tomcat acima, se o executássemos conforme abaixo, a porta 8080 utilizada pelo contêiner no endereço 172.17.0.2 seria mapeada para a porta 8888 na máquina local, ou seja, em http://localhost:8888, como pode ser observado na figura abaixo:
Compartilhamento de volumes
Outra característica interessante dos contêineres é que eles executam em um espaço de dados separado da máquina local no qual executa. Desse modo, caso existam dados que sejam produzidos pelo contêiner que precisam ser repassados para a máquina local ou vice versa, a solução para isso, recomendada pelo Docker, é por meio de volumes. O exemplo a seguir ilustra esse cenário. Para isso, será utilizada uma imagem do servidor de banco de dados MySQL.
O Docker Hub oferece uma documentação detalhada de como fazer uso da imagem para a criação de contêineres executando o MySQL. O problema que desejamos demonstrar é que, ao utilizar um banco de dados para o armazenamento de dados de uma aplicação, quando o contêiner encerra sua execução ou é destruído, os dados armazenados internamente no banco de dados se perdem, caso não sejam compartilhados com a máquina local. Uma das formas de fazer isso é pode meio de volumes que basicamente mapeiam um diretório ou arquivo na máquina local com um diretório ou arquivo dentro do contêiner.
O comando abaixo ilustra essa situação:
$ docker run --name mysql-mlops-01 -v "$(pwd)/datadir":/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mlops mysql
2022-03-26 14:19:06+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
2022-03-26 14:19:06+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-03-26 14:19:06+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
2022-03-26 14:19:06+00:00 [Note] [Entrypoint]: Initializing database files
2022-03-26T14:19:06.277742Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.28) initializing of server in progress as process 43
2022-03-26T14:19:06.284569Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-03-26T14:19:14.442141Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-03-26T14:19:18.914419Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2022-03-26 14:19:21+00:00 [Note] [Entrypoint]: Database files initialized
2022-03-26 14:19:21+00:00 [Note] [Entrypoint]: Starting temporary server
....
2022-03-26 14:19:25+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
2022-03-26T14:19:25.527652Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 1
2022-03-26T14:19:25.539381Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-03-26T14:19:25.680864Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-03-26T14:19:25.865450Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2022-03-26T14:19:25.865500Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2022-03-26T14:19:25.866682Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2022-03-26T14:19:25.881075Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
2022-03-26T14:19:25.881074Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
Observamos que na instrução do docker run temos alguns parâmetros novos. O primeiro é o parâmetro --name que permite atribuirmos um nome para nosso contêiner que entrará em execução. No caso, atribuímos a ele o nome mysql-mlops-01 e podemos utilizar esse nome para referência-lo nos demais comandos que faremos uso.
O segundo parâmetro é o -v que permite o compartilhamento de um diretório local (no exemplo), com um diretório dentro do contêiner. No caso, o diretório local é representado por $(pwd)/datadir , ou seja, a pasta corrente onde o domando docker run está sendo executado $(pwd) terá um subdiretório datadir que será associado ao diretório var/lib/mysql dentro do contêiner.
Inicialmente, na primeira execução do contêiner, a pasta local $(pwd)/datadir está vazia mas, ao utilizar o banco de dados dentro do contêiner, os dados referentes a base de dados criada são copiados, ao término da execução, para essa pasta e, numa execução futura do contêiner, o banco de dados é restaurado a partir dos dados locais transferidos para o contêiner.
Finalmente, o parâmetro -e permite definir uma variável de ambiente que é utilizada pelo contêiner. Uma das variáveis que o contêiner do MySQL permite ser especificada é a MYSQL_ROOT_PASSWORD que indica a senha de administrador (root) no banco de dados. Em nosso caso, definimos essa senha como mlops. Essa senha será utilizada para que possamos conectar ao banco de dados e executar instruções em SQL.
Com o contêiner em execução, o comando a seguir conecta no contêiner e executa um comando simples no MySQL para exemplificar que a mesma foi alterada.
$ docker exec -it mysql-mlops-01 /bin/bash
root@79580350c91a:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.28 MySQL Community Server - GPL
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database MLOPS;
Query OK, 1 row affected (0.01 sec)
mysql> quit;
Bye
root@79580350c91a:/# exit
No exemplo acima, abrimos um prompt de comando no contêiner em execução, conectamos ao banco de dados e criamos uma nova base de dados, nomeada MLOPS, no MySQL. Os comandos apresentados a seguir irão parar e remover o contêiner em execução.
Ao verificar o diretório local $(pwd)/datadir observamos que o mesmo contêm dados referentes ao banco de dados que estava armazenado dentro do contêiner.
$ ls -l datadir/
total 185772
-rw-r----- 1 netdata netdata 56 mar 26 11:19 auto.cnf
-rw-r----- 1 netdata netdata 3116922 mar 26 11:19 binlog.000001
-rw-r----- 1 netdata netdata 368 mar 26 11:36 binlog.000002
-rw-r----- 1 netdata netdata 32 mar 26 11:19 binlog.index
-rw------- 1 netdata netdata 1676 mar 26 11:19 ca-key.pem
-rw-r--r-- 1 netdata netdata 1112 mar 26 11:19 ca.pem
-rw-r--r-- 1 netdata netdata 1112 mar 26 11:19 client-cert.pem
-rw------- 1 netdata netdata 1676 mar 26 11:19 client-key.pem
-rw-r----- 1 netdata netdata 196608 mar 26 11:30 '#ib_16384_0.dblwr'
-rw-r----- 1 netdata netdata 8585216 mar 26 11:19 '#ib_16384_1.dblwr'
-rw-r----- 1 netdata netdata 4062 mar 26 11:36 ib_buffer_pool
-rw-r----- 1 netdata netdata 12582912 mar 26 11:36 ibdata1
-rw-r----- 1 netdata netdata 50331648 mar 26 11:30 ib_logfile0
-rw-r----- 1 netdata netdata 50331648 mar 26 11:19 ib_logfile1
drwxr-x--- 2 netdata netdata 4096 mar 26 11:36 '#innodb_temp'
drwxr-x--- 2 netdata netdata 4096 mar 26 11:30 MLOPS
drwxr-x--- 2 netdata netdata 4096 mar 26 11:19 mysql
-rw-r----- 1 netdata netdata 31457280 mar 26 11:30 mysql.ibd
drwxr-x--- 2 netdata netdata 4096 mar 26 11:19 performance_schema
-rw------- 1 netdata netdata 1680 mar 26 11:19 private_key.pem
-rw-r--r-- 1 netdata netdata 452 mar 26 11:19 public_key.pem
-rw-r--r-- 1 netdata netdata 1112 mar 26 11:19 server-cert.pem
-rw------- 1 netdata netdata 1680 mar 26 11:19 server-key.pem
drwxr-x--- 2 netdata netdata 4096 mar 26 11:19 sys
-rw-r----- 1 netdata netdata 16777216 mar 26 11:30 undo_001
-rw-r----- 1 netdata netdata 16777216 mar 26 11:21 undo_002
Desse modo, ao colocar o contêiner em execução novamente, e conectarmos ao mesmo via prompt de comando, podemos consultar as bases de dados presentes e a base MLOPS criada anteriormente, estará lá.
$ docker run --name mysql-mlops-01 -v "$(pwd)/datadir":/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mlops mysql
2022-03-26 14:40:09+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
2022-03-26 14:40:09+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-03-26 14:40:09+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
2022-03-26T14:40:10.042369Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 1
2022-03-26T14:40:11.323343Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-03-26T14:40:13.475029Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-03-26T14:40:13.594808Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2022-03-26T14:40:13.594839Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2022-03-26T14:40:13.595929Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2022-03-26T14:40:13.613367Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2022-03-26T14:40:13.613448Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
$ docker exec -it mysql-mlops-01 /bin/bash
root@2aff1c318c15:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.28 MySQL Community Server - GPL
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| MLOPS |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> quit
Bye
root@2aff1c318c15:/# exit
Removendo contêineres, imagens ou limpando todo ambiente
A medida que imagens e contêineres são criados, executados e encerrados pode ser que parte dos arquivos utilizados pelos mesmos permaneçam na máquina local e demandem uma limpeza periódica. Para consultar a lista de contêineres disponíveis em execução e/ou encerrados é possível utilizar o comando docker ps -a, conforme ilustrado abaixo:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4615bf8ce7f7 tomcat "catalina.sh run" 4 minutes ago Up 4 minutes 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp cool_heisenberg
529d2796888a python:sample "python ./script.py" 2 hours ago Exited (0) 2 hours ago interesting_wescoff
No exemplo acima observa-se que existem dois contêineres, um em execução e outro cuja execução já se encerrou a duas horas atrás.
Para remover contêineres utiliza-se o comando docker rm fornecendo como parâmetro a identificação do contêiner que se deseja remover. Entretanto, só podem ser removidos contêineres que não estejam em execução. Do contrário, primeiro o mesmo deve ser parado antes de ser removido.
Os comandos a seguir removem todos os contêineres localizados.
$ docker stop 4615bf8ce7f7
4615bf8ce7f7
$ docker rm 4615bf8ce7f7 529d2796888a
529d2796888a
Error: No such container: 4615bf8ce7f7
Observa-se que, ao tentar executar o docker rm no ID do contêiner do Tomcat foi exibida uma mensagem de erro indicando que o contêiner com ID 4615bf8ce7f7 não existe. Isso porque ao iniciarmos a execução do contêiner utilizamos o parâmetro --rm que remove automaticamente o contêiner assim que o mesmo encerra sua execução, o que foi feito com o comando docker stop.
Já as imagens podem ser consultadas e removidas de maneira similar. Para consultar a lista de imagens utilizamos o comando docker imagens docker image ls -a. Esse comando apresenta a lista de imagens que foram baixadas, incluíndo as camadas de imagem intermediárias.
$ docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 4fec572aaf81 2 hours ago 929MB
aurimrv/python sample 9862ce240bbe 2 hours ago 929MB
python sample 9862ce240bbe 2 hours ago 929MB
<none> <none> ca94e718b78b 2 hours ago 929MB
<none> <none> c311c48f19db 2 hours ago 919MB
<none> <none> ea7e1c3c6991 2 hours ago 919MB
python 3 ee2a4300ffa2 30 hours ago 919MB
python latest ee2a4300ffa2 30 hours ago 919MB
tomcat latest 97f970b9f6d1 5 days ago 680MB
Para remover uma imagem utiliza-se o comando docker rmi seguido do ID das imagens desejadas.Por exemplo, o comando abaixo remove a imagem do Tomcat com ID 97f970b9f6d1.
Uma opção mais drástica e que permite uma limpeza de todo o sistema seria a execução do comando docker system prune -a.
$ docker system prune -a
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all images without at least one container associated to them
- all build cache
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: aurimrv/python:sample
untagged: aurimrv/python@sha256:49a87389f8af762b96318c71942e1ccd9bd3a59203870a93a1452d65aae66972
untagged: python:sample
deleted: sha256:9862ce240bbecce01d5cb7f57a2e3307d1733397122c9905377fbe867b01a88f
deleted: sha256:4fec572aaf81180fcb0689045b281d2b570eb28e3c5064bf433441c5859235cd
deleted: sha256:a4e5524503a0dd9f7386af337b0054861dd5d4779f9ec32da75c39276eb70daf
deleted: sha256:ca94e718b78b7b0d3dc728d3ed8e31fd2ba1e90639e8185d1ab7913b5b1468af
deleted: sha256:f3a02a46be5e804985318f365035fa7edf801bec0e7edaee8f6090886e50ce0f
deleted: sha256:ea7e1c3c6991990656ef58af3807b51fab54d37d35d1ab2cc884aa57b42f8408
deleted: sha256:828d254f82a4ef46769178a9978b65e06d10694e4859a20aa0875063ce5ab4c4
deleted: sha256:c311c48f19dbf0817f480f4d208fc880b80e40a113b8f293dfcdd23eaa1d9f56
deleted: sha256:1316c4822760638f7d7b8b10a7bafcc87504eeafeb550ca63ca93ed4570f22fd
untagged: python:3
untagged: python:latest
untagged: python@sha256:6441e2f0bd2e566de0df6445cb8e7e395ea1a376dd702de908d70401d3700961
deleted: sha256:ee2a4300ffa25463a9e22ec4108dab2e2a80c1007a38c59e5a659c8157d27ca8
deleted: sha256:9b1f782d893e5e62978cd131578743d03695fcd9c671bfc53a02cec42bcd79dc
deleted: sha256:8e2f7234436e79bddbd3fe27ba4ac7ec8a28dc9ecd94736df8cc4ad707e9a6b4
deleted: sha256:e21b4a94be334967a8b4d35c725f6c84b3e841649fd2e0ebe16469493032578c
deleted: sha256:79da52d6547f4a882f3374c89f7fb1719f0a42ce7aa1ee676a1d2b74e3df7e83
deleted: sha256:49ad93c5fd7af64479d03986dffcca005e9978dbae23b0f1af00c4a038891fe6
deleted: sha256:3ba522f21511dd7dc3df1b12d4d74751d35ede46e2a978a2437f5836665746bf
deleted: sha256:a8db7d07f7124d9886940f6d6404b6f7f4ec7f094822f40456670c05796588ca
deleted: sha256:c43bfc7bb5e729f0fb22644eacf0137c53665c5b8758ed35cf90351e29102658
deleted: sha256:c9a63110150bce5ba04ee231fc765e35acb9e6a03d3ec68ae1215883278b03dd
Total reclaimed space: 929MB
Mais informações sobre remoção de contêineres, imagens e limpeza do sistema podem ser obtidas no artigo de Anderson (2020).