প্রতিদিনের ছবি: ল্যাব 3—সবচেয়ে সাম্প্রতিক ছবিগুলির একটি কোলাজ তৈরি করুন৷

১. সংক্ষিপ্ত বিবরণ

এই কোড ল্যাবে, আপনি একটি নতুন ক্লাউড রান সার্ভিস, কোলাজ সার্ভিস তৈরি করবেন, যা ক্লাউড শিডিউলার দ্বারা একটি নির্দিষ্ট সময় অন্তর চালু হবে। সার্ভিসটি সর্বশেষ আপলোড করা ছবিগুলো সংগ্রহ করে এবং সেগুলোর একটি কোলাজ তৈরি করে: এটি ক্লাউড ফায়ারস্টোরে সাম্প্রতিক ছবিগুলোর তালিকা খুঁজে বের করে এবং তারপর ক্লাউড স্টোরেজ থেকে আসল ছবির ফাইলগুলো ডাউনলোড করে।

df20f5d0402b54b4.png

আপনি যা শিখবেন

  • ক্লাউড রান
  • ক্লাউড শিডিউলার
  • ক্লাউড স্টোরেজ
  • ক্লাউড ফায়ারস্টোর

২. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিতে পরিবেশ সেটআপ

  1. Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না, এবং আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
  • সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে প্রজেক্ট আইডি অবশ্যই অনন্য হতে হবে এবং এটি অপরিবর্তনীয় (একবার সেট করার পর পরিবর্তন করা যায় না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর দরকার নেই। বেশিরভাগ কোডল্যাবে, আপনাকে প্রজেক্ট আইডি উল্লেখ করতে হবে (এবং এটি সাধারণত PROJECT_ID হিসাবে চিহ্নিত করা হয়), তাই যদি এটি আপনার পছন্দ না হয়, তবে এলোমেলোভাবে অন্য একটি তৈরি করুন, অথবা, আপনি নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এরপর প্রজেক্ট তৈরি হয়ে গেলে এটি "স্থির" হয়ে যায়।
  • তৃতীয় আরেকটি ভ্যালু আছে, যা হলো প্রজেক্ট নম্বর এবং কিছু এপিআই এটি ব্যবহার করে। এই তিনটি ভ্যালু সম্পর্কে আরও জানতে ডকুমেন্টেশন দেখুন।
  1. এরপরে, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হওয়ার কথা নয়, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর যাতে কোনো বিলিং না হয়, সেজন্য রিসোর্সগুলো বন্ধ করতে কোডল্যাবের শেষে দেওয়া যেকোনো "ক্লিন-আপ" নির্দেশাবলী অনুসরণ করুন। গুগল ক্লাউডের নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।

ক্লাউড শেল শুরু করুন

যদিও গুগল ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালনা করা যায়, এই কোডল্যাবে আপনি গুগল ক্লাউড শেল ব্যবহার করবেন, যা ক্লাউডে চালিত একটি কমান্ড লাইন পরিবেশ।

GCP কনসোল থেকে উপরের ডানদিকের টুলবারে থাকা ক্লাউড শেল আইকনে ক্লিক করুন:

bce75f34b2c53987.png

পরিবেশটি প্রস্তুত করতে এবং এর সাথে সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগবে। এটি শেষ হলে, আপনি এইরকম কিছু দেখতে পাবেন:

f6ef2b5f13479f3a.png

এই ভার্চুয়াল মেশিনটিতে আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুলস লোড করা আছে। এটি একটি স্থায়ী ৫ জিবি হোম ডিরেক্টরি প্রদান করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক পারফরম্যান্স ও অথেনটিকেশনকে ব্যাপকভাবে উন্নত করে। এই ল্যাবে আপনার সমস্ত কাজ শুধুমাত্র একটি ব্রাউজার দিয়েই করা যাবে।

৩. এপিআই সক্রিয় করুন

নিয়মিত বিরতিতে ক্লাউড রান সার্ভিসটি চালু করার জন্য আপনার একটি ক্লাউড শিডিউলারের প্রয়োজন হবে। এটি সক্রিয় আছে কিনা তা নিশ্চিত করুন:

gcloud services enable cloudscheduler.googleapis.com

অপারেশনটি সফলভাবে সম্পন্ন হতে দেখা উচিত:

Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.

৪. কোডটি ক্লোন করুন

আগের কোড ল্যাবে যদি কোডটি ক্লোন না করে থাকেন, তবে এবার তা করুন:

git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop

এরপর আপনি সার্ভিসটি যে ডিরেক্টরিতে রয়েছে সেখানে যেতে পারেন:

cd serverless-photosharing-workshop/services/collage/nodejs

পরিষেবাটির জন্য আপনার কাছে নিম্নলিখিত ফাইল বিন্যাস থাকবে:

services
 |
 ├── collage
      |
      ├── nodejs
           |
           ├── Dockerfile
           ├── index.js
           ├── package.json

ফোল্ডারটির ভিতরে ৩টি ফাইল আছে:

  • index.js Node.js কোড রয়েছে
  • package.json লাইব্রেরির নির্ভরতাগুলো সংজ্ঞায়িত করে।
  • Dockerfile কন্টেইনার ইমেজ সংজ্ঞায়িত করে।

৫. কোডটি অন্বেষণ করুন

নির্ভরশীলতা

package.json ফাইলটি প্রয়োজনীয় লাইব্রেরি নির্ভরতাগুলো নির্ধারণ করে:

{
  "name": "collage_service",
  "version": "0.0.1",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "bluebird": "^3.7.2",
    "express": "^4.17.1",
    "imagemagick": "^0.1.3",
    "@google-cloud/firestore": "^4.9.9",
    "@google-cloud/storage": "^5.8.3"
  }
}

