Manter seus dadosPersist your data

Caso você não tenha notado, a lista de tarefas pendentes será apagada todas as vezes que você iniciar o contêiner.In case you didn't notice, the todo list is being wiped clean every single time you launch the container. Por que é isso?Why is this? Vamos nos aprofundar em como o contêiner está funcionando.Let's dive into how the container is working.

O sistema de arquivos do contêinerThe container's filesystem

Quando um contêiner é executado, ele usa as várias camadas de uma imagem para seu sistema de arquivos.When a container runs, it uses the various layers from an image for its filesystem. Cada contêiner também obtém seu próprio "espaço transitório" para criar, atualizar ou remover arquivos.Each container also gets its own "scratch space" to create, update, or remove files. As alterações não serão vistas em outro contêiner, mesmo se estiverem usando a mesma imagem.Any changes won't be seen in another container, even if they are using the same image.

Veja isso na práticaSee this in practice

Para ver isso em ação, você vai iniciar dois contêineres e criar um arquivo em cada um.To see this in action, you're going to start two containers and create a file in each. O que você verá é que os arquivos criados em um contêiner não estão disponíveis em outro.What you'll see is that the files created in one container aren't available in another.

  1. Inicie um ubuntu contêiner que criará um arquivo chamado /data.txt com um número aleatório entre 1 e 10000.Start a ubuntu container that will create a file named /data.txt with a random number between 1 and 10000.

    docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
    

    Caso esteja curioso sobre o comando, você está iniciando um shell bash e invocando dois comandos (por que ele tem o && ).In case you're curious about the command, you're starting a bash shell and invoking two commands (why it has the &&). A primeira parte escolhe um único número aleatório e grava-o em /data.txt .The first portion picks a single random number and writes it to /data.txt. O segundo comando está simplesmente assistindo a um arquivo para manter o contêiner em execução.The second command is simply watching a file to keep the container running.

  2. Validar você pode ver a saída usando exec para entrar no contêiner.Validate you can see the output by using exec to get into the container. Para fazer isso, abra a extensão VS Code e clique na opção anexar Shell .To do so, open the VS Code extension and on click on the Attach Shell option. Isso usará exec para abrir um shell no contêiner dentro do vs Code terminal.This will use exec to open a shell in the container within the VS Code terminal.

    VS Code abrir a CLI no contêiner do Ubuntu

    Você verá um terminal que está executando um shell no contêiner do Ubuntu.You will see a terminal that is running a shell in the Ubuntu container. Execute o comando a seguir para ver o conteúdo do /data.txt arquivo.Run the following command to see the content of the /data.txt file. Feche este terminal mais tarde.Close this terminal afterwards again.

    cat /data.txt
    

    Se você preferir a linha de comando, poderá usar o docker exec comando para fazer o mesmo.If you prefer the command line, you can use the docker exec command to do the same. Você precisa obter a ID do contêiner (use docker ps para obtê-lo) e obter o conteúdo com o comando a seguir.You need to get the container's ID (use docker ps to get it) and get the content with the following command.

    docker exec <container-id> cat /data.txt
    

    Você deve ver um número aleatório!You should see a random number!

  3. Agora, inicie outro ubuntu contêiner (a mesma imagem) e você verá que não tem o mesmo arquivo.Now, start another ubuntu container (the same image) and you'll see you don't have the same file.

    docker run -it ubuntu ls /
    

    E olhe!And look! Não há nenhum data.txt arquivo lá!There's no data.txt file there! Isso ocorre porque ele foi gravado no espaço transitório apenas para o primeiro contêiner.That's because it was written to the scratch space for only the first container.

  4. Vá em frente e remova o primeiro contêiner usando o docker rm -f comando.Go ahead and remove the first container using the docker rm -f command.

Volumes de contêinerContainer volumes

