リモートWebサーバへのSSHファイル転送を自動化
プロトタイプを気軽にリモートWebサーバにアップロードする用。
https://[ドメイン]/[プロジェクト名]/[日付]/
みたいにサブディレクトリの日付を変えて履歴を追えるようにする。
環境
- Windows 11
- Node.JS
- Next.js / Nuxt / Astro など
- さくらのレンタルサーバー
SSH接続
秘密/公開鍵ペア作成
ssh-keygen
特にオプションは指定しない。
最近の暗号化形式のデフォルトは rsa
ではなく ed25519
。
C:\Users\[ユーザー名]/.ssh/
に秘密鍵id_ed25519
と公開鍵id_ed25519.pub
が作られる。
さくらのレンタルサーバに公開鍵を登録
- サーバーコントロールパネルにアクセス
-
サーバー情報
->SSH公開鍵
->新規追加
- 下記内容で登録
- 追加方法 ->
作成済みの公開鍵を登録
- 公開鍵 ->
id_ed25519.pub
のテキストをコピペ - コメント -> 鍵ペアを識別しやすくする用
- 追加方法 ->
SSH Config
sshコマンドを簡略化するために~/.ssh/config
にSSH Configを作成する
Host [接続名]
User [ユーザー名]
Port 22
HostName [ドメイン名].sakura.ne.jp
IdentityFile ~/.ssh/id_ed25519
接続名はdev
にしたので、
ssh dev
だけで接続できるようになります
ビルド設定
日付などを元にバージョン文字列を作成
アップロード先のサブディレクトリを/[プロジェクト名]/[バージョン文字列]
としたいので、日付を元にバージョン文字列を作成する。
export const getVersion = () => {
// YY-MM-DD
const date = new Date().toLocaleDateString('sv-SE')
const revision = ''
return revision !== '' ? `${date}-${rev}` : date
}
同じ日に2つ以上のバージョンを作成する場合は末尾に_[数字]
を追加する。
2025-06-01
や2025-06-01_1
のような文字列が作られる。
これを、Next.js / Nuxt / Astro などでビルドする時に利用する。
一例としてAstroでの使用例を挙げるが、Next.js / Nuxtでも考え方は同じ。
Astroのビルド例
import { defineConfig } from 'astro/config'
const PROJECT_NAME = 'project'
const base = `/${PROJECT_NAME}/${getVersion()}/`
export default defineConfig({
base,
})
astro dev
で開発中はhttp://localhost:4321/project/2025-06-01/
のようなサブディレクトリで実行される。
astro build
でビルドすると/dist/
にサブディレクトリを含まずに出力される。
ちなみに、Astroの設定ファイルで指定したbase
の値はimport.meta.env.BASE_URL
で参照できる。
<a href={${import.meta.env.BASE_URL}about/}>
<img src={`${import.meta.env.BASE_URL}images/about.svg`} alt='' />
</a>
BASE_URLが切り替わっても上記のようにしておくと柔軟に対応できる。
public
にファイルを格納する場合もサブディレクトリを意識する必要はない。
ただし、CSSからpublic
内のファイルを参照したい場合はSassの変数を使ったひと工夫が必要。
export default defineConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: `$base-url: '${BASE}';`
},
},
},
},
})
これで、SCSSの全ファイルの先頭に$base-urlが挿入されるのでどこからでも参照できるようになる。
background-image: url("#{$base-url + 'images/bg.webp'}");
SSHファイル転送のスクリプト
Node.jsでファイル転送のスクリプトを書く。
- リモートサーバのサブディレクトリを中身ごと削除(存在しなければ無視される)
- サブディレクトリを作成
- サブディレクトリにファイル転送
の順番で処理を行う。
共有したくない情報を環境変数に移す
ファイル転送のスクリプトをGitで管理すると、リモートサーバの情報なども共有されることになる。
他のメンバーに見られて困る場合はローカル開発環境の環境変数に格納しておく。
今回は環境変数に格納する情報を以下の2つとする。
%DEV_SSH_NAME%
SSHの接続名、今回はdev
。
隠すほどでもないけど、他のメンバーが別の接続名を使いたい場合にも便利かもしれない。
%DEV_SSH_DIR%
リモートサーバの転送先のベースディレクトリ。
今回はさくらのレンタルサーバの例として/home/[ユーザー名]/www/
とする。
このベースディレクトリがhttps://[ドメイン]/
に対応するので、この文字列にサブディレクトリを足して最終的な転送先が決まる。
スクリプト
コマンド実行のところだけを抜粋。
実際はexec
にコールバックを渡して処理を順番に行う。
import child_process from 'child_process'
const { exec } = child_process
const PROJECT_NAME = 'project'
const SRC_DIR = './dist/'
const DEST_DIR = `${PROJECT_NAME}/${getVersion()}/`
// 1. サブディレクトリを中身ごと削除
exec(`ssh %DEV_SSH_NAME% "rm -rf %DEV_SSH_DIR%${DEST_DIR}/"`)
// 2. サブディレクトリを作成
exec(`ssh %DEV_SSH_NAME% "mkdir -pv %DEV_SSH_DIR%${DEST_DIR}/"`)
// 3. サブディレクトリにファイル転送
exec(`scp -r ${SRC_DIR}* %DEV_SSH_NAME%:%DEV_SSH_DIR%${DEST_DIR}/`)
これをnpm-scriptsに登録してビルド後に実行させる。