iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0

https://ithelp.ithome.com.tw/upload/images/20231014/20136558kU8ffoEtvB.jpg
我們這28天已經完成了前後端的程式,今天我們要將後端的程式部署上去!

使用的平台


申請使用Google Cloud Storage

首先要先有google帳戶,登入之後點選前往控制台
https://ithelp.ithome.com.tw/upload/images/20231022/20136558IHnrJl1YBF.jpg

專案和服務帳戶建立

點選左上角專案,新增專案
https://ithelp.ithome.com.tw/upload/images/20231022/20136558WXO28wSv48.jpg

接著點選IAM與管理裡的服務帳戶,並建立服務帳戶
https://ithelp.ithome.com.tw/upload/images/20231022/20136558KHVfrwixfM.jpg
https://ithelp.ithome.com.tw/upload/images/20231022/20136558vTGwE6uXg9.jpg

生成金鑰

建立好服務帳戶後,要來生成金鑰,點選最右側的動作-管理金鑰
https://ithelp.ithome.com.tw/upload/images/20231022/20136558uLAfY6ujM4.jpg

點選新增金鑰
https://ithelp.ithome.com.tw/upload/images/20231022/20136558nN36vuyipp.jpg

選擇JSON格式,最後會在本機下載金鑰檔案並出現以下訊息表示金鑰生成成功。
https://ithelp.ithome.com.tw/upload/images/20231022/20136558ZJs0fmAZmP.jpg

值區建立

接著點選Cloud Storage
https://ithelp.ithome.com.tw/upload/images/20231022/20136558Bvg9PyQySb.jpg

接著在值區旁邊點選建立,會進到以下畫面,填寫值區的相關資料
https://ithelp.ithome.com.tw/upload/images/20231022/20136558v7hAYiDiMz.jpg
https://ithelp.ithome.com.tw/upload/images/20231022/20136558jc80layz9M.jpg
https://ithelp.ithome.com.tw/upload/images/20231022/20136558yx1qPT26ZQ.jpg

建立成功後會看到以下畫面
https://ithelp.ithome.com.tw/upload/images/20231022/201365580bkEaTG6Wc.jpg

修改公開存取權
上面可以看公開存取權還是非公開,這樣我們的後端api無法取得圖片資料,所以我們要來調整存取權

點選授予存取權
https://ithelp.ithome.com.tw/upload/images/20231022/20136558hW4RV2oY7L.jpg
選擇主體:allUsers角色:儲存空間物件檢視者
https://ithelp.ithome.com.tw/upload/images/20231022/20136558HboCCx9ygk.jpg

完成就可以看到我們的公開存取權變為在網際網路上公開
https://ithelp.ithome.com.tw/upload/images/20231022/20136558UPrtpxPIXw.jpg

後端部署(render)

安裝google cloud storage套件

npm install @google-cloud/storage

後端專案調整

我們要先去設定PORT,因為原先是帶入我們local的來源,使用express的環境變數,來帶入部署後的路徑。

server.js

設定前端環境變數

//server.js
{...}

//Connect Database
connectDB();

const corsOptions = {
    origin: process.env.FRONTEND || 'http://localhost:3000', // 設定允許的來源
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', // 設定允許的 HTTP 方法
    optionsSuccessStatus: 204,
};

images-controller.js

圖片上傳的路徑也要調整成google cloud storage的url

//images-controller.js
{...}
const config = require('config');
const path = require('path');
const HttpError = require('../models/http-error');
//引入google storage
const {Storage} = require('@google-cloud/storage');
//這裡的keyFilePath要抓的檔案就是剛剛前面生成的金鑰檔案,路徑是會放在專案最外層也就是blog-platform-backend下面
const keyFilePath = path.join(__dirname, '../keys.json');

