Skip to content

Commit 194676a

Browse files
committed
update docker nginx + jwt + product model + command to populate
1 parent d68f8a8 commit 194676a

File tree

21 files changed

+328
-24
lines changed

21 files changed

+328
-24
lines changed

.env

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,11 @@ DB_USER=django_user
1414
DB_PASSWORD=django_pass
1515
DB_HOST=db
1616
DB_PORT=5432
17+
18+
# Nuevas configuraciones
19+
PGADMIN_DEFAULT_EMAIL=[email protected]
20+
PGADMIN_DEFAULT_PASSWORD=admin_password_here
21+
22+
# Opcional: Cambia puertos si 80/5050 están ocupados en Windows
23+
NGINX_HOST_PORT=80
24+
PGADMIN_PORT=5050

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ venv/
88
*.sock
99
/static/
1010
/media/
11+
logs/
1112
# .env
1213
.idea/
1314
.vscode/
@@ -16,3 +17,4 @@ __pycache__/
1617
*.pid
1718
*.seed
1819
*.tar
20+
migrations

docker-compose.override.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ services:
66
environment:
77
DEBUG: "1"
88
volumes:
9-
- .:/app
9+
- ./:/app
10+
- ./logs/web:/var/log/app
11+
ports:
12+
- "8000:8000"
13+

docker-compose.yml

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ services:
1111
POSTGRES_DB: ${POSTGRES_DB}
1212
POSTGRES_USER: ${POSTGRES_USER}
1313
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
14-
ports:
15-
- "${POSTGRES_PORT}:5432"
14+
# ports:
15+
# - "${POSTGRES_PORT}:5432"
1616
volumes:
1717
- postgres_data:/var/lib/postgresql/data
1818
healthcheck:
@@ -31,30 +31,63 @@ services:
3131
- .env
3232
command: >
3333
sh -c "python manage.py migrate &&
34-
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000"
34+
python manage.py collectstatic --noinput &&
35+
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000"
3536
volumes:
36-
- .:/app
37-
ports:
38-
- "8000:8000"
39-
environment:
40-
DB_NAME: ${DB_NAME}
41-
DB_USER: ${DB_USER}
42-
DB_PASSWORD: ${DB_PASSWORD}
43-
DB_HOST: ${DB_HOST}
44-
DB_PORT: ${DB_PORT}
45-
DEBUG: ${DEBUG}
46-
SECRET_KEY: ${SECRET_KEY}
37+
- .:/app:ro # en producción es preferible readonly o no montar (a gusto)
38+
- ./logs/web:/var/log/app # logs persistentes del servicio web
39+
# ports:
40+
# - "8000:8000"
41+
# environment:
42+
# DB_NAME: ${DB_NAME}
43+
# DB_USER: ${DB_USER}
44+
# DB_PASSWORD: ${DB_PASSWORD}
45+
# DB_HOST: ${DB_HOST}
46+
# DB_PORT: ${DB_PORT}
47+
# DEBUG: ${DEBUG}
48+
# SECRET_KEY: ${SECRET_KEY}
4749
depends_on:
4850
db:
4951
condition: service_healthy
5052
healthcheck:
51-
test: ["CMD", "curl", "-f", "http://localhost:8000"]
53+
test: ["CMD", "curl", "-f", "http://localhost:8000/health/ || exit 1"]
5254
interval: 10s
5355
timeout: 5s
5456
retries: 5
5557
networks:
5658
- django_network
5759

60+
nginx:
61+
image: nginx:stable-alpine
62+
container_name: django_nginx
63+
ports:
64+
- "80:80"
65+
volumes:
66+
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
67+
- ./staticfiles:/static:ro # carpeta donde collectstatic pondrá los archivos
68+
- ./logs/nginx:/var/log/nginx # logs persistentes de nginx
69+
depends_on:
70+
- web
71+
networks:
72+
- django_network
73+
74+
pgadmin:
75+
image: dpage/pgadmin4
76+
container_name: pgadmin
77+
env_file:
78+
- .env
79+
environment:
80+
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
81+
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
82+
ports:
83+
- "5050:80"
84+
volumes:
85+
- ./logs/pgadmin:/var/lib/pgadmin
86+
depends_on:
87+
- db
88+
networks:
89+
- django_network
90+
5891
volumes:
5992
postgres_data:
6093