Com o experimento anterior, você viu que cada contêiner inicia na definição da imagem sempre que ele é iniciado.With the previous experiment, you saw that each container starts from the image definition each time it starts. Embora os contêineres possam criar, atualizar e excluir arquivos, essas alterações são perdidas quando o contêiner é removido e todas as alterações são isoladas nesse contêiner.While containers can create, update, and delete files, those changes are lost when the container is removed and all changes are isolated to that container. Com os volumes, você pode alterar tudo isso.With volumes, you can change all of this.

Os volumes fornecem a capacidade de conectar caminhos específicos do sistema de arquivos do contêiner de volta ao computador host.Volumes provide the ability to connect specific filesystem paths of the container back to the host machine. Se um diretório no contêiner for montado, as alterações nesse diretório também serão vistas no computador host.If a directory in the container is mounted, changes in that directory are also seen on the host machine. Se você montar esse mesmo diretório em reinicializações de contêiner, verá os mesmos arquivos.If you mount that same directory across container restarts, you'd see the same files.

Há dois tipos principais de volumes.There are two main types of volumes. você eventualmente usará ambos, mas começará com volumes nomeados.you will eventually use both, but you will start with named volumes.

Manter seus dados de todoPersist your Todo data

Por padrão, o aplicativo todo armazena seus dados em um banco de dados SQLite em /etc/todos/todo.db .By default, the todo app stores its data in a SQLite Database at /etc/todos/todo.db. Se você não estiver familiarizado com o SQLite, nenhuma preocupação!If you're not familiar with SQLite, no worries! Ele é simplesmente um banco de dados relacional no qual todos eles são armazenados em um único arquivo.It's simply a relational database in which all of the data is stored in a single file. Embora esse não seja o melhor para aplicativos em grande escala, ele funciona para demonstrações pequenas.While this isn't the best for large-scale applications, it works for small demos. Falaremos sobre como mudar isso para um mecanismo de banco de dados real mais tarde.We'll talk about switching this to an actual database engine later.

Com o banco de dados sendo um único arquivo, se você puder persistir esse arquivo no host e disponibilizá-lo para o próximo contêiner, ele deverá ser capaz de selecionar onde o último parou.With the database being a single file, if you can persist that file on the host and make it available to the next container, it should be able to pick up where the last one left off. Ao criar um volume e anexá-lo (geralmente chamado de "montagem") no diretório em que os dados são armazenados, você pode manter os dados.By creating a volume and attaching (often called "mounting") it to the directory the data is stored in, you can persist the data. Como o contêiner grava no todo.db arquivo, ele é mantido para o host no volume.As the container writes to the todo.db file, it's persisted to the host in the volume.

Conforme mencionado, você vai usar um volume nomeado.As mentioned, you're going to use a named volume. Imagine um volume nomeado como simplesmente um Bucket de dados.Think of a named volume as simply a bucket of data. O Docker mantém o local físico no disco e você só precisa se lembrar do nome do volume.Docker maintains the physical location on the disk and you only need to remember the name of the volume. Toda vez que você usar o volume, o Docker garantirá que os dados corretos sejam fornecidos.Every time you use the volume, Docker will make sure the correct data is provided.

  1. Crie um volume usando o docker volume create comando.Create a volume by using the docker volume create command.

    docker volume create todo-db
    
  2. Pare o contêiner de aplicativo todo novamente no modo de exibição do Docker (ou com docker rm -f <id> ), pois ele ainda está em execução sem usar o volume persistente.Stop the todo app container once again in the Docker view (or with docker rm -f <id>), as it is still running without using the persistent volume.

  3. Inicie o contêiner de aplicativo todo, mas adicione o -v sinalizador para especificar uma montagem de volume.Start the todo app container, but add the -v flag to specify a volume mount. Você usará o volume nomeado e o montará para /etc/todos o, que capturará todos os arquivos criados no caminho.you will use the named volume and mount it to /etc/todos, which will capture all files created at the path.

    docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
    
  4. Depois que o contêiner for iniciado, abra o aplicativo e adicione alguns itens à sua lista de tarefas pendentes.Once the container starts up, open the app and add a few items to your todo list.

    Itens adicionados à lista de tarefas pendentes

  5. Remova o contêiner do aplicativo de tarefas pendentes.Remove the container for the todo app. Use a exibição do Docker ou docker ps para obter a ID e, em seguida, docker rm -f <id> removê-la.Use the Docker view or docker ps to get the ID and then docker rm -f <id> to remove it.

  6. Inicie um novo contêiner usando o mesmo comando acima.Start a new container using the same command from above.

  7. Abra o aplicativo.Open the app. Você deve ver seus itens ainda em sua lista!You should see your items still in your list!

  8. Vá em frente e remova o contêiner quando terminar de verificar sua lista.Go ahead and remove the container when you're done checking out your list.

