טיפ פייתון: פיתוח עם docker compose
דוקר קומפוז מספק דרך קלה להתחיל לכתוב יישומים בתוך קונטיינר. למרות שהרבה אנשים לא אוהבים להשתמש בו לסביבת פרודקשן (בגלל היעדר יכולות לניהול קונטיינרים רצים), בסביבת פיתוח עדיין מאוד נוח להשתמש בו במצבים שעובדים על כמה פרויקטים שונים ושכל פרויקט צריך את התלויות והתוכנות הנוספות שלו.
בדוגמה של פייתון אפשר לדמיין שנרצה לעבוד על כמה פרויקטי פייתון שכל אחד מהם משתמש בגירסת פייתון אחרת וספריות אחרות, וכל אחד מהם גם משתמש בבסיס נתונים שונה או גירסה שונה של בסיס הנתונים. בעוד שקל לנהל סט חבילות ספציפי לפרויקט עם סביבות וירטואליות, כשמתחילים להוסיף את התוכנות מסביב דברים עלולים להסתבך.
באמצעות דוקר קומפוז אפשר לבנות מערכת שמורכבת מקונטיינר של אפליקציה שמתחברת לבסיס נתונים מסוג מסוים, לבחור גירסת פייתון וסביבה וירטואלית וגירסה של בסיס הנתונים ולהריץ ולהוריד את כל המערכות בפקודה אחת.
בשביל לפתח על המחשב שלנו קוד פייתון עם docker-compose נצטרך להתמודד עם האתגרים הבאים:
נרצה שהקוד בתוך הקונטיינר יהיה זהה לקוד בספריית הפיתוח.
נרצה לשמור את המודולים שהפרויקט משתמש בהם בסביבה וירטואלית ספציפית לפרויקט, שלא קשורה לגירסאות פייתון שמותקנות אצלי במחשב המארח.
נרצה לאפשר לקוד לתקשר עם בסיס נתונים שגם יעלה מתוך ה compose.
נעדיף לא לבנות אימג' בשביל הפיתוח כדי לחסוך פעולות build.
1. תיאור הפיתרון
עם docker compose אפשר לבנות פיתרון שעונה על כל האתגרים:
נמפה את הקוד מתיקיית הפיתוח לתיקייה בתוך הקונטיינר
נשתמש בסקריפט entrypoint שימופה לתוך הקונטיינר שיתקין את התלויות מקובץ
requirements.txt
לתוך סביבה וירטואלית בתוך הקונטיינר.נשמור את הסביבה הוירטואלית על volume כדי שבהפעלות הבאות לא נצטרך להתקין מחדש את התלויות.
2. מימוש קוד הפיתרון
נראה דוגמה באמצעות תוכנית flask שמתחברת לבסיס נתונים Postgresql ושולפת משם מידע להחזיר ללקוח. אני יוצר תיקיה עבור הפרויקט ובתוכה קובץ בשם main.py
עם התוכן הבא:
from flask import Flask
import psycopg2
import os
conn = psycopg2.connect(
database="postgres",
user=os.environ['DB_USER'],
password=os.environ['DB_PASS'],
host=os.environ['DB_HOST'],
port= os.environ['DB_PORT']
)
app = Flask(__name__)
@app.route("/")
def hello_world():
cursor = conn.cursor()
cursor.execute("select version()")
data = cursor.fetchone()
return f"Using database version {data}"
וקובץ בשם requirements.txt
עם התוכן הבא:
flask
psycopg2
עכשיו אני יוצר קובץ בשם docker-compose.yml
עם התוכן הבא:
version: "3.9"
services:
app:
image: python:3.11-bullseye
command: /bin/bash /usr/local/bin/entrypoint.sh
ports:
- 5000:5000
volumes:
- .:/app
- ./entrypoint-dev.sh:/usr/local/bin/entrypoint.sh
- venv:/venv
environment:
DB_USER: "postgres"
DB_PASS: "monkey"
DB_HOST: "db"
DB_PORT: "5432"
db:
image: postgres:15.2
environment:
POSTGRES_PASSWORD: "monkey"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
venv:
pgdata:
וקובץ בשם entrypoint-dev.sh
עם התוכן הבא:
#!/bin/bash
cd /app
if [[ ! -d /venv/venv ]]
then
python -m venv /venv/venv
fi
source /venv/venv/bin/activate
pip install -r requirements.txt
flask --app main run --host 0.0.0.0 --port 5000
אחרי כל אלה אפשר לצאת לדרך. מפעילים:
$ docker compose up
ויכולים לגלוש מהדפדפן לכתובת localhost:5000
כדי לראות את העמוד הראשי שידפיס את הגירסה של בסיס הנתונים אליה אנחנו מחוברים.