#1 Docker: Divide y conquista.

jonathan carrasco garcia
Crehana
Published in
6 min readMay 16, 2018

Hola, dado que este es mi primer post en medium, haré una breve presentación de lo que iré posteando a lo largo del tiempo, por este medio.

Tengo pensado escribir una serie de posts hablando sobre la evolución de mi proyecto, en donde básicamente escribiré acerca de como voy integrando nuevas tecnologías, resolviendo problemas, o simplemente probando ideas que se me ocurran en mi proyecto.

Pero antes de hablar del proyecto quisiera aclarar que esto no es un tutorial o guía sobre como desarrollar o implementar alguna tecnología, yo considero esto como historias o experiencias que todo programador pasa o podria pasar en el camino en el desarrollo de alguna plataforma, la razón de esto es porque cuando estaba tratando de escribir un post tipo tutorial o explicando sobre una tecnología me sentia repetitivo, algo aburrido y con poco aporte a la comunidad, sabiendo esto, comencemos.

Cual es la idea ?

El objetivo de mi proyecto es crear una aplicación web en donde las personas puedan compartir sus itinerarios de viajes, indicando el horario, presupuesto, lugares a visitar, fotos, ubicaciones y mas información que podrían ayudar a otros viajeros a realizar sus viajes.

Primeros pasos:

