DevContainer; Docker como entorno de desarrollo con Django y Postgesql
Angel riera
Posted on February 25, 2022
Docker para mi se a convertido en una necesidad para solucionar los problemas de entorno de desarrollo ya sea ambiente laborar o con grupos de trabajo, además la idea de no tener que instalar ningún software en mi terminal wsl me evita pasar ratos actualizando y descargando versiones, y solucionando diferentes problemas de estos softwares
con visual estudio code aprovechamos la maquina virtual generada por docker como nuestro entorno de desarrollo, con los softwares requeridos para nuestro proyecto
Requerimientos:
- instalar docker Destokc https://www.docker.com/products/docker-desktop
- Intalar los plugins de vscode
Docker simple Imagen
la principal función de docker es tener un servidor aparte del nuestro para ejecutar el proyecto, para ello creamos una build con los archivos de nuestro proyecto que seran trasladados a el contenedor de docker ademas esta build debera tener algunas instalaciones para trabajar con las herramientas del proyecto
- Creamos un archivo
Dokerfile
preferiblemente que este alado demanage.py
FROM python:3.8
EXPOSE 8000
# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE=1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED=1
# Install pip requirements
#COPY backend/requirements.txt /backend/
#RUN python -m pip install --upgrade pip
#RUN python -m pip install -r requirements.txt
#RUN python3 manage.py makemigrations
#RUN python3 manage.py migrate
WORKDIR /app
COPY . ./app
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "pythonPath.to.wsgi"]
Detalles:
-
FROM python:3.8
⇒ imagen que vamos a descargar desde docker hub, continene una terminal de linux expecializada para desarrollo con la herramienta objetiva -
EXPOSE 8000
⇒ le decimos que puerto usara dentro del container “localhost:8000” ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
Ejecucion de los comandos
# Install pip requirements
#COPY backend/requirements.txt /backend/
#python -m pip install --upgrade pip
#RUN python -m pip install -r requirements.txt
#RUN python3 manage.py makemigrations
#RUN python3 manage.py migrate
esta toda la logica que se va a ejecutar tras crear en contenedor, lo comento para que no se ejecute para acelerar el desarrollo en local, pero recuerda ejecutar estos comandos manualmente mas adelante
WORKDIR /app
⇒ le decimos al contenedor que en “/app” sera el espacio de trabajoCOPY . ./app
⇒ copia todos los archivos en “.” a la direccion dentro del contenedor “./app”CMD ["gunicorn", "--bind", "0.0.0.0:8000", "pythonPath.to.wsgi"]
⇒ la ejecucion de gunicorn- Acontinuacion podemos ejecutar la build lo cual llevar todo nuestro proyecto a un contenedor
docker build
⇒ ejecuta la build con nuestro proyecto dentro del container- Cada ves que modifiquemos algo de nuestro proyecto tenemos que apagar la ejecucion del container y volver a crear la build y ejecutarla, evitaremos todo este proceso en el con el
devcontainer
mas adelante
Hoja de comandos para la administracion de docker:
`docker version`
“Docker hub para ver las imágenes disponibles”
`docker images` ⇒ verifica todas las imagenes disponibles
`docker rmi [nombre de la imagen]` ⇒ elimina una imagen del sistema
`docker rmi $(docker images -aq)` ⇒ Script que elimina todas las imagenes
`docker pull hello-word` ⇒ descarga la imagen
`docker run hello-word` ⇒ ejecuta la imagen
`docker search [nombre de la imagen]` ⇒ Busca las versiones de las imágenes
`docker run ubuntu echo 'hello world'` ⇒ ejecuta los programas disponibles dentro de la imagen
`docker run -it ubuntu bash` ⇒ ejecuta de manera interactiva los programas disponibles dentro de la imagen
“ todos los contenedores al crearse mueren vuelven a un estado en stop automáticamente”
`docker ps` ⇒ muestra las imágenes que están en ejecución y sus datos
`docker ps -a` ⇒ todos los contenedores existentes en stop
`docker ps -aq` ⇒ todos los contenedores existentes en stop solo mostrando una lista de id’s
`docker rm [id o nombre]` ⇒ elimina del historial un contenedor ejecutado a través del nombre o id devuelto en el historial
`docker rm $(docker ps -aq)` ⇒ Script que elimina todos los contenedores en stop
`docker rm $(docker ps -aq) -f` ⇒ Fuerza a detener y eliminar los contenedores
`docker start [id o nombre]` ⇒ vuelve a ejecutar un contenedor del historial o en stop
`docker stop [id o nombre]` ⇒ detiene el contenedor en ejcucion
`docker exec -it [id o nombre] bash` ⇒ ejecuta un programa disponible dentro del contenedor en un contenedor previamente creado
Docker compose
podemos ejecutar nuestro proyecto normalmente dentro del container, el problema es que nuestro container no tiene una lectura para nuestra base de datos local, también hay otros servicios locales que necesita nuestro proyecto para ejecutarse, por ello usamos el compose
- Creamos un archivo docker-compose.yml, en el mismo directorio de Dockerfile, ya que lo vamos a linkear en el siguiente paso
- agregamos esta configuración
version: '3.4'
services:
redis:
restart: always
image: redis:5
ports:
- "6379:6379"
db:
restart: always
#restart: unless-stopped
image: postgres
volumes:
- ./data/db:/var/lib/postgresql/data
ports:
- 5432:5432 # para que sea visible en nuestro entorno local
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
django:
restart: always
image: django
container_name: django
build:
context: .
dockerfile: ./Dockerfile
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
# command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- ALLOWED_HOSTS=127.0.0.1, localhost
volumes:
- .:/workspace
depends_on:
- db
- redis
Explicaciones:
cada subcategoría de services
será una imagen o una terminal de linux que se ejecutara en nuestro container, ose la maquina virtual que creamos,
django: # => nombre de imagen personalizada
restart: always # => momento de ejecuciones
image: django # => nombre de imagen personalizada
container_name: django # nombre de imagen personalizada
build: # => definimos que imagen tendrá esta terminal
context: . # => definimos en que ruta buscar la imagen
dockerfile: ./Dockerfile # => el archivo que creamos en el paso anteriro
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
# command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000" #=> el puerto que usa la imagen : el puerto en el que estará disponible en el enrtorno local
environment: #=> variables de entorno en el path
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- ALLOWED_HOSTS=127.0.0.1, localhost
volumes:
- .:/workspace #=> define que archivos de nuestro proyecto se llevara al container
depends_on: #=> define que otras terminales se va a conectar
- db
- redis
-
aquí prefiero agregar las variables de entorno a nuestro proyecto local para poder alternar entre entornos virtuales
- definición de los datos de postgres
- sttigns usando las nuevas variables de entorno
- variables de entorno definidas en el docker-compose agregadas al .env
ejecutamos
docker-compose build
en la terminal deberia funcionar correctamenteRecuerda ejecutar los comandos omitidos en el Dockerfile
Devcointainer
con esta herramienta de trabajo podremos usar nuestro container como espacio de trabajo, para no tener que parar , y crear nuevamente la build después de cada edición de nuestro proyecto
- en el entorno de desarrollo crea una carpeta
.devcontainer
que contendrá los siguientes archivos - El archivo
devcontainer.json
contiene la inicialización del contenedor por medio de vscode
1. contenido del archivo
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.217.1/containers/docker-existing-docker-compose
// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml.
{
"name": "Existing Docker Compose (Extend)",
// Update the 'dockerComposeFile' list if you have more compose files or use different names.
// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
"dockerComposeFile": [
"../docker-compose.yml"
],
// The 'service' property is the name of the service for the container that VS Code should
// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
"service": "django",
// The optional 'workspaceFolder' property is the path VS Code should open by default when
// connected. This is typically a file mount in .devcontainer/docker-compose.yml
"workspaceFolder": "/workspace",
// Set *default* container specific settings.json values on container create.
"settings": {
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.linting.pylintPath": "/usr/local/bin/pylint"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python"
],
"remoteEnv": {
"PATH": "${containerEnv:PATH}"
},
// The 'service' property is the name of the service for the container that VS Code should
// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Uncomment the next line if you want start specific services in your Docker Compose config.
// "runServices": [],
// Uncomment the next line if you want to keep your containers running after VS Code shuts down.
"shutdownAction": "stopCompose",
// Uncomment the next line to run commands after the container is created - for example installing curl.
// "postCreateCommand": "apt-get update && apt-get install -y curl",
// Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
// "remoteUser": "vscode"
}
Descripcion:
"dockerComposeFile":
⇒ busca la ubicación de docker-compose
"service": "django"
, ⇒ define cual de las imágenes de docker-compose
"workspaceFolder": "/workspace",
⇒ define cual serán los archivos que tomara encuentra para actualizarlos en tiempo real
-
para ejecutar nuestro espacio de trabajo deberás cerrar el vscode y volverlo a abrir y utilizar la siguiente opción
Reopen in Container
-
Recuerda ejecutar los comandos omitidos en el Dockerfile en el primer apartado
#RUN python -m pip install --upgrade pip #RUN python -m pip install -r requirements.txt #RUN python3 manage.py makemigrations #RUN python3 manage.py migrate
Posted on February 25, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.