iT邦幫忙

0

[不做怎麼知道系列之Android開發者的30天後端養成故事 Day21] - 整套Django自動上雲端 #資料庫也雲端 #GCP #CircleCI

https://ithelp.ithome.com.tw/upload/images/20200229/20124548kjDm9muFf7.png

哈囉,我們又見面了,昨天 原本要把雲端資料庫也整合好的,可是出了點意外 XD,所以改成今天來完成,我們這次選擇的雲端資料庫是 Google Cloud PlatformCloud SQL 服務。

我想達成的目標是「Commit、Push 到 Github 後,CircleCI 自動執行 CI/CD,部署到 GAE (Google App Engine)」

前幾天已經走過 CI/CD 且部署到 GAE 了,就差 SQLite 沒有被改為一個真正的雲端資料庫,然而,可是我遇到的問題是:「push 到 Github 後,CircleCI 在跑測試時會報錯,錯誤訊息是: can't connect to local mysql server through socket,但把測試的 job 拿掉之後,卻又可以正常 deploy 到 GAE 執行」

中間的環節有 Google Cloud SQL、Google App Engine、CircleCI 的 build-and-test job、deploy job 以及 django 的資料庫設定,總共五個不確定的因素,我就要一個一個去找出來,光是這次要把 SQLite 換成 Google Cloud SQL 就試了 30 次,心累 QQ,希望我浪費掉的這些時間可以幫助到你們。

Google Cloud SQL

我挑的方案是 MySQL 第二代 5.7 版 standard-1,也就是標準最便宜的方案,但對我來說很夠用了,連接方式很簡單,在 Google Cloud Platform(GCP) 的選單切換到儲存空間分類的 SQL,然後點 建立執行個體,選擇適合你的方案,這樣就算建立完成

https://ithelp.ithome.com.tw/upload/images/20200229/20124548EVboD9FfCW.png

然後點選左邊選單的 資料庫 → 建立資料庫,輸入你的資料庫名稱,我這邊的資料庫名字是 shop,用於在 django 的 settings.py 輸入 NAME 欄位

https://ithelp.ithome.com.tw/upload/images/20200229/20124548NJwgjmw2FT.png

建立好資料庫之後,切回到選單的 總覽,找到 執行個體連線名稱 (也就是 Connection Name),先複製起來,等等貼到 django 的 settings.py,資料庫的部分到這邊就算搞定,是不是簡單 !? 麻煩的在別的地方 XD

https://ithelp.ithome.com.tw/upload/images/20200229/201245485v4BzW9zoT.png

設定 Django 的資料庫

settings.py

這邊是其中一個卡住我的地方,因為我還想要到 CircleCI 做測試,可是我並不知道在封閉的環境之下,到底要怎麼連線到 Cloud SQL,但經過多番嘗試,最終結果是,Django 的測試中,不需要真的連到資料庫,只有在發佈到 App Engine 才連線到真正的資料庫就可以了,真是痛過才知道 QQ

...

if os.getenv('GAE_APPLICATION', None):
	DATABASES = {
		### mysql of google cloud sql
		'default': {
			'ENGINE': 'django.db.backends.mysql',
			# 這個`shop`,就是在 Cloud SQL 所建立的
            # 資料庫名稱(上文有提到該注意的地方)
			'NAME': 'shop',
			# 在上文提到的 Connection Name
            # 的前面加入 /cloudsql/
			'HOST': '/cloudsql/django-shop-269303:asia-east1:django-mysql',
			# 帳號密碼應該用更安全的方式來放
            # 暫時我還不知道怎麼用比較好 QQ
			'USER': 'rs',
			'PASSWORD': 'admin',
		}
	}
else:
	DATABASES = {
		### for testing env
		'default': {
			'ENGINE': 'django.db.backends.mysql',
			'NAME': 'shop',
			# 除了正式發佈之外的環境
            # 就連線到本機端進行測試即可
			'HOST': '127.0.0.1',
			# 帳號密碼應該用更安全的方式來放
            # 暫時我還不知道怎麼用比較好 QQ
			'USER': 'rs',
			'PASSWORD': 'admin',
		}
	}

