دوستان عذر میخوام
من از دیشب یه مشکلی برام پیش اومد و امروز نمیتونم در خدمتتون باشم
ایشالا فردا هم خلاصهی جلسهی دیروز و هم توضیحات مربوط به فاز بعدی پروژه رو میذارم براتون
ممنونم بابت بردباریتون 🙃❤️
من از دیشب یه مشکلی برام پیش اومد و امروز نمیتونم در خدمتتون باشم
ایشالا فردا هم خلاصهی جلسهی دیروز و هم توضیحات مربوط به فاز بعدی پروژه رو میذارم براتون
ممنونم بابت بردباریتون 🙃❤️
🙏10❤5
سلام و وقت بخیر خدمت دوستان عزیزم که با ما همراه بودید
اول از همه پوزش بابت این دو روز که من خیلی درگیر بودم، و جدای از اون، دو بار دیتاسنترمون با خاموشی کامل مواجه شد و فشار کاری و شببیداری نذاشت که این دوره رو اونجوری که دلم می خواست ادامه بدم 🤓
ولی امروز اومدم با خلاصهی جلسه دوم و انتشار فاز دوم پروژه
با ما همراه باشید 🤓❤️
اول از همه پوزش بابت این دو روز که من خیلی درگیر بودم، و جدای از اون، دو بار دیتاسنترمون با خاموشی کامل مواجه شد و فشار کاری و شببیداری نذاشت که این دوره رو اونجوری که دلم می خواست ادامه بدم 🤓
ولی امروز اومدم با خلاصهی جلسه دوم و انتشار فاز دوم پروژه
با ما همراه باشید 🤓❤️
😍7❤5👏1👌1
خلاصهی جلسهی آنلاین دوم:
خب توی قسمت ما اومدیم و یک اپلیکیشن ساده رو به شکلهای مختلف اجرا کردیم! و توی این قدمها عملاً میخواستیم ببینیم داکر و داکرکامپوز چه نقشی رو توی application deployment بازی میکنن. به صورت کلی فلوی این جلسه به این صورت بود:
1. run application on My laptop (we call it locally) => run application on a gitlab ci job (raw process, without contianer)
2. build docker image and run application on docker container locally => build and run application on gitlab ci job (container, using docker run command)
3. use docker compose to build and run application locally => use docker compose to build and run application locally (container, using docker compose)
۱. اپلیکیشن سادهی ما با زبان پایتون و با استفاده از فریمورک fastapi بود:
و با استفاده از کامند زیر میشه این وبسرور رو اجرا کرد:
و خب اگه دوست دارین میتونین از virtual environment پایتون استفاده کنین (اگه بلد نیستین سرچ کنین) (خط کامنت شدهی اول برای این موضوعه)
با این کامند میشه از عملکرد درست اپلیکیشن اطمینان حاصل کرد
۲. در قسمت بعدی میریم سراغ این که با استفاده از رانری که در جلسهی قبل ستاپ کردیم، یه جاب بنویسیم که اپلیکیشن توش اجرا بشه:
در توضیح قسمتهای مختلف گفتیم که
- مشخص کردن stage مهمه که نشون میده جاب شما متعلق به چه stageایه و توی چه ترتیبی قراره اجرا بشه
- وقتی image رو مشخص کنی، تعیین میکنی که کانتینری که جاب شما ایجاد میکنه با چه ایمیجی ساخته بشه، میتونین از ایمیجهای پابلیک (مثل داکرهاب) استفاده کنین. (میتونین تحقیق کنین که چجوری میشه از ایمیجهای پرایوت استفاده کرد. یعنی ایمیجهایی که روی رجیستریهایی هستند که نیاز به authentication دارند) ما در این جاب از ایمیج python3.10 استفاده میکنیم.
- با استفاده از before-scripts میتونین کامندهایی که قبل از اجرای کامندهای اصلیتون باید اجرا بشه رو مشخص میکنین، که توی این قسمت پکیجهای fastapi و uvicorn رو نصب میکنیم
- در قسمت scripts میایم اپلیکیشن رو اجرا و با کارکتر & به بکگراند منتقلش میکنیم، سپس چندثانیه صبر میکنیم تا سرور بالا بیاد و بعد بهش ریکوئست میزنیم.
* مشکلی که توی جلسه خوردیم و حلش کردیم این بود که بعد از اجرای اپلیکیشن صبر نمیکردیم که سرور بالا بیاد، با گذاشتن sleep تونستیم خروجی مناسب رو بگیریم.
۳. گفتیم برای این که اپلیکیشن رو به صورت کانتینری اجرا کنیم باید اول یک داکر ایمیج براش درست کنیم، و برای ساختن داکر ایمیج باید داکرفایل داشته باشیم، پس فرآیندش این شکلیه:
Writing Dockerfile => Build Docker image from Dockerfile => Run a container based on Docker image => expose port or mount a directory (optional)
اول از همه گفتیم که docker imageها به صورت لایه لایه ساخته میشن، و تعیین میکنن که container ساخته شده بر اساس این image چجوری خواهد بود. هر خط از dockerfile یه لایه به داکر ایمیج اضافه میکنه.
ادامه در پیام بعد 👇
خب توی قسمت ما اومدیم و یک اپلیکیشن ساده رو به شکلهای مختلف اجرا کردیم! و توی این قدمها عملاً میخواستیم ببینیم داکر و داکرکامپوز چه نقشی رو توی application deployment بازی میکنن. به صورت کلی فلوی این جلسه به این صورت بود:
1. run application on My laptop (we call it locally) => run application on a gitlab ci job (raw process, without contianer)
2. build docker image and run application on docker container locally => build and run application on gitlab ci job (container, using docker run command)
3. use docker compose to build and run application locally => use docker compose to build and run application locally (container, using docker compose)
۱. اپلیکیشن سادهی ما با زبان پایتون و با استفاده از فریمورک fastapi بود:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Let's call the API"}
و با استفاده از کامند زیر میشه این وبسرور رو اجرا کرد:
# python3.10 -m venv .venv
pip install --upgrade pip
pip install fastapi uvicorn
uvicorn app:app --host 0.0.0.0 --port 8000
و خب اگه دوست دارین میتونین از virtual environment پایتون استفاده کنین (اگه بلد نیستین سرچ کنین) (خط کامنت شدهی اول برای این موضوعه)
با این کامند میشه از عملکرد درست اپلیکیشن اطمینان حاصل کرد
curl localhost:8000
۲. در قسمت بعدی میریم سراغ این که با استفاده از رانری که در جلسهی قبل ستاپ کردیم، یه جاب بنویسیم که اپلیکیشن توش اجرا بشه:
stages:
- run
run-app:
stage: run
image: python:3.10
before_script:
- pip install --upgrade pip
- pip install fastapi uvicorn
script:
- uvicorn app:app --host 0.0.0.0 --port 8000 &
- sleep 3
- curl localhost:8000 -s
در توضیح قسمتهای مختلف گفتیم که
- مشخص کردن stage مهمه که نشون میده جاب شما متعلق به چه stageایه و توی چه ترتیبی قراره اجرا بشه
- وقتی image رو مشخص کنی، تعیین میکنی که کانتینری که جاب شما ایجاد میکنه با چه ایمیجی ساخته بشه، میتونین از ایمیجهای پابلیک (مثل داکرهاب) استفاده کنین. (میتونین تحقیق کنین که چجوری میشه از ایمیجهای پرایوت استفاده کرد. یعنی ایمیجهایی که روی رجیستریهایی هستند که نیاز به authentication دارند) ما در این جاب از ایمیج python3.10 استفاده میکنیم.
- با استفاده از before-scripts میتونین کامندهایی که قبل از اجرای کامندهای اصلیتون باید اجرا بشه رو مشخص میکنین، که توی این قسمت پکیجهای fastapi و uvicorn رو نصب میکنیم
- در قسمت scripts میایم اپلیکیشن رو اجرا و با کارکتر & به بکگراند منتقلش میکنیم، سپس چندثانیه صبر میکنیم تا سرور بالا بیاد و بعد بهش ریکوئست میزنیم.
* مشکلی که توی جلسه خوردیم و حلش کردیم این بود که بعد از اجرای اپلیکیشن صبر نمیکردیم که سرور بالا بیاد، با گذاشتن sleep تونستیم خروجی مناسب رو بگیریم.
۳. گفتیم برای این که اپلیکیشن رو به صورت کانتینری اجرا کنیم باید اول یک داکر ایمیج براش درست کنیم، و برای ساختن داکر ایمیج باید داکرفایل داشته باشیم، پس فرآیندش این شکلیه:
Writing Dockerfile => Build Docker image from Dockerfile => Run a container based on Docker image => expose port or mount a directory (optional)
FROM python:3.10
WORKDIR /code
RUN pip install fastapi uvicorn
COPY app.py /code/app.py
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
اول از همه گفتیم که docker imageها به صورت لایه لایه ساخته میشن، و تعیین میکنن که container ساخته شده بر اساس این image چجوری خواهد بود. هر خط از dockerfile یه لایه به داکر ایمیج اضافه میکنه.
ادامه در پیام بعد 👇
👌4
ادامهی خلاصهی جلسهی آنلاین دوم:
در توضیح قسمتهای مختلف گفتیم که
- با
- با
- با
- با
- با
حالا کافیه با این کامند از روی dockerfileمون یه docker image داشته باشیم:
با `-t`مشخص میکنیم ایمیج ما چی باشه، به صورت کلی ایمیج از قسمتهای آدرس رجیستری، ریپوزیتوری، اسم ایمیج، و تگ ایمیج تشکیل شده، مثلاَ:
registry address:
registry repository:
docker image name:
docker tag:
که عموماً اسم ایمیج مشخصاً میکنه اپلیکیشن چیه، و تگ ایمیج ورژن اون اپلیکیشن رو مشخص میکنه.
و در کامندهای docker اگه آدرس رجیستری رو تعیین نکنیم، به صورت پیشفرض از docker.io استفاده میکنه (یا دیگر آدرسهای داکرهاب)
اگه تگ ایمیج رو مشخص نکنین به صورت پیشفرض از تگ
حالا با استفاده از کامند زیر میشه از روی داکر ایمیج ساخته شده کانتینر ساخت و اپلیکیشن رو توی یه کانتینر اجرا کرد:
با
نکتهی مهم قسمت
و سپس ایمیجی که میخواین ازش استفاده کنین رو تعیین میکنین.
دقت کنید که همهی این آپشنهای مربوط به کامند docker run رو باید قبل از ایمیج بذارین!!
(میتونین در مورد override کردن CMD موقع اجرا تحقیق کنین 😉) این تحقیق بشدت توصیه میشه!!!!!
در توضیح قسمتهای مختلف گفتیم که
- با
FROM مشخص میکنیم که base image ما چی باشه، در واقع از یک ایمیج از قبل ساخته شده استفاده میکنیم تا بهش چیزهای اختصاصی خودمون رو اضافه کنیم و یه ایمیج جدید داشته باشیم. (میتونین در مورد FROM scratch تحقیق کنین 😉)- با
WORKDIR مشخص میکنین current directory یا دایرکتوریای که موقع بیلد و موقع اجرا (build time and run time) در حال حاضر روش هستین چیه.- با
RUN میتونین موقع بیلد کامند ران کنین، در واقع در ایمیج نهایی و کانتینرهایی که از روش ساخته خواهد شد مطمئنین که این کامندها زده شده. مثلا در مثال ما مطمئنیم که پکیجهای fastapi و uvicorn نصب شدند.- با
COPY میتونین فایلهایی رو از فایلسیستم جایی که داره ایمیجتون بیلد میشه به داکر ایمیجتون منتقل کنید. و مطمئن باشید که در کانتینرهایی که از این ایمیج ساخته خواهد شد اون فایلها وجود خواهند داشت- با
CMD میتونین تعیین کنین که در زمان اجرای کانتینر ساخته شده بر اساس این ایمیج چه کامندی اجرا بشه، عموماً شما توی این کامند اپلیکیشنتون رو اجرا میکنین. این کامند در زمان بیلد اجرا نخواهد شد. (میتونین در رابطه با ENTRYPOINT تحقیق کنین 😉)حالا کافیه با این کامند از روی dockerfileمون یه docker image داشته باشیم:
docker build -t mostafabayat/mostafaops:v1 .
با `-t`مشخص میکنیم ایمیج ما چی باشه، به صورت کلی ایمیج از قسمتهای آدرس رجیستری، ریپوزیتوری، اسم ایمیج، و تگ ایمیج تشکیل شده، مثلاَ:
docker.io/mostafabayat/mostafaops:v1
registry address:
docker.ioregistry repository:
mostafabayat (my account in dockerhub)docker image name:
mostafaopsdocker tag:
v1که عموماً اسم ایمیج مشخصاً میکنه اپلیکیشن چیه، و تگ ایمیج ورژن اون اپلیکیشن رو مشخص میکنه.
و در کامندهای docker اگه آدرس رجیستری رو تعیین نکنیم، به صورت پیشفرض از docker.io استفاده میکنه (یا دیگر آدرسهای داکرهاب)
اگه تگ ایمیج رو مشخص نکنین به صورت پیشفرض از تگ
latest استفاده میشه.حالا با استفاده از کامند زیر میشه از روی داکر ایمیج ساخته شده کانتینر ساخت و اپلیکیشن رو توی یه کانتینر اجرا کرد:
docker run --name app --rm -p 8000:8000 mostafabayat/mostafaops:v1
با
--name میشه برای کانتینرتون اسم تعیین کنین، با --rm مشخص میکنین که بعد از تموم شدن این کانتینر اثری ازش نمونه و کاملاً پاک بشه.نکتهی مهم قسمت
-p 8000:8000 عه که با این قسمت مشخص میکنین که چه پورتی از کامپیوتر یا سرورتون (که بهش میگیم host) به چه پورتی از کانتینر متصل بشه! با هم صحبت کردیم که یه کانتینر به لحاظ نتورکی و به لحاظ فایل سیستم از هاست ایزولهست. و اگه این قسمت رو نذارین از کرومتون مثلا نمیتونین بهش دسترسی داشته باشین.و سپس ایمیجی که میخواین ازش استفاده کنین رو تعیین میکنین.
دقت کنید که همهی این آپشنهای مربوط به کامند docker run رو باید قبل از ایمیج بذارین!!
(میتونین در مورد override کردن CMD موقع اجرا تحقیق کنین 😉) این تحقیق بشدت توصیه میشه!!!!!
👌4
ادامهی خلاصهی جلسهی آنلاین دوم:
حالا میایم یک جاب مینویسیم که همهی این اتفاقات در یک جاب gitlab ci بیفته:
همون طور که میبینیم این بار از ایمیج docker استفاده کردیم تا کامندهای docker رو بتونیم اجرا کنیم، بعد گفتیم که این کافی نیست و باید حتما daemon داکر داشته باشیم، برای این موضوع از services در gitlab ci استفاده میکنیم که به ما امکان اجرای سرویسهای دیگه رو در کنار جابمون میده، مثلا یه docker daemon 🤓
و در مورد مفهوم dind یا docker in docker صحبت کردیم، که عملا docker daemon داره در یک کانتینر اجرا میشه. و ایمیج اون سرویس رو docker:24.0.2-dind گذاشتیم. با هم دیدیم که اگه از این daemon استفاده نکنیم کامندهای docker مون ارور عدم اتصال به داکر رو میدن.
بعد اومدیم با همون کامندهایی که در موردشون صحبت کردیم این بار توی یه جاب اپلیکیشنمون رو اجرا کردیم. برای این که اپلیکیشن رو به بکگراند ببریم و بتونیم با curl اپلیکیشن رو تست کنیم از
یه مشکلی که توی جلسه داشتیم و متوجهش نشدیم این بود که با این که
بلکه باید به این شکل به کانتینر دیمن یا همون dind ریکوئست زد، چون daemon اونجا در حال اجراست و اونجا پورت باز شده:
نکتهی مهم و پایانی در این قسمت اینه که بعد از بیلد کردن docker imageتون، شما اگه اپلیکیشنتون قراره جای دیگهای (مثلا کوبرنتیز 😉🤓) اجرا بشه میتونین ایمیج رو در یک رجیستری پوش کنین (مثلا داکرهاب یا رجیستریای که خودتون ستاپ کردین) و موقع اجرای اپلیکیشن صرفاً اون ایمیج رو پول کنین و اجرا کنید (بدون این که اپلیکیشن رو بیلد کنید).
۴. در قسمت آخر اومدیم برای اپلیکیشن docker compose نوشتیم و اون رو در ci اجرا کردیم.
این داکر کامپوز هم اپلیکیشن رو بیلد میکنه و هم اجراش میکنه و هم روی پورت 8000 توی هاست اکسپوزش میکنه.
با این کامند به سادگی!!
حالا روی یه جاب مینویسم و تمام 🔥
حالا میایم یک جاب مینویسیم که همهی این اتفاقات در یک جاب gitlab ci بیفته:
run-in-docker:
stage: run
image: docker:24.0.2
services:
- docker:24.0.2-dind
before_script:
- apk add curl
script:
- docker build -t mostafabayat/mostafaops:v1 .
- docker run --name app -d --rm --network host mostafabayat/mostafaops:v1
- sleep 7
- curl docker:8000
همون طور که میبینیم این بار از ایمیج docker استفاده کردیم تا کامندهای docker رو بتونیم اجرا کنیم، بعد گفتیم که این کافی نیست و باید حتما daemon داکر داشته باشیم، برای این موضوع از services در gitlab ci استفاده میکنیم که به ما امکان اجرای سرویسهای دیگه رو در کنار جابمون میده، مثلا یه docker daemon 🤓
و در مورد مفهوم dind یا docker in docker صحبت کردیم، که عملا docker daemon داره در یک کانتینر اجرا میشه. و ایمیج اون سرویس رو docker:24.0.2-dind گذاشتیم. با هم دیدیم که اگه از این daemon استفاده نکنیم کامندهای docker مون ارور عدم اتصال به داکر رو میدن.
بعد اومدیم با همون کامندهایی که در موردشون صحبت کردیم این بار توی یه جاب اپلیکیشنمون رو اجرا کردیم. برای این که اپلیکیشن رو به بکگراند ببریم و بتونیم با curl اپلیکیشن رو تست کنیم از
-d توی کامند docker run استفاده کردیم.یه مشکلی که توی جلسه داشتیم و متوجهش نشدیم این بود که با این که
-p گذاشته بودیم نمیتونستیم به اپلیکیشن ریکوئست بزنیم. که متوجه شدم این پورت در جایی که docker daemon وجود داره expose میشه پس نباید به این شکل به اپلیکیشن ریکوئست زد:curl localhost:8000
بلکه باید به این شکل به کانتینر دیمن یا همون dind ریکوئست زد، چون daemon اونجا در حال اجراست و اونجا پورت باز شده:
curl docker:8000
نکتهی مهم و پایانی در این قسمت اینه که بعد از بیلد کردن docker imageتون، شما اگه اپلیکیشنتون قراره جای دیگهای (مثلا کوبرنتیز 😉🤓) اجرا بشه میتونین ایمیج رو در یک رجیستری پوش کنین (مثلا داکرهاب یا رجیستریای که خودتون ستاپ کردین) و موقع اجرای اپلیکیشن صرفاً اون ایمیج رو پول کنین و اجرا کنید (بدون این که اپلیکیشن رو بیلد کنید).
۴. در قسمت آخر اومدیم برای اپلیکیشن docker compose نوشتیم و اون رو در ci اجرا کردیم.
services:
mosiops:
build:
context: .
container_name: mosiops
restart: always
ports:
- 8000:8000
این داکر کامپوز هم اپلیکیشن رو بیلد میکنه و هم اجراش میکنه و هم روی پورت 8000 توی هاست اکسپوزش میکنه.
docker compose up
با این کامند به سادگی!!
حالا روی یه جاب مینویسم و تمام 🔥
run-in-docker-compose:
stage: run
image: docker:24.0.2
services:
- docker:24.0.2-dind
before_script:
- apk add curl
script:
- docker compose up -d
- sleep 7
- curl docker:8000
👍4
MostafaOps-Phase2.pdf
148.1 KB
فاز دوم پروژه
کوبرنتیز نصب میکنیم 🔥
یه ویدیو گذاشتم که به نظرم خیلی کامله
شما یه هفته فرصت دارین تا باهاش کلنجار برین و سعی کنین ستاپ کنین.
هر جایی که براتون گنگ بود میتونین به من پیام بدین تا بهتون منبع معرفی کنم
هفتهی بعد با هم میریم جلسه و یه کوبرنتیز از اول نصب میکنیم و آماده میشیم برای پارت دوم 🤓🔥
کوبرنتیز نصب میکنیم 🔥
یه ویدیو گذاشتم که به نظرم خیلی کامله
شما یه هفته فرصت دارین تا باهاش کلنجار برین و سعی کنین ستاپ کنین.
هر جایی که براتون گنگ بود میتونین به من پیام بدین تا بهتون منبع معرفی کنم
هفتهی بعد با هم میریم جلسه و یه کوبرنتیز از اول نصب میکنیم و آماده میشیم برای پارت دوم 🤓🔥
🔥6
MostafaOps
MostafaOps-Phase2.pdf
این آرتیکلها هم از دوست خوبم بشدت توصیه میشه:
«چرا کوبرنتیز این شکلی طراحی شده؟»
قسمت یک:
https://virgool.io/@hemmati.ali.a/kubernetes-design-principles-pu8opvf0gxyx
قسمت دو:
https://virgool.io/paasino/kubernetes-design-principles-2-fals1tgr93tn
قسمت سه:
https://virgool.io/paasino/kubernetes-design-principles-3-tlqbinzgjbqt
قسمت چهار:
https://virgool.io/paasino/kubernetes-design-principles-4-h7ibnqpulzqr
«چرا کوبرنتیز این شکلی طراحی شده؟»
قسمت یک:
https://virgool.io/@hemmati.ali.a/kubernetes-design-principles-pu8opvf0gxyx
قسمت دو:
https://virgool.io/paasino/kubernetes-design-principles-2-fals1tgr93tn
قسمت سه:
https://virgool.io/paasino/kubernetes-design-principles-3-tlqbinzgjbqt
قسمت چهار:
https://virgool.io/paasino/kubernetes-design-principles-4-h7ibnqpulzqr
ویرگول
چرا کوبرنتیز این شکلی طراحی شده؟ - قسمت اول
اصول طراحی کوبرنتیز و دلیل هر کدوم رو تو یه سری نوشته بررسی میکنیم
🙏6❤1
سلام دوباره
امیدوارم حالتون خوب باشه 🤓
امروز ساعت ۲۱ فاز دوم پروژه رو با هم انجام میدیم و سعی میکنیم کوبرنتیز رو هرچه بیشتر یاد بگیریم.
خیلی این بخش رو توصیه میکنم 🤓
https://meet.google.com/fvd-svch-kan
منتظرتونم ❤️
امیدوارم حالتون خوب باشه 🤓
امروز ساعت ۲۱ فاز دوم پروژه رو با هم انجام میدیم و سعی میکنیم کوبرنتیز رو هرچه بیشتر یاد بگیریم.
خیلی این بخش رو توصیه میکنم 🤓
https://meet.google.com/fvd-svch-kan
منتظرتونم ❤️
Google
Real-time meetings by Google. Using your browser, share your video, desktop, and presentations with teammates and customers.
🙏3❤1
بخش دوم نصب کوبرنتیز رو ۱۰:۳۰ دقیقه شروع میکنیم با هم
بیاین که قسمت اصلی ماجرا اینجاست 🤓
بیاین که قسمت اصلی ماجرا اینجاست 🤓
👍3🤩2❤1
MostafaOps-Phase3.pdf
148 KB
خب فاز سوم پروژه و احتمالاً پایانی پروژه رو هم امشب میذارم.
چون احتمالاً این سختترین و جذابترین قسمت پروژهست (و خیلی از دواپسها فقط همین قسمت رو بلدن 😉) یه جلسه خواهیم داشت که این فاز و کارهایی که باید بکنین رو بهتون توضیح خواهم داد تا کمترین ابهام وجود داشته باشه.
به زودی خبرش رو میدم. علیالحساب متن پروژه رو بخونین و مفاهیمش رو یه سرچ ریز بزنین 🤓
چون احتمالاً این سختترین و جذابترین قسمت پروژهست (و خیلی از دواپسها فقط همین قسمت رو بلدن 😉) یه جلسه خواهیم داشت که این فاز و کارهایی که باید بکنین رو بهتون توضیح خواهم داد تا کمترین ابهام وجود داشته باشه.
به زودی خبرش رو میدم. علیالحساب متن پروژه رو بخونین و مفاهیمش رو یه سرچ ریز بزنین 🤓
👍4👏3❤2
سلام دوستان عزیز،
قبل از هر چیز از همهتون بابت وقفههایی که در طول برگزاری این دوره پیش اومد، عذرخواهی میکنم. راستش انتظار نداشتم اوضاع به این شکل پیش بره. من در حال حاضر درگیر فرآیند مهاجرت هستم و چندین چالش شخصی دیگه هم به وجود اومده. بهویژه یک بار به دلیل مریضی و بار دیگه به دلیل لغو پروازها به خاطر وضعیت اخیر ایران، برنامههای مهاجرتم دچار پیچیدگی و تأخیر شده.
با این حال، امیدوارم طی یک هفتهی آینده بتونم کارهای شخصیام رو به سرانجام برسونم و با انرژی بیشتر، فاز نهایی این دوره رو با هم جلو ببریم. اگر سوال یا نکتهای هست، من در خدمتتون هستم و تمام تلاشم رو میکنم که پاسخگو باشم.
ممنون از درک و صبوری شما.
قبل از هر چیز از همهتون بابت وقفههایی که در طول برگزاری این دوره پیش اومد، عذرخواهی میکنم. راستش انتظار نداشتم اوضاع به این شکل پیش بره. من در حال حاضر درگیر فرآیند مهاجرت هستم و چندین چالش شخصی دیگه هم به وجود اومده. بهویژه یک بار به دلیل مریضی و بار دیگه به دلیل لغو پروازها به خاطر وضعیت اخیر ایران، برنامههای مهاجرتم دچار پیچیدگی و تأخیر شده.
با این حال، امیدوارم طی یک هفتهی آینده بتونم کارهای شخصیام رو به سرانجام برسونم و با انرژی بیشتر، فاز نهایی این دوره رو با هم جلو ببریم. اگر سوال یا نکتهای هست، من در خدمتتون هستم و تمام تلاشم رو میکنم که پاسخگو باشم.
ممنون از درک و صبوری شما.
❤12🔥3👏1