Python-en-equipo / MarketPlace

Aplicación web Tipo Marketplace, registro de usuarios, post y compras de usuarios y vendedores desarrollada con Django y Tailwind
11 stars 1 forks source link

Deploy automatico #62

Closed devrrior closed 2 years ago

devrrior commented 2 years ago
devrrior commented 2 years ago

Documentación del deploy automático

Antes de empezar a configurar el workflow para el deploy automático, hice ciertos cambios en el Dockerfile y docker-compose, incluso elaboré un nuevo Dockerfile para el desarrollo local. Además cambié ciertas cosas en settings.py, para el deploy. Estos cambios los explicaré detalladamente más adelante.

Ejecución del proyecto en docker como espacio de trabajo

Como ya explicaba Angel en su documentacion, para usar Docker durante el desarrollo del proyecto debemo tener ciertas cosas:

Para poder correr nuestro contenedor debemos seguir los siguientes pasos:

  1. Abrir nuestrar terminal, de preferencia bash.
  2. Ubicarnos en nuestro proyecto.
  3. Construir nuestro contenedor mediante el siguiente comando docker-compose build
  4. Una vez se haya creado con exito, debemos de ejecutar lo siguiente docker-compose up
  5. Listo!

Con estos pasos ya podremos desarrollar el proyecto con Docker.

Tips y recomendaciones

Cambios en settings.py

  1. Primero cambie el valor de DEBUG por una variable de entorno, esto permitira cambiarlo cuando sea necesario.
  2. Para probar la implementacion tuve que realizar el despliegue en un heroku privado, por lo cual tuve que agregar el dominio del heroku privado en ALLOWED_HOSTS.
  3. Algo importante para que los formularios funcionen, es agregar una variable la cual es CSRF_TRUSTED_ORIGINS, esto permitara utilizar los formularios y asi no tengamos problemas con CSRF_TOKEN.
  4. Por último tuve que comentar la configuración de REDIS, ya que no se esta utilizando en el despliegue.

DEBUG = env('DEBUG')

ALLOWED_HOSTS = ["localhost", "127.0.0.1", "http://127.0.0.1:8000/", "django-ecommerce-v1.herokuapp.com", "test-marketplace-django.herokuapp.com"]

CSRF_TRUSTED_ORIGINS = ['https://test-marketplace-django.herokuapp.com', 'https://django-ecommerce-v1.herokuapp.com']

# CACHE REDIS
# CACHES = {
#     "default": {
#         "BACKEND": "django_redis.cache.RedisCache",
#         "LOCATION": "redis://127.0.0.1:6379/1",
#         "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
#         "KEY_PREFIX": "ecomm",
#     }
# }

Mejoras en Dockerfile

En el Docker files hice ciertas mejoras, a continuación las listo:

  1. La primera mejora es cambiar la imagen que se utiliza en el contenedor, utilice la imagen alpine, esta imagen nos ofrece la ventaja de que su peso es muy pequeño, por lo que disminuye el tiempo de construcción del contenedor.
  2. Otro cambio que realice fue que para aprovechar la cacheabilidad que tiene Docker, fue que en lugar de copiar todo el proyecto, primero copie el requirements-deploy.txt (en este archivo estan las librerias necesarias para correr nuestro proyecto). Despues se actualiza los paquetes de la imagen, instalo ciertos paquetes los cuales son necesarios para la instalación de las librerias que necesita el proeycto y actualizó pip. Una vez hecho esto copio el proyecto al contenedor. Como comentaba al principio hice esto pasos para usar la cacheabilidad, con esto si realizamos algun cambio en el proyecto y queramos correr el contenedor, no tenga que instalar de nuevo las librerias que necesita el proyecto, esto nos ayudará a ahorrar tiempo.
  3. Por ultimo creé un script muy básico donde se apliquen las migraciones que hemos creado y después corra el servidor en heroku.
FROM python:3.8-alpine3.15

# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE=1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED=1

WORKDIR /app

COPY ./requirements-deploy.txt ./

RUN  apk update \
  && apk add --no-cache gcc musl-dev postgresql-dev python3-dev jpeg-dev zlib-dev \
  && pip install --upgrade pip

RUN python -m pip install -r requirements-deploy.txt 

COPY ./ ./

CMD [ "sh", "entrypoint.sh" ]
#!/bin/sh

python manage.py collectstatic --noinput
python manage.py migrate

gunicorn config.wsgi:application --bind 0.0.0.0:$PORT

Creación de local.Dockerfile

Ademas de crear un Dockerfile para el deploy, creé un Dockerfile para que los desarrolladores puedan correr el proyecto sin ningún problema, el archivo es casi lo mismo, solo que para correr el proyecto lo indico en el docker-compose.

FROM python:3.8-alpine3.15

# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE=1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED=1

WORKDIR /app

COPY ./requirements.txt ./

RUN  apk update \
  && apk add --no-cache gcc musl-dev postgresql-dev python3-dev  jpeg-dev zlib-dev \
  && pip install --upgrade pip

RUN python -m pip install -r requirements.txt 

COPY ./ ./

Mejoras en docker-compose.yml