ক্লাউড স্টোরেজের মধ্যে ইমেজ ফাইল পড়া এবং সংরক্ষণ করার জন্য আমরা ক্লাউড স্টোরেজ লাইব্রেরির উপর নির্ভর করি। পূর্বে সংরক্ষিত ছবির মেটাডেটা আনার জন্য আমরা ক্লাউড ফায়ারস্টোরের উপর একটি নির্ভরতা ঘোষণা করি। এক্সপ্রেস হলো একটি জাভাস্ক্রিপ্ট / নোড ওয়েব ফ্রেমওয়ার্ক। প্রমিজ পরিচালনার জন্য ব্লুবার্ড ব্যবহৃত হয়, এবং ইমেজম্যাজিক হলো ইমেজ সম্পাদনার একটি লাইব্রেরি।

ডকারফাইল

Dockerfile অ্যাপ্লিকেশনটির জন্য কন্টেইনার ইমেজ নির্ধারণ করে:

FROM node:14-slim

# installing Imagemagick
RUN set -ex; \
  apt-get -y update; \
  apt-get -y install imagemagick; \
  rm -rf /var/lib/apt/lists/*

WORKDIR /picadaily/services/collage
COPY package*.json ./
RUN npm install --production
COPY . .
CMD [ "npm", "start" ]

আমরা একটি হালকা নোড ১৪ বেস ইমেজ ব্যবহার করছি। আমরা ইমেজম্যাজিক লাইব্রেরিটি ইনস্টল করছি। এরপর আমাদের কোডের জন্য প্রয়োজনীয় এনপিএম মডিউলগুলো ইনস্টল করছি এবং ‘npm start’ কমান্ড দিয়ে আমাদের নোড কোডটি রান করছি।

index.js

চলুন আমাদের index.js কোডটি আরও ভালোভাবে দেখি:

const express = require('express');
const imageMagick = require('imagemagick');
const Promise = require("bluebird");
const path = require('path');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');

আমাদের প্রোগ্রামটি চালানোর জন্য বিভিন্ন ডিপেন্ডেন্সি প্রয়োজন: এক্সপ্রেস হলো আমাদের ব্যবহৃত নোড ওয়েব ফ্রেমওয়ার্ক, ইমেজম্যাজিক হলো ইমেজ ম্যানিপুলেশনের জন্য একটি লাইব্রেরি, ব্লুবার্ড হলো জাভাস্ক্রিপ্ট প্রমিজ হ্যান্ডেল করার একটি লাইব্রেরি, পাথ ব্যবহৃত হয় ফাইল ও ডিরেক্টরির পাথ পরিচালনার জন্য, এবং স্টোরেজ ও ফায়ারস্টোর হলো যথাক্রমে গুগল ক্লাউড স্টোরেজ (আমাদের ইমেজের বাকেটগুলো) এবং ক্লাউড ফায়ারস্টোর ডেটাস্টোরের সাথে কাজ করার জন্য।

const app = express();

app.get('/', async (req, res) => {
    try {
        console.log('Collage request');

        /* ... */

    } catch (err) {
        console.log(`Error: creating the collage: ${err}`);
        console.error(err);
        res.status(500).send(err);
    }
});