...

Django 需要做的更動就這樣,再來是對我來講很麻煩的 CircleCI config.yml 設定檔

CircleCIconfig.yml 設定檔

config.yml 放在專案資料夾底下的 .circle 資料夾,這資料夾怎麼來的,可以參考 Day13

因為我對 CircleCI 的各種設定都還很不熟,所以並不知道詳細執行情況會變什麼樣子,只能透過每次執行出來的錯誤訊息,和透過 ssh 連線進去當下的環境做除錯,就這樣來來回回三十次才成功 QQ,現在就記下來,避免之後再遇到同樣的問題。

config.yml

分成兩個 job,build-and-test 用來做測試,deploy 用來部署到 GAE

build-and-test 疊了兩層 docker image,是 pythonmysql,這個 mysql 的 docker image,就是卡住我的最主要原因,他會自動在本地端執行 mysql server,所以在測試的階段,就可以連到本地端的 mysql 進行測試。

而我卡住的原因,就是以為在 build-and-test 的階段,就連上真正的 Cloud SQL,我就在這邊安裝了各種套件: Cloud SDKCloud SQL Proxypymysqlmysql-client,然後還把 docker 換成 circleci/cloud-sdk,各種折騰,才發現根本不需要。只要導入 mysql 的 docker image,然後在 django 連到本地的 mysql 即可。

version: 2.1

orbs: 
  python: circleci/python@0.2.1

jobs:
  build-and-test:
    docker:
      - image: circleci/python:3.7
      - image: circleci/mysql:5.7
        environment:
          MYSQL_DATABASE: shop
          MYSQL_ROOT_HOST: "%"
          MYSQL_USER: rs
          MYSQL_PASSWORD: admin
    executor: python/default
    steps:
      - checkout
      - restore_cache:
          key: deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}
      - run:
          command: |
            python3 -m venv venv
            . venv/bin/activate
            pip install -r requirements.txt
      - save_cache:
          key: deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}
          paths:
            - "venv"
      - run:
          name: Running tests
          command: |
            . venv/bin/activate
            python manage.py test
      - store_artifacts:
          path: test-reports/
          destination: python_app
      - persist_to_workspace:
          root: .
          paths:
            - build-and-text
            - app.yaml

  deploy:
    docker:
      - image: google/cloud-sdk
    steps:
      - checkout
      - run:
          name: Authorizing gcloud
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account django-shop-269303@appspot.gserviceaccount.com --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: Deploy to App Engine
          command: |
            gcloud app deploy

workflows:
  main:
    jobs:
      - build-and-test
      - deploy:
          requires:
            - build-and-test

就這樣一點東西,搞了我一整天的時間 QQ,看來觀念還是要正確,才不會亂試浪費時間啊 ~ 終於有種撥雲見日的感覺了 !

https://images.pexels.com/photos/1133505/pexels-photo-1133505.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260

Photo by Johannes Plenio from Pexels

單日心得總結

因為我沒有把整套伺服器加資料庫放到雲端的經驗,也不知道通常是怎麼串起來的,再加上我還要透過 CircleCI 來做 CI/CD,整套流程要串起來真的是有點不知所措,都不知道到底是哪個環節出了問題,只能一個一個去試,真的很浪費時間,可是我身邊的朋友都沒有用過 CircleCI,也沒有用 DjangoCircleCI 最後架在 GAE 上的經驗,只好自己踩踩雷了。

經過這次的體驗,又更懂架站的流程了呢~

我是 RS,這是我的 不做怎麼知道系列 文章,我們 明天見。


https://ithelp.ithome.com.tw/upload/images/20200219/20124548meDsnCPamL.png


尚未有邦友留言

立即登入留言