En este archivo modifiqué pocas cosas, es lo siguiente:

  1. Primero que nada comente la imagen redis, ya que no se utiliza por el momento.
  2. Otra cosa fue que esta utilizando la distribución alpine, la cual como ya comentaba anteriormente, sirve para que la imagen se construye en el menor tiempo posible.
  3. Tambien cambié el puerto en el cual comparte entre nuestra computadora personal y el contenedor.
  4. En la parte build, cambie el nombre del Dockerfile, por local.Dockerfile.
  5. Ya que en local.Dockerfile no indicamos que corra el proyecto, en este archivo le indicamos que haga las migraciones pertinentes y que al final corra nuestro proyecto.
  6. Por último en enviroment, agrego las variables de entorno que faltan, tales como DEBUG y DJANGO_KEY.
version: '3.4'

services:
  # redis:
  #   restart: always
  #   image: redis:5
  #   ports:
  #     - "6379:6379"

  db:
    restart: always
    #restart: unless-stopped
    image: postgres:14.1-alpine3.15 
    volumes:
      - ./data/db:/var/lib/postgresql/data
    ports:
      - 5431:5432 # para que sea visible en nuestro entorno local 
    environment:
      - POSTGRES_NAME=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres

  django:    
    restart: always
    container_name: django
    build:      
      context: .
      dockerfile: ./local.Dockerfile
    command: >
      sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_NAME=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_HOST=db
      - ALLOWED_HOSTS=127.0.0.1, localhost     
      - DJANGO_KEY=123
      - DEBUG=True

    volumes:
      - .:/app
    depends_on:
      - db

Cambios en django-test.yml para el deploy automático

Para agregar el deploy automático use una Github Action ya precreada, solo agregue la configuración pertinente, tales como:

Tambien agregue las variables de entorno que necesita nuestro proyecto, estas las pasara a Heroku.

# some config
  release:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.12 # This is the action
        with:
          heroku_api_key: ${{secrets.TEST_HEROKU_API_KEY}}
          heroku_app_name: "test-marketplace-django" #Must be unique in Heroku
          heroku_email: "devrrior@gmail.com"
          usedocker: true
        env:
          HD_POSTGRES_NAME: ${{secrets.TEST_NAME_DB_HEROKU}}
          HD_POSTGRES_USER: ${{secrets.TEST_USER_DB_HEROKU}}
          HD_POSTGRES_PASSWORD: ${{secrets.TEST_PASSWORD_DB_HEROKU}}
          HD_POSTGRES_HOST: ${{secrets.TEST_HOST_DB_HEROKU}}
          HD_DJANGO_KEY: ${{secrets.DJANGO_KEY}}
          HD_DEBUG: ${{secrets.DEBUG}}
          HD_AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
          HD_AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
          HD_AWS_STORAGE_BUCKET_NAME: ${{secrets.AWS_STORAGE_BUCKET_NAME}}

Cambios en devcontainer.json

En este archivo realicé los siguientes cambios:

{
  "name": "MarketPlace",

  "dockerComposeFile": ["../docker-compose.yml"],

  "service": "django",

  "workspaceFolder": "/app", // Carpeta donde se encuentra el proyecto en el contenedor

  "settings": {
    "python.defaultInterpreterPath": "/usr/local/bin/python", // Para que vs code encuentre los modulos necesarios
    "python.linting.enabled": true,
    "python.linting.pylintEnabled": true,
    "python.linting.pylintPath": "/usr/local/bin/pylint",
    "python.languageServer": "Pylance", // Activar autocompletado
  },

  "extensions": ["ms-python.python", "VisualStudioExptTeam.vscodeintellicode"],

  "remoteEnv": {
    "PATH": "${containerEnv:PATH}"
  },

  "shutdownAction": "stopCompose"

}
CodeRagnarok07 commented 2 years ago

Es mas eficiente en cuanto a rapidez y se elimino el redis, el devcontainer no lleva modificaciones? no hay algo que se pueda mejorar allí?, estaba teniendo el problema de que la imagen de python que había creado se corrompe por alguna razon cada ves que tengo que hacer re build, al menos, mas que todo por que no se cerraba bien el docker, y creo que era por la configuration del devcontainer, si esta configuracion ya esta bien entonces no creo que tenga que hacer re build cierto, por medio de dev container se modifican los archivos y paquetes en tiempo real

devrrior commented 2 years ago

No había pensado la configuración de devcontainer, es un punto que se me paso ya que no uso VS Code. Pero de todas maneras me informaré de como funciona devcontainer y su configuración necesaria, para que no tengan ningun problema.

devrrior commented 2 years ago

Es mas eficiente en cuanto a rapidez y se elimino el redis, el devcontainer no lleva modificaciones? no hay algo que se pueda mejorar allí?, estaba teniendo el problema de que la imagen de python que había creado se corrompe por alguna razon cada ves que tengo que hacer re build, al menos, mas que todo por que no se cerraba bien el docker, y creo que era por la configuration del devcontainer, si esta configuracion ya esta bien entonces no creo que tenga que hacer re build cierto, por medio de dev container se modifican los archivos y paquetes en tiempo real

Ya pude probar lo de devcontainer, pude agregar ciertas cosas como el autocompletado e indicarle donde se encuentra el interpretador de python dentro del container. Ademas que arregle une error de que no encontraba en que directorio se encontraba el proyecto dentro del container. En cuanto el error a la hora de cerrar el contenedor, a mi no me sucede eso, igual si puedes checarlo con la nueva config para ver si el error persiste.