توی پست قبلی اومدیم باهم یک پروژه React رو با Docker روی سرور مستقر کردیم. من لینک مقاله قبلی رو براتون میزارم یه نگاهی بهش بندازید اگه فرصت داشتید.
اما توی این پست قراره یکم قضیه رو جالب ترش کنیم و همراه همون پروژه Front-end، یه پروژه Back-end به همراه یه Database به کمک Docker compose لانچ کنیم.
هدف اصلی این مقاله درک و یادگیری Docker compose هستش و باهم ببینیم به کمک این تکنولوژی چجوری پروژه هامون به زیباترین شکل ممکن روی سرور قرار میگیره و بجای ۳ بار اجرا کردن دستور Docker run فقط با یه دستور docker-compose up سه تا سرویسمون رو لانچ میکنیم.
داستان ازین قراره که وقتی پروژه شما به چند تا سرویس نیاز داره که همزمان و در کنار هم کار کنه، یکم با روشهای قدیمی سخته مستقر کردنشون روی سرور و همچنین نگهداریشون. یه قدم بیایم جلو تر، اگه ما قرار بود این سه تا سرویس (Front و Back و Database) رو با سه تا دستور زیر اجرا کنیم یه همچین چیزی میشد:
docker run --name Front -p 80:80 -d front-end
docker run --name Back -p 5000:5000 -v ./Back/data:/app/data -d back-end
docker run --rm --name Database -e POSTGRES_PASSWORD=docker -p 5432:5432 -v ./Database:/var/lib/postgresql/data -d postgres
همونطور که میبینید سه بار مجبوریم دستور docker run رو اجرا کنیم. اگه میخواستیم ارتباطشون رو باهم راحت تر برقرار کنیم هم با دستور network-- میومدیم هر سه Container رو توی یک شبکه قرار میدادیم که راحتتر باهم ارتباط برقرار کنن.
حالا بیاید همین کارو با Docker compose انجام بدیم. اول بیاید باهم ببینیم ساختار Directory هامون چجوریه:
Project |_ Front |_ Back |_ Database |_ docker-compose.yml
خب تلکیف Directory های Front و Back مشخصه، پروژههامون توشه. ولی Directory عه Database رو درست کردم که در واقع Data های Database رو توش نگهدارم که اگه Container مون پاک شد Data ها پاک نشه.
خب حالا بریم سراغ اصل ماجرا و ببینیم داخل فایل docker-compose.yml مون چه خبره:
version: '3' services: database: image: postgres:13 environment: - POSTGRES_PASSWORD=<YOUR_PASSWORD> ports: - 5432:5432 volumes: - ./Database:/var/lib/postgresql/data back: build: ./Back ports: - 5000:5000 volumes: - ./Back/data:/app/data depends_on: - database front: build: ./Front ports: - 80:80 depends_on: - back
همونطور که میبینید اینقدر فایل گویا هست که کامل خودش توضیح میده ماجرا رو. یه چند تا نکته رو بگم فقط در جریان باشید. وقتی از build استفاده میکنیم یعنی برو تو Directory و دنبال Dockerfile بگرد و از رو اون build کن. من معمولا اول Database رو بالا میارم و بعد پروژه Back رو. چون پروژهام به محض بالا اومدن باید وصل بشه به Database و Table هارو Auto Migrate کنه و ساختار Database رو برای خودش بسازه یه جورایی. برای همینم از depends_on استفاده میکنم که صبر کنه هر موقع Database کامل اومد بالا و مستقر شد بیاد شروع کنه Container عه Back رو بسازه برام. آخر سر هم که Front رو میارم بالا و فقط برای اینکه بدونم پشت سر هم اجرا و به ترتیب میان بالا از depends_on برای فرانت هم استفاده کردم وگرنه لزومی نداره اگه شما استفاده نکردید.
حالا کنار فایل docker-compose.yml شما کافیه دستور docker-compose up رو بزنید و ببینید که به ترتیب سه تا سرویس لانچ میشه براتون.
اگر لازم داشتید هر سری برای up شدن build مجدد هم بشه میتونید از دستور docker-compose up --build استفاده کنید.
دوست دارم یه نکته ریز رو بگم چون این حرکت Docker واقعا قشنگه. وقتی با Docker compose سه تا سرویس رو لانچ میکنیم، چون توی یه network قرار میگیرن، شما کافیه توی پروژه Back تون اوجایی که دارید به Database وصل میشید بجای ip اون Container اسمشو صدا بزنید و DNS داکر خودش اینو متوجه میشه که کلمه Database معادل چه ip میشه و دیگه نیاز نیست نگران این باشید که هر سری down و up میکنید ip تون تغییر میکنه. بزارید یه مثال بزنم تا باهم ببینیم.
تکه کد زیر نحوه متصل شدن به Database عه postgres توی golang عه:
package main import ( "database/sql" "fmt" _ "github.com/lib/pq" ) const ( host = "localhost" port = 5432 user = "postgres" password = "your-password" dbname = "your-dbname" ) func main() { psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+ "password=%s dbname=%s sslmode=disable", host, port, user, password, dbname) db, err := sql.Open("postgres", psqlInfo) if err != nil { panic(err) } defer db.Close() err = db.Ping() if err != nil { panic(err) } fmt.Println("Successfully connected!") }
به لطف Docker compose فقط کافیه بجای کلمه localhost کلمه database رو بزارید و با توجه به تعریف بالا Docker خودش میفهمه Database چه ip ای داره و پروژه Back تون رو به Database تون متصل میکنه.
خیلی ممنونم که تا انتهای این مقاله همراه من بودید. امیدوارم که تونسته باشم مطلب رو برسونم. خیلی خوشحال میشم اگه نظری درباره مقاله دارید یا اگه جاییش رو واضح توضیح ندادم یا از قلم انداختم با من در میون بزارید.