<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thierry</title>
    <description>The latest articles on DEV Community by Thierry (@0xthierry).</description>
    <link>https://dev.to/0xthierry</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F174971%2F24244228-b931-46dc-a4fa-28d4c586c2be.jpeg</url>
      <title>DEV Community: Thierry</title>
      <link>https://dev.to/0xthierry</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0xthierry"/>
    <language>en</language>
    <item>
      <title>Integração do NodeJS com a REST API do Docker #1 - Modulo de interação com o Docker</title>
      <dc:creator>Thierry</dc:creator>
      <pubDate>Sat, 02 May 2020 17:05:28 +0000</pubDate>
      <link>https://dev.to/thierrysantos/integracao-do-nodejs-com-a-rest-api-do-docker-1-modulo-de-interacao-com-o-docker-ipn</link>
      <guid>https://dev.to/thierrysantos/integracao-do-nodejs-com-a-rest-api-do-docker-1-modulo-de-interacao-com-o-docker-ipn</guid>
      <description>&lt;p&gt;Essa semana decidi me aprofundar e conhecer mais sobre o funcionamento e a API Docker e resolvi criar um executor de código. Nesse post iremos iniciar o desenvolvimento de uma API que irá receber um repositorio git(mas não necessáriamente somente git) e iremos executar o código desse repositório de forma isolada em um container.&lt;/p&gt;

&lt;p&gt;Para prosseguir com esse tutorial você precisar ter o &lt;a href="https://nodejs.org/en/download/"&gt;NodeJS&lt;/a&gt; e &lt;a href="https://docs.docker.com/get-docker/"&gt;Docker&lt;/a&gt; instalado.&lt;/p&gt;

&lt;p&gt;Você precisar habilitar que o Docker receba &lt;a href="https://docs.docker.com/engine/install/linux-postinstall/#configuring-remote-access-with-systemd-unit-file"&gt;requisições&lt;/a&gt; através da sua API.&lt;/p&gt;

&lt;p&gt;Melhorias são bem-vindas, se quiser adicione seus comentários com sugestões de melhorias ou novas funcionalidades. O projeto final pode ser acessado abaixo.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/thierrysantos"&gt;
        thierrysantos
      &lt;/a&gt; / &lt;a href="https://github.com/thierrysantos/sandbox"&gt;
        sandbox
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Code executor in sandbox 🚀
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  O que é sandbox ?
&lt;/h2&gt;

&lt;p&gt;O sandbox é um ambiente isolado que ira realizar a execução do código.&lt;/p&gt;

&lt;p&gt;Dentre as diversas aplicabilidades irei citar algumas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aplicações que precisam executar um código não confiavel&lt;/li&gt;
&lt;li&gt;Aplicações que precisam limitar recursos como memória, cpu...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com a melhoria do projeto irei desenvolver algumas das aplicabilidades citada acima e irei registrar o desenvolvimento em outros post's.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup inicial
&lt;/h2&gt;

&lt;p&gt;Nesse passo iremos instalar as dependencias do projeto e configurar o compilador do typescript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;sandbox-tutorial
&lt;span class="nb"&gt;cd &lt;/span&gt;sandbox-tutorial
&lt;span class="c"&gt;# Diretório que ficará o código&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;src
&lt;span class="c"&gt;# Iniciando o projeto&lt;/span&gt;
yarn init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="c"&gt;# ou&lt;/span&gt;
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Configurando o compilador do Typescript
&lt;/h3&gt;

&lt;p&gt;Iremos utilizar esse comando a baixo para iniciarmos nosso projeto Typescript.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsc &lt;span class="nt"&gt;--init&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ele vai gerar um arquivo com nome tsconfig.json, nesse arquivo iremos modificar o rootDir e outDir do compilador&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rootDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src"&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Instalando as dependencias
&lt;/h3&gt;