myproject/settings.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
from pathlib import Path
3+
from datetime import timedelta
34

45
# Build paths inside the project like this: BASE_DIR / 'subdir'.
56
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -30,6 +31,7 @@
3031
'rest_framework',
3132
# Apps locales
3233
'users',
34+
'products',
3335
]
3436

3537
MIDDLEWARE = [
@@ -113,6 +115,7 @@
113115

114116
# Archivos estáticos
115117
STATIC_URL = 'static/'
118+
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # coincidir con ./staticfiles
116119

117120
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
118121

@@ -121,10 +124,43 @@
121124

122125
# 🔥 CONFIGURACIÓN DE REST FRAMEWORK
123126
REST_FRAMEWORK = {
124-
'DEFAULT_AUTHENTICATION_CLASSES': [
125-
'rest_framework.authentication.SessionAuthentication',
126-
],
127-
'DEFAULT_PERMISSION_CLASSES': [
128-
'rest_framework.permissions.IsAuthenticated',
129-
],
130-
}
127+
'DEFAULT_AUTHENTICATION_CLASSES': (
128+
'rest_framework_simplejwt.authentication.JWTAuthentication',
129+
),
130+
}
131+
132+
SIMPLE_JWT = {
133+
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
134+
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
135+
'AUTH_HEADER_TYPES': ('Bearer',),
136+
}
137+
138+
LOG_DIR = os.path.join(BASE_DIR, 'logs')
139+
os.makedirs(LOG_DIR, exist_ok=True)
140+
141+
LOGGING = {
142+
'version': 1,
143+
'disable_existing_loggers': False,
144+
'formatters': {
145+
'verbose': {
146+
'format': '[{levelname}] {asctime} {module} {message}',
147+
'style': '{',
148+
},
149+
},
150+
'handlers': {
151+
'file': {
152+
'level': 'INFO',
153+
'class': 'logging.FileHandler',
154+
'filename': os.path.join(LOG_DIR, 'app.log'),
155+
'formatter': 'verbose',
156+
},
157+
'console': {
158+
'class': 'logging.StreamHandler',
159+
},
160+
},
161+
'root': {
162+
'handlers': ['file', 'console'],
163+
'level': 'INFO',
164+
},
165+
}
166+

myproject/urls.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11

22
from django.contrib import admin
33
from django.urls import path, include
4+
from rest_framework_simplejwt.views import (
5+
TokenObtainPairView,
6+
TokenRefreshView,
7+
)
48

59
urlpatterns = [
610
path('admin/', admin.site.urls),
711
path('api/', include('users.urls')),
12+
path('api/login/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
13+
path('api/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
14+
path('api/', include('products.urls')),
815
]

nginx/nginx.conf

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
user nginx;
2+
worker_processes auto;
3+
error_log /var/log/nginx/error.log warn;
4+
pid /var/run/nginx.pid;
5+
6+
events {
7+
worker_connections 1024;
8+
}
9+
10+
http {
11+
include /etc/nginx/mime.types;
12+
default_type application/octet-stream;
13+
sendfile on;
14+
keepalive_timeout 65;
15+
16+
upstream django {
17+
server web:8000;
18+
}
19+
20+
server {
21+
listen 80;
22+
server_name _;
23+
24+
# Serve static files
25+
location /static/ {
26+
alias /static/;
27+
}
28+
29+
# Healthcheck (si tienes ruta /health/)
30+
location /health/ {
31+
proxy_pass http://django/health/;
32+
}
33+
34+
# Proxy pass all other requests to Django
35+
location / {
36+
proxy_set_header Host $host;
37+
proxy_set_header X-Real-IP $remote_addr;
38+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
39+
proxy_set_header X-Forwarded-Proto $scheme;
40+
proxy_pass http://django;
41+
}
42+
}
43+
}

products/__init__.py

Whitespace-only changes.

products/admin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.contrib import admin
2+
from .models import Product
3+
4+
@admin.register(Product)
5+
class ProductAdmin(admin.ModelAdmin):
6+
list_display = ('id', 'name', 'price', 'stock', 'owner', 'is_public')

products/apps.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class ProductsConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'products'

0 commit comments

Comments
 (0)