“Build a Serverless App with Cloud Run that Creates PDF Files”
Daftar Isi
Pengantar
Cloud Run tidak memiliki server, sehingga mengabstraksikan semua manajemen infrastruktur dan memungkinkan Anda fokus membangun aplikasi alih-alih mengkhawatirkan biaya overhead. Sebagai produk tanpa server Google, produk ini dapat diskalakan ke nol, artinya tidak akan dikenakan biaya saat tidak digunakan. Ini juga memungkinkan Anda menggunakan paket biner khusus berdasarkan wadah, yang berarti membangun artefak terisolasi yang konsisten sekarang layak dilakukan.
Architecture
Enable the Cloud Run API
- Buka menu APIs & Services > Library
- enable API
Deploy a simple Cloud Run service
- Clone repository
git clone https://github.com/rosera/pet-theory.git
- masuk ke folder
cd pet-theory/lab03
- Edit bagian ini di package.json
... "scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, ...
npm install express npm install body-parser npm install child_process npm install @google-cloud/storage
gcloud builds submit \ --tag gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter
- buka menu Container Registry > Images
- deploy app
gcloud run deploy pdf-converter \ --image gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter \ --platform managed \ --region us-central1 \ --no-allow-unauthenticated \ --max-instances=1
- Buat environment
SERVICE_URL=$(gcloud beta run services describe pdf-converter --platform managed --region us-central1 --format="value(status.url)")
echo $SERVICE_URL
- Buat post request
curl -X POST $SERVICE_URL
curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" $SERVICE_URL
Trigger your Cloud Run service when a new file is uploaded
- Buat bucket
gsutil mb gs://$GOOGLE_CLOUD_PROJECT-upload gsutil mb gs://$GOOGLE_CLOUD_PROJECT-processed
- Setting Pub/Sub notification
gsutil notification create -t new-doc -f json -e OBJECT_FINALIZE gs://$GOOGLE_CLOUD_PROJECT-upload
- Buat new service account dengan Pub/Sub
gcloud iam service-accounts create pubsub-cloud-run-invoker --display-name "PubSub Cloud Run Invoker"
- Buat permission
gcloud beta run services add-iam-policy-binding pdf-converter --member=serviceAccount:pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com --role=roles/run.invoker --platform managed --region us-central1
- cek project list
gcloud projects list
- Buat project_number environment
PROJECT_NUMBER=[project number]
- enable project
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com --role=roles/iam.serviceAccountTokenCreator
- Buat Pub/Sub pdf
gcloud beta pubsub subscriptions create pdf-conv-sub --topic new-doc --push-endpoint=$SERVICE_URL --push-auth-service-account=pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
- Copy beberapa test file ke upload bucket
gsutil -m cp gs://spls/gsp644/* gs://$GOOGLE_CLOUD_PROJECT-upload
- delete / clean data
gsutil -m rm gs://$GOOGLE_CLOUD_PROJECT-upload/*
Docker containers
Update the Docker container
- Edit file
Dockerfile
FROM node:12 RUN apt-get update -y \ && apt-get install -y libreoffice \ && apt-get clean WORKDIR /usr/src/app COPY package.json package*.json ./ RUN npm install --only=production COPY . . CMD [ "npm", "start" ]
- Edit index.js , tambahkan di top line
const {promisify} = require('util'); const {Storage} = require('@google-cloud/storage'); const exec = promisify(require('child_process').exec); const storage = new Storage();
- Replace the
app.post('/', async (req, res)
with the following code
app.post('/', async (req, res) => { try { const file = decodeBase64Json(req.body.message.data); await downloadFile(file.bucket, file.name); const pdfFileName = await convertFile(file.name); await uploadFile(process.env.PDF_BUCKET, pdfFileName); await deleteFile(file.bucket, file.name); } catch (ex) { console.log(`Error: ${ex}`); } res.set('Content-Type', 'text/plain'); res.send('\n\nOK\n\n'); })
- Tambahkan code libreOffice pada bagian paling bawah line
async function downloadFile(bucketName, fileName) { const options = {destination: `/tmp/${fileName}`}; await storage.bucket(bucketName).file(fileName).download(options); } async function convertFile(fileName) { const cmd = 'libreoffice --headless --convert-to pdf --outdir /tmp ' + `"/tmp/${fileName}"`; console.log(cmd); const { stdout, stderr } = await exec(cmd); if (stderr) { throw stderr; } console.log(stdout); pdfFileName = fileName.replace(/\.\w+$/, '.pdf'); return pdfFileName; } async function deleteFile(bucketName, fileName) { await storage.bucket(bucketName).file(fileName).delete(); } async function uploadFile(bucketName, fileName) { await storage.bucket(bucketName).upload(`/tmp/${fileName}`); }
- Build Container
gcloud builds submit \ --tag gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter
- deploy latest app
gcloud run deploy pdf-converter \ --image gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter \ --platform managed \ --region us-central1 \ --memory=2Gi \ --no-allow-unauthenticated \ --max-instances=1 \ --set-env-vars PDF_BUCKET=$GOOGLE_CLOUD_PROJECT-processed
Testing the pdf-conversion service
- test deployment
curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" $SERVICE_URL
- Upload beberapa data
gsutil -m cp gs://spls/gsp644/* gs://$GOOGLE_CLOUD_PROJECT-upload
Penutup
Sahabat Blog Learning & Doing demikianlah penjelasan mengenai Build a Serverless App with Cloud Run that Creates PDF Files. Semoga Bermanfaat . Sampai ketemu lagi di postingan berikut nya.