הפעלת בסיס נתונים בתוך קונטיינר

בחלק הבא של הקורס נרצה לראות איך להריץ קונטיינרים מתוך אימג'ים קיימים, איך לתקשר עם קונטיינרים אלה, איך למשוך אימג'ים מהרשת ואיך לנהל את האימג'ים על הדיסק. בשביל הדוגמה הראשונה נעבוד עם אימג' של בסיס נתונים PostgreSQL.

1. מה אפשר ללמוד מדף האימג' ב Docker Hub

בסיס הנתונים PostgreSQL הוא סוג של Service. הוא רץ כל הזמן ברקע ומאזין לבקשות ומחזיר תשובות. אנחנו מתקשרים עם פוסטגרס או דרך קובץ תקשורת מיוחד (שנקרא Unix Socket) או דרך פרוטוקול TCP בפורט 5432. בעבודה עם דוקר יהיה לנו יותר נוח לעבוד בחיבור TCP ולדמיין שבסיס הנתונים רץ על מכונה אחרת מהאפליקציה שצריכה אותו.

בעולם של דוקר אנחנו לא "מתקינים" תוכנה אלא "מושכים" את האימג' שלה ויוצרים ממנו קונטיינר.

נמשיך לדף האימג' בדוקר האב ונראה מה אפשר ללמוד ממנו לפני הרצת הקונטיינר הראשון: https://hub.docker.com/_/postgres.

הדבר הראשון לשים לב אליו הוא הטקסט Docker Official Images. אלה אימג'ים רשמיים של דוקר ולכן יש יותר סיכוי שהם יהיו בטוחים לשימוש ולא ינסו להשתמש במחשב שלנו כדי לכרות ביטקוינים.

אני ממשיך לרשימת ה Supported tags. כל אימג' מכיל בנוסף לשם שלו גם תגית שמציינת משהו לגבי אופן הבניה הספציפי. לדוגמה ברשימה שלנו של Postgresql אני רואה שהתגית מורכבת ממספר הגירסה ובחלק מהגירסאות מופיע -alpine. אלפין היא הפצת לינוקס קטנטנה ובדוקר נותנים לנו לבחור בין מכונה שמריצה לינוקס מלא (מבוסס Debian) ובתוכו שרת PostgreSQL, לבין מכונה שמריצה הפצת לינוקס מצומצמת ובתוכה שרת PostgreSQL. האימג' הרגיל בטח יהיה יותר גדול אבל כשנתחבר אליו יהיה יותר קל להתמצא כי מותקנים עליו יותר כלים.

החלק החשוב הבא הוא ה Environment Variables. ב Docker משתני סביבה הם הדרך הנפוצה ביותר להעביר מידע לקונטיינר. בדוגמה של בסיס הנתונים נשים לב למשתני הסביבה הבאים:

  1. המשתנה POSTGRES_PASSWORD שקובע את סיסמת המנהל לבסיס הנתונים
  2. המשתנה POSTGRES_USER שקובע את שם המשתמש שמנהל את בסיס הנתונים
  3. המשתנה POSTGRES_DB שקובע את שם בסיס הנתונים שייווצר

כשנתחבר לבסיס הנתונים נצטרך לדעת את שלושת הערכים האלה כדי שנוכל לעבוד איתו. פריטי מידע כמו שמות משתמשים וסיסמאות כמעט אף פעם לא נשמרים בתוך האימג'.

עד כאן אנחנו יודעים מספיק כדי להפעיל בסיס נתונים PostgreSQL דרך דוקר. עכשיו ניגש לעבודה ונפעיל אחד כזה.

2. יצירת הקונטיינר

בואו נפעיל מחלון cmd או wsl את הפקודה הבאה:

$ docker run postgres

כדי לנסות לפתוח בסיס נתונים. אבל זה לא יעבוד. תראו את הפלט:

Error: Database is uninitialized and superuser password is not specified.
       You must specify POSTGRES_PASSWORD to a non-empty value for the
       superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".

       You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
       connections without a password. This is *not* recommended.

       See PostgreSQL documentation about "trust":
       https://www.postgresql.org/docs/current/auth-trust.html

למרות השגיאה הפקודה כן עשתה משהו - היא משכה את האימג' ממאגר האימג'ים המרכזי של דוקר אליי למחשב. אני יכול לראות את כל האימג'ים שיש לי על המחשב עם הפקודה:

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
postgres     latest    293e4ed402ba   6 days ago   315MB

שימו לב שבגלל שלא ציינתי tag באופן אוטומטי התגית שנבחרה היא latest. אני יכול לנסות להריץ תגית אחרת עם סימן נקודותיים ואחריו התגית:

$ docker run postgres:12-alpine
Unable to find image 'postgres:12-alpine' locally
12-alpine: Pulling from library/postgres
540db60ca938: Pull complete 
a3cb73039552: Pull complete 
39855706e49a: Pull complete 
3f0f1a7f7d33: Pull complete 
2f65e3924365: Pull complete 
44817ec3b5bb: Pull complete 
310cea271e89: Pull complete 
717b5444b286: Pull complete 
Digest: sha256:002161f3f4472b37e6014e7d5136a81076ebec5add084a2cd433cf84a416bb11
Status: Downloaded newer image for postgres:12-alpine
Error: Database is uninitialized and superuser password is not specified.
       You must specify POSTGRES_PASSWORD to a non-empty value for the
       superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".

       You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
       connections without a password. This is *not* recommended.

       See PostgreSQL documentation about "trust":
       https://www.postgresql.org/docs/current/auth-trust.html

וגם זה לא עבד מאותה סיבה, אבל כן שווה כבר לראות את הגודל השונה של שתי האימג'ים:

$ docker image ls
REPOSITORY   TAG         IMAGE ID       CREATED      SIZE
postgres     12-alpine   a58cf5527d36   6 days ago   158MB
postgres     latest      293e4ed402ba   6 days ago   315MB

עכשיו בואו נתקן את הבעיה ונפעיל את בסיס הנתונים. דוקר התלונן שלא בחרנו סיסמה ולכן הוא לא יכל ליצור את הקונטיינר. אנחנו זוכרים שהסיסמה, כמו גם שם המשתמש ושם בסיס הנתונים, עוברים בתור משתני סביבה. אנחנו יוצרים אותם בשורת הפקודה עם המתג -e.

סך הכל הפקודה הבאה מריצה את בסיס הנתונים עם בחירת שם משתמש, שם בסיס נתונים וסיסמה:

$ docker run  -e POSTGRES_PASSWORD=ninja -e POSTGRES_USER=ynon -e POSTGRES_DB=helloworld postgres

אני יכול לראות בחלון את הפלט של הפקודה וכל הפרטים על בסיס הנתונים. עכשיו שיש לי בסיס נתונים המשימה הבאה תהיה להתחבר אליו ורצוי מקונטיינר אחר. בשביל זה אני צריך לגלות מה כתובת ה IP של הקונטיינר שיצרתי. זיכרו שלמרות שקונטיינר רץ אצלי על המחשב, הוא מתנהג בתור מכונה נפרדת - עם כתובת IP ופורטים משלו.

בשביל לקבל מידע מפורט על הקונטיינר אני מפעיל מחלון אחר את הפקודה docker inspect ומעביר לה את מזהה הקונטיינר. כלומר תחילה אפעיל docker ps, אסתכל מה ה Container ID ואז אריץ docker inspect עם ערך זה. במקרה שלי:

$ docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS      NAMES
2e4d7cd70573   postgres   "docker-entrypoint.s…"   59 minutes ago   Up 59 minutes   5432/tcp   db

$ docker inspect 2e4d7cd70573

דוקר אינספקט מדפיס המון פלט לגבי הקונטיינר ומה שמעניין אותי הוא כתובת ה IP כלומר השדה IPAddress. תיאורטית קונטיינר יכול להחזיק מספר כרטיסי רשת (וירטואליים) וכך יהיו לו מספר כתובות IP. במקרה שלנו תהיה רק אחת כי זו ברירת המחדל.

אצלי כתובת ה IP היא 172.17.0.2. בעזרתה נוכל להפעיל קונטיינר אחר וממנו להתחבר לקונטיינר בסיס הנתונים שלנו. אני משתמש באותו אימג' בשם postgres שכבר הורדנו ובונה ממנו קונטיינר חדש בחלון אחר:

$ docker run --rm -it postgres /bin/bash

שימו לב לפרמטרים:

  1. הפעם אני לא מעביר משתני סביבה. אני לא רוצה ליצור בסיס נתונים אלא להתחבר לבסיס נתונים קיים.

  2. אני מעביר את הפרמטר --rm כדי למחוק את הקונטיינר אוטומטית מיד אחרי שהוא ייסגר.

  3. אני מעביר את הפרמטרים -it כדי לקבל גישה אינטרקטיבית לקונטיינר.

  4. אחרי שם האימג' אני מעביר את שם התוכנית /bin/bash. בדרך כלל אימג' פוסטגרס יוצר קונטיינר שמפעיל בסיס נתונים, אבל כשאני מעביר פקודה בסוף שורת ה run אני מבקש מדוקר להפעיל את הפקודה שלי ולא את הפקודה שמוגדרת באימג'.

