১. সংক্ষিপ্ত বিবরণ
ডকার হলো অ্যাপ্লিকেশন তৈরি, সরবরাহ এবং চালানোর জন্য একটি উন্মুক্ত প্ল্যাটফর্ম। ডকারের সাহায্যে, আপনি আপনার অ্যাপ্লিকেশনগুলোকে আপনার পরিকাঠামো থেকে আলাদা করতে পারেন এবং আপনার পরিকাঠামোকে একটি পরিচালিত অ্যাপ্লিকেশনের মতো ব্যবহার করতে পারেন। ডকার আপনাকে দ্রুত কোড সরবরাহ করতে, দ্রুত পরীক্ষা করতে, দ্রুত স্থাপন করতে এবং কোড লেখা ও চালানোর মধ্যবর্তী সময়কাল সংক্ষিপ্ত করতে সাহায্য করে।
ডকার কার্নেল কন্টেইনারাইজেশন ফিচারগুলোর সাথে এমন সব ওয়ার্কফ্লো এবং টুলিং-কে একত্রিত করে এই কাজটি করে থাকে, যা আপনাকে আপনার অ্যাপ্লিকেশনগুলো পরিচালনা ও স্থাপন করতে সাহায্য করে।
ডকার কন্টেইনার সরাসরি কুবারনেটিসে ব্যবহার করা যায়, যার ফলে এগুলি কুবারনেটিস ইঞ্জিনে সহজে চালানো যায়। ডকারের মূল বিষয়গুলি শেখার পর, আপনি কুবারনেটিস এবং কন্টেইনারাইজড অ্যাপ্লিকেশন তৈরি শুরু করার দক্ষতা অর্জন করবেন।
আপনি যা শিখবেন
এই ল্যাবে, আপনারা নিম্নলিখিত বিষয়গুলো করতে শিখবেন:
- একটি নমুনা অ্যাপ্লিকেশনের জন্য একটি ডকারফাইল তৈরি করুন।
- একটি ছবি তৈরি করুন
- ইমেজটি স্থানীয়ভাবে একটি কন্টেইনার হিসেবে চালান
- কন্টেইনারের আচরণ পরিবর্তন করুন
- ছবিটি আর্টিফ্যাক্ট রেজিস্ট্রি-তে পুশ করুন।
পূর্বশর্ত
এটি একটি প্রাথমিক স্তরের ল্যাব। ডকার এবং কন্টেইনার সম্পর্কে পূর্ব অভিজ্ঞতা খুব কম বা একেবারেই নেই বলে ধরে নেওয়া হচ্ছে। ক্লাউড শেল এবং কমান্ড লাইনের সাথে পরিচিতি থাকলে ভালো, তবে তা আবশ্যক নয়।
স্ব-গতিতে পরিবেশ সেটআপ
- Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।