উপরে, আমাদের নোড হ্যান্ডলারের কাঠামোটি দেখানো হয়েছে: আমাদের অ্যাপটি HTTP GET অনুরোধের উত্তর দেয়। এবং কোনো সমস্যা হলে তার জন্য আমরা কিছুটা এরর হ্যান্ডলিং-এর ব্যবস্থা রেখেছি। চলুন এখন দেখে নেওয়া যাক এই কাঠামোর ভেতরে কী আছে।

const thumbnailFiles = [];
const pictureStore = new Firestore().collection('pictures');
const snapshot = await pictureStore
    .where('thumbnail', '==', true)
    .orderBy('created', 'desc')
    .limit(4).get();

if (snapshot.empty) {
    console.log('Empty collection, no collage to make');
    res.status(204).send("No collage created.");
} else {

    /* ... */

}

আমাদের কোলাজ পরিষেবার জন্য কমপক্ষে চারটি ছবির (যেগুলোর থাম্বনেইল তৈরি করা হয়েছে) প্রয়োজন হবে, তাই প্রথমে অবশ্যই ৪টি ছবি আপলোড করুন।

আমরা ক্লাউড ফায়ারস্টোরে সংরক্ষিত মেটাডেটা থেকে আমাদের ব্যবহারকারীদের আপলোড করা সর্বশেষ ৪টি ছবি সংগ্রহ করি। প্রাপ্ত কালেকশনটি খালি কি না, তা আমরা যাচাই করি এবং তারপর আমাদের কোডের else শাখায় পরবর্তী ধাপে অগ্রসর হই।

চলুন ফাইলের নামগুলোর তালিকা সংগ্রহ করা যাক:

snapshot.forEach(doc => {
    thumbnailFiles.push(doc.id);
});
console.log(`Picture file names: ${JSON.stringify(thumbnailFiles)}`);

আমরা থাম্বনেইল বাকেট থেকে ওই ফাইলগুলোর প্রত্যেকটি ডাউনলোড করতে যাচ্ছি, যার নামটি একটি এনভায়রনমেন্ট ভেরিয়েবল থেকে আসছে, যা আমরা ডিপ্লয়মেন্টের সময় সেট করেছিলাম:

const thumbBucket = storage.bucket(process.env.BUCKET_THUMBNAILS);

await Promise.all(thumbnailFiles.map(async fileName => {
    const filePath = path.resolve('/tmp', fileName);
    await thumbBucket.file(fileName).download({
        destination: filePath
    });
}));
console.log('Downloaded all thumbnails');

সর্বশেষ থাম্বনেইলগুলো আপলোড হয়ে গেলে, আমরা ImageMagick লাইব্রেরি ব্যবহার করে সেই থাম্বনেইল ছবিগুলো দিয়ে একটি ৪x৪ গ্রিড তৈরি করব। আমরা Bluebird লাইব্রেরি এবং এর Promise ইমপ্লিমেন্টেশন ব্যবহার করে কলব্যাক-চালিত কোডকে async / await বান্ধব কোডে রূপান্তরিত করি, তারপর যে প্রমিসটি ইমেজ কোলাজ তৈরি করছে, সেটির জন্য await ব্যবহার করি:

const collagePath = path.resolve('/tmp', 'collage.png');

const thumbnailPaths = thumbnailFiles.map(f => path.resolve('/tmp', f));
const convert = Promise.promisify(im.convert);
await convert([
    '(', ...thumbnailPaths.slice(0, 2), '+append', ')',
    '(', ...thumbnailPaths.slice(2), '+append', ')',
    '-size', '400x400', 'xc:none', '-background', 'none',  '-append',
    collagePath]);
console.log("Created local collage picture");

যেহেতু কোলাজ ছবিটি স্থানীয়ভাবে ডিস্কের টেম্পোরারি ফোল্ডারে সেভ করা হয়েছে, এখন আমাদের এটিকে ক্লাউড স্টোরেজে আপলোড করতে হবে এবং তারপর একটি সফল প্রতিক্রিয়া (স্ট্যাটাস কোড 2xx) ফেরত দিতে হবে:

await thumbBucket.upload(collagePath);
console.log("Uploaded collage to Cloud Storage bucket ${process.env.BUCKET_THUMBNAILS}");

res.status(204).send("Collage created.");