התוצאה היא כניסה לתוך שורת פקודה לעבודה אינטרקטיבית בקונטיינר. בתוך המסוף שנפתח אני יכול לכתוב hostname כדי להיווכח שאני בתוך קונטיינר ולגלות את ה Container ID, ואחר כך להפעיל:

$ psql -h 172.17.0.2 -U ynon mydb

כדי להפעיל לקוח psql אינטרקטיבי שיתחבר לבסיס הנתונים על הקונטיינר השני. הפקודה מבקשת ממני סיסמה ואני מקליד את הסיסמה שבחרתי לבסיס הנתונים ואז פותחת לי גישה אינטרקטיבית ל DB. שימו לב רק להחליף את כתובת ה IP בכתובת ה IP של הקונטיינר שלכם.

בתוך החלון האינטרקטיבי אני יכול להפעיל את הפקודות הבאות כדי ליצור טבלה ולהכניס לתוכה נתונים:

# create table test(x integer, y integer);
# insert into test values(10, 20);
# select * from test;

בסוף אני יכול לצאת מ psql וזה יוציא אותי גם מהקונטיינר וימחק אותו.

נזכור שבסיס הנתונים עדיין רץ ולכן אם אני מריץ מחדש קונטיינר של לקוח psql אני יכול להתחבר לאותו בסיס נתונים ולראות את הנתונים שה psql הקודם יצר.

3. סיכום

בשיעור ראינו איך להפעיל קונטיינר מתוך אימג' של בסיס נתונים ואיך להתחבר אליו דרך CLI Client מקונטיינר אחר. למדנו לקרוא דף תיעוד של Image ב Dockerhub והבנו איך להעביר פרמטרים לקונטיינר.

אלה הפקודות המרכזיות שראינו בפרק:

# create a container from an image
$ docker run <image>

# list all images on disk
$ docker image ls

# delete a container
$ docker rm <container_id>

# list all running containers
$ docker ps

# list all containers (active and inactive)
$ docker ps -a

# delete a container
$ docker rm <container_id>

# Run a postgres container with a database
$ docker run  -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=ninja -e POSTGRES_USER=ynon -e POSTGRES_DB=helloworld postgres

# Create a new volume
$ docker volume create <volume_name>

# List all volumes
$ docker volume ls

# Create a psql client container and connect to a DB
$ docker run -it --rm postgres psql -h localhost -U ynon helloworld

אנחנו כבר רואים שאנחנו יכולים להשתמש בדוקר כדי לשפר את חווית הפיתוח שלנו, להתקין בקלות תוכנות ולקבל מספר גירסאות של תוכנה על המחשב.

עכשיו אתם- חפשו ב Docker Hub אימג' שמעניין אתכם ונסו להפעיל אותו. נסו לגלות כמה שיותר מידע דרך קריאת דף האימג' ואם בחרתם אימג' של סרביס נסו להתחבר אליו ממכונה אחרת.


בשיעור ראינו איך להפעיל קונטיינר מתוך אימג' של בסיס נתונים ואיך להתחבר אליו דרך CLI Client מקונטיינר אחר. למדנו לקרוא דף תיעוד של Image ב Dockerhub והבנו איך להעביר פרמטרים לקונטיינר.

קישור לדף התיעוד של פוסטגרס ב Dockerhub: https://hub.docker.com/_/postgres

קישור להורדת DBeaver תוכנת חיבור לבסיס הנתונים https://dbeaver.io/

אלה הפקודות המרכזיות שראינו בפרק:

# Create a postgres DB
$ docker run -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_USER=ynon -e POSTGRES_DB=dbname postgres

# Create a postgres DB container running a shell
$ docker run -it --rm postgres /bin/bash

# Create a postgresql DB with ports mapped
$ docker run -p 5432:5432 -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_USER=ynon -e POSTGRES_DB=dbname postgres

אנחנו כבר רואים שאנחנו יכולים להשתמש בדוקר כדי לשפר את חווית הפיתוח שלנו, להתקין בקלות תוכנות ולקבל מספר גירסאות של תוכנה על המחשב.

עכשיו אתם- חפשו ב Docker Hub אימג' שמעניין אתכם ונסו להפעיל אותו. נסו לגלות כמה שיותר מידע דרך קריאת דף האימג' ואם בחרתם אימג' של סרביס נסו להתחבר אליו ממכונה אחרת.