├── 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 |
--------------------------------------------------------------------------------