এখন আমাদের নোড স্ক্রিপ্টকে আগত অনুরোধগুলি শোনার জন্য প্রস্তুত করার পালা:

const PORT = process.env.PORT || 8080;

app.listen(PORT, () => {
    console.log(`Started collage service on port ${PORT}`);
});

আমাদের সোর্স ফাইলের শেষে, এক্সপ্রেসকে দিয়ে আমাদের ওয়েব অ্যাপ্লিকেশনটি ডিফল্ট ৮০৮০ পোর্টে চালু করানোর নির্দেশনা রয়েছে।

৬. স্থানীয়ভাবে পরীক্ষা করুন

ক্লাউডে ডেপ্লয় করার আগে কোডটি সঠিকভাবে কাজ করছে কিনা তা নিশ্চিত করতে আপনার লোকাল মেশিনে পরীক্ষা করে নিন।

collage/nodejs ফোল্ডারের ভিতরে, npm ডিপেন্ডেন্সিগুলো ইনস্টল করুন এবং সার্ভারটি চালু করুন:

npm install; npm start

সবকিছু ঠিকঠাক থাকলে, সার্ভারটি ৮০৮০ পোর্টে চালু হয়ে যাবে:

Started collage service on port 8080

প্রস্থান করতে CTRL-C ব্যবহার করুন।

৭. ক্লাউড রান-এ বিল্ড এবং ডিপ্লয় করুন

Cloud Run-এ ডেপ্লয় করার আগে, Cloud Run-এর অঞ্চলটি সমর্থিত অঞ্চলগুলির মধ্যে একটিতে এবং প্ল্যাটফর্মটি managed এ সেট করুন।

gcloud config set run/region europe-west1
gcloud config set run/platform managed

আপনি যাচাই করে দেখতে পারেন যে কনফিগারেশনটি সেট করা আছে কিনা:

gcloud config list

...
[run]
platform = managed
region = europe-west1

ম্যানুয়ালি ক্লাউড বিল্ড ব্যবহার করে কন্টেইনার ইমেজ তৈরি ও প্রকাশ করার পরিবর্তে, আপনি গুগল ক্লাউড বিল্ডপ্যাকস ব্যবহার করে আপনার জন্য কন্টেইনার ইমেজ তৈরি করতে ক্লাউড রানের উপরও নির্ভর করতে পারেন।

কন্টেইনার ইমেজটি বিল্ড করতে নিম্নলিখিত কমান্ডটি চালান:

BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT
SERVICE_NAME=collage-service
gcloud run deploy $SERVICE_NAME \
    --source . \
    --no-allow-unauthenticated \
    --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS

–-source ফ্ল্যাগটি লক্ষ্য করুন। এটি ক্লাউড রান-এর সোর্স-ভিত্তিক ডেপ্লয়মেন্ট । যদি সোর্স কোড ডিরেক্টরিতে একটি Dockerfile থাকে, তাহলে আপলোড করা সোর্স কোডটি সেই Dockerfile ব্যবহার করে বিল্ড করা হয়। যদি সোর্স কোড ডিরেক্টরিতে কোনো Dockerfile না থাকে, তাহলে গুগল ক্লাউড বিল্ডপ্যাকস স্বয়ংক্রিয়ভাবে আপনার ব্যবহৃত ভাষা শনাক্ত করে এবং গুগল দ্বারা পরিচালিত একটি সুরক্ষিত বেস ইমেজ ব্যবহার করে একটি প্রোডাকশন-রেডি কন্টেইনার ইমেজ তৈরি করার জন্য কোডের ডিপেন্ডেন্সিগুলো ফেচ করে। এই ফ্ল্যাগটি ক্লাউড রান-কে Dockerfile সংজ্ঞায়িত কন্টেইনার ইমেজটি বিল্ড করার জন্য গুগল ক্লাউড বিল্ডপ্যাকস ব্যবহার করতে নির্দেশ দেয়।

আরও মনে রাখবেন যে, সোর্স-ভিত্তিক ডেপ্লয়মেন্টে বিল্ড করা কন্টেইনারগুলো সংরক্ষণের জন্য আর্টিফ্যাক্ট রেজিস্ট্রি ব্যবহার করা হয়। আর্টিফ্যাক্ট রেজিস্ট্রি হলো গুগল কন্টেইনার রেজিস্ট্রি-র একটি আধুনিক সংস্করণ। প্রজেক্টে এপিআই (API) আগে থেকে এনাবল করা না থাকলে, সিএলআই (CLI) এটি এনাবল করার জন্য প্রম্পট করবে এবং আপনি যে অঞ্চলে ডেপ্লয় করছেন, সেখানে cloud-run-source-deploy নামে একটি রিপোজিটরি তৈরি করবে।