Alegria!Hooray! Agora você aprendeu a manter os dados!You've now learned how to persist data!

Dica

Embora os volumes nomeados e as montagens de ligação (que falaremos em um minuto) sejam os dois tipos principais de volumes com suporte em uma instalação padrão do mecanismo do Docker, há muitos plug-ins de driver de volume disponíveis para dar suporte a NFS, SFTP, NetApp e muito mais!While named volumes and bind mounts (which we'll talk about in a minute) are the two main types of volumes supported by a default Docker engine installation, there are many volume driver plugins available to support NFS, SFTP, NetApp, and more! Isso será especialmente importante quando você começar a executar contêineres em vários hosts em um ambiente clusterizado com Swarm, kubernetes e assim por diante.This will be especially important once you start running containers on multiple hosts in a clustered environment with Swarm, Kubernetes, and so on.

Aprofunde-se no seu volumeDive into your volume

Muitas pessoas freqüentemente perguntam "onde o Docker realmente armazena meus dados quando uso um volume nomeado?"A lot of people frequently ask "Where is Docker actually storing my data when I use a named volume?" Se você quiser saber, poderá usar o docker volume inspect comando.If you want to know, you can use the docker volume inspect command.

docker volume inspect todo-db
[
    {
        "CreatedAt": "2019-09-26T02:18:36Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": {},
        "Scope": "local"
    }
]

O Mountpoint é o local real no disco onde os dados são armazenados.The Mountpoint is the actual location on the disk where the data is stored. Observe que na maioria das máquinas, você precisará ter acesso de raiz para acessar esse diretório do host.Note that on most machines, you'll need to have root access to access this directory from the host. Mas é aí que está!But, that's where it is!

Observação

Acessando dados de volume diretamente no Docker desktop Durante a execução no Docker desktop, os comandos do Docker são realmente executados dentro de uma VM pequena em seu computador.Accessing Volume data directly on Docker Desktop While running in Docker Desktop, the Docker commands are actually running inside a small VM on your machine. Se você quisesse examinar o conteúdo real do diretório mountpoint , precisaria primeiro entrar dentro da VM.If you wanted to look at the actual contents of the Mountpoint directory, you would need to first get inside of the VM. No WSL 2, ele está dentro de um WSL 2 distribuição e pode ser acessado por meio do explorador de arquivos.In WSL 2, this is inside a WSL 2 distro and can be accessed through the File Explorer.

RecapitulaçãoRecap

Neste ponto, você tem um aplicativo funcional que pode sobreviver a reinicializações!At this point, you have a functioning application that can survive restarts! Você pode mostrá-lo para seus investidores e esperar que eles possam pegar sua visão!You can show it off to your investors and hope they can catch your vision!

No entanto, você viu anteriormente que a recriação de imagens para cada alteração leva bastante tempo.However, you saw earlier that rebuilding images for every change takes quite a bit of time. Precisa ser uma maneira melhor de fazer alterações, certo?There's got to be a better way to make changes, right? Com montagens de associação (que mencionamos anteriormente), há uma maneira melhor!With bind mounts (which we hinted at earlier), there is a better way! Vamos dar uma olhada agora!Let's take a look at that now!

Próximas etapasNext steps

Continue com o tutorial!Continue with the tutorial!