- প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না, এবং আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
- সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে প্রজেক্ট আইডি অবশ্যই অনন্য হতে হবে এবং এটি অপরিবর্তনীয় (একবার সেট করার পর পরিবর্তন করা যায় না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর দরকার নেই। বেশিরভাগ কোডল্যাবে, আপনাকে প্রজেক্ট আইডি উল্লেখ করতে হবে (এবং এটি সাধারণত
PROJECT_IDহিসাবে চিহ্নিত করা হয়), তাই যদি এটি আপনার পছন্দ না হয়, তবে এলোমেলোভাবে অন্য একটি তৈরি করুন, অথবা, আপনি নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এরপর প্রজেক্ট তৈরি হয়ে গেলে এটি "স্থির" হয়ে যায়। - তৃতীয় আরেকটি ভ্যালু আছে, যা হলো প্রজেক্ট নম্বর এবং কিছু এপিআই এটি ব্যবহার করে। এই তিনটি ভ্যালু সম্পর্কে আরও জানতে ডকুমেন্টেশন দেখুন।
- এরপরে, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হওয়ার কথা নয়, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর যাতে কোনো বিলিং না হয়, সেজন্য রিসোর্সগুলো বন্ধ করতে কোডল্যাবের শেষে দেওয়া যেকোনো "ক্লিন-আপ" নির্দেশাবলী অনুসরণ করুন। গুগল ক্লাউডের নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।
২. নমুনা আবেদন
এই ল্যাবটি সহজ করার জন্য একটি নমুনা অ্যাপ্লিকেশন সরবরাহ করা হয়েছে। এই অংশে, কন্টেইনারাইজেশন প্রক্রিয়ায় যাওয়ার আগে আপনি সোর্স কোডটি সংগ্রহ করবেন এবং অ্যাপ্লিকেশনটিকে তার নেটিভ ফর্মে বিল্ড করবেন।
উৎস কোড
এই ল্যাবের সোর্স কোড এবং স্যাম্পল অ্যাপ্লিকেশন ডকুমেন্টেশন GoogleCloudPlatform/container-developer-workshop রিপোজিটরিতে পাওয়া যাবে।
গিট কনফিগার করুন
git config --global user.name ${USER}
git config --global user.email ${USER}@qwiklabs.net
নমুনা অ্যাপ্লিকেশন ক্লাউড সোর্স রিপোজিটরি ক্লোন করুন
gcloud source repos clone sample-app ${HOME}/sample-app &&
cd ${HOME}/sample-app &&
git checkout main
আউটপুট
Cloning into '/home/student_03_49720296e995/sample-app'... remote: Finding sources: 100% (16/16) remote: Total 16 (delta 0), reused 16 (delta 0) Receiving objects: 100% (16/16), 47.23 KiB | 681.00 KiB/s, done. warning: remote HEAD refers to nonexistent ref, unable to checkout. Project [qwiklabs-gcp-02-4327c4e03d82] repository [sample-app] was cloned to [/home/student_03_49720296e995/sample-app]. Branch 'main' set up to track remote branch 'main' from 'origin'. Switched to a new branch 'main'
নমুনা অ্যাপ্লিকেশনটি তৈরি করুন
cd ${HOME}/sample-app
./mvnw compile
আউটপুট
[INFO] Scanning for projects... ... [INFO] Compiling 1 source file to /home/student_03_49720296e995/sample-app/target/classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 10.080 s [INFO] Finished at: 2022-02-23T17:14:30Z [INFO] ------------------------------------------------------------------------
নমুনা অ্যাপ্লিকেশনটি চালান
cd ${HOME}/sample-app
./mvnw exec:java
আউটপুট
[INFO] Scanning for projects... ... Listening at http://localhost:8080
চলমান অ্যাপ্লিকেশনটির প্রিভিউ দেখুন
- ক্লাউড শেল ওয়েব প্রিভিউ বোতামে ক্লিক করুন
- পোর্ট ৮০৮০-তে প্রিভিউ ক্লিক করুন
যখন আপনার কাজ শেষ হবে
- চলমান অ্যাপ্লিকেশনটি বন্ধ করতে ক্লাউড শেলে CTRL + c চাপুন।
৩. ডকারফাইল
ডকারফাইল ব্যবহার করে অ্যাপ্লিকেশনটিকে কন্টেইনারাইজ করা
একটি অ্যাপ্লিকেশনকে কন্টেইনারে প্যাকেজ করার একটি পদ্ধতি হলো ডকারফাইল (Dockerfile) ব্যবহার করা। ডকারফাইলটি একটি স্ক্রিপ্টের মতো, যা ডেমনকে (daemon) কন্টেইনার ইমেজটি কীভাবে অ্যাসেম্বল করতে হবে সে বিষয়ে নির্দেশ দেয়। আরও তথ্যের জন্য ডকারফাইল রেফারেন্স ডকুমেন্টেশন দেখুন।
স্যাম্পল অ্যাপ্লিকেশন রিপোজিটরিতে একটি খালি Dockerfile তৈরি করুন।
touch ${HOME}/sample-app/Dockerfile
আপনার পছন্দের এডিটরে Dockerfile-টি খুলুন।
vi ${HOME}/sample-app/Dockerfile
একটি শুরুর ছবি বেছে নিন
ডকারফাইল পদ্ধতি ব্যবহার করে একটি কন্টেইনার তৈরি করতে হলে, অ্যাপ্লিকেশনটি সম্পর্কে সরাসরি জ্ঞান থাকা প্রয়োজন। ডকারফাইল তৈরির প্রথম ধাপ হলো এমন একটি ইমেজ নির্বাচন করা যা আপনার ইমেজের ভিত্তি হিসেবে ব্যবহৃত হবে। এই ইমেজটি একটি প্যারেন্ট বা বেস ইমেজ হওয়া উচিত, যা কোনো বিশ্বস্ত উৎস, সাধারণত আপনার কোম্পানি, দ্বারা রক্ষণাবেক্ষণ ও প্রকাশিত হয়।
FROM নির্দেশনাটি একটি নতুন বিল্ড পর্যায় শুরু করে এবং পরবর্তী ক্রমিক কমান্ডগুলোর জন্য ভিত্তি চিত্র নির্ধারণ করে। তাই FROM নির্দেশনাটি সাধারণত একটি Dockerfile-এর প্রথম নির্দেশনা হয় এবং ভেরিয়েবল সমর্থন করার জন্য এর আগে শুধুমাত্র একটি ঐচ্ছিক ARG নির্দেশনা থাকতে পারে।
সিনট্যাক্স: FROM <image>[:<tag> | @<digest>] [AS <name>]
একটি ইমেজের ফরম্যাট হলো <image>:<tag> অথবা <image>@<digest> । যদি কোনো ট্যাগ বা ডাইজেস্ট নির্দিষ্ট করা না থাকে, তবে এটি ডিফল্টভাবে :latest ট্যাগটি ব্যবহার করে। ইমেজটি সংরক্ষণের জন্য ব্যবহৃত রেজিস্ট্রির উপর ভিত্তি করে <image> এর ফরম্যাট পরিবর্তিত হয়। আর্টিফ্যাক্ট রেজিস্ট্রির জন্য <image> ফরম্যাটটি হলো <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag> ।
এই ল্যাবের জন্য আমরা পাবলিক openjdk:11.0-jdk ইমেজটি ব্যবহার করব, আপনার Dockerfile-এ নিম্নলিখিত লাইনটি যোগ করুন।
FROM openjdk:11.0-jdk
ওয়ার্কিং ডিরেক্টরি সেট করুন
Dockerfile-এ পরবর্তী যেকোনো ধারাবাহিক নির্দেশাবলীর জন্য WORKDIR নির্দেশটি ওয়ার্কিং ডিরেক্টরি নির্ধারণ করে। আরও তথ্যের জন্য Dockerfile রেফারেন্স ডকুমেন্টেশনের WORKDIR বিভাগটি দেখুন।
সিনট্যাক্স: WORKDIR <path>
এই ল্যাবের জন্য আমরা /app ডিরেক্টরিকে আমাদের WORKDIR হিসেবে ব্যবহার করব, আপনার Dockerfile-এর শেষে নিম্নলিখিত লাইনটি যোগ করুন।
WORKDIR /app
অ্যাপ্লিকেশন ফাইলগুলো কপি করুন
COPY নির্দেশনাটি ডিরেক্টরি বা ফাইলগুলিকে <source> অবস্থান থেকে ইমেজ ফাইলসিস্টেমের <destination> পাথে কপি করে। একাধিক <source> রিসোর্স নির্দিষ্ট করা যেতে পারে এবং সেগুলি সবই বিল্ড কনটেক্সটের সাপেক্ষে নির্ধারিত হয়। বিল্ড কনটেক্সট সম্পর্কে Build সেকশনে আরও আলোচনা করা হবে। আরও তথ্যের জন্য Dockerfile রেফারেন্স ডকুমেন্টেশনের COPY সেকশনটি দেখুন।
সিনট্যাক্স: COPY <source>... <destination>
এই ল্যাবের জন্য আমরা রিপোজিটরির সমস্ত ফাইল ইমেজ ফাইলসিস্টেমে কপি করব, আপনার Dockerfile-এর শেষে নিম্নলিখিত লাইনটি যোগ করুন।
COPY . /app
অ্যাপ্লিকেশনটি সংকলন করুন
RUN নির্দেশনাটি বর্তমান ইমেজের উপরে একটি নতুন ইমেজ লেয়ারে কমান্ডগুলো কার্যকর করে এবং ফলাফলগুলো কমিট করে। ফলস্বরূপ প্রাপ্ত কমিট করা ইমেজটি Dockerfile-এর পরবর্তী ধাপগুলোর জন্য ব্যবহৃত হবে। আরও তথ্যের জন্য Dockerfile রেফারেন্স ডকুমেন্টেশনের RUN সেকশনটি দেখুন।
সিনট্যাক্স: RUN <command>
এই ল্যাবের জন্য আমরা Maven ব্যবহার করে অ্যাপ্লিকেশনটিকে একটি JAR ফাইলে কম্পাইল করব, আপনার Dockerfile-এর শেষে নিম্নলিখিত লাইনটি যোগ করুন।
RUN ./mvnw compile assembly:single
অ্যাপ্লিকেশনটি শুরু করুন
CMD ইনস্ট্রাকশনটি একটি চলমান কন্টেইনারের জন্য ডিফল্ট কমান্ড প্রদান করে। একটি Dockerfile-এ শুধুমাত্র একটি CMD ইনস্ট্রাকশন থাকতে পারে; যদি একাধিক CMD নির্দিষ্ট করা হয়, তবে কেবল সর্বশেষ CMD-টিই কার্যকর হবে। CMD এবং ENTRYPOINT উভয় ইনস্ট্রাকশন ব্যবহার করে আরও উন্নত কার্যকারিতা পাওয়া যায়, কিন্তু এই ল্যাবে তা আলোচনা করা হয়নি। আরও তথ্যের জন্য Dockerfile রেফারেন্স ডকুমেন্টেশনের `CMD` সেকশনটি দেখুন।
সিনট্যাক্স: CMD ["executable","param1","param2"]
এই ল্যাবের জন্য আমরা যে JAR ফাইলটি কম্পাইল করেছি, সেটি রান করতে আপনার Dockerfile-এর শেষে নিম্নলিখিত লাইনটি যোগ করুন।
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]
চূড়ান্ত ডকারফাইল
চূড়ান্ত ডকারফাইলটি হবে
FROM openjdk:11.0-jdk
WORKDIR /app
COPY . /app
RUN ./mvnw compile assembly:single
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]
ডকারফাইলটি স্থানীয়ভাবে কমিট করুন।
cd ${HOME}/sample-app
git add Dockerfile
git commit -m "Added Dockerfile"
৪. নির্মাণ করুন
এখন আমরা docker build কমান্ড ব্যবহার করে Dockerfile থেকে ইমেজটি তৈরি করব। এই কমান্ডটি আমাদের Dockerfile-এর নির্দেশনা অনুযায়ী ইমেজটি তৈরি করার জন্য ডকার ডেমনকে নির্দেশ দেয়। আরও তথ্যের জন্য `docker build` রেফারেন্স ডকুমেন্টেশন দেখুন।
ছবিটি তৈরি করুন
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker build --tag sample-app:${IMAGE_TAG} .
আউটপুট
Sending build context to Docker daemon 221.2kB Step 1/4 : FROM openjdk:11.0-jdk 11.0-jdk: Pulling from library/openjdk 0c6b8ff8c37e: Pull complete 412caad352a3: Pull complete e6d3e61f7a50: Pull complete 461bb1d8c517: Pull complete e442ee9d8dd9: Pull complete 542c9fe4a7ba: Pull complete 41de18d1833d: Pull complete Digest: sha256:d72b1b9e94e07278649d91c635e34737ae8f181c191b771bde6816f9bb4bd08a Status: Downloaded newer image for openjdk:11.0-jdk ---> 2924126f1829 Step 2/4 : WORKDIR /app ---> Running in ea037abb273d Removing intermediate container ea037abb273d ---> bd9b6d078082 Step 3/4 : COPY . /app ---> b9aec2b5de51 Step 4/4 : RUN ./mvnw compile jar:jar ---> Running in 3f5ff737b7fd [INFO] Scanning for projects... ... [INFO] Building jar: /app/target/sample-app-1.0.0.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 22.952 s [INFO] Finished at: 2022-02-23T18:09:08Z [INFO] ------------------------------------------------------------------------ Removing intermediate container 331443caebd3 ---> 152f65cc441e Step 5/5 : CMD ["java", "-jar", "/app/target/sample-app-1.0.0.jar"] ---> Running in 3d595a72231c Removing intermediate container 3d595a72231c ---> 0e40d7548cab Successfully built 0e40d7548cab Successfully tagged sample-app:aaa8895
৫. দৌড়
আমাদের কন্টেইনার ইমেজ সফলভাবে বিল্ড করার পর, আমরা এখন 'docker run' কমান্ড ব্যবহার করে আমাদের অ্যাপ্লিকেশনটি চালাতে এবং এটি প্রত্যাশিতভাবে কাজ করছে কিনা তা নিশ্চিত করতে পারি। এই কমান্ডটি টেস্টিং বা ডিবাগিংয়ের জন্য আমাদের কন্টেইনারটিকে কমান্ড প্রম্পটের ফোরগ্রাউন্ডে চালু করবে। আরও তথ্যের জন্য ' docker run' রেফারেন্স ডকুমেন্টেশন দেখুন।
ইমেজটি ব্যবহার করে একটি কন্টেইনার চালান
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-p 8080:8080 \
sample-app:${IMAGE_TAG}
আউটপুট
Listening at http://localhost:8080
কন্টেইনারে চলমান অ্যাপ্লিকেশনটির প্রিভিউ দেখুন
- ক্লাউড শেল ওয়েব প্রিভিউ বোতামে ক্লিক করুন
- পোর্ট ৮০৮০-তে প্রিভিউ ক্লিক করুন
- কন্টেইনারগুলো বন্ধ করতে ক্লাউড শেলে CTRL + c চাপুন।
কন্টেইনারের আচরণ পরিবর্তন করা
Docker Run চালালে Dockerfile-এর ডিফল্ট কনফিগারেশন ব্যবহৃত হয়। এই আচরণ পরিবর্তন করার জন্য অতিরিক্ত নির্দেশাবলী এবং প্যারামিটার যোগ করা যেতে পারে।
TRACE লগিং সক্ষম করুন
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-p 8080:8080 \
sample-app:${IMAGE_TAG} \
java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar /app/target/sample-app-1.0.0-jar-with-dependencies.jar
কন্টেইনারে চলমান অ্যাপ্লিকেশনটির প্রিভিউ দেখুন
- ক্লাউড শেল ওয়েব প্রিভিউ বোতামে ক্লিক করুন
- পোর্ট ৮০৮০-তে প্রিভিউ ক্লিক করুন
- ক্লাউড শেল ট্যাবে যান এবং অতিরিক্ত লগিং দেখুন।
- কন্টেইনারটি বন্ধ করতে ক্লাউড শেলে CTRL + c চাপুন।
বন্দর পরিবর্তন করুন
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-e PORT=8081 \
-p 8081:8081 \
sample-app:${IMAGE_TAG}
কন্টেইনারে চলমান অ্যাপ্লিকেশনটির প্রিভিউ দেখুন
- ক্লাউড শেল ওয়েব প্রিভিউ বোতামে ক্লিক করুন
- পোর্ট পরিবর্তন করতে ক্লিক করুন
- ৮০৮১ লিখুন
- পরিবর্তন করুন এবং প্রিভিউতে ক্লিক করুন
- কন্টেইনারটি বন্ধ করতে ক্লাউড শেলে CTRL + c চাপুন।
৬. ধাক্কা দিন
কন্টেইনার ইমেজটি সঠিকভাবে চলছে বলে নিশ্চিত হওয়ার পর এবং এই কন্টেইনারটি অন্যান্য পরিবেশে ও/অথবা অন্যান্য ব্যবহারকারীদের চালানোর জন্য উপলব্ধ করতে চাইলে, আমাদের ইমেজটি একটি শেয়ার্ড রিপোজিটরিতে পুশ করতে হবে। এটি একটি স্বয়ংক্রিয় বিল্ড পাইপলাইনের অংশ হিসেবে হওয়া উচিত, কিন্তু আমাদের টেস্ট এনভায়রনমেন্টে আগে থেকেই একটি রিপোজিটরি কনফিগার করা আছে এবং আমরা ম্যানুয়ালি আমাদের ইমেজটি পুশ করতে পারি।
স্যাম্পল-অ্যাপ রিপোজিটরিতে ডকারফাইল কমিটটি পুশ করুন।
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
git push
আর্টিফ্যাক্ট রেজিস্ট্রির জন্য ছবিটি ট্যাগ করুন।
docker tag sample-app:${IMAGE_TAG} \
us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}
আর্টিফ্যাক্ট রেজিস্ট্রির জন্য আপনার পরিচয়পত্র কনফিগার করুন।
gcloud auth configure-docker us-central1-docker.pkg.dev
যখন জিজ্ঞাসা করা হবে Do you want to continue (Y/n)? তখন y উত্তর দিন এবং Enter চাপুন।
ছবিটি আর্টিফ্যাক্ট রেজিস্ট্রি-তে পুশ করুন।
docker push us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}
আউটপুট
The push refers to repository [us-central1-docker.pkg.dev/qwiklabs-gcp-04-b47ced695a3c/apps/sample-app] 453b97f86449: Pushed e86791aa0382: Pushed d404c7ee0850: Pushed fe4f44af763d: Pushed 7c072cee6a29: Pushed 1e5fdc3d671c: Pushed 613ab28cf833: Pushed bed676ceab7a: Pushed 6398d5cccd2c: Pushed 0b0f2f2f5279: Pushed aaa8895: digest: sha256:459de00f86f159cc63f98687f7c9563fd65a2eb9bcc71c23dda3351baf13607a size: 2424
৭. অভিনন্দন!
অভিনন্দন, আপনি কোডল্যাবটি সম্পন্ন করেছেন!
আপনি যা যা আলোচনা করেছেন
- একটি নমুনা অ্যাপ্লিকেশনের জন্য একটি ডকারফাইল তৈরি করা হয়েছে।
- একটি ভাবমূর্তি তৈরি করা হয়েছে
- ইমেজটি স্থানীয়ভাবে একটি কন্টেইনার হিসেবে চালানো হয়েছে
- কন্টেইনারের আচরণ পরিবর্তন করা হয়েছে
- ছবিটি আর্টিফ্যাক্ট রেজিস্ট্রি-তে পুশ করা হয়েছে।