Aufbau eines Docker Containers

Django, Flask, Bottle, WSGI, CGI…
Antworten
csaeum
User
Beiträge: 4
Registriert: Montag 24. Mai 2021, 07:15
Wohnort: Küps
Kontaktdaten:

Hallo Leute ich bin der neue und hätte gerne ein paar Probleme :D

Kurz zu mir:
Ich arbeite schon seit 2004 im Web und habe von Mambo über Joomla zu Modx dann Typolight (Contao) zum Schluß SuluCMS gearbeitet.

Ich arbeite nun seit ca 6 Monaten bei meinen Projekten auch mit Docker und habe mir hier einen zusammengebaut (Docker-Compose) der alles hat was ich so brauche.
Diese sind auf Basis von PHP und ich habe diese wie hier zu sehen aufgebaut ( https://github.com/csaeum/WSC-Matomo ).

Nun möchte ich mich in Python ( aka Django) und hier besonder mit Django-CMS einarbeiten.
Einige Sachen sind für mich noch sehr neu, darum habt ein wenig Geduld mit mir.

Ich habe gestern den Container von ( https://www.django-cms.org/en/blog/2021 ... 5-minutes/ ) mit meinen Traefik zum laufen bekommen und kann nun schonmal testen.

Leider fehlt mir hier der Ansatz der Volumes so das Daten auch fest gespeichert werden wenn man mal runterfährt usw.

Daher nun der Versuch eines eigenen Containers den ich kenne.

Ich habe es soweit also verstanden, es braucht als DB PostgreSQL, ich brauche ein Image das Python ausführt und hier würde ich am liebsten gleich ein Image nutzen was mir schon Django reinholt. Dann würde ich am liebsten mich in den Container einloggen und das Skript für DjangoCMS Installer starten:
How to install: Install django CMS in your environment with Nephila’s django CMS Installer or download the package from PyPi.
Genau hier stecke ich gerade fest.

Soweit ich schon recherchiert habe gibt es scheinbar kein Django Image. Also muss ich mit einen Dockerfile arbeiten oder?
Für kleine Webseiten brauch ich hier Gunicorn oder ähnliche oder reicht der "VorschauServer"?

Anbei noch meine Docker-Compose Datei:

Code: Alles auswählen

version: '3'

volumes:
  www-data:
    driver: local-persist
    driver_opts:
      mountpoint: ${CONTAINERVOLUMES}/html
  postgres-data:
    driver: local-persist
    driver_opts:
      mountpoint: ${CONTAINERVOLUMES}/postgres
  elastic-data:
    driver: local-persist
    driver_opts:
      mountpoint: ${CONTAINERVOLUMES}/elastic
  redis-data:
    driver: local-persist
    driver_opts:
      mountpoint: ${CONTAINERVOLUMES}/redis

services:
#  sshd:
#    image: hermsi/alpine-sshd
#    container_name: ${COMPOSE_PROJECT_NAME}-SSH
#    environment:
#      ROOT_PASSWORD: ${ROOT_PASSWORD}
#    ports:
#      - "${SSH_PORT}:22"
#    volumes:
#      - www-data:/var/www/html

  django:
    image:

  webserver:
    container_name: ${COMPOSE_PROJECT_NAME}-WebServer
    build: .
    command: python manage.py runserver 0.0.0.0:80
    volumes:
      - .:/code
    ports:
      - "8000:80"
    depends_on:
      - postgres
    volumes:
      - www-data:/app
    networks:
      - default
      - proxy

    labels:
      - traefik.enable=true
      # Routers
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=${HOSTRULE}
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}.entrypoints=websecure
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls.certresolver=myresolver
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}.service=${COMPOSE_PROJECT_NAME}_SVC
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}.middlewares=${COMPOSE_PROJECT_NAME}_Header
      - traefik.http.services.${COMPOSE_PROJECT_NAME}_SVC.loadBalancer.server.port=80
      - traefik.http.middlewares.${COMPOSE_PROJECT_NAME}_Header.headers.customrequestheaders.X-Forwarded-Proto=https
      - traefik.http.middlewares.${COMPOSE_PROJECT_NAME}_Header.headers.customrequestheaders.X-Forwarded-Ssl=on
      - traefik.http.middlewares.${COMPOSE_PROJECT_NAME}_Header.headers.customrequestheaders.X-Forwarded-Port=443
      - traefik.docker.network=traefik_proxy

  postgres:
    image: postgres:9.6-alpine
    container_name: ${COMPOSE_PROJECT_NAME}-Postgres
    volumes:
      - postgres-data:/var/lib/postgres/data
    environment:
      POSTGRES_DB: ${POSTGRES_DATABASE}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

  redis:
    image: redis:alpine
    container_name: ${COMPOSE_PROJECT_NAME}-Redis
    volumes:
      - redis-data:/data

#  elastic:
#    image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2
#    container_name: ${COMPOSE_PROJECT_NAME}-Elastic
#    volumes:
#      - elastic-data:/usr/share/elasticsearch/data
#    ulimits:
#      memlock:
#        soft: -1
#        hard: -1
#      nofile:
#        soft: 65535
#        hard: 65535
#    environment:
#      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
#      - discovery.type=single-node
#      - bootstrap.memory_lock=true
#    expose:
#      - 9200
#      - 9300

networks:
  proxy:
    external:
      name: ${PROXY_NETWORK}

csaeum
User
Beiträge: 4
Registriert: Montag 24. Mai 2021, 07:15
Wohnort: Küps
Kontaktdaten:

So ich bin ja nicht ganz untätig ;)

Also soweit ich nun besser weiß ist Gunicorn auch so aufzurufen, es ist nicht wie der Apache direkt ein Dienst "Ja es ist doch ein Dienst" aber man muss es in Python starten und es ist dann nur für die Enviroment zuständig oder wo man es draus aufruft?

Also wäre es doch besser wenn ich es wie zb hier aufrufen würde?

Code: Alles auswählen

web:
    restart: always
    build: ./web
    expose:
      - "8000"
    links:
      - postgres:postgres
      - redis:redis
    volumes:
      - web-django:/usr/src/app
      - web-static:/usr/src/app/static
    env_file: .env
    environment:
      DEBUG: 'true'
    command: /usr/local/bin/gunicorn docker_django.wsgi:application -w 2 -b :8000

  nginx:
    restart: always
    build: ./nginx/
    ports:
      - "80:80"
    volumes:
      - web-static:/www/static
    links:
      - web:web
Dazu dann noch eine Frage:
Da ich ja Traefik nutze als Proxy und für Letsencrypt usw brauch ich dann eigentlich den NGNIX oder wäre der nur für die statischen Sachen wichtig
Weil in diesem sind ja das Volume web-static gemountet.

Ngnix ist ja gerade in dem Bereich "statische Daten" sehr schnell.
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

Wenn ich irgendwas auf Django-Basis aufbaue, steht die Container-ifzierung eigentlich immer relativ weit hinten. Ich baue die Anwendung lokal zusammen und erst wenn das Deployment näher rückt, kommt Docker ins Spiel. Container sind ja keine VMs, sondern (konzeptuell bzw. idealisiert) als statische Einheiten zu begreifen an denen sich "nichts" ändert. Dass man sich in einen Container überhaupt einloggen und da ein Skript ausführen kann, würde ich eher als Debugging-Feature verstehen und nicht als regulären Weg, um etwas zu installieren. Alles, was die Anwendung braucht, um zu laufen (Einstellungen, Credentials, Datenbankinhalte, etc.), kann von außen in Form von Konfigurationsdateien, .env-Dateien, Migrations, Fixtures, usw. "zugefüttert" werden, oder liegt (je nach lokaler Infrastruktur) auf externen Servern.

Daher schlage ich vor, du machst dich erst einmal mit Django-CMS ohne Container vertraut. Für den allerersten Versuch brauchst du denke ich nicht mal Postgresql; da reicht sqlite. Wenn es dann ernster wird, kann man anfangen, ein Docker-File zu schreiben (z. B. auf Basis des offiziellen Python-Images), in das man die notwendigen Pakete installiert und in dem dann ein geeigneter WSGI-Server (gunicorn, uWsgi, etc.) läuft. Und im letzten Schritt kann man sich dann mit dem Docker-Compose-File befassen.

Das ist zumindest die Vorgehensweise, die ich selbst wähle und vorschlagen würde.
csaeum
User
Beiträge: 4
Registriert: Montag 24. Mai 2021, 07:15
Wohnort: Küps
Kontaktdaten:

Danke @nezzcarth
ja diese Aussagen kann ich nachvollziehen. Aber ich mach es halt anders, weil ich dies lieber so in einer "Basis" habe mit der ich danach machen kann was ich will und wie ich es brauche.

Dennoch danke
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

csaeum hat geschrieben: Montag 24. Mai 2021, 08:12 Ich habe es soweit also verstanden, es braucht als DB PostgreSQL, ich brauche ein Image das Python ausführt und hier würde ich am liebsten gleich ein Image nutzen was mir schon Django reinholt. Dann würde ich am liebsten mich in den Container einloggen und das Skript für DjangoCMS Installer starten:
How to install: Install django CMS in your environment with Nephila’s django CMS Installer or download the package from PyPi.
Genau hier stecke ich gerade fest.
Ich kann verstehen dass man in die Richtung geht wenn man mit Docker noch keine Erfahrung hat, dass ist aber so nicht gedacht. Die Idee ist dass du ein Dockerfile hast, davon baust du ein Image (idealerweise automatisiert über CI/CD) und dieses Image wird dann deployed. Der laufende Container bleibt dabei unverändert und bei einer Datenbank hat man Volumes für die Persistenz.

Eine Sache die du auch machen könntest ist docker-compose nur für Abhängigkeiten zu nutzen und deine eigene Anwendung separat laufen zu lassen. Auf die Weise kannst die bestehende Docker Container nutzen, musst aber keinen eigenen für deine Anwendung bauen. Das dürfte wesentlich leichter sein als einen Docker Container als VM zu missbrauchen und du hast die Komplexität gegenüber deinem Ansatz einen Docker Container als VM zu missbrauchen deutlich reduziert.
Da ich ja Traefik nutze als Proxy und für Letsencrypt usw brauch ich dann eigentlich den NGNIX oder wäre der nur für die statischen Sachen wichtig
Weil in diesem sind ja das Volume web-static gemountet.

Ngnix ist ja gerade in dem Bereich "statische Daten" sehr schnell.
Nginx wird in der Regel für statische Sachen aber auch teilweise für Compression oder TLS Termination usw. genutzt, dafür nutzt du aber ja schon Traefik. Wenn es wirklich nur eine kleinere Anwendung ist würde ich überlegen nginx weg zu lassen und statische Dateien von der Django Anwendung ausliefern lassen. Macht alles ein bisschen einfacher. Wenn es mit der Performance schwierig wird, kannst du es ja auch nginx dazuholen.
Antworten