Como a muchos de nosotros (Tech's) nos pasa, siempre tenemos miles de cosas por hacer y dejamos de lado ciertos proyectos o ideas que se nos pasa por la mente, algunas veces en nuestro afán de querer implementar lo ultimo, probar nuevas tecnologías o simplemente querer hacerlo perfecto, perdemos el foco de terminar el proyecto dado que estamos mas al pendiente de aprender nuevas tecnologías, cosa que esta bien, pero eso te puede llevar a no culminar el proyecto, así que primero trate de enfocarme en terminar la funcionalidad mínima para luego implementar nuevas tecnologías, ( … 3 semanas después …) luego de varias horas de trabajo (durante varios dias) pude completar la funcionalidad mínima para poder hacer realidad este proyecto.

De que esta echo ?

Como primer punto les presentare mi stack de tecnología:

  • Como lenguaje de programación tenemos Python.
  • Como framework por el lado de backend usaremos Django.
  • La vieja confiable (o no) Jquery.
  • Algunas librerias tipicas: Google maps, API de youtube, bootstrap, entre otros.

Porque no usas angular, React o cualquier framework para el lado de front ?

Mi perfil como desarrollador esta mas inclinado por el lado de backend, por este motivo queria dejar lo mas simple posible el lado front , ya para luego en el futuro, mejorarlo usando nuevas tecnologías, ademas por experiencia previa si me meto a aplicar tecnologías que no domino era muy probable que termine aprendiendo dicha tecnología (lado bueno) pero sin culminar el proyecto (lado malo).

Vamos al grano !!!

Para este episodio vamos a resolver un problema, que algunos de mis visitantes reportaron, y era que cuando ellos trataban de ingresar a mi web, pero por algún motivo no lograban entrar, algo que logre detectar gracias a que los visitantes me enviaron impresiones de pantalla, era que ellos trataban de ingresar sin usar https, en teoria mi configuración de nginx hay un proxy pass que se encarga de redireccionar (pero al parecer esta fallando).

Y … Como esta implementado tu web en el servidor ?

Encontre esta imagen que ilustra perfectamente de como esta implementado mi servidor.

Solo mencionar que estoy usando Digital Ocean y toda esta implementación en dos contenedores de Docker uno con Django + Gunicorn + supervisor + nginx y otro con la base de datos.

Mi teoria es que por algún motivo cuando el cliente hace una petición para ingresar a mi web nginx no esta realizando la redireccion correctamente. La solución que he planteado es separar nginx en otro contenedor.

Veamos como esta implementado en la actualidad (fecha que escribir este post):

version: '3'

services:
db:
image:
mdillon/postgis
container_name: "mi_pagina"
ports:
- "5433:5432"
volumes:
- 'pgdata:/var/lib/postgresql/data/'
env_file:
env
web:
build:
.
command: /bin/bash /var/www/mi_pagina/code/entrypoint.sh
ports:
- "8080:80"
- "443:443"
depends_on:
- db
volumes:
- /etc/letsencrypt/:/etc/letsencrypt/
- /var/www/mi_pagina_media/:/var/www/mi_pagina/code/media/
env_file: env

volumes:
pgdata:

Decidi hacer toda la construcción de los contenedores haciendo uso de docker-compose, algunos dicen que no es recomendable, pero yo lo veo super practico, ademas si noto que da problemas en el futuro no es tan complicado cambiarlo.

Como observación quisiera mencionar que use un servicio gratuito para agregar ssl a mi pagina (https://certbot.eff.org/) y bueno como les mencione parecer mi configuración de Nginx por algún motivo no re direcciona a los usuarios cuando tratan de acceder a mi web sin usar https.

A continuación les comparto mi configuración en Nginx:

upstream mi_pagina{
server 127.0.0.1:8000;
}

server {
listen 80;
server_name www.mi_pagina.com mi_pagina.com;

return 301 https://mi_pagina.com$request_uri;
}

server {
listen 80;
server_name mi_pagina.com;

return 301 https://mi_pagina.com$request_uri;
}

server {
listen 80;
server_name www.lifeinjona.com lifeinjona.com;

return 301 https://mi_pagina.com$request_uri;
}

server {
listen 443 ssl http2;
server_name www.mi_pagina.com;

ssl_certificate /etc/letsencrypt/live/www.mi_pagina.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.mi_pagina.com/privkey.pem;

return 301 https://mi_pagina.com$request_uri;
}

server {

listen 443 ssl;
server_name mi_pagina.com;

client_max_body_size 1G;
client_body_timeout 120s;
root /var/www/mi_pagina/code;

access_log /var/log/mi_pagina.log;
error_log /var/log/mi_pagina.log;

proxy_connect_timeout 1200;
proxy_read_timeout 1200;


ssl_certificate /etc/letsencrypt/live/mi_pagina.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mi_pagina.com/privkey.pem;

ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
keepalive_timeout 70;

location / {
send_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_redirect off;
proxy_pass http://mi_pagina/;
}

location /static/ {
alias /var/www/mi_pagina/code/staticfiles/;
expires 1w;
access_log off;

add_header Cache-Control "public";

# Custom fonts
if ($request_filename ~* ^.*\.(eot|ttf|woff)(\?.*)?$){
add_header Access-Control-Allow-Origin *;
}
}

location /media/ {
client_max_body_size 50m;
alias /var/www/mi_pagina/code/media/;
expires 1w;
access_log off;

add_header Cache-Control "public";

# Custom fonts
if ($request_filename ~* ^.*\.(eot|ttf|woff)(\?.*)?$){
add_header Access-Control-Allow-Origin *;
}
}
}

Como veran, he agregado varios proxy pass con la finalidad de asegurarme de que realice la redireccion correctamente pero como les mencione algo esta fallando.

Vamos a arreglarlo:
Pues llego el gran dia , aunque en realidad no se que esta fallando, pero algo que me recomendaron es separar el servicio de Nginx en otro contenedor, así que eso es lo que voy a hacer en este momento (mientras escribo este post).

Ok, Ya pasaron varias horas cambiando la configuración, probando y probando, y pude separar nginx en otro contenedor , quedando como resultado esto:

version: '3'

services:
db:
image:
mdillon/postgis
container_name: "migranaventura_postgres"
ports:
- "5433:5432"
volumes:
- 'pgdata:/var/lib/postgresql/data/'
env_file:
env
web:
image:
nginx:latest
container_name: "migranaventura_nginx"
ports:
- "80:80"
- "443:443"
restart:
always
volumes:
- /var/www/migranaventura/static:/var/www/migranaventura/code/staticfiles/
- /var/www/migranaventura_media/:/var/www/migranaventura/code/media/
- /etc/letsencrypt/:/etc/letsencrypt/
- /var/www/migranaventura/conf/Docker/nginx/nginx-app.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
environment:
- NGINX_PORT=80
app:
build:
.
expose:
- "8000"
command:
/bin/bash /var/www/migranaventura/code/entrypoint.sh
volumes:
- /var/www/migranaventura/static:/var/www/migranaventura/code/staticfiles/
- /var/www/migranaventura_media/:/var/www/migranaventura/code/media/
depends_on:
- db
env_file: env

volumes:
pgdata:

Podrán notar que tuve que crear volumenes para media y static, para que el contenedor de nginx tenga acceso.

Luego del cambio hubo un par de incidencias en donde los usuarios no podian ingresar a mi web, entonces como conclusion, si bien es cierto separar los servicios en contenedores diferentes es recomendado, no se pudo resolver complemente el problema, por el dia de hoy sera todo, hasta en un siguiente episodio.

Postdata: Cualquier recomendación en la caja de comentarios será bienvenido.

--

--