Cómo desplegar aplicaciones Django en Swarm

yamila-moreno

https://moduslaborandi.net

Principales componentes

  • Back

    Django Rest Framework, stateless, env vars

  • Front

    Single Page Application, leaflet.js

  • Base de datos

    PostgreSQL

Dockerizamos nuestras aplicaciones

  • Back

    Django Rest Framework, stateless, env vars

    + Dockerfile

  • Front

    Single Page Application, leaflet.js

    + Dockerfile

  • Base de datos

    PostgreSQL

Back > Dockerfile

            
FROM python:3.6-slim
LABEL maintainer="Yamila Moreno"

WORKDIR /

# Install dependencies
RUN apt-get update
RUN apt-get install -y -qq curl vim

# Install requirements
COPY requirements.txt /routes_api/
RUN pip install -r /routes_api/requirements.txt

# Setup the application
COPY . /routes_api

WORKDIR /routes_api
            
            

Front > Dockerfile

            
FROM abiosoft/caddy:latest
LABEL maintainer="Yamila Moreno"

# Caddy config
COPY Caddyfile /etc/Caddyfile
COPY . /routes_front
            
            

Travis-CI

  • Back

    Django Rest Framework, stateless, env vars

    Dockerfile

    + .travis.yml

  • Front

    Single Page Application, leaflet.js

    Dockerfile

    + .travis.yml

  • Base de datos

    PostgreSQL

Back > .travis.yml

            
branches:
  only:
    - master

env:
  global:
    - secure: "G+8KyEaXSDvcg..." # DOCKER_USER
    - secure: "X1M4tt6zA6Y3L..." # DOCKER_PASS
    - TEST_ENV=test_env

before_script:
  - docker build -f Dockerfile -t ryms/routes_api:latest .

script:
  - docker run -e TEST_ENV ryms/routes_api:latest pytest

after_success:
  - docker login -u $DOCKER_USER -p $DOCKER_PASS
  - docker push ryms/routes_api:latest
            
            

Front > .travis.yml

            
branches:
  only:
    - master

env:
  global:
    - secure: "G+8KyEaXSDvcgUGG..." # DOCKER_USER
    - secure: "X1M4tt6zA6Y3LCH4..." # DOCKER_PASS

before_script:
- docker build -f Dockerfile -t ryms/routes_front:latest .

script:
  - docker login -u $DOCKER_USER -p $DOCKER_PASS
  - docker push ryms/routes_front:latest
            
            

Principales componentes

  • Back

    Django Rest Framework, stateless, env vars

    Dockerfile

    .travis.yml

  • Front

    Single Page Application, leaflet.js

    Dockerfile

    .travis.yml

  • Base de datos

    PostgreSQL

¡A desplegar!

  • Swarm Mngr

    + docker-compose.yml

  • Swarm Worker

  • Swarm Worker

docker-compose.yml > PostgreSQL

            
version: "3.3"

services:
  routes_db:
    image: postgres:9.6
    environment:
      - "POSTGRES_DB=routes"
    volumes:
      - db-data:/var/lib/postgresql/data
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
            
            

docker-compose.yml > api

            
services:
    routes_db: [...]

    routes_api:
     image: ryms/routes_api:latest
     volumes:
       - static-data:/routes_api/static
     environment:
       POSTGRES_HOST: routes_db
       POSTGRES_USER: postgres
     command: >
        bash -c
        "export POSTGRES_DB=$$(< /run/secrets/POSTGRES_DB)
        && python manage.py migrate
        && python manage.py collectstatic --noinput
        && gunicorn project.wsgi -b 0.0.0.0:8000"
     deploy:
       replicas: 3
     secrets:
       - POSTGRES_DB

            
            
            
services:
    [...]

volumes:
    static-data:
      driver: local

secrets:
    POSTGRES_DB:
      external: true
            
            

docker-compose.yml > front

            
services:
    routes_db: [...]

    routes_api: [...]

    routes_front:
        image: ryms/routes_front:latest
        volumes:
          - static-data:/routes_api_static:ro
        deploy:
          replicas: 3

   volumes:
       static-data:
         driver: local
            
            

docker-compose.yml > prometheus

            
services:
    routes_db: [...]
    routes_api: [...]
    routes_front: [...]
    prometheus:
        image: basi/prometheus-swarm:latest
        ports:
          - "9090:9090"
        command: >
          -config.file=/etc/prometheus/prometheus.yml
          -storage.local.path=/prometheus
          -web.console.libraries=/etc/prometheus/console_libraries
          -web.console.templates=/etc/prometheus/consoles
          -alertmanager.url=http://alertmanager:9093
        deploy:
          placement:
            constraints:
              - node.role == manager
          resources:
            limits:
              cpus: '0.50'
              memory: 1024M
            
            

docker-compose.yml > traefik

                      
services:
  traefik:
     image: traefik
     command: --web --docker --docker.swarmmode --docker.watch --docker.domain=traefik --logLevel=DEBUG --web.metrics --web.metrics.prometheus
     ports:
       - "80:80"
       - "8080:8080"
     networks:
       - traefik-net
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - /dev/null:/traefk.toml
     labels:
       - "traefik.enable=false"
     deploy:
       placement:
         constraints:
            - node.role == manager
                      
                      
                      
services:

      routes_api:
        image: ryms/routes_api:latest
        volumes:
          - static-data:/routes_api/static
        environment:
          POSTGRES_HOST: routes_db
          POSTGRES_USER: postgres
        command: >
           bash -c
           '...
           && gunicorn project.wsgi -b 0.0.0.0:8000'
        networks:
          - traefik-net
        deploy:
          replicas: 3
          labels:
            - "traefik.backend=routes_api"
            - "traefik.port=8000"
            - "traefik.frontend.rule=Host:routes.com;PathPrefix:/api,/admin"
            - "traefik.enable=true"