--no-allow-unauthenticated ফ্ল্যাগটি ক্লাউড রান সার্ভিসকে একটি অভ্যন্তরীণ সার্ভিসে পরিণত করে, যা শুধুমাত্র নির্দিষ্ট সার্ভিস অ্যাকাউন্ট দ্বারাই চালু হবে।

৮. ক্লাউড শিডিউলার সেট আপ করুন

এখন যেহেতু ক্লাউড রান সার্ভিসটি প্রস্তুত এবং ডেপ্লয় করা হয়ে গেছে, তাই প্রতি মিনিটে সার্ভিসটি চালু করার জন্য একটি নিয়মিত শিডিউল তৈরি করার সময় এসেছে।

একটি পরিষেবা অ্যাকাউন্ট তৈরি করুন:

SERVICE_ACCOUNT=collage-scheduler-sa
gcloud iam service-accounts create $SERVICE_ACCOUNT \
   --display-name "Collage Scheduler Service Account"

ক্লাউড রান পরিষেবা চালু করার জন্য পরিষেবা অ্যাকাউন্টকে অনুমতি দিন:

gcloud run services add-iam-policy-binding $SERVICE_NAME \
   --member=serviceAccount:$SERVICE_ACCOUNT@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
   --role=roles/run.invoker

প্রতি ১ মিনিট পর পর কার্যকর হওয়ার জন্য একটি ক্লাউড শিডিউলার জব তৈরি করুন:

SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --format 'value(status.url)')
gcloud scheduler jobs create http $SERVICE_NAME-job --schedule "* * * * *" \
   --http-method=GET \
   --location=europe-west1 \
   --uri=$SERVICE_URL \
   --oidc-service-account-email=$SERVICE_ACCOUNT@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
   --oidc-token-audience=$SERVICE_URL

এটি সেটআপ করা আছে এবং ক্লাউড রান সার্ভিস ইউআরএল-কে নির্দেশ করছে কিনা, তা আপনি ক্লাউড কনসোলের ক্লাউড শিডিউলার সেকশনে গিয়ে দেখতে পারেন:

35119e28c1da53f3.png

৯. পরিষেবাটি পরীক্ষা করুন

সেটআপটি কাজ করছে কিনা তা পরীক্ষা করতে, thumbnails বাকেটে কোলাজ ইমেজটি (যার নাম collage.png ) দেখুন। এছাড়াও আপনি সার্ভিসটির লগগুলোও দেখতে পারেন:

93922335a384be2e.png

১০. পরিষ্কার করা (ঐচ্ছিক)

আপনি যদি এই সিরিজের অন্য ল্যাবগুলো চালিয়ে যেতে না চান, তাহলে খরচ বাঁচাতে এবং সার্বিকভাবে একজন ভালো ক্লাউড ব্যবহারকারী হতে রিসোর্সগুলো পরিষ্কার করতে পারেন। আপনি নিম্নলিখিত উপায়ে একে একে রিসোর্সগুলো পরিষ্কার করতে পারেন।

পরিষেবাটি মুছে ফেলুন:

gcloud run services delete $SERVICE_NAME -q

ক্লাউড শিডিউলার জবটি মুছে ফেলুন:

gcloud scheduler jobs delete $SERVICE_NAME-job -q

বিকল্পভাবে, আপনি পুরো প্রজেক্টটি মুছে ফেলতে পারেন:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

১১. অভিনন্দন!

অভিনন্দন! আপনি একটি নির্ধারিত পরিষেবা তৈরি করেছেন: ক্লাউড শিডিউলারের সৌজন্যে, যা প্রতি মিনিটে একটি পাব/সাব টপিকে বার্তা পাঠায়, আপনার ক্লাউড রান কোলাজ পরিষেবাটি চালু হয় এবং ছবিগুলোকে একসাথে জুড়ে দিয়ে চূড়ান্ত ছবিটি তৈরি করতে সক্ষম হয়।

আমরা যা আলোচনা করেছি

  • ক্লাউড রান
  • ক্লাউড শিডিউলার
  • ক্লাউড স্টোরেজ
  • ক্লাউড ফায়ারস্টোর

পরবর্তী পদক্ষেপ