&lt;p&gt;Iremos instalar as seguintes dependencias:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/express"&gt;express&lt;/a&gt; - Para criação da API&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/fs-extra"&gt;fs-extra&lt;/a&gt; - Para manipulação de arquivos&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/nodegit"&gt;nodegit&lt;/a&gt; - Para acesso a repositórios git&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/handlebars"&gt;handlebars&lt;/a&gt; - Para criação de dockerfile&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/uuid"&gt;uuid&lt;/a&gt; - Para geração de ID's&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/axios"&gt;axios&lt;/a&gt; - Para fazer requisições à API REST do Docker&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/yup"&gt;yup&lt;/a&gt; - Para criar validações
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add express fs-extra nodegit handlebars uuid axios yup
&lt;span class="c"&gt;# ou &lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;express fs-extra nodegit handlebars uuid axios yup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;E seus tipos&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @types/express @types/fs-extra @types/nodegit @types/handlebars @types/uuid @types/axios @types/yup &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;span class="c"&gt;# ou &lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @types/express @types/fs-extra @types/nodegit @types/handlebars @types/uuid @types/axios @types/yup &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Agora iremos instalar as dependencias de desenvolvimento:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/nodemon"&gt;nodemon&lt;/a&gt; - Para fazer reiniciar a aplicação ao atualizarmos o código&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/typescript"&gt;typescript&lt;/a&gt; - Para compilar nosso código Typescript para Javascript&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/concurrently"&gt;concurrently&lt;/a&gt; - Para executarmos comandos concorrentes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/dotenv"&gt;dotenv&lt;/a&gt; - Para carregar nossas variáveis de ambiente
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add nodemon typescript concurrently dotenv &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;span class="c"&gt;# ou &lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;nodemon typescript concurrently dotenv &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No package.json iremos adicionar um script para a execução da aplicação:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"concurrently &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;tsc -w&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;nodemon dist/index.js&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Interação com o Docker
&lt;/h2&gt;

