├── README.md ├── LICENSE └── pt_br └── deploy_django_docker_gunicorn.md /README.md: -------------------------------------------------------------------------------- 1 | ### PT-BR 2 | **Descrição do Repositório:** 3 | > Este repositório contém uma coleção de tutoriais e guias úteis em arquivos Markdown (.md) para ajudar desenvolvedores em tarefas como deploy com Docker, configuração de ambientes e outras práticas essenciais. Feito para a comunidade e aberto para contribuições! 4 | 5 |
6 | 7 | ### EN-US 8 | **Repository Description:** 9 | > This repository contains a collection of useful tutorials and guides in Markdown (.md) files to assist developers with tasks like Docker deployment, environment setup, and other essential practices. Created for the community and open for contributions! 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Willamy Domingos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pt_br/deploy_django_docker_gunicorn.md: -------------------------------------------------------------------------------- 1 | # Documentação de Deploy - Django, PostgreSQL e Nginx no Docker 2 | 3 | Este documento descreve o processo de deploy de uma aplicação **Django** utilizando **Docker**, **Docker Compose** e **Nginx** como servidor web. A aplicação será servida por **Gunicorn**, um servidor **WSGI** para **Python**, e o banco de dados utilizado é o **PostgreSQL**. 4 | 5 |
6 | 7 | ## Estrutura do Projeto 8 | 9 | A estrutura do projeto é organizada da seguinte forma: 10 | 11 | ```plaintext 12 | project-root/ 13 | ├── app/ (Diretório da aplicação Django) 14 | ├── settings.py 15 | ├── wsgi.py 16 | ├── ... 17 | ├── other_apps/ (Outros diretórios de Apps do projeto) 18 | ├── static/ 19 | ├── media/ 20 | ├── wait-for-it.sh 21 | ├── Dockerfile 22 | ├── docker-compose.yml 23 | ├── nginx.conf 24 | ├── requirements.txt 25 | ├── manage.py 26 | └── .env 27 | ``` 28 | 29 | ### Arquivos importantes 30 | 31 | - **Dockerfile**: Define a imagem Docker para a aplicação Django. 32 | - **docker-compose.yml**: Define os serviços (Django, PostgreSQL, e Nginx) que serão executados em containers Docker. 33 | - **nginx.conf**: Configuração do servidor Nginx que faz proxy reverso para o Gunicorn. 34 | - **requirements.txt**: Lista todas as dependências Python da aplicação. 35 | - **.env**: Arquivo de variáveis de ambiente para configuração dos serviços. 36 | - **wait-for-it.sh**: Script utilizado para garantir que o banco de dados PostgreSQL esteja pronto antes de rodar as migrações e iniciar o servidor. 37 | 38 | > **Obs.:** O arquivo `wait-for-it.sh` está disponível em: 39 | [https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh](https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh). 40 | 41 |
42 | 43 | ## Ajustes no `settings.py` Recomendados para o Projeto 44 | 45 | #### 1. Ajustar o apontamento do Banco de Dados para as variáveis de ambiente 46 | 47 | > ***Obs.:** A biblioteca `python-decouple` é recomendada para facilitar a leitura das variáveis de ambiente.* \ 48 | > *Documentação: [https://pypi.org/project/python-decouple/](https://pypi.org/project/python-decouple/)* 49 | 50 | ```python 51 | DATABASES = { 52 | 'default': { 53 | 'ENGINE': 'django.db.backends.postgresql', 54 | 'NAME': config('DB_NAME'), 55 | 'USER': config('DB_USER'), 56 | 'PASSWORD': config('DB_PASSWORD'), 57 | 'HOST': config('DB_HOST'), 58 | 'PORT': config('DB_PORT'), 59 | 'OPTIONS': { 60 | 'options': f'-c search_path={config("DB_SCHEMA", default='public')}' 61 | } 62 | } 63 | } 64 | ``` 65 | 66 | #### 2. Estrutura recomendada para os diretórios **static** e **media** 67 | 68 | ```python 69 | # Static files (CSS, JavaScript, Images, ...) 70 | STATIC_URL = '/static/' 71 | STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ] 72 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 73 | 74 | # Media files (Images, Files) 75 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 76 | MEDIA_URL = '/media/' 77 | ``` 78 | 79 |
80 | 81 | --- 82 | 83 |
84 | 85 | # Arquivos de Configuração 86 | 87 | ## 1. Dockerfile 88 | 89 | O `Dockerfile` define a imagem Docker para a aplicação Django. Ele instala as dependências necessárias e copia o código da aplicação para dentro do container. 90 | 91 | ```dockerfile 92 | # Imagem base do Python 3.12 (slim) 93 | FROM python:3.12-slim 94 | 95 | # Define o diretório de trabalho 96 | WORKDIR /app 97 | 98 | # Instala as dependências do sistema operacional 99 | RUN apt-get update && apt-get install -y curl 100 | 101 | # Copia o script wait-for-it.sh para o container 102 | COPY wait-for-it.sh /app/ 103 | 104 | # Atribui permissão de execução para o wait-for-it.sh 105 | RUN chmod +x /app/wait-for-it.sh 106 | 107 | # Copia o arquivo requirements.txt com as dependências do projeto 108 | COPY requirements.txt /app/ 109 | 110 | # Instala as dependências Python do projeto 111 | RUN pip install --no-cache-dir -r requirements.txt 112 | 113 | # Copia o código da aplicação para o container 114 | COPY . /app/ 115 | 116 | # Expõe a porta 8000 117 | EXPOSE 8000 118 | ``` 119 | 120 | ### Explicação 121 | 122 | - **python:3.12-slim**: Utiliza a imagem base do Python 3.12 (slim) para manter o container leve. 123 | 124 | > ***Obs.:** Ajuste para a versão do Python do seu projeto.* 125 | 126 | - **WORKDIR /app**: Define o diretório de trabalho como `/app`. 127 | - **EXPOSE 8000**: Expondo a porta 8000 para o Django servir a aplicação. 128 | 129 |
130 | 131 | ## 2. docker-compose.yml 132 | 133 | O `docker-compose.yml` define os serviços que serão executados em containers Docker. Ele inclui o serviço de banco de dados PostgreSQL, o serviço da aplicação Django, e o servidor Nginx. 134 | 135 | ```yaml 136 | services: 137 | db: 138 | image: postgres:latest 139 | container_name: postgres_db 140 | volumes: 141 | - postgres_data:/var/lib/postgresql/data 142 | env_file: 143 | - .env 144 | environment: 145 | POSTGRES_DB: ${DB_NAME} 146 | POSTGRES_USER: ${DB_USER} 147 | POSTGRES_PASSWORD: ${DB_PASSWORD} 148 | ports: 149 | - "5432:5432" 150 | networks: 151 | - app_network 152 | 153 | web: 154 | build: . 155 | container_name: django_app 156 | command: > 157 | sh -c "./wait-for-it.sh db:5432 -- python manage.py makemigrations && 158 | python manage.py migrate && 159 | python manage.py collectstatic --noinput && 160 | gunicorn app.wsgi:application --bind 0.0.0.0:8000" 161 | volumes: 162 | - static_volume:/app/staticfiles 163 | - media_volume:/app/media 164 | env_file: 165 | - .env 166 | depends_on: 167 | - db 168 | networks: 169 | - app_network 170 | 171 | nginx: 172 | image: nginx:latest 173 | container_name: nginx_server 174 | volumes: 175 | - ./nginx.conf:/etc/nginx/nginx.conf 176 | - static_volume:/app/staticfiles 177 | - media_volume:/app/media 178 | ports: 179 | - "80:80" 180 | depends_on: 181 | - web 182 | networks: 183 | - app_network 184 | 185 | networks: 186 | app_network: 187 | driver: bridge 188 | 189 | volumes: 190 | postgres_data: 191 | static_volume: 192 | media_volume: 193 | ``` 194 | 195 | ### Explicação 196 | 197 | - **db**: Serviço do PostgreSQL. Ele utiliza o volume `postgres_data` para persistir dados e as variáveis de ambiente no arquivo `.env`. 198 | - **web**: Serviço da aplicação Django, que constrói a imagem a partir do `Dockerfile` e executa comandos como migrações, coleta de estáticos e inicialização do servidor Gunicorn. 199 | 200 | > ***Obs.:** É imprescindível que a lib **Gunicorn** esteja presente no arquivo `requirements.txt`* 201 | 202 | - **nginx**: Serviço do servidor Nginx, configurado para servir os arquivos estáticos e fazer proxy reverso para o Gunicorn. 203 | 204 |
205 | 206 | ## 3. nginx.conf 207 | 208 | O arquivo `nginx.conf` configura o servidor Nginx, que fará o proxy reverso para o Gunicorn e servirá os arquivos estáticos e de mídia. 209 | 210 | ```nginx 211 | worker_processes auto; 212 | 213 | events { 214 | worker_connections 1024; 215 | } 216 | 217 | http { 218 | sendfile on; 219 | tcp_nopush on; 220 | tcp_nodelay on; 221 | keepalive_timeout 65; 222 | types_hash_max_size 2048; 223 | include /etc/nginx/mime.types; 224 | default_type application/octet-stream; 225 | upstream django { 226 | server web:8000; 227 | } 228 | 229 | server { 230 | listen 80; 231 | server_name localhost; 232 | 233 | location /static/ { 234 | alias /app/staticfiles/; 235 | } 236 | 237 | location /media/ { 238 | alias /app/media/; 239 | } 240 | 241 | location / { 242 | proxy_pass http://django; 243 | proxy_set_header Host $host; 244 | proxy_set_header X-Real-IP $remote_addr; 245 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 246 | proxy_set_header X-Forwarded-Proto $scheme; 247 | } 248 | } 249 | } 250 | ``` 251 | 252 | ### Explicação 253 | 254 | - **upstream django**: Define o servidor Gunicorn (`web:8000`) como o destino do proxy. 255 | - **location /static/**: Serve os arquivos estáticos do Django. 256 | - **location /media/**: Serve os arquivos de mídia do Django. 257 | - **proxy_pass**: Redireciona as requisições para o servidor Gunicorn. 258 | - **worker_connections**: Este parâmetro define o número máximo de conexões que um único worker (processo) do Nginx pode manter simultaneamente. No exemplo, ele está configurado para `1024`, o que significa que cada worker pode lidar com até 1024 conexões simultâneas. Aumentar esse valor pode ser útil se você espera um grande volume de tráfego na aplicação. No entanto, valores muito altos podem levar a uma maior utilização de memória, portanto, é importante encontrar um equilíbrio com o número de workers e a carga do servidor. 259 | 260 |
261 | 262 | ## 4. Variáveis de Ambiente 263 | 264 | O arquivo `.env` deve conter as variáveis de configuração necessárias para os serviços, como informações do banco de dados. 265 | 266 | Exemplo de `.env`: 267 | 268 | ```env 269 | DB_NAME=name 270 | DB_USER=postgres 271 | DB_PASSWORD=admin@123 272 | DB_HOST=db 273 | DB_PORT=5432 274 | DB_SCHEMA=schema_db 275 | ``` 276 | 277 | #### ⚠️ **Observação Importante:** 278 | 279 | Como está sendo usado a configuração `networks` no `docker-compose.yml`, o *host* do Banco de Dados no arquivo `.env` precisa ser o nome do serviço do PostgreSQL, que no caso é `db`, e não `localhost` ou `127.0.0.1`. 280 | 281 |
282 | 283 | --- 284 | 285 |
286 | 287 | ## Como Rodar o Projeto 288 | 289 | ### 1. Construir as imagens e iniciar os containers 290 | 291 | #### Execute os comandos 292 | 293 | ```bash 294 | docker-compose build 295 | ``` 296 | 297 | ```bash 298 | docker-compose up -d 299 | ``` 300 | 301 | ### 2. Criar o superusuário Django 302 | 303 | Após iniciar os containers, crie o *superuser* Django para acessar o painel administrativo: 304 | 305 | ```bash 306 | docker-compose exec web python manage.py createsuperuser 307 | ``` 308 | 309 | ### 3. Acessar a aplicação 310 | 311 | A aplicação estará disponível no `http://localhost`, onde o Nginx estará servindo a aplicação Django através do Gunicorn. 312 | 313 |
314 | 315 | --- 316 | 317 |
318 | 319 | ## Situações Adversas 320 | 321 | ### 1. Precisar remover todos os Volumes e recriar 322 | 323 | Para remover todos os volumes e recriar tudo novamente, execute o seguinte comando: 324 | 325 | ```bash 326 | docker-compose down -v 327 | ``` 328 | 329 | Se necessário, execute o comando abaixo para limpar todo o Docker completamente: 330 | 331 | ```bash 332 | docker system prune -a 333 | ``` 334 | 335 | Em seguida, execute novamente os comandos da seção **1. Construir as imagens e iniciar os containers** 336 | 337 |
338 | 339 | ### 2. Precisar apenas atualizar o conteúdo do container da aplicação Django 340 | 341 | Essa ação é útil quando há apenas a modificação de um bloco de código do projeto, ou implementação de uma nova funcionalidade. Para isso, execute o seguinte comando: 342 | 343 | ```bash 344 | docker-compose up -d --build web 345 | ``` 346 | 347 | Isso irá subir o novo código fonte para o container da aplicação, que no exemplo chama-se `web`. 348 | --------------------------------------------------------------------------------