Skip to main content

· 8 min read
zaxro

S3 靜態網站設定

info

如果有打算限制能近來的域名,就請不要用靜態網站,就用預設的 RestApi 模式,接 cloudfront 透過 header 去限定。

官網教學很詳細! 要在 Amazon S3 上設定靜態網站,如果是使用 UI 的話,請按照以下步驟進行操作:

  1. UI: 建立新的 S3 Bucket 或選擇一個現有的 Bucket。(Cli:aws s3 mb s3://me-profile --profile ford --region us-west-1 在 us-west-1 建立 s3 bucket,bucket 名稱是 me-profile,使用的 user 是 ford)
  2. UI:在 Bucket 屬性中啟用靜態網站主機。
  3. UI:指定要使用的索引文件(index.html)和錯誤文件。(Cli:aws s3 website s3://bucket-name --index-document index.html --error-document error.html)
  4. UI :將必要的文件添加到 Bucket 中。(可以用 也可以用 cli Cli:aws s3 sync ./dist/ s3://fordserver-front --delete --profile ford)
  5. UI :配置 Bucket 策略以允許公開訪問文件,預設會全擋。
  6. UI :新增儲存貯體政策,將儲存貯體內容設為可供大眾讀取,把這個 json 複製貼上
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::Bucket-Name/*"
]
}
]
}

Resource 更新為您的儲存貯體名稱!

· 5 min read
zaxro

Build code registry

把 code 推到 github 教學很多,可以 google 一下,不過要注意的是現在推 code 都要先在官網申請 token,新手很容易卡在這。

ways to build image and push

執行 CI 前,要確認有 Dockerfile 並且在地端可以 docker run 服務起來,CI 過程會用該 Dokcerfile 產生 image。

way1. build image and push from local side by docker command,use CI after to renew

  1. 在地端 build 完,然後推到 github container registry(需要用 github ui 建立 token,並給 token) ,然後把 token 存到 txt 檔

  2. 用 token 登入 github

cat token.txt | docker login ghcr.io -u suyuying --password-stdin

-u 換成自己的 username

token.txt把 token 放在裡面

· 8 min read
zaxro

基本介紹

GitHub Action 是 continuous integration and continuous delivery (CI/CD)平台, 除了一般的 build test deploy 他另外有給專案管理的各種小功能,例如給 pull request 打標籤。 提供免費的 runner 幫你執行任務,也接受 self-hosted runner。

· 3 min read
zaxro

.env 傳入方法

參考自這篇 stack overflow

兩種方式,這依據你的.env 裡面到底有多少個變數。但共同點都是在 github worlflow 過程使用 secrets 上下文,例如${{ secrets.XXX }},去把存放在 github registry 裡面的環境變數,存放到指定位置的.env 檔。

single vaiable

如果只有一個變數,就把該變數放到 github registry 裡面,取上下文來用就好

    - name: 'Create env file'
run: |
touch .env
echo API_ENDPOINT="https://xxx.execute-api.us-west-2.amazonaws.com" >> .env
echo API_KEY=${{ secrets.API_KEY }} >> .env
cat .env

Better method for multiple variables

如果有很多個變數在.env 檔,就把.env 檔整份 copy 到 github registry 裡面

例如:

.env
ALGORITHM="HS256"
ACCESS_TOKEN_EXPIRE_MINUTES=60
# 對password加鹽的物件
# sql連線網址
SQLALCHEMY_DATABASE_URL="sqlite:///./sql_app.db"
TOKENURL="token"
ARTICLE_CATEGORY='[\"PythonBasic\",\"Fastapi\",\"DataScience\",\"PythonModule\",\"LinuxShellScript\",\"JavaScriptBasic\",\"React\"]'

就把他整份裡面的值 copy 到 config 裡面就好,假設 key 叫做 ENV_FILE,然後 yml 檔這樣寫

     - name: 'Create env file'
run: |
echo "${{ secrets.ENV_FILE }}" > .env

他就會把你所有 value 送到.env 檔了。

info

記錄一下我遇到的狀況,因為這個真的卡頗久,也試不出來一個方法,所以就先記錄吧,也歡迎提供解答 python dotenv 在.env 檔裡面寫入 list ,要用以下方法表述 ARTICLE_CATEGORY='["PythonBasic","Fastapi","DataScience","PythonModule","LinuxShellScript","JavaScriptBasic","React"]',配合 json.loads(os.environ.get('ARTICLE_CATEGORY'))去拿資料。

但是在使用 action 遇到一個問題,echo ${{ secrets.ENV_FILE }} > .env 會輸入空值進去,echo "${{ secrets.ENV_FILE }}" > .env 這樣才會有值,但問題在使用""包住會把 ARTICLE_CATEGORY='["PythonBasic","Fastapi","DataScience","PythonModule","LinuxShellScript","JavaScriptBasic","React"]'轉成 ARTICLE_CATEGORY='[PythonBasic,Fastapi,DataScience,PythonModule,LinuxShellScript,JavaScriptBasic,React]' 這個格式在讀 json.loads(os.environ.get('ARTICLE_CATEGORY'))就會遇到問題,會報 error 因為這個格式他不行。

目前在處理 list 部分,都先用ARTICLE_CATEGORY='[\"PythonBasic\",\"Fastapi\",\"DataScience\",\"PythonModule\",\"LinuxShellScript\",\"JavaScriptBasic\",\"React\"]' 送資料。然後用json.loads(os.environ.get('ARTICLE_CATEGORY'))去拿資料

· 2 min read
zaxro

docker create context 是用來建立一個新的 context,以指向一個 remote Docker daemon,用於管理 Docker 主機和 Docker registry 的機制。

可以使用 docker context use 指令來切換 context,切換完成後即可使用 docker 指令操作 remote Docker daemon。如果使用雲端 container,例如 azure web container service,就可以用這個指令去管理雲端 container。包含新建 刪除都可以使用,所以不要太開心一次起一大堆雲端 container 這樣會被 charging 到爆。

info

如果有用到 docker buildx 可能會把 docker context 跟 docker buildx create --name 搞混, 兩個是不同的.

以下是 docker create context 指令的教學:

使用 docker create context 指令可以建立一個新的 context,用來指向一個 remote Docker daemon。以下是指令的詳細說明:

docker context create CONTEXT_NAME --docker "host=REMOTE_DOCKER_HOST" --description "CONTEXT_DESCRIPTION"
  • CONTEXT_NAME: 指定新建立的 context 的名稱。
  • REMOTE_DOCKER_HOST: 指定 remote Docker daemon 的位置,可以是一個 IP 或是一個 domain name。
  • CONTEXT_DESCRIPTION: 可以加入對 context 的描述,方便管理。

例如,以下指令建立一個名為 mycontext 的 context,指向一個 remote Docker daemon,並加入描述:

docker context create mycontext --docker "host=myremotehost:2376" --description "My remote Docker daemon"

建立完成後,可以使用 docker context use 指令來切換 context:

docker context use mycontext

· 7 min read
zaxro

volume of docker

以前都在弄自己的小專案,只要東西跑得起來就好,沒想過會遇過因為硬碟吃滿導致 container 服務掛掉的問題。

docker 掛載 volume 會有三種方式,綁定掛載(Bind Mount),命名卷(Named Volume),匿名卷(Anonymous Volume),前兩種在 container 被刪除時不會被刪,會永久保存,docker 內沒被掛載或使用 Anonymous Volume 則都會被刪除。

tip
  1. docker logs 資料包含哪些?

Docker 會捕捉所有容器的標准輸出(和標准錯誤),並以 JSON 格式將其寫入文件中。 JSON 格式將每行注釋為其源(stdout 或 stderr)和其時間戳。 每個日誌文件僅包含有關一個容器的信息。

  1. docker logs 什麼時候會被刪除? 當 container 被 rm -f 掉的時候 (單純 restart 還會在)!如果要刪除 container 又想保留 docker log,請用docker logs CONTAINER_ID > container.log .

    如果是一般非 docker log,要把打掛載出來

  2. 沒有掛載出來的資料,例如你把 log(非 stdout)寫到某檔案,但該檔案沒被掛載,在本機找得到嗎? 如果沒有掛載出來的資料,例如,程式把特定 log 寫到特定資料夾內(非 standard-out),且你 docker 沒有掛載該資料夾,這樣你在你的 host 主機是不會看到該資料夾的檔案的,他不會在/var/lib/docker 底下,而是在 docker 維護的可寫層中(/var/lib/docker/overlay2),這時候要拿到該檔案,只能透過docker cp指令,把檔案拿出來!

    基本上是建議把 app log 放在 std-out 中,透過 docker 管理 log 的機制去限制 log 大小,像這篇提到的解法,不然可能會遇到的情況像是 db 資料把/var/lib/docker/overlay2 塞爆之類的情況,像這篇

    # Copy the logs out to the host
docker copy CONTAINER_ID:/path/to/your/log_file /host/path/to/store

# Mount a directory for them
docker run -d \
-v /host/path/to/store/logs:/container/path/stored/logs \
your-image

如何減少不必要的硬體佔用

因為 docker 運行過程本身 log 也會佔用硬碟資源,為了不讓這個 log 過度膨脹,可以用以下方式限制

  1. 修改 docker 設定檔
/etc/docker/daemon.json
{
"log-driver":"json-file",
"log-opts": {"max-size":"500m", "max-file":"3"}
}

`systemctl daemon-reload`
`systemctl restart docker
`
  1. 修改 docker-compose.yml
services:
hellow:
build: .
container_name: mattermost
restart: always
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"

並使用以下指令重啟,一般 restart 不會吃新 config

docker-compose -f docker-compose.yml up -d --force-recreate mm
danger

下這個指令前務必想好是否重要資訊有用 Bind Mount or Named Volume 掛載出來!

  1. docker 指令
docker run --log-opt max-size=10m --log-opt max-file=5 nginx

官網 log 管理,管理 docker log 方式很多,預設都適用 json-file,設定可已透過修改/etc/docker/daemon.json 並重啟達成。

預設是在同一份檔案,無限大小寫入,透過以上方法,可以限定檔案大小跟可產生檔案數量,當 log 容量到達上限時,Docker 程序將停止寫入該日誌文件,並開始使用新名稱啟動新的日誌文件。默認情況下,新日誌文件將具有與舊日誌文件相同的名稱,但會在末尾添加連續號(例如,access.log.1、access.log.2 等)。

Docker 保留的日誌文件數量由max-file選項決定。默認情況下,Docker 將保留最多 1 個日誌文件(要配置max-size才會生效)。當達到最大日誌文件數量時,Docker 將開始使用新的日誌數據覆蓋最舊的日誌文件。

(ps:資訊以此連結為準,設定可能會改變的)

what should do when you find / or /var are full

info

預設 docker 的東西都放在/var/lib/docker 底下

/var/lib/docker
builder  buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes

可以在該資料夾底下用du -sh ./*確認哪個地方吃得異常兇, 並用docker system df看資料佔用,如果不用的 image 很多可以清除

docker image prune --all

他會刪除所有沒有被 container 使用的 image,警示如下:

WARNING! This will remove all images without at least one container associated to them.

  1. 如果當初沒有做任何預防,導致/var 真的爆了,可以優先檢查以下幾項

檢查 docker logs 是否佔太兇

其實就是去/var/lib/docker/containers,執行du -sh ./* 看哪個 container 佔最多資源,然後去看裡面那隻放 docker logs 的檔名為 container-id-json.log 的檔案是否長太大,確認後可以砍掉。

檢查 named volume 中存放資訊

其實就是去/var/lib/docker/volumes 底下,看有沒有某個 volume 佔太多資源,然後裡面放的東西可能不重要(例如 nginx log)

檢查 image 跟沒用的 container

image 指令:刪除沒有被活動的 container 使用的 image docker image prune --all

container 指令:刪除停止的 container docker container prune

檢查 /var/lib/docker/overlay2

如果沒有掛載,他會持續把資料寫入這隻,也可能會造成硬碟爆掉

整理

檢查順序

  1. docker system df
  2. 檢查 local volume,docker logs,image,container 佔用情況
  3. 檢查 /var/lib/docker/overlay2

可以的對策有

  1. 如果是 docker logs 那可以限制 docker logs 大小
  2. 如果是 local volume 那就要跟 rd 討論 log 格式了
  3. 如果是/var/lib/docker/overlay2,這個狀況就比較多,ex mysql 對 binary log 的自動清除要開之類的
  4. 沒有在用的 container volume image 用指令清掉就好

· 5 min read
zaxro

基本介紹

danger

如果不支援多平台,就會出現在 arm build,然後在 amd deploy 失敗,上網查不到原因的問題。

Docker Buildx 是 Docker 官方提供的一個命令行工具,用於通過 Dockerfile 构建 Docker 映像。它的主要特點是可以跨平臺構建 Docker 映像,並支持多種 CPU 架構(如 x86、ARM、IBM Power 等),是一個用來建立和管理 multi-arch Docker image 的工具。

info

docker buildx 的單位是 node,跟 docker context 不同,前者是建立影像的主機,可以使用多個節點來加速 Docker 映像的建立過程,後者則是用來管理 Docker 主機和 Docker registry 的機制,定義了一個或多個 Docker 主機和 Docker registry 的設定。

以下是使用 Docker Buildx 構建 Docker 映像的基本步驟:

1. 啟用 multi-arch 支援

要使用 docker buildx 建立 multi-arch Docker image,必須先啟用 multi-arch 支援(Docker Desktop 預配置了 binfmt_misc 對其他平台的支持,可以忽略此指令)。可以使用以下指令啟用 multi-arch 支援:

docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

2. 建立 builder(node)

要使用 docker buildx 建立 multi-arch Docker image,必須先建立一個 builder。使用以下指令建立 builder:

docker buildx create --name mybuilder

3. 設定 builder

建立 builder 後,必須將 builder 設定為目前使用的 builder。使用以下指令設定 builder:

docker buildx use mybuilder

4. 建立 Dockerfile

接下來,建立一個 Dockerfile,並在其中指定要建立的 Docker image。例如,在 Dockerfile 中可以指定要建立的 image 為 ubuntu:latest,並在其中安裝一些軟體套件:

FROM --platform=$TARGETPLATFORM ubuntu:latest

RUN apt-get update && \\
apt-get install -y software-properties-common && \\
add-apt-repository -y ppa:nginx/stable && \\
apt-get update && \\
apt-get install -y nginx

5. 建立 multi-arch Docker image

建立 Dockerfile 後,可以使用以下指令建立 multi-arch Docker image:

docker buildx build --platform linux/arm/v7 -t myimage:latest --load .

在上面的命令中,--platform 參數指定了要構建的 CPU 架構,-t 參數指定了映像的標籤,. 表示當前目錄是 Dockerfile 所在的目錄。

--load 相當於--output=type=docker 沒有指定會出現 warning

WARN[0000] No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load

--push 遠端 registry 相當於--output=type=registry

info

https://github.com/docker/buildx/issues/59 2023/3/9 使用--platform 配合--load,不能支援多平台,一次一個平台,否則會報錯 --push 支援一次多平台 image

error: docker exporter does not currently support exporting manifest lists

建立完成後,可以使用以下指令查看建立的 Docker image:

docker images myimage

推送 Docker 映像:

$ docker push myimage:latest

以上就是使用 Docker Buildx 構建 Docker 映像的基本步驟。使用 Docker Buildx 可以讓我們更方便地構建跨平臺的 Docker 映像,提高了開發效率。

info

docker buildx rm docker-test 刪除

docker buildx use docker-test切換

docker buildx create --name my-node 是建立節點嗎?

是的,docker buildx create --name my-node 指令會建立一個名為 my-node 的節點。節點是用來建立 Docker 映像的主機,可以使用多個節點來加速 Docker 映像的建立過程,或者建立不同平台的 Docker 映像。

建立節點時,可以使用 --driver 選項指定節點的驅動程式,例如 docker-containerdocker。驅動程式還可以是其他第三方平台,例如 AWS、Azure 或 Google Cloud。

在建立節點時,可以指定節點的名稱、驅動程式、驅動程式選項、Docker 映像等資訊。例如,以下是建立一個名為 my-node 的節點,使用 Docker 容器作為驅動程式,使用 moby/buildkit:v0.8.1 作為 Docker 映像的示範指令:

docker buildx create --name my-node --driver docker-container --driver-opt image=moby/buildkit:v0.8.1

建立節點後,可以使用 docker buildx ls 指令列出所有節點。建立 Docker 映像時,可以使用 --builder 選項指定要使用的節點。例如:

docker buildx build --builder my-node --platform linux/amd64 -t myimage:latest .

可以使用名為 my-node 的節點建立 Docker 映像,並指定要建立的平台為 linux/amd64。

· 11 min read
zaxro

前言

一開始是跳著學,直接 google 怎麼用 github action 做到 CI 建立 image 並推到 github container,不過這關過完後,在 deploy 到 azure web container 就卡關了,這邊貼卡關的部分

· 4 min read
zaxro

sed

一般打印 印 5~7 行 其他行數 silence

cat -n xxxx.md | sed -n '5,7p'

把 whois 檢查 domain 中的 Registry Expiry Date 的前面的空格去掉,以下意思是把 0 個以上的 space 去掉

sed 's/\s\{0,\}Registry Expiry Date: //'

· One min read
zaxro
  1. 1劫持:dns server 管理端或者你的域名解析商把你的 url 對應 ip 換成其他 ip 或 url
  2. 2污染:dns serer 的某個節點catch 被駭然後改掉,把這個 url 換成其他 ip 或 url

小結:劫持是官方被駭或故意改的(大陸常發生),污染是路由到dns server過程某台路由器被駭。