exports.uploadImage =  (req, res,next) => {

    if (!req.file) {
        return next(new HttpError('No file uploaded', 400));
    }
    const storage = new Storage({
        keyFilename: keyFilePath,
        projectId: 'blog-platform-*****',
     });

    const bucket = storage.bucket('blog-platform');
    const blob = bucket.file(req.file.originalname);
    const blobStream = blob.createWriteStream();

    blobStream.on('error', (err) => {
        res.status(500).send(err);
     });

     blobStream.on('finish', () => {
        // The image URL to access the file in GCS
        const publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
        res.status(200).json({ success: true, data: { url: publicUrl } });
     });
  
    blobStream.end(req.file.buffer);
};
const bucket = storage.bucket('blog-platform');
{...}
 const storage = new Storage({
        keyFilename: keyFilePath,
        projectId: 'blog-platform-*****',
 });

上面的projectId可以在這裡找到
https://ithelp.ithome.com.tw/upload/images/20231022/20136558SPvWUPvsBB.jpg
bucket就是我們建立的值區名稱blog-platform

image-route.js

const express = require('express');
const multer = require('multer');
const auth = require('../../middleware/auth');
const router = express.Router();
const imageControllers = require("../../controllers/images-controller");
const config = require('config');


const multerStorage = multer.memoryStorage();  // Store the file in memory

const fileFilter = (req, file, cb) => {
  const allowedTypes = ["image/jpeg", "image/jpg", "image/png"];
  if (!allowedTypes.includes(file.mimetype)) {
    const error = new Error("不支援的檔案類型(只支援jpg、jpeg、png)");
    error.code = "LIMIT_FILE_TYPES";
    return cb(error, false);
  }
  cb(null, true);
};


const upload = multer({ 
  storage: multerStorage,
  fileFilter: fileFilter,
  limits:{
    fileSize: config.get("fileMaxSize")
  } 
});

// Image upload route
router.post('/upload', auth, upload.single('image'), imageControllers.uploadImage, imageControllers.uploadErrorHandler);


module.exports = router;

🔺調整完記得推送到github上面

MongoDB連線路徑調整

原先我們是抓取for vscode的,但我們要調整成透過driver的url
點選Drivers
https://ithelp.ithome.com.tw/upload/images/20231014/20136558wRoR0iXS92.jpg
複製下面的url
https://ithelp.ithome.com.tw/upload/images/20231014/20136558yRZGHwd9Me.jpg
然後再回到default.json修改路徑

🔺調整完記得推送到github上面

部署

先到render用GitHub註冊帳號
https://ithelp.ithome.com.tw/upload/images/20231014/20136558tICUWDisiB.jpg

登入後,點選Web services
https://ithelp.ithome.com.tw/upload/images/20231014/20136558Ra9ze1NWbz.jpg

選擇Build and deploy from a Git repository
https://ithelp.ithome.com.tw/upload/images/20231014/20136558or6cJxhQFT.jpg

Connect a repository
https://ithelp.ithome.com.tw/upload/images/20231014/20136558etihHliNfh.jpg

設定部署的資料和再點選Create Web Service
https://ithelp.ithome.com.tw/upload/images/20231014/201365585rhAd0eVXU.jpg

此時會看到錯誤訊息
https://ithelp.ithome.com.tw/upload/images/20231014/20136558i59Fpk1EXU.jpg
上面的訊息簡單來說就是伺服器的ip沒有被加到mongoDB的白名單裡面,所以無法存取資料庫

取得IP後到MongoDB將上面的IP都設在白名單內
https://ithelp.ithome.com.tw/upload/images/20231015/20136558GBzTW2l3py.jpg
https://ithelp.ithome.com.tw/upload/images/20231015/20136558scTXSzNqa1.jpg

接著應該就可以成功部署了
https://ithelp.ithome.com.tw/upload/images/20231014/20136558SBC4qqo0Z2.jpg

新增process.env.BACKEND的環境變數
https://ithelp.ithome.com.tw/upload/images/20231015/20136558CvcKLCY2XX.jpg

🔺因為我們有用到圖片上傳,在render需要付費解鎖Disk($7/month),才能存放上傳的圖片。

參考資料


上一篇
[Day28] 使用者頁面和更新使用者資料開發
下一篇
[Day30]前端程式部署(Vercel)
系列文
初探全端之旅: 以MERN技術建立個人部落格31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言