&lt;p&gt;O módulo de interação com o Docker vai ser reposável pela criação e gerencimento dos containers e imagens.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;src
&lt;span class="nb"&gt;mkdir &lt;/span&gt;docker
&lt;span class="c"&gt;# Iremos criar dois arquivos&lt;/span&gt;
&lt;span class="c"&gt;# Camada de interação com o Docker&lt;/span&gt;
&lt;span class="nb"&gt;touch &lt;/span&gt;docker/docker.repository.ts
&lt;span class="c"&gt;# Camada com as regras de negócios&lt;/span&gt;
&lt;span class="nb"&gt;touch &lt;/span&gt;docker/docker.service.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No docker.repository iremos mapear os seguintes endpoints(Você pode encontrar os enpoints disponívels na &lt;a href="https://docs.docker.com/engine/api/v1.40/"&gt;documentação&lt;/a&gt; do Docker): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/engine/api/v1.40/#tag/Container"&gt;/containers&lt;/a&gt; - Gerenciamento dos containers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/engine/api/v1.40/#operation/ImageBuild"&gt;/build&lt;/a&gt; - Build de uma imagem&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/engine/api/v1.40/#operation/ImagePrune"&gt;/images/prune&lt;/a&gt; - Remover imagens não utilizadas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Iremos criar uma pasta utils com um arquivo chamado axios e iremos configurar a baseURL:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir utils
touch utils/axios.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;E iremos adicionar o &lt;a href="https://docs.docker.com/engine/install/linux-postinstall/#configuring-remote-access-with-systemd-unit-file"&gt;endereço&lt;/a&gt; da api do Docker(No meu caso é esse abaixo, mas você deve colocar o endereço que você configurou no &lt;strong&gt;docker.service&lt;/strong&gt;):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:5555/v1.40&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;E nosso &lt;strong&gt;docker.repository&lt;/strong&gt; ficará assim:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils/axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IContainerConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./interfaces&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DockerRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;createContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IContainerConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/containers/create`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;getOneContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/containers/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/json`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;deleteContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;removeVolumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;force&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/containers/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;removeVolumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;force&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;startContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/containers/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/start`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;buildImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;dockerfileContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReadStream&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/build&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dockerfileContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/x-tar"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;pruneImage&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/images/prune`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Agora iremos criar um arquivo que conterá algumas interfaces para tiparmos algumas entidades do Docker:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;docker/interfaces.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IContainerHostConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;CpuShares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;Memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;AutoRemove&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;Mounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bind&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;volume&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tmpfs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;npipe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;ReadOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IContainerConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;ExposedPorts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;Tty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;OpenStdin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;StdinOnce&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;Cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;Volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;WorkingDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;Entrypoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;HostConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IContainerHostConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IContainer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;Created&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;Running&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;Paused&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;StartedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;FinishedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nl"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IContainerConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;E por fim o &lt;strong&gt;docker.service&lt;/strong&gt; que vai disponibilizar todo o gerencimento dos containers para os demais módulos da aplicação:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IContainerConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./interfaces&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DockerRepository&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./docker.repository&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DockerService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;dockerRepository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DockerRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;createContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IContainerConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;containerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dockerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;getOneContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dockerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOneContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;deleteContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dockerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deleteContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;startContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dockerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;buildImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;dockerfileContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReadStream&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dockerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buildImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dockerfileContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;pruneImage&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dockerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pruneImage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Com isso finalizamos a interação com o Docker, nos próximos dias iremos desenvolver as outras camadas.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/thierrysantos"&gt;
        thierrysantos
      &lt;/a&gt; / &lt;a href="https://github.com/thierrysantos/sandbox"&gt;
        sandbox
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Code executor in sandbox 🚀
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Sandbox&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Code executor in sandbox&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
Summary 📝
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#Motivation"&gt;Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#Architecture"&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#Prerequisites"&gt;Prerequisites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#Installing"&gt;Installing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#proof-of-concepts"&gt;Proof of concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#next-steps"&gt;Next steps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#built-with"&gt;Built With&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#Contributing"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#License"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Motivation 💝
&lt;/h2&gt;
&lt;p&gt;The goal of this project is to permit execute code from a determined source(actualy only git pr's are open) and limit time of execution, cpu consumption and memory consumption.&lt;/p&gt;
&lt;h2&gt;
Architecture 🔨
&lt;/h2&gt;
&lt;p&gt;It is the initial architecture and we are basically doing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Downloading source code&lt;/li&gt;
&lt;li&gt;Creating a image&lt;/li&gt;
&lt;li&gt;Creating a container&lt;/li&gt;
&lt;li&gt;Starting a container&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/sandbox/master/#next"&gt;Here&lt;/a&gt; you can see the next steps of this project and possible modifications in architecture.&lt;/p&gt;
&lt;p&gt;
&lt;a rel="noopener noreferrer" href="https://camo.githubusercontent.com/0c31f78744d55e2bace4f913bd54102fb7a7f93baf9263533770029b5d206fef/68747470733a2f2f692e6962622e636f2f78474d577737582f696e697469616c6172636869746563747572652e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/0c31f78744d55e2bace4f913bd54102fb7a7f93baf9263533770029b5d206fef/68747470733a2f2f692e6962622e636f2f78474d577737582f696e697469616c6172636869746563747572652e706e67" alt="Application architecture"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;
Getting Started 💻
&lt;/h2&gt;
&lt;p&gt;These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.&lt;/p&gt;
&lt;h3&gt;
Prerequisites&lt;/h3&gt;
&lt;p&gt;You need to have &lt;a href="https://docs.docker.com/get-docker/" rel="nofollow"&gt;Docker&lt;/a&gt; and &lt;a href="https://nodejs.org/en/download/" rel="nofollow"&gt;NodeJS&lt;/a&gt; already installed to follow the nexts steps.&lt;/p&gt;
&lt;p&gt;Your Docker must be able to receive requests. &lt;a href="https://docs.docker.com/engine/install/linux-postinstall/#configuring-remote-access-with-systemd-unit-file" rel="nofollow"&gt;Here&lt;/a&gt; you can see how to enable it.&lt;/p&gt;
&lt;h3&gt;
Installing&lt;/h3&gt;
&lt;p&gt;A step by…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/thierrysantos/sandbox"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>docker</category>
      <category>typescript</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Desenvolvendo um bot para o telegram: Setup inicial</title>
      <dc:creator>Thierry</dc:creator>
      <pubDate>Sat, 25 Jan 2020 23:03:13 +0000</pubDate>
      <link>https://dev.to/thierrysantos/desenvolvendo-um-bot-para-o-telegram-setup-inicial-40mk</link>
      <guid>https://dev.to/thierrysantos/desenvolvendo-um-bot-para-o-telegram-setup-inicial-40mk</guid>
      <description>&lt;p&gt;Hoje iremos iniciar o desenvolvimento de um bot para o Telegram, a ideia desse projeto é que o nosso bot realize a conversão de um texto para áudio e um áudio para texto. Isso pode ser útil nos momentos que não podemos ouvir um áudio(então iremos converter para texto) ou nos momentos que não conseguimos ler um texto(então iremos converter para áudio).&lt;/p&gt;

&lt;p&gt;Esse projeto será um série de posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Telegram
&lt;/h2&gt;

&lt;p&gt;O Telegram é um serviço de mensagens instantâneas(similar ao WhatsApp), ele pussui uma API (Application Programming Interface) que possibilita que você utilize diversos serviços, mas o que nos interessa é parte dos bots.&lt;/p&gt;

&lt;p&gt;Você pode criar bots que serão executados dentro do telegram, e os usuários poderão interagir com eles, você pode criar diversos tipos de serviços e monetizar eles.&lt;/p&gt;

&lt;p&gt;Nesse &lt;a href="https://botanalytics.co/blog/2017/06/19/make-chat-better-with-20-best-telegram-bots/"&gt;post&lt;/a&gt; tem uma lista de bots mais utilizados.&lt;/p&gt;

&lt;p&gt;Obs: Para prosseguir nesse tutorial é necessário ter uma conta no &lt;a href="https://telegram.org/"&gt;Telegram&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  GCP
&lt;/h2&gt;

&lt;p&gt;Nesse projeto iremos utilizar o GCP(Google Cloud Platform) que é uma suíte de computação em nuvem oferecida pelo Google. Para ser mais específico iremos utilizar os seguintes serviços:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text to Speech&lt;/strong&gt; que realiza a conversão de texto para áudio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech to Text&lt;/strong&gt; que realiza conversão de áudio para texto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Obs: Para prosseguir nesse tutorial é necessário ter uma conta no &lt;a href="https://cloud.google.com/"&gt;GCP&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando o bot no telegram
&lt;/h2&gt;

&lt;p&gt;Para criarmos um bot precisaremos da ajuda do BotFather(Ele é o pai dos bots e é a partir dele que criamos nosso bot), iremos na barra de busca e pesquisaremos por &lt;em&gt;BotFather&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_rJBnJ2a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/search-telegram-bot_llxjar.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_rJBnJ2a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/search-telegram-bot_llxjar.jpg" alt="Procurando pelo BotFather"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao clicar nele iremos clicar no botão de &lt;strong&gt;start&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--woRRvcKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/start-telegram-bot_litumu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--woRRvcKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/start-telegram-bot_litumu.jpg" alt="Tela inicial do BotFather"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E ele vai exibir uma série de comandos que podemos utilizar, no nosso caso iremos utilizar o comando &lt;strong&gt;/newbot&lt;/strong&gt;, esse comando é utilizado para a criação de um novo bot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_vsM_sM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/see-commands_utqlxe.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_vsM_sM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/see-commands_utqlxe.jpg" alt="Lista de comandos BotFather"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois que enviarmos esse comando ele vai pedir algumas informações do seu bot como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nome do bot&lt;/li&gt;
&lt;li&gt;Username(que deve finalizar com a palavra bot)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bukz2zS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/name-and-username_nw711a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bukz2zS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/name-and-username_nw711a.jpg" alt="Configurando nome e username"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E no final ele irá gerar um token, guarde esse token pois iremos utilizar para o desenvolvimento do bot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jGw4JrpS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/token_hmudib.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jGw4JrpS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989511/token_hmudib.jpg" alt="Token de acesso do bot telegram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Concluindo esses passos já temos o necessário para desenvolvermos um bot para o telegram.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um projeto no GCP
&lt;/h2&gt;

&lt;p&gt;Para criar um novo projeto iremos clicar em &lt;strong&gt;My First Project&lt;/strong&gt;(Pode ser que esteja com outro nome para você, mas é no mesmo local) na barra superior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y866gmtf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/click-my-first-project_w1ojha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y866gmtf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/click-my-first-project_w1ojha.png" alt="Novo projeto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos clicar em &lt;strong&gt;novo projeto&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---jo7rNNv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/new-project_pv9n3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---jo7rNNv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/new-project_pv9n3t.png" alt="Criando um novo projeto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos adicionar o nome do projeto e então clicar em &lt;strong&gt;criar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RhOFV3zI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/creating-project_t5l4iw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RhOFV3zI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/creating-project_t5l4iw.png" alt="Adicionando o nome do projeto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com o projeto criado agora precisamos ativar os serviços que iremos utilizar, no nosso caso será o &lt;a href="https://console.cloud.google.com/apis/library/speech.googleapis.com"&gt;Speech To Text&lt;/a&gt; e &lt;a href="https://console.cloud.google.com/apis/library/texttospeech.googleapis.com"&gt;Text to Speech&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uHMi-Zyk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/active-service_mhbkci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uHMi-Zyk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/active-service_mhbkci.png" alt="Ativando o serviço"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com os serviços ativos, iremos criar uma credencial para consumirmos essas API's. No menu lateral iremos em &lt;strong&gt;API's e serviços&lt;/strong&gt; na opção &lt;strong&gt;credenciais&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kqfKv-zR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/credentials-options_fssj6u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kqfKv-zR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/credentials-options_fssj6u.png" alt="Menu lateral"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos clicar em &lt;strong&gt;Criar credenciais&lt;/strong&gt; e na opção &lt;strong&gt;Conta de serviço&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nUAUeYKI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/service-account_p23hud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nUAUeYKI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989708/service-account_p23hud.png" alt="Menu lateral com as opções de credenciais"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos preencher as opções necessárias e clicar em criar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wL_TM5HU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/create-account-service_dsej2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wL_TM5HU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/create-account-service_dsej2t.png" alt="Preenchendo informações para criar as credenciais"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adicionaremos o tipo de permissão, iremos clicar em &lt;strong&gt;Projeto&lt;/strong&gt; e depois na opção &lt;strong&gt;Proprietário&lt;/strong&gt;, e clicar em &lt;strong&gt;Continuar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gc5YR1Dd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/acess-proprie_vtvfty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gc5YR1Dd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/acess-proprie_vtvfty.png" alt="Adicionando o tipo de credencial"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos clicar em &lt;strong&gt;criar chave&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LIwVZax3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/concluir_aafq8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LIwVZax3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/concluir_aafq8a.png" alt="Clicando no botão para criar chave"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iremos escolher a opção &lt;strong&gt;JSON&lt;/strong&gt;(Guarde esse arquivo e não compartilhe, pois ele dará acesso aos recursos do seu projeto), então clicaremos em &lt;strong&gt;criar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qBtnBxiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/create-json-token_tjzv1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qBtnBxiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/create-json-token_tjzv1m.png" alt="Escolhendo o tipo de credencial"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E depois clicaremos no botão &lt;strong&gt;concluir&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LIwVZax3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/concluir_aafq8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LIwVZax3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/dir3du3ky/image/upload/v1579989707/concluir_aafq8a.png" alt="Concluindo a criação de credencial"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essas são as configurações iniciais necessárias para iniciar o projeto, nos próximos post's iremos desenvolver a solução.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/thierrysantos"&gt;
        thierrysantos
      &lt;/a&gt; / &lt;a href="https://github.com/thierrysantos/text-speech-telegram-bot"&gt;
        text-speech-telegram-bot
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Bot that convert Text to Speech and Speech to Text ⭐🚀
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Telegram Bot TextSpeech&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Telegram bot that convert Text to Speech and Speech to Text&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
Summary 📝
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/#Motivation"&gt;Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/#Prerequisites"&gt;Prerequisites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/#Installing"&gt;Installing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/#Demo"&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/#built-with"&gt;Built With&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/#Contributing"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/#License"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Motivation 💝
&lt;/h2&gt;
&lt;p&gt;Convert a text to audio to listen when you can't read or convert an audio to text when you can't listen.&lt;/p&gt;
&lt;h2&gt;
Getting Started 💻
&lt;/h2&gt;
&lt;p&gt;These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.&lt;/p&gt;
&lt;h3&gt;
Prerequisites&lt;/h3&gt;
&lt;p&gt;You need to have NodeJS already installed.&lt;/p&gt;
&lt;h3&gt;
Installing&lt;/h3&gt;
&lt;p&gt;A step by step series of examples that tell you how to get a development env running&lt;/p&gt;
&lt;p&gt;Cloning project&lt;/p&gt;
&lt;div class="highlight highlight-source-shell js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/thierrysantos/text-speech-telegram-bot.git&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Installing project depencies&lt;/p&gt;
&lt;div class="highlight highlight-source-shell js-code-highlight"&gt;
&lt;pre&gt;yarn
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
npm install&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Start project&lt;/p&gt;
&lt;div class="highlight highlight-source-shell js-code-highlight"&gt;
&lt;pre&gt;yarn dev
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
npm run dev
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
docker-compose up&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
Demo 📋
&lt;/h2&gt;
&lt;p&gt;
&lt;a rel="noopener noreferrer" href="https://camo.githubusercontent.com/c13f1c70aaf35618f8e4b231c0f2f5c615bc5a6ff8a2ac95d466b8c3fae41864/68747470733a2f2f692e6962622e636f2f306e33704d6b372f57686174732d4170702d496d6167652d323032302d30362d31352d61742d32312d33322d31362e6a7067"&gt;&lt;img src="https://camo.githubusercontent.com/c13f1c70aaf35618f8e4b231c0f2f5c615bc5a6ff8a2ac95d466b8c3fae41864/68747470733a2f2f692e6962622e636f2f306e33704d6b372f57686174732d4170702d496d6167652d323032302d30362d31352d61742d32312d33322d31362e6a7067" alt="Bot demo"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
Built With 💎
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/" rel="nofollow"&gt;Typescript&lt;/a&gt; - TypeScript is a typed superset of JavaScript that compiles to plain JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
Contributing 💖
&lt;/h2&gt;

&lt;p&gt;Please read &lt;a href="https://raw.githubusercontent.com/thierrysantos/text-speech-telegram-bot/master/CONTRIBUTING.md"&gt;CONTRIBUTING.md&lt;/a&gt; for details…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/thierrysantos/text-speech-telegram-bot"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>javascript</category>
      <category>gcp</category>
      <category>tutorial</category>
      <category>bot</category>
    </item>
  </channel>
</rss>
