{"id":571289,"date":"2025-05-28T04:03:06","date_gmt":"2025-05-28T03:03:06","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=571289"},"modified":"2025-09-15T09:30:27","modified_gmt":"2025-09-15T08:30:27","slug":"implantacao-de-aplicativos-do-django-no-kubernetes","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/pt-br\/pycharm\/2025\/05\/implantacao-de-aplicativos-do-django-no-kubernetes\/","title":{"rendered":"Implanta\u00e7\u00e3o de aplicativos do Django no Kubernetes"},"content":{"rendered":"<p>Por ser uma plataforma de c\u00f3digo aberto de orquestra\u00e7\u00e3o de containers que automatiza a implanta\u00e7\u00e3o, o escalamento e o balanceamento de carga, o Kubernetes oferece resili\u00eancia e flexibilidade sem igual no gerenciamento dos seus aplicativos do Django<strong>. <\/strong><\/p>\n<p>Quer voc\u00ea esteja iniciando um projeto de pequena escala ou gerenciando uma aplica\u00e7\u00e3o complexa, o Kubernetes fornece um ambiente robusto para incrementar o seu aplicativo do Django, garantindo que ele esteja pronto para atender \u00e0s demandas do desenvolvimento moderno para a Web.<\/p>\n<p>Ao automatizar a implanta\u00e7\u00e3o, o escalamento e a opera\u00e7\u00e3o de aplicativos em containers, o <a href=\"https:\/\/kubernetes.io\/\" target=\"_blank\" rel=\"noopener\">Kubernetes<\/a> (ou K8s) oferece in\u00fameros benef\u00edcios para as organiza\u00e7\u00f5es no ritmo acelerado do setor de tecnologia.<\/p>\n<p>N\u00e3o importa se voc\u00ea \u00e9 um desenvolvedor em Django buscando aumentar as suas habilidades de implanta\u00e7\u00e3o ou um entusiasta do Kubernetes pronto para explorar a integra\u00e7\u00e3o com o Django: este guia tem algo para todos.<\/p>\n<p><!--more--><\/p>\n<p>A introdu\u00e7\u00e3o deste tutorial explora a rela\u00e7\u00e3o simbi\u00f3tica entre o Django e o Kubernetes, permitindo que voc\u00ea coloque a sua aplica\u00e7\u00e3o Web em containers de forma transparente, distribua cargas de trabalho entre clusters e garanta alta disponibilidade.<\/p>\n<h2 class=\"wp-block-heading\">Django<\/h2>\n<p>O Django \u00e9 um framework de alto n\u00edvel para a Web em Python que \u00e9 um modelo de efici\u00eancia e simplicidade no mundo do desenvolvimento para a Web. O Django nasceu da necessidade de criar aplicativos Web que fossem r\u00e1pidos, robustos e f\u00e1ceis de manter, e tornou-se a primeira escolha de desenvolvedores e organiza\u00e7\u00f5es.<\/p>\n<p>Em sua ess\u00eancia, o Django adota a filosofia de &#8220;pilhas inclu\u00eddas&#8221; e oferece uma grande variedade de ferramentas, bibliotecas e conven\u00e7\u00f5es incorporadas, que facilitam o processo de desenvolvimento. Ele simplifica tarefas complexas, como roteamento de URLs, integra\u00e7\u00e3o com bancos de dados e autentica\u00e7\u00e3o de usu\u00e1rios, permitindo que os desenvolvedores se concentrem em criar seus aplicativos.<\/p>\n<p>Um dos benef\u00edcios mais importantes do Django \u00e9 o fato de ele seguir o princ\u00edpio &#8220;n\u00e3o se repita&#8221; (&#8220;Don&#8217;t repeat yourself&#8221;, DRY), reduzindo a redund\u00e2ncia e tornando o c\u00f3digo mais f\u00e1cil de manter. Ele tamb\u00e9m segue o padr\u00e3o de arquitetura &#8220;modelo-visualiza\u00e7\u00e3o-controlador&#8221; (MVC), tornando os aplicativos mais estruturados e f\u00e1ceis de gerenciar.<\/p>\n<p>O Django tamb\u00e9m d\u00e1 prioridade \u00e0 seguran\u00e7a, o que o torna menos sujeito a vulnerabilidades comuns na Web. Ele j\u00e1 inclui recursos como a prote\u00e7\u00e3o contra &#8220;cross-site scripting&#8221; (XSS) e &#8220;cross-site request forgery&#8221; (CSRF) desde a instala\u00e7\u00e3o. O Django oferece uma combina\u00e7\u00e3o poderosa de rapidez, simplicidade e seguran\u00e7a, e \u00e9 a escolha ideal para desenvolvedores que busquem criar aplicativos robustos e cheios de recursos para a Web, com o m\u00ednimo de esfor\u00e7o.<\/p>\n<h2 class=\"wp-block-heading\">Orquestradores de containers<\/h2>\n<p>Os orquestradores de containers s\u00e3o ferramentas essenciais para gerenciar e automatizar a implanta\u00e7\u00e3o, escalamento e opera\u00e7\u00f5es de aplicativos em containers. H\u00e1 v\u00e1rios orquestradores de containers dispon\u00edveis no mercado. Alguns dos mais populares s\u00e3o:<\/p>\n<p>1. <strong>Kubernetes<\/strong>, a principal plataforma de orquestra\u00e7\u00e3o de containers, oferece um ambiente robusto e adapt\u00e1vel para lidar com aplicativos em containers. Ele automatiza tarefas como o escalamento, o balanceamento de cargas e as verifica\u00e7\u00f5es de sa\u00fade dos containers e tem um amplo ecossistema de extens\u00f5es.<\/p>\n<p>2. <strong>Docker Swarm<\/strong> \u00e9 uma solu\u00e7\u00e3o de orquestra\u00e7\u00e3o de containers oferecida pela Docker. Ele foi projetado para ser simples de configurar e usar, e \u00e9 uma boa escolha para aplica\u00e7\u00f5es menores ou organiza\u00e7\u00f5es que j\u00e1 usam o Docker, pois ele usa a mesma interface de linha de comando e a mesma API que o Docker.<\/p>\n<p>3. <strong>OpenShift<\/strong> \u00e9 uma plataforma corporativa de Kubernetes desenvolvida pela Red Hat. Ele adiciona ao Kubernetes ferramentas operacionais e de desenvolvedor, simplificando a implanta\u00e7\u00e3o e o gerenciamento de aplicativos em containers.<\/p>\n<p>4. <strong>Nomad<\/strong>, desenvolvido pela HashiCorp, \u00e9 um orquestrador leve e amig\u00e1vel ao usu\u00e1rio, capaz de gerenciar aplicativos com e sem containers.<\/p>\n<p>5. <strong>Apache Mesos<\/strong> \u00e9 um kernel distribu\u00eddo de sistema, de c\u00f3digo aberto. J\u00e1 o DC\/OS (Data Center Operating System) \u00e9 uma plataforma de n\u00edvel corporativo criada sobre o Mesos. O DC\/OS amplia o alcance do Mesos com recursos adicionais para gerenciar e escalar aplicativos em containers.<\/p>\n<p>As equipes de software trabalham primariamente com plataformas gerenciadas oferecidas por provedores conhecidos de nuvem, como AWS, Google Cloud Platform e Azure. Esses provedores oferecem servi\u00e7os como Amazon EKS, Google GKE e Azure AKS, todos eles solu\u00e7\u00f5es gerenciadas de Kubernetes. Esses servi\u00e7os simplificam a configura\u00e7\u00e3o, expans\u00e3o e administra\u00e7\u00e3o de clusters de Kubernetes e integram-se de forma transparente com seus respectivos ambientes de nuvem, garantindo efici\u00eancia na orquestra\u00e7\u00e3o de containers e na implanta\u00e7\u00e3o de aplicativos.<\/p>\n<h2 class=\"wp-block-heading\">Como criar um aplicativo do Django no PyCharm<\/h2>\n<p>Neste tutorial, vamos come\u00e7ar gerando um aplicativo m\u00ednimo do Django. Depois, vamos coloc\u00e1-lo em um container e, na etapa final, implant\u00e1-lo em um cluster local de Kubernetes usando o Docker Desktop.<\/p>\n<p>Se voc\u00ea for novato em trabalhar com o framework Django, mas estiver ansioso para criar um aplicativo do zero com ele, leia esta <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">postagem<\/a> de blog.<\/p>\n<p>Voc\u00ea pode acessar <a href=\"https:\/\/github.com\/mukulmantosh\/django-kubernetes\" target=\"_blank\" rel=\"noopener\">aqui<\/a> o c\u00f3digo-fonte usado neste tutorial.<\/p>\n<p>Vamos come\u00e7ar criando um novo <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2023\/04\/create-a-django-app-in-pycharm\/\">aplicativo do Django no PyCharm<\/a>.<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\">\n                                                <a href=\"https:\/\/www.jetbrains.com\/pycharm\/web-development\/django\/\" class=\"btn\" target=\"\" rel=\"noopener\">Experimente o PyCharm Pro gratuitamente<\/a>\n                                                    <\/div>\n<\/p>\n<\/div>\n<p>Para criar o seu projeto, abra o PyCharm e clique em <strong>New Project<\/strong>. Se o PyCharm j\u00e1 estiver em execu\u00e7\u00e3o, selecione <strong>File | New Project<\/strong> no menu principal.<\/p>\n<p>Forne\u00e7a os dados essenciais, como o nome do projeto, o local e o tipo de interpretador, usando o <a href=\"https:\/\/docs.python.org\/3\/library\/venv.html\" target=\"_blank\" rel=\"noopener\">venv<\/a> ou um ambiente personalizado.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/1y08c3RPd7rqmf5qxcZfrWrzDAekMhwhPIWRa10ipnziCXebOqe8WsMfTXG55efz48CBi5eF_zg7clWjfrHI843CGaueY1wwvBZ0qeei_umc2hAPhLtfuEh0DdLF3NKoSW2iPGbpUCtsEzlF5NKUj0o-1.png\" width=\"624\" height=\"465\"><\/p>\n<p>Em seguida, clique em <strong>Create<\/strong>.<\/p>\n<p>O PyCharm far\u00e1 o trabalho pesado, configurando o seu projeto e criando o ambiente virtual.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/odWqcTk4mIote11wJzVTV42umN0Ffu_aSMfv9RRVQs2V9BYcL9_q6dSz-e56unGs-HkDc5GrogOvGqDWJNS3FgYOG7MFAcrXAa6U54Fca1nd9aXo8MjUye5_42sEXIb11rTKyiCAWQWPehKrBeyVMT4-1.png\" width=\"624\" height=\"351\"><\/p>\n<h3 class=\"wp-block-heading\">Gunicorn<\/h3>\n<p>Depois de criar o projeto, instale o <a href=\"https:\/\/gunicorn.org\/\" target=\"_blank\" rel=\"noopener\">Gunicorn<\/a>, um servidor de HTTP em Python para interfaces de gateways de servidores Web (WSGI). O Gunicorn \u00e9 um servidor-modelo de trabalho para a Web, usado com aplicativos de Web em Python antes do fork, e costuma ser usado em combina\u00e7\u00e3o com frameworks de Web como o Django, o Flask e outros, para implantar aplicativos de Web e disponibiliz\u00e1-los na Internet.<\/p>\n<p>A janela de ferramentas <strong>Python Packages<\/strong> \u00e9 a maneira mais r\u00e1pida e f\u00e1cil de pr\u00e9-visualizar e instalar pacotes para o interpretador Python selecionado no momento.<\/p>\n<p>Voc\u00ea pode abrir essa janela de ferramentas acionando <strong>View | Tool Windows | Python Packages<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/srzllJqDAcLfQmEuJcLcizPVMAGYJGJ4Y5YnAXyT35Q0ntHxXgZgWu0bkviI6RgnVJAyQltuEnmFqnR0nyTtdaJ3oBJc9ofrEnG0HmzsfXz-_kBMiMGb_YzPBJ_pyMtP-RWRBUBGtUihUPKW4CBQPi8-1.png\" width=\"624\" height=\"187\"><\/p>\n<h3 class=\"wp-block-heading\">Psycopg 2<\/h3>\n<p>O <a href=\"https:\/\/www.psycopg.org\/docs\/\" target=\"_blank\" rel=\"noopener\">Psycopg 2<\/a> \u00e9 uma biblioteca do Python usada para se conectar a bancos de dados PostgreSQL e interagir com eles. Ele fornece uma interface no Python para trabalhar com o PostgreSQL, um dos mais populares sistemas de c\u00f3digo aberto para o gerenciamento de bancos de dados relacionais. O Psycopg 2 permite que os desenvolvedores Python executem diversas opera\u00e7\u00f5es de banco de dados, como incluir, atualizar e recuperar dados, al\u00e9m de executar consultas em SQL e gerenciar conex\u00f5es a bancos de dados dentro de programas em Python.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1273\" height=\"455\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/image-7.png\" alt=\"\" class=\"wp-image-452825\" \/><\/figure>\n<p>Antes de instalar o <code>psycopg2<\/code>, voc\u00ea precisa instalar as depend\u00eancias em n\u00edvel de sistema, usando <code>brew install libpq<\/code> no macOS ou <code>apt-get install libpq-dev<\/code> no Linux.<\/p>\n<p>Refer\u00eancia: <a href=\"https:\/\/www.postgresql.org\/docs\/16\/libpq.html\" target=\"_blank\" rel=\"noopener\">postgresql.org\/docs\/16\/libpq.html<\/a><\/p>\n<p>O <code>libpq<\/code> \u00e9 a biblioteca de cliente do PostgreSQL. \u00c9 uma biblioteca em C que fornece os recursos necess\u00e1rios para os aplicativos-clientes se conectarem a servidores de bancos de dados PostgreSQL, interagirem com eles e gerenci\u00e1-los.\u00a0<\/p>\n<p>Depois de terminar as modifica\u00e7\u00f5es espec\u00edficas, atualize a se\u00e7\u00e3o de <code>settings.py<\/code> referente a <code>DATABASES<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/qpVWdOZBeTsiOkfJIMn4VybYiIS99u_XxR5_6yYhbLNNI3WpMUwmHTk2g7oaQ1o03GXdY7Y23TtHzNM6ht9-onbAVwvPZ06qgVoIAlpuJjddtuHWJhtr9DO3R8I4PHKCM8vBHvPut02m_k6m_vfQ2uc-1.png\" width=\"624\" height=\"220\"><\/p>\n<p>Nunca deixe de passar as suas credenciais secretas atrav\u00e9s de vari\u00e1veis de ambiente.<\/p>\n<h3 class=\"wp-block-heading\">STATIC_ROOT<\/h3>\n<p>No Django, <code>STATIC_ROOT<\/code> \u00e9 uma configura\u00e7\u00e3o usada para especificar o caminho absoluto no sistema de arquivos onde os arquivos est\u00e1ticos coletados ser\u00e3o armazenados quando voc\u00ea executar o comando de gerenciamento <code>collectstatic<\/code>. Tipicamente, os arquivos est\u00e1ticos incluem recursos de CSS, JavaScript, imagens e outros usados pelo seu aplicativo de Web. A configura\u00e7\u00e3o <code>STATIC_ROOT<\/code> \u00e9 essencial para os servidores fornecerem arquivos est\u00e1ticos em um ambiente de produ\u00e7\u00e3o.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/D-VP39aKKQITKIi2IG_T6hBWEvUCDzTaLfbrDofs-JlOHmFP51Vl2QYH6dmpufWRhgUTPoOtmyKBj155vIGL8DqWyiR79W3NdiYibTb228Yx2Tj0pwC5bPd5F6BCtbMbTvfKHJ6lDYBlmbLqv1jUmoA-1.png\" width=\"624\" height=\"323\"><\/p>\n<p>Defina uma vari\u00e1vel de ambiente para <code>STATIC_ROOT<\/code> na linha 127. Essa vari\u00e1vel apontar\u00e1 para um caminho de arquivo, que por sua vez levar\u00e1 a um volume persistente do Kubernetes. Explicarei mais tarde como fazer essa configura\u00e7\u00e3o.<\/p>\n<p>Para coletar arquivos est\u00e1ticos, execute este comando:<\/p>\n<p><code>python manage.py collectstatic<\/code><\/p>\n<p>Este comando reunir\u00e1 os arquivos est\u00e1ticos e os colocar\u00e1 no diret\u00f3rio especificado em <code>STATIC_ROOT<\/code>. Ent\u00e3o, voc\u00ea poder\u00e1 fornecer esses recursos diretamente, atrav\u00e9s de um servidor de Web NGINX ou Apache \u2014 uma abordagem mais eficiente para ambientes de produ\u00e7\u00e3o.<\/p>\n<h3 class=\"wp-block-heading\">Dockerfile<\/h3>\n<p>Um Dockerfile \u00e9 um documento simples de texto que cont\u00e9m diretivas para construir imagens do Docker.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"636\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/image-4.png\" alt=\"\" class=\"wp-image-452658\" \/><\/figure>\n<p>1. <strong><code>FROM python:3.11<\/code><\/strong>: Esta linha especifica a imagem de base da imagem do Docker, usando a imagem oficial do Python 3.11 do Docker Hub. Ser\u00e1 feito o build do aplicativo e ele ser\u00e1 executado sobre essa imagem de base, que j\u00e1 tem o Python pr\u00e9-instalado.<\/p>\n<p>2. <strong><code>ENV PYTHONUNBUFFERED 1<\/code><\/strong>: Esta linha atribui o valor <code>1<\/code> \u00e0 vari\u00e1vel de ambiente <code>PYTHONUNBUFFERED<\/code>. Costuma-se recomendar definir esta vari\u00e1vel de ambiente ao executar o Python em containers do Docker, para garantir que o Python n\u00e3o coloque a sa\u00edda em um buffer. Isso ajuda a obter logs e informa\u00e7\u00f5es de depura\u00e7\u00e3o do aplicativo em tempo real.<\/p>\n<p>3. <strong><code>WORKDIR \/app<\/code><\/strong>: Esta linha define <code>\/app<\/code> como o diret\u00f3rio de trabalho no container do Docker. Todos os comandos subsequentes ser\u00e3o executados nesse diret\u00f3rio.<\/p>\n<p>4. <strong><code>COPY . \/app<\/code><\/strong>: Esta linha copia o conte\u00fado do diret\u00f3rio atual (aquele onde est\u00e1 localizado o Dockerfile) para o diret\u00f3rio <code>\/app<\/code> dentro do container. Isso inclui o c\u00f3digo do seu aplicativo e quaisquer arquivos necess\u00e1rios \u00e0 imagem do Docker.<\/p>\n<p>5. <strong><code>RUN pip install -r requirements.txt<\/code><\/strong>: Esta linha executa o comando <code>pip install<\/code>, para instalar as depend\u00eancias do Python listadas no arquivo <code>requirements.txt<\/code>, localizado no diret\u00f3rio <code>\/app<\/code>. Esta \u00e9 uma pr\u00e1tica comum para aplicativos em Python, pois ela permite a voc\u00ea gerenciar as depend\u00eancias do aplicativo.<\/p>\n<p>6. <strong><code>EXPOSE 8000<\/code><\/strong>: Informa ao Docker que o container estar\u00e1 escutando a porta 8000. Esta linha n\u00e3o publica de fato a porta. \u00c9 uma declara\u00e7\u00e3o de metadado para indicar quais portas o container poder\u00e1 usar.<\/p>\n<p>7. <strong><code>CMD [\"gunicorn\", \"django_kubernetes_tutorial.wsgi:application\", \"--bind\", \"0.0.0.0:8000\"]<\/code><\/strong>: Esta linha especifica o comando-padr\u00e3o a ser executado na inicializa\u00e7\u00e3o do container. Esse comando usa o Gunicorn como servidor para o aplicativo do Django e especifica que o Gunicorn dever\u00e1 escutar todas as interfaces de rede (<code>0.0.0.0<\/code>) na porta 8000, usando o aplicativo do WSGI definido em <code>django_kubernetes_tutorial.wsgi:application<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">DockerHub<\/h3>\n<p>Visite <a href=\"http:\/\/hub.docker.com\" target=\"_blank\" rel=\"noopener\">hub.docker.com<\/a> e fa\u00e7a login ou crie uma conta na plataforma.<\/p>\n<p>Clique em <strong>Create repository<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/j6njSAI3cnn1FeazOY-aKjKXXZPQXnTi7tzWC4hK2-FSZ-oUj3vz3oc2yOYFsGyvWbKZZ9B3nAMOLAA4r68yN6GEJFjsGccTMvWW1ph26pXKCpcPkzJjLwBJMC5J_kUXiKVzlSg6ZatV5tol2QXjlnw-1.png\" width=\"624\" height=\"432\"><\/p>\n<p>Em seguida, informe o nome do reposit\u00f3rio e defina a visibilidade como p\u00fablica. Se voc\u00ea estiver trabalhando com dados sens\u00edveis ou confidenciais, defina a visibilidade como <strong>Private<\/strong>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/Vj1dqmm0ro7S-McOV4FwMNyc2sWoZ-mVmiD0TbptoeAyK44vbSvJIXcRrvcUxcw_CxPtt_Q3R0VTzkLlpuEUdKiM9Po1ZGbTwZFfJgo7yCkRV2Vzjck_q52H4lUcABbHLOE0FvdDZagx1dvHveEkvgc-1.png\" width=\"624\" height=\"453\"><\/p>\n<p>Depois de criar o reposit\u00f3rio, voc\u00ea precisar\u00e1 fazer o build da imagem do Docker e depois fazer o push da imagem para o registro.<\/p>\n<p>Antes de executar o comando, certifique-se de que o seu arquivo <code>requirements.txt<\/code> esteja atualizado, executando o seguinte comando:<\/p>\n<p><code>pip freeze &gt; requirements.txt<\/code><\/p>\n<p>Para construir uma imagem, execute o comando a seguir:\u00a0<\/p>\n<p><code>docker build -t mukulmantosh\/django-kubernetes:1.0 .<\/code><\/p>\n<p><code>docker build -t \/django-kubernetes:1.0 .<\/code><\/p>\n<p>Este comando variar\u00e1 em fun\u00e7\u00e3o das suas circunst\u00e2ncias espec\u00edficas e voc\u00ea precisar\u00e1 usar o seu nome pessoal de usu\u00e1rio.<\/p>\n<p>Agora, voc\u00ea precisa se autenticar no Docker Hub para fazer o push da imagem para o registro.<\/p>\n<p>Digite este comando no terminal:<\/p>\n<p><code>docker login<\/code><\/p>\n<p>Digite o seu nome de usu\u00e1rio e senha. Depois de ter se autenticado com sucesso, voc\u00ea poder\u00e1 fazer o push da imagem, executando este comando:<\/p>\n<p><code>docker push mukulmantosh\/django-kubernetes:1.0\u00a0<\/code><\/p>\n<p><code>docker push \/django-kubernetes:1.0\u00a0<\/code><\/p>\n<p>Depois de o push da imagem ter sido conclu\u00eddo com sucesso, voc\u00ea poder\u00e1 observar as altera\u00e7\u00f5es no Docker Hub.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/R5Dsklfxw_4yJZDE5-Sqg7sA5hsK6Ss_xuqoZMcrsWyLEMHz2Cn7CxrAxMDpD44HfIMihudAfwQope_6FpIXHqgYlgrrGg1bSuYgoJr9nxDpJCzQyQHQatqOpW-R-nywAhkz8FWNyCa0zVy9CX_fLwo-1.png\" width=\"624\" height=\"239\"><\/p>\n<p>Se voc\u00ea n\u00e3o estiver planejando fazer push de mais nenhuma imagem para o registro, poder\u00e1 encerrar a sess\u00e3o, executando este comando:<\/p>\n<p><code>docker logout<\/code><\/p>\n<p>Se voc\u00ea quiser fazer um pull local dessa imagem, visite <a href=\"https:\/\/hub.docker.com\/r\/mukulmantosh\/django-kubernetes\" target=\"_blank\" rel=\"noopener\">hub.docker.com\/r\/mukulmantosh\/django-kubernetes<\/a>.<\/p>\n<h2 class=\"wp-block-heading\">Configura\u00e7\u00e3o do Kubernetes: como criar arquivos em YAML<\/h2>\n<p><strong>Esta se\u00e7\u00e3o do tutorial descreve a implanta\u00e7\u00e3o de aplicativos em clusters locais do Kubernetes.<\/strong><\/p>\n<p>Neste tutorial, usaremos o Docker Desktop, mas voc\u00ea tamb\u00e9m pode usar o minikube ou o kind.<\/p>\n<h3 class=\"wp-block-heading\">Namespaces<\/h3>\n<p>No Kubernetes, <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/overview\/working-with-objects\/namespaces\/\" target=\"_blank\" rel=\"noopener\">namespaces<\/a> \u00e9 uma parti\u00e7\u00e3o virtual dentro de um cluster, usada para agrupar e isolar recursos e objetos. \u00c9 uma maneira de criar diversos clusters virtuais dentro de um \u00fanico cluster f\u00edsico.\u00a0<\/p>\n<p>Voc\u00ea pode criar e gerenciar namespaces usando o <code><a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/\" target=\"_blank\" rel=\"noopener\">kubectl<\/a><\/code>, a ferramenta de linha de comando do Kubernetes, ou definindo-os em manifestos em YAML ao implantar recursos.\u00a0<\/p>\n<ul>\n<li>Se voc\u00ea tiver escolhido o Docker Desktop como a sua plataforma de prefer\u00eancia para executar o Kubernetes, n\u00e3o se esque\u00e7a de habilitar o Kubernetes nas configura\u00e7\u00f5es, clicando na caixa de op\u00e7\u00e3o <strong>Enable Kubernetes<\/strong>.<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/945ORpQLrnTDqbNfZTK-1A8KjfxdrWZCocP992yiPSNgv57t-GLr5RvRV7I5TJurmuVDW24Xm-i7c4eBIC7gV4UrhJJb9PKhEhuqHJmWvpG87mCgema7ZiXljFZ-6-Qxp4aOmvzRr1vjzcpDUJTkf6E-1.png\" width=\"624\" height=\"368\"><\/p>\n<p>Execute o comando a seguir no terminal para criar o namespace:<\/p>\n<p><code>kubectl create ns django-app<\/code><\/p>\n<h2 class=\"wp-block-heading\">Como implementar bancos de dados com o K8s<\/h2>\n<p>Para come\u00e7ar, vamos estabelecer uma inst\u00e2ncia do PostgreSQL no nosso cluster do Kubernetes no ambiente local.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolume<\/h3>\n<p>No Kubernetes, um <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\" target=\"_blank\" rel=\"noopener\">volume persistente<\/a> (PV) \u00e9 um espa\u00e7o de armazenamento provisionado no cluster por um administrador. Ao armazenarem dados de forma independente do ciclo de vida de um pod, os PVs permitem que o gerenciamento e a abstra\u00e7\u00e3o dos recursos de armazenamento sejam mais dissociados e flex\u00edveis. Isso significa que os dados podem persistir mesmo que o pod que os utiliza seja exclu\u00eddo ou reatribu\u00eddo a um n\u00f3 diferente no cluster.<\/p>\n<p>Vamos criar um volume persistente e cham\u00e1-lo de <code>pv.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/7ad-L7W-VSSsV1aouIP2RqA7mHcjvr9TwzQPSbqKtg5ED_ZQigyZzVmqyM7XeEp343xKGKvQpdOUHTrHloOCsWgP5ufp_q43LK97-2gozI6AZ5iXA1b5aiI8yyvFbVYHxKzFMjwYfX4ELEbuZvUOUWM-1.png\" width=\"624\" height=\"631\"><\/p>\n<p>Esta configura\u00e7\u00e3o em YAML define um recurso do tipo PersistentVolume, com o nome de <code>postgres-pv<\/code> e uma capacidade de 1 gigabyte, montado com o modo de acesso <code>ReadWriteOnce<\/code> e acessado por um caminho local no sistema de arquivos do n\u00f3, localizado em <code>\/data\/db<\/code>. Este PV pode ser usado para fornecer armazenamento persistente a pods que precisem de acesso a um diret\u00f3rio no sistema de arquivos do n\u00f3. Ele \u00e9 adequado para aplica\u00e7\u00f5es como o PostgreSQL ou outros servi\u00e7os din\u00e2micos que precisem de armazenamento persistente.<\/p>\n<p>Para produ\u00e7\u00e3o, recomendamos usar o <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/statefulset\/\" target=\"_blank\" rel=\"noopener\">StatefulSets<\/a> do Kubernetes ou solu\u00e7\u00f5es de nuvem como o AWS RDS ou o Google CloudSQL.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolumeClaim<\/h3>\n<p>No Kubernetes, um <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-persistent-volume-storage\/#create-a-persistentvolumeclaim\" target=\"_blank\" rel=\"noopener\">PersistentVolumeClaim<\/a> (PVC) \u00e9 um objeto de recurso usado por um pod para requisitar a um PV uma quantidade espec\u00edfica de armazenamento com certas propriedades. Os PVCs s\u00e3o uma maneira de os aplicativos requisitarem recursos de armazenamento sem precisarem saber os detalhes da infraestrutura subjacente.<\/p>\n<p>Ao criar e usar PVCs, o Kubernetes fornece uma maneira de alocar e gerenciar dinamicamente recursos de armazenamento para os aplicativos, enquanto abstrai a infraestrutura subjacente de armazenamento, facilitando trabalhar com aplicativos din\u00e2micos e gerenci\u00e1-los em ambientes com containers.<\/p>\n<p>Vamos criar um PVC e cham\u00e1-lo de <code>pvc.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/X_Td_1FR8BElq2OK1mODusNTDcPHevnlT18IkCN8E08fT2rfkfsIY2iawyk3dcl7Dxlpr2NeDimz-RtJQbeH5QPqmM0nHWggq-fU4zw_dDbeH-2utnnKWGusBWt-CXO9-BM3M5ygvErDHfOlZtoWh7w-1.png\" width=\"624\" height=\"577\"><\/p>\n<p>Um PVC solicita recursos de armazenamento e \u00e9 vinculado a um PV, que por sua vez fornece o armazenamento real.\u00a0<\/p>\n<p>Esta configura\u00e7\u00e3o em YAML define um PersistentVolumeClaim com o nome de <code>postgres-pvc<\/code>, dentro do namespace <code>django-app<\/code>. Esse PVC requisita um gigabyte de armazenamento, com o modo de acesso <code>ReadWriteOnce<\/code>, e especifica explicitamente a StorageClass <code>manual<\/code>. Este PVC dever\u00e1 ser vinculado a um PV j\u00e1 existente, com o nome de <code>postgres-pv<\/code>. Na pr\u00e1tica, estar\u00e1 reservando esse volume para ser usado por pods que referenciem esse PVC dentro do namespace <code>django-app<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p>No Kubernetes, um <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/configmap\/\" target=\"_blank\" rel=\"noopener\">ConfigMap<\/a> \u00e9 um objeto de API usado para armazenar dados de configura\u00e7\u00f5es em pares de chaves e valores. ConfigMaps s\u00e3o uma maneira de dissociar os dados de configura\u00e7\u00f5es do c\u00f3digo do aplicativo, facilitando gerenciar e atualizar configura\u00e7\u00f5es sem modificar ou reimplantar containers. Eles s\u00e3o especialmente \u00fateis para configurar aplicativos, microsservi\u00e7os e outros componentes dentro de um cluster do Kubernetes.<\/p>\n<p>Vamos criar um ConfigMap e cham\u00e1-lo de <code>cm.yml<\/code>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/wvDyPcHd888DKzevEdpSAURy5e6IzinJthTUHK5z58-BnPhFx0bXrnaexUXpzJkhbXkbZa-zgdjcttbKIvI01hznnCrw9-E9LAmSlMD4o1GDQ-99rjgKgqIF9vXsacJ3_K_XPckDmAWrpEvFDYmOw_Y-1.png\" width=\"624\" height=\"524\"><\/p>\n<p>Por raz\u00f5es de seguran\u00e7a, embora este tutorial use ConfigMaps, recomenda-se armazenar credenciais sens\u00edveis no <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/\" target=\"_blank\" rel=\"noopener\">Secrets<\/a> do Kubernetes ou explorar alternativas como o Bitnami Sealed Secrets, a AWS Parameter Store ou o HashiCorp Vault.<\/p>\n<h3 class=\"wp-block-heading\">Deployment (implanta\u00e7\u00e3o)<\/h3>\n<p>No Kubernetes, um <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/deployment\/\" target=\"_blank\" rel=\"noopener\">Deployment<\/a> (implanta\u00e7\u00e3o) \u00e9 um objeto de recurso usado para gerenciar a implanta\u00e7\u00e3o e o escalamento de aplicativos. Faz parte do grupo da API do Kubernetes e \u00e9 uma maneira declarativa de definir e gerenciar o estado desejado do seu aplicativo.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/fu5av6IILewmdL6cpFurozbGqH6gWdutfRmxwUb-0FGPs6j05xNSE4jwYeDsD2BKA_GE8WOaTqx2C85DX2mkz21LPzBFl_BHcSD-lIXthE0zaYSgUEWZ-gIQB07qIZ0V-iIm0cWiBCpmHcqvlpuirso-1.png\" width=\"624\" height=\"735\"><\/p>\n<p>Um Deployment \u00e9 um recurso de n\u00edvel superior do Kubernetes, usado para gerenciar e escalar pods de aplicativos.\u00a0<\/p>\n<p>Esta configura\u00e7\u00e3o em YAML define um Deployment com o nome de <code>postgres<\/code> no namespace <code>django-app<\/code>. Ela implanta uma \u00fanica r\u00e9plica de um banco de dados PostgreSQL (vers\u00e3o 16.0) com armazenamento persistente. O pod do banco de dados \u00e9 rotulado como <code>app: postgresdb<\/code> e o armazenamento \u00e9 fornecido por um PVC com o nome de <code>postgres-pvc<\/code>. A configura\u00e7\u00e3o e as credenciais do container do PostgreSQL s\u00e3o fornecidas atrav\u00e9s de um ConfigMap com o nome de <code>db-secret-credentials<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">Servi\u00e7o<\/h3>\n<p>No Kubernetes, um <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/\" target=\"_blank\" rel=\"noopener\">servi\u00e7o<\/a> \u00e9 um objeto de recurso usado para expor um conjunto de pods como um servi\u00e7o de rede. Os Services permitem a comunica\u00e7\u00e3o pela rede entre diferentes partes do seu aplicativo em execu\u00e7\u00e3o em um cluster do Kubernetes. Eles fornecem um endpoint est\u00e1vel para os clientes acessarem essas partes. Os Services abstraem a infraestrutura de rede subjacente, facilitando conectar e descobrir os componentes do seu aplicativo.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/p4NneUHgkfOqr2cp1bIZVYEH1weBKgZ5cWjPOgnATHQGdQwULM9BlzPRJXyPqf0v3FqHrztZ9rmL6P3RSInOE6vNC21UenOjGz-872-KzklWAQGm2Rr3uOKIQMRMlLvCIHiswccwGtI-eVeBI7b61EI-1.png\" width=\"624\" height=\"525\"><\/p>\n<p>Esta configura\u00e7\u00e3o em YAML define um Service NodePort com o nome de <code>postgres-service<\/code>, dentro do namespace <code>django-app<\/code>. Ela exp\u00f5e o servi\u00e7o do PostgreSQL em execu\u00e7\u00e3o em pods rotulados como &#8220;<code>app: postgresdb<\/code>&#8220;, na porta 5432 dentro do cluster. Clientes externos podem acessar o Service no endere\u00e7o IP de qualquer n\u00f3, usando a porta 30004. Este Service disponibiliza uma maneira de tornar o banco de dados PostgreSQL acess\u00edvel de fora do cluster do Kubernetes.<\/p>\n<h2 class=\"wp-block-heading\">Como criar configura\u00e7\u00f5es em YAML para um aplicativo do Django<\/h2>\n<h3 class=\"wp-block-heading\">PersistentVolume<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/FJCpL5-QEQHMI7w0j2XnboyV-y6NOoRZPzOd3GXJju2CLizk2kmnXEBcDaUSAOuvHfFrOcKel3VcVs0fimdgovM9NSn5aw31hDTYSkyAgYSK14EqO-bj2CgL2p-6h20IDY0Ei-szg63ZKYIr77kIOZs-1.png\" width=\"624\" height=\"525\"><\/p>\n<p>Este c\u00f3digo em YAML define um PersistentVolume com o nome de <code>staticfiles-pv<\/code> e uma capacidade de armazenamento de 1 GB, permitindo que v\u00e1rios pods leiam e gravem nele ao mesmo tempo. O armazenamento \u00e9 fornecido por um caminho no host local, situado em <code>\/data\/static<\/code>. Os arquivos est\u00e1ticos do Django ser\u00e3o armazenados nesse local.<\/p>\n<h3 class=\"wp-block-heading\">PersistentVolumeClaim<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/01PqOjeQXzeBx4RIkSdTRXttHzaEZexNL_OsQPfaCiOqbLTY85QhXOSCx0ojmGxSINUpuO4FhcZLk4Sl5YosJISr4GBMWeecUeObtbGiGXR9k_uQftED-89TurtbyVoaujef1ixQ4FQ8zSoa8j2MWp4-1.png\" width=\"624\" height=\"504\"><\/p>\n<p>Este c\u00f3digo em YAML define um PVC com o nome de <code>staticfiles-pvc<\/code>, no namespace <code>django-app<\/code>. Ele requisita armazenamento a um PV com a StorageClass &#8220;manual&#8221;, com uma capacidade de pelo menos 1 GB, e especifica que precisa do n\u00edvel de acesso <code>ReadWriteMany<\/code>. A requisi\u00e7\u00e3o \u00e9 explicitamente vinculada a um PV j\u00e1 existente, chamado <code>staticfiles-pv<\/code>, para atender \u00e0s suas necessidades de armazenamento. Isso permite que os pods no namespace <code>django-app<\/code> usem este PVC para acessar e usar o armazenamento fornecido pelo PV associado.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/zWM1NlnXZNXcXFBqcJo2iDvVn1HsVKmSqrrWASDo8g7iQFtHKQksufKcirqeKrpNKhLPw-EBLT5BPAapQDSvNTRF1Z9yzZlTO2bxOs2PdQNJYSwMdkDKXnMQJekawNLJe7FzJXuhAcyjKIZ6wjBw28c-1.png\" width=\"624\" height=\"459\"><\/p>\n<p>Este c\u00f3digo em YAML define um ConfigMap com o nome de <code>app-cm<\/code> no namespace <code>django-app<\/code>. Esse ConfigMap cont\u00e9m diversos pares de chaves e valores, que armazenam dados de configura\u00e7\u00e3o. Ele pode ser usado por pods ou outros recursos dentro do namespace <code>django-app<\/code> para acessar par\u00e2metros de configura\u00e7\u00e3o, como dados de conex\u00f5es a bancos de dados e caminhos para arquivos est\u00e1ticos.<\/p>\n<h3 class=\"wp-block-heading\">Deployment (implanta\u00e7\u00e3o)<\/h3>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" width=\"1258\" height=\"1678\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/deploy.png\" alt=\"\" class=\"wp-image-456835\" style=\"aspect-ratio:0.7497020262216925;width:582px;height:auto\" \/><\/figure>\n<p>Este c\u00f3digo em YAML define um Deployment com o nome de <code>django-app-deploy<\/code>, no namespace <code>django-app<\/code>. Ela cria uma r\u00e9plica (pod) que executa um container com uma imagem e uma configura\u00e7\u00e3o espec\u00edficas do Docker. Esse pod est\u00e1 associado a dois volumes, <code>postgres-db-storage<\/code> e <code>staticfiles<\/code>, fornecidos por PVCs. O container est\u00e1 configurado para usar as vari\u00e1veis de ambiente de um ConfigMap com o nome de <code>app-cm<\/code> e escutar a porta 8000. Os volumes s\u00e3o montados em caminhos espec\u00edficos dentro do container, para darem acesso ao armazenamento do banco de dados e a arquivos est\u00e1ticos. Este Deployment \u00e9 uma maneira comum de executar um aplicativo do Django usando o Kubernetes.<\/p>\n<p>Se voc\u00ea estiver interessado em fazer pull de imagens de um registro privativo, leia <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/pull-image-private-registry\/\" target=\"_blank\" rel=\"noopener\">isto<\/a>.\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Service (servi\u00e7o)<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/Z0wfNZT1VrOT-9FznBYsl1LGu_b635fuSFtpoLRacsqfBiLAOi_tw7p87Ao8p9ZPx8-84e5NFerr3krbB5OsW2Vo9ps_hAvlaXV-2ga2RBLsm7vfPJ0rUUyzvvBg4NoQ0c_K7BO8I4u5vOgbUT1BBU-1.png\" width=\"624\" height=\"577\"><\/p>\n<p>O Service escuta a porta 8000 e direciona o tr\u00e1fego de entrada para pods rotulados como <code>app: django-application<\/code>. Esta \u00e9 uma configura\u00e7\u00e3o comum para expor e balancear a carga de aplicativos Web em um cluster de Kubernetes no qual estejam sendo executadas diversas inst\u00e2ncias de um mesmo aplicativo. O Service garante uma distribui\u00e7\u00e3o uniforme do tr\u00e1fego entre essas inst\u00e2ncias.<\/p>\n<h2 class=\"wp-block-heading\">NGINX<\/h2>\n<p>O <a href=\"https:\/\/www.nginx.com\/\" target=\"_blank\" rel=\"noopener\">NGINX<\/a> \u00e9 um servidor de Web e de proxy reversa de alto desempenho, conhecido por sua rapidez, confiabilidade e escalabilidade. Ele cuida de forma eficiente do tr\u00e1fego de Web, do balanceamento de carga e da entrega de conte\u00fado, o que o torna uma escolha popular em servidores de Web e de aplicativos.<\/p>\n<h3 class=\"wp-block-heading\">ConfigMap<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/Itj5_NS6IlHVlnJ49MnCsE2Hu8x0X7X2EW_Nm3qy7ujShq1mBmawFBCFk4iKbsDZ890n2xTJFGs1TlmRrZ0QDqL35IC6mj07cq8tz1GVisueNR4cDsqPZW1gTD5j7ZoTBJcWba5VpFXXZAwagXE0y60-1.png\" width=\"624\" height=\"460\"><\/p>\n<p>Este c\u00f3digo em YAML define um ConfigMap do Kubernetes com o nome de <code>nginx-cm<\/code> no namespace <code>django-app<\/code>. Esse ConfigMap cont\u00e9m um par de chave e valor no qual a chave \u00e9 <code>default.conf<\/code> e o valor \u00e9 um arquivo de configura\u00e7\u00e3o do NGINX com diversas linhas que faz proxy da solicita\u00e7\u00e3o para o servidor de back-end.\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Deployment (implanta\u00e7\u00e3o)<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/4ErlDKYewor2Owj0YrtS7O01WkXzFkTBHoN5LGlEGBfvX_MGUzXgxF0ur0eDSIBD2HdJlbg4zpAE1v1OwT_LkSYR3RS4hQFnW3jwX_wEjE_L4cCIeuHI-wspyiTGaw6z8JnHXw8buX0yvbWsr3eSNDo-1.png\" width=\"624\" height=\"727\"><\/p>\n<p>Este c\u00f3digo em YAML define um Deployment que cria e gerencia pods que executam um container do NGINX com volumes e configura\u00e7\u00f5es espec\u00edficos. Esse Deployment garante que sempre esteja sendo executada uma r\u00e9plica de cada pod no namespace <code>django-app<\/code>. Ela tamb\u00e9m substitui a configura\u00e7\u00e3o-padr\u00e3o do NGINX pelo ConfigMap <code>nginx-cm<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">Service (servi\u00e7o)<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/PqinRZHVtGiapAjd5aD4-mA4sRmxTlRnfkSl5y6GRrPY4KpD2MsuMkkKspX1J-JHNwEdSlxb_Vtuex3SRd0caY4x-zI744KCZ-AKgjYc976FWHiEZVl9dM-oyJuPgE-DoEyU46RLokubkL-otadMZ40-1.png\" width=\"624\" height=\"631\"><\/p>\n<p>Esta configura\u00e7\u00e3o em YAML cria um Service do Kubernetes com o nome de <code>nginx-service<\/code> no namespace <code>django-app<\/code>. Ela exp\u00f5e pods com o r\u00f3tulo <code>app:nginx<\/code> na porta 80 dentro do cluster e tamb\u00e9m torna o servi\u00e7o acess\u00edvel na NodePort 30005 em cada n\u00f3 do cluster. Isso permite que o tr\u00e1fego externo chegue aos pods que est\u00e3o executando o aplicativo do NGINX, atrav\u00e9s do servi\u00e7o NodePort.<\/p>\n<h2 class=\"wp-block-heading\">Como gerenciar cargas de trabalho em lote atrav\u00e9s de jobs do Kubernetes<\/h2>\n<p>No Kubernetes, um <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/job\/\" target=\"_blank\" rel=\"noopener\">Job<\/a> \u00e9 um objeto de recurso que representa uma \u00fanica unidade de trabalho ou uma tarefa finita. Os Jobs s\u00e3o projetados para executarem tarefas at\u00e9 o final, com um n\u00famero especificado de execu\u00e7\u00f5es terminadas com sucesso.\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Migra\u00e7\u00e3o de bancos de dados<\/h3>\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" width=\"1326\" height=\"1394\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/03\/migration.png\" alt=\"\" class=\"wp-image-456823\" style=\"aspect-ratio:0.9512195121951219;width:597px;height:auto\" \/><\/figure>\n<p>Esta configura\u00e7\u00e3o em YAML define um Job do Kubernetes com o nome de <code>django-db-migrations<\/code>, no namespace <code>django-app<\/code>. Esse Job executa um container usando uma imagem do Docker especial para migra\u00e7\u00f5es do Django e monta um PVC para fornecer o armazenamento para os arquivos relacionados ao banco de dados. Se o Job falhar, ele poder\u00e1 ser tentado novamente at\u00e9 15 vezes e reter\u00e1 seu pod por 100 segundos depois de terminar. O Job criar\u00e1 novas tabelas no PostgreSQL.<\/p>\n<h3 class=\"wp-block-heading\">Arquivos est\u00e1ticos<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/41sZvQpth3_7rpCpoCuUY0k588q9aANJoVs6DxWJSGF2qvZQDo0u9jcxEbjjEb9IQ3oLUTNkboM61EoKbGOxsnsJFHfzLYjlwFqq8TXtuYNLZne2h358Yn-MyoNrk8JVGRpu0erDPr4yHqevTlXzxtY-1.png\" width=\"624\" height=\"643\"><\/p>\n<p>Esta configura\u00e7\u00e3o em YAML define um Job do Kubernetes com o nome de <code>django-staticfiles<\/code>, no namespace <code>django-app<\/code>. Esse Job executa um container usando uma imagem do Docker especial para coletar arquivos est\u00e1ticos para um aplicativo do Django e monta um PVC para fornecer o armazenamento para os arquivos est\u00e1ticos. Se o Job falhar, ele poder\u00e1 ser tentado novamente at\u00e9 tr\u00eas vezes e reter\u00e1 seu pod por 100 segundos depois de terminar, para fins de depura\u00e7\u00e3o. O Job copiar\u00e1 os arquivos est\u00e1ticos para o caminho de montagem (mountPath), que \u00e9 <code>\/data\/static<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">Para iniciar o aplicativo<\/h2>\n<p>Para iniciar o aplicativo, navegue at\u00e9 o diret\u00f3rio <code>k8s<\/code> e execute o comando a seguir:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/t7jeYgU4ZqFBXc-2WwudXN8V4cibZZt5M0Tob6-0zV570MXlHkql6QBw4Oxibl5WWdGnfB9510sYpfjnIhsjvs9AObRuhIrR91r8b3Q8Vu2pJYuLfFhm2ixDw7Oddkvh-5tP3nUADGAu5DX725cJ6YI-1.png\" width=\"624\" height=\"392\"><\/p>\n<p>Depois de implantar o aplicativo, use o comando a seguir para verificar o status dos pods em execu\u00e7\u00e3o:<\/p>\n<p><code>kubectl get pods -n django-app -w<\/code><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/PiIyWEPFMtnrTpvspZ6gc65Z81xUgAbiqSQ2XgphxJ229PKgASge2sNzU0_YG_vC-k_hFBMNH1lF1CTBbY5oDWnNDne1Cf3nI809BP6bIUr0xHvRbNsOI_TkLwLwu7QFmcnKBarHlsK7tu8dBsqjgMA-1.png\" width=\"624\" height=\"108\"><\/p>\n<h3 class=\"wp-block-heading\">Como criar um superusu\u00e1rio no Django<\/h3>\n<p>Depois que todos os seus aplicativos estiverem sendo executados normalmente, crie um superusu\u00e1rio para fazer login como administrador no Django.<\/p>\n<p>Execute este comando para obter a lista dos pods em execu\u00e7\u00e3o:<\/p>\n<p><code>kubectl get pods -n django-app<\/code><\/p>\n<p>Para entrar no shell do container, execute:<\/p>\n<p><code>kubectl exec -it  -n django-app -- sh<\/code><\/p>\n<p>Em seguida, execute:<\/p>\n<p><code>python manage.py createsuperuser<\/code><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/y65m6YcxuejXhXIdGCr7_aqy_gGj4FhrtWsddWZgxWv2nBEnCedmQoPNupQQ0JRn7sMMwElFo09TMoPImbR6v2Sc3rirDBW6sLK2daaNbh3NDfvT83DrtTDHPiutsdc3vKC-V5nfXNYjrIzt26igd_o-1.png\" width=\"624\" height=\"197\"><\/p>\n<p>Depois de criar o superusu\u00e1rio com sucesso, abra <a href=\"http:\/\/127.0.0.1:30005\" target=\"_blank\" rel=\"noopener\">http:\/\/127.0.0.1:30005<\/a> em um navegador. Voc\u00ea ser\u00e1 direcionado \u00e0 p\u00e1gina-padr\u00e3o de boas-vindas.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/tpozSD_EtSgHLFQ1ud5EV4_OJFdmgSUGlS6u4iEMI9rVrduVIlaJS1NHoD4D6WhjCdC7oASEobsfm9ar0cWUxEydoSVsTfuoOWTJw-5usNmJrusEyD50SGJYbKUWU_BLgdbipbfYeeKBcW1ecK8_gsQ-1.png\" width=\"624\" height=\"321\"><\/p>\n<p>Depois, v\u00e1 at\u00e9 a administra\u00e7\u00e3o do Django, em <a href=\"http:\/\/127.0.0.1:30005\/admin\" target=\"_blank\" rel=\"noopener\">http:\/\/127.0.0.1:30005\/admin<\/a>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/WcwAvYrT3499Hr32HybiT6VuuanZh8keoS95n0N3-lasuJ8z4rsmQydIp4MLCGVORtQLZnECw2y3IKB9e2J8Mg8ScRF1HpvD-bu68MSYv_Ti_GBr3P4Y0gtc8B6aaUfg2kRF2VLj0NXUWLDRCiy3sjg-1.png\" width=\"624\" height=\"447\"><\/p>\n<p>Digite o nome de usu\u00e1rio e a senha que voc\u00ea acabou de criar.\u00a0<\/p>\n<p>Depois de autenticado, voc\u00ea ser\u00e1 redirecionado \u00e0 p\u00e1gina de administra\u00e7\u00e3o do Django.\u00a0<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/u4my3QzTYVifPI-wEPH__wlI6M7tUITtpDeoPnoK6bM6NC2nSAutEumLtR3CScqWcEFrnH8KrkH3k2QMna_Yyz2mnTO1qF8idfFOiG263r8k7Y_6wU-QsbihmY7Av08sRX_05wSc72Nw9DKnFiYOgeE-1.png\" width=\"624\" height=\"400\"><\/p>\n<p>Se voc\u00ea tentar fazer login atrav\u00e9s de localhost:30005\/admin, talvez receba um erro <em>403 Forbidden<\/em> (CSRF).<\/p>\n<p>Voc\u00ea pode resolver isso no arquivo <code>settings.py<\/code>, sob <code>CSRF_TRUSTED_ORIGINS<\/code>.<\/p>\n<p><code>CSRF_TRUSTED_ORIGINS<\/code> \u00e9 uma <a href=\"https:\/\/docs.djangoproject.com\/en\/4.2\/ref\/settings\/#std-setting-CSRF_TRUSTED_ORIGINS\" target=\"_blank\" rel=\"noopener\">configura\u00e7\u00e3o<\/a> no Django usada para especificar uma lista de origens confi\u00e1veis para prote\u00e7\u00e3o contra &#8220;cross-site request forgery&#8221; (CSRF). CSRF \u00e9 uma vulnerabilidade de seguran\u00e7a que pode ocorrer quando quem faz um ataque engana um usu\u00e1rio e o faz enviar sem saber uma solicita\u00e7\u00e3o indesejada a um aplicativo Web. Para evitar isso, o Django incorpora uma prote\u00e7\u00e3o contra CSRF.<\/p>\n<p><code>CSRF_TRUSTED_ORIGINS<\/code> permite que voc\u00ea defina uma lista de origens (Web sites) a partir das quais ser\u00e3o aceitas solicita\u00e7\u00f5es com prote\u00e7\u00e3o contra CSRF. Qualquer solicita\u00e7\u00e3o proveniente de uma origem n\u00e3o inclu\u00edda nessa lista ser\u00e1 considerada potencialmente maliciosa e devidamente bloqueada.<\/p>\n<p>Esta configura\u00e7\u00e3o pode ser usada para permitir certas solicita\u00e7\u00f5es de outras origens ao seu aplicativo do Django, sem deixar de manter a seguran\u00e7a contra ataques de CSRF. Ela \u00e9 especialmente \u00fatil em situa\u00e7\u00f5es nas quais o seu aplicativo precise interagir com outros servi\u00e7os ou APIs de Web hospedados em dom\u00ednios diferentes.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/DTDVeAkR8-rHFCbeoMqWHHSSCBDNjQ96OLDPcexK0TVmbzk9bRgHajXVqFiy4r_yTd6mE1GM7TGuCwYcTJ0owbKhhjLxaJlgE9_KjgEk6APxHsHsPXtdRtJwRbYgejaoHuxpWzUEsaUAt3oHjzrTvVM-2.png\" width=\"624\" height=\"428\"><\/p>\n<p>Se voc\u00ea estiver usando ferramentas de interface gr\u00e1fica como o <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/access-application-cluster\/web-ui-dashboard\/\" target=\"_blank\" rel=\"noopener\">Kubernetes Dashboard<\/a>, poder\u00e1 visualizar facilmente os seus pods em execu\u00e7\u00e3o, implanta\u00e7\u00f5es, volumes persistentes, etc.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/2lssXclYX6wG01Kf5SX7hng9Yxd0JuqeFAYR-UDdEBIXJyzNZItFQFGMT1UxAifh3FywhRmaWzrwafuv0L9nciqBE7yf09hf7sYmpijHkrZoe_MXeBIow9q_CrlZAUHLmNHDzMTcO8XZqWHOxjZHcnw-2.png\" width=\"624\" height=\"325\"><\/p>\n<h2 class=\"wp-block-heading\">Suporte ao Kubernetes no PyCharm\u00a0<\/h2>\n<p>O PyCharm oferece um editor incrementado e suporte de runtime sob medida para o Kubernetes, trazendo in\u00fameros recursos para simplificar o seu gerenciamento do Kubernetes. Esses recursos incluem:<\/p>\n<ul>\n<li>Navegar pelos objetos do cluster, extraindo, editando suas configura\u00e7\u00f5es e descrevendo-os.<\/li>\n<li>Visualizar eventos.<\/li>\n<li>Visualizar e baixar logs de pods.<\/li>\n<li>Anexar o console de pods.<\/li>\n<li>Executar o shell em pods.<\/li>\n<li>Encaminhar portas para um pod.<\/li>\n<li>Aplicar configura\u00e7\u00f5es de recursos em YAML a partir do editor.<\/li>\n<li>Excluir recursos do cluster.<\/li>\n<li>Completar registros ConfigMap e Secret a partir do cluster.<\/li>\n<li>Configurar os caminhos para <code>kubectl<\/code>.<\/li>\n<li>Configurar arquivos <code>kubeconfig<\/code> personalizados, globalmente ou por projeto.<\/li>\n<li>Alternar entre contextos e namespaces.<\/li>\n<li>Usar o esquema de API do cluster ativo (incluindo a CRD) para editar manifestos de recursos.<\/li>\n<\/ul>\n<p>Assista a este <a href=\"https:\/\/www.youtube.com\/watch?v=NqotF4kRvTc\" target=\"_blank\" rel=\"noopener\">v\u00eddeo<\/a> para saber mais sobre como trabalhar com o Kubernetes no PyCharm Professional.<\/p>\n<p>Experimente o PyCharm gratuitamente para as suas tarefas do Kubernetes!<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\">\n                                                <a href=\"https:\/\/www.jetbrains.com\/pycharm\/download\/\" class=\"btn\" target=\"\" rel=\"noopener\">BAIXAR O PYCHARM<\/a>\n                                                    <\/div>\n<\/p>\n<\/div>\n<h2 class=\"wp-block-heading\">Refer\u00eancias<\/h2>\n<p>J\u00e1 tem uma s\u00f3lida compreens\u00e3o do Kubernetes? Ent\u00e3o, passe para a pr\u00f3xima etapa da sua jornada pela programa\u00e7\u00e3o, explorando solu\u00e7\u00f5es de nuvem. Confira nossos tutoriais sobre o <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/fastapi-aws-kubernetes\/\" target=\"_blank\" rel=\"noopener\">AWS EKS<\/a> e o <a href=\"https:\/\/www.jetbrains.com\/pycharm\/guide\/tutorials\/cloud-code-pycharm\/\" target=\"_blank\" rel=\"noopener\">Google Kubernetes Engine<\/a>.<\/p>\n\n\n<p><em>Artigo original em ingl\u00eas por:<\/em><\/p>\n\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/mukul-200x200.jpg\" width=\"200\" height=\"200\" alt=\"Mukul Mantosh\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Mukul Mantosh<\/h4>\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":571294,"comment_status":"closed","ping_status":"closed","template":"","categories":[8377],"tags":[963,5635,154],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm\/571289"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/comments?post=571289"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm\/571289\/revisions"}],"predecessor-version":[{"id":601102,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm\/571289\/revisions\/601102"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media\/571294"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media?parent=571289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/categories?post=571289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/tags?post=571289"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/cross-post-tag?post=571289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}