Ccmmutty logo
Commutty IT
0 pv4 min read

シンボリックリンクデプロイ 具体的実装例

https://cdn.magicode.io/media/notebox/blob_taT00Xm

これは何

現場で採用されることの多いECSを用いてのブルーグリーンデプロイもいいけど、短時間のサービス停止を許容する場合や、開発環境だけでもこの手法を使うとコンテナのビルド時間分時間の節約になったり楽ちんな場合があるよってお話。

シンボリックリンクデプロイとは

シンボリックリンク(Windowsで言うショートカットのようなもの)を用いて、旧Verと新Verを切り替える手法。

メリット

  1. 瞬時の切り替え:
    • デプロイ時にシンボリックリンクを変更することで、古いバージョンから新しいバージョンへの切り替えを非常に速く行うことができる。
    • ダウンタイムを最小限に抑えることが可能。
  2. 簡単なロールバック:
    • シンボリックリンクを元のバージョンに戻すことで、迅速かつ簡単にロールバックが可能。
  3. ファイルの重複回避:
    • 同一ファイルを複数のバージョンで共有でき、ディスクスペースの節約につながる。
  4. バージョン管理の簡略化:
    • 複数のバージョンを簡単に管理できるようになる。

デメリット

  1. シンボリックリンクの管理:
    • シンボリックリンク自体の管理が必要となり、リンクの更新や整合性を確保するための手間が増える。
  2. ファイルシステム依存:
    • シンボリックリンクはファイルシステムに依存するため、特定の環境(古いWindows環境など)では制限される場合がある。

実際の配置と原理

以下に実際の配置例を示します。
Fig.1 シンボリックリンク配置例
原理は簡単で、各リリースVerで固めたソースを配置しそのソースへシンボリックリンクを向けるというだけです。
例えばサービスのルートディレクトリをcurrentに設定し、currentというシンボリックリンクを作成。その参照先(実体)は使用中のVer(図中では青い四角で囲まれたところが紐づいており、v1.2.0のソースへ向いている)というような感じ。
次回リリース時には新規にリソースを配置し参照先を新しいソースに変更、逆に過去のVerに戻したいときはこのcurrentへの参照先をv1.1.0やv1.0.0に戻すだけです。

デプロイshellのサンプル

デメリット部分のシンボリックリンクの管理を容易にするため、実運用の際には特定のフォルダへ圧縮ファイルを配置しshellによる自動デプロイを行っていました。
配置例はFig.1を参照。
#!/bin/bash

function judge_exec_result() {

  if [[ ! $1 -eq 0 ]];
  then
    echo "コマンド実行に失敗しました。"

    exit -1
  fi

  return 0
}


# ---------------- メイン処理 ---------------- #
readonly SYSTEM_NAME="SystemName"
readonly DEPLOY_DIR="/deploy"


cd ${DEPLOY_DIR}

# *.tar.gzで名前の順で並べ替え、一番最後の(新しい)ファイル名を取得
readonly RESOURCE_FILE_NAME=`ls -1v *.tar.gz | tail -1`
# 拡張子を削除
readonly TARGET_NAME=${RESOURCE_FILE_NAME%.*.*}

# ファイルの存在/命名規則チェック (${SYSTEM_NAME}_vX.Y.Z_2yyymmdd)
if [[ ! ${TARGET_NAME} =~ ^${SYSTEM_NAME}_(v[0-9]+\.[0-9]+\.[0-9]+)_(2[0-9]{3})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$ ]];
then
  echo "リリース対象ファイルが見つかりませんでした。"
  echo "命名規則通りのファイルが存在しないか、 ${DEPLOY_DIR} に余計なtar.gzファイルが配置されている可能性があります。"

  exit -1
fi

read -n1 -p "${RESOURCE_FILE_NAME} をリリースします。よろしいですか? (y/n):" yn
if [[ ! $yn = [yY] ]];
then
  echo ""
  echo "リリース作業を中止しました。"

  exit -1
fi
echo ""

echo "リリース資源を展開..."
tar -zxvf ${RESOURCE_FILE_NAME}

judge_exec_result $?
echo ""

echo "フォルダ名リネーム..."
mv ./${SYSTEM_NAME} ${TARGET_NAME}

judge_exec_result $?
echo ""

echo "シンボリックリンク設定..."
ln -nfs ${DEPLOY_DIR}/${TARGET_NAME} current

judge_exec_result $?
echo ""

# その他DBのmigration、権限設定、ログフォルダの設定 etc...

echo "リリースは正常に終了しました。"

おまけ

デプロイshell中の正規表現を可視化したもの。
Fig.2 デプロイshellサンプル中のファイル命名規則

Discussion

コメントにはログインが必要です。