dev環境もう必要ない？GitHub Codespaces を使ったインスタントな実行環境の用意

## はじめに
`「dev環境」`、`「stg環境」`、`「prod環境」`は、ソフトウェア開発およびデプロイメントのプロセスで一般的に使用される環境です、それぞれの環境は異なる目的で使用されます。

- **dev環境**(開発環境):
    - 目的: ソフトウェアの開発とテスト。
    - 特徴:
        - 開発者が新しい機能を開発し、既存のコードを変更するための場所。
        - 最新のコードが頻繁にデプロイされ、開発者が効率的に作業できるようになっています。
        - バグの検出と修正が行われます。
- **stg環境**(最終テスト環境):
    - 目的: 本番環境に近い状態でアプリケーションの最終的なテストと品質保証。
    - 特徴:
        - 本番環境と同じ設定やリソースを使用します。
        - ユーザーがアプリケーションをテストし、品質を確認します。
        - デプロイ前に最終的な確認と調整を行います。
- **prod環境**(本番環境):
    - 目的: ユーザーや顧客に提供される実際のサービスおよびアプリケーションの運用。
    - 特徴:
        - ユーザーがアプリケーションにアクセスし、サービスを利用します。
        - パフォーマンス、セキュリティ、信頼性が最優先されます。
        - データのバックアップや冗長性の確保など、本番環境においては高い信頼性が求められます。

従来、すべての環境コードベースで管理され、同じクラウドプロバイダーを使用するのが一般的です。

例えば、AWSをprod環境で使用している場合、dev環境やstg環境も同様にAWSを使用してインフラを構築し、これらの環境を一貫したコードで定義・管理します。

## 従来運用のデメリット
stg環境がともかく、dev環境がprod環境と必ずしも同じインフラを必要とは限らないと思います、
なぜならdev環境の主な役割が`ソフトウェアやアプリケーションの開発、テスト、およびデバッグを行うこと`だからです。

従来の運用では、1番のデメリットはやはりデプロイの不自由さです。
限られたdev環境を占有することで、チーム内でのリソース利用の調整が必要となり、特にエンジニアチームが大規模であればあるほど、その影響は著しくなります。さらに、開発マネージャーや他の関係者を巻き込んでテストを行う場合、この問題は一層顕著になります。

サービスがコンテナ化されている場合、ローカルの開発環境も基本的には同じ Dockerfile から作成されるコンテナで構成されています。
コンテナ環境に最適な、さらに従来の開発環境よりも利便性の高い選択肢を模索してみたところ、一つ有望な候補が浮かびました。:point_up_tone1:

## github codespace

![1200x630-codespaces-social.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/e7b7bb83-5608-afb3-7a17-8a07e600ae4b.jpeg)

:::note info
codespaceとは
クラウドでホストされている開発環境です。 構成ファイルをリポジトリにコミットすることで、GitHub Codespaces のプロジェクトをカスタマイズできます。
これにより、プロジェクトのすべてのユーザーに対して繰り返し可能な codespace 構成が作成されます。
:::
[公式ページ](https://github.co.jp/features/codespaces)

簡単に説明すると、`.devcontainer.json`ファイルをリポジトリに作成し、依存関係を記入するだけで、GitHubが提供するクラウド上でアプリケーションを動かすことができます。
コンテナサービスであれば、既存のdev環境にかなり近い環境を瞬時に作成できます。
さらに、他の人と競合することなく、修正を加えても再度デプロイする必要もありません。

## GitHub Codespaceを使った実行環境の作成

使い方はこちらのLaravel製の[サンプルリポジトリ](https://github.com/flemzord/codespaces-laravel/tree/main)使って説明します。

`devcontainer.json`に依存関係などと立ち上げコマンドを記述してあるのと利用するコンテナ構成はローカルでビルドする PHP のものと、サードパーティの PostgreSQL、Redis、MailHog の4つで、シンプルな構成になってます。
```json:.devcontainer/devcontainer.json
{
    "name": "codespaces-laravel",
    "dockerComposeFile": ["docker-compose.yml"],
    "workspaceFolder": "/workspace",
    "service": "app",
    "shutdownAction": "stopCompose",
    "extensions": [
		"editorconfig.editorconfig",
        "ryannaddy.laravel-artisan",
        "amiralizadeh9480.laravel-extra-intellisense",
        "stef-k.laravel-goto-controller",
        "codingyu.laravel-goto-view",
        "mikestead.dotenv",
        "eg2.tslint",
        "christian-kohler.path-intellisense",
        "esbenp.prettier-vscode",
        "CoenraadS.bracket-pair-colorizer"
	],
    "settings": {
        "#terminal.integrated.shell.linux": "/bin/bash"
    },
    "forwardPorts": [80],
	"postCreateCommand": "cp .env.example .env && composer install && php artisan key:generate && yarn install && yarn run development",
	"portsAttributes": {
		"80": {
			"label": "HTTP"
		}
	},
}
```

```yaml: .devcontainer/docker-compose.yml
  app:
    build: ./docker/app
    volumes:
      - ../:/workspace:cached
    ports:
      - 80:80
    tty: true
    environment:
        APP_ENV: local
        PHP_EXTENSION_XDEBUG: 1
        PHP_EXTENSION_PGSQL: 1
        PHP_EXTENSION_PDO_PGSQL: 1
        APACHE_DOCUMENT_ROOT: /workspace/public
  db:
    image: postgres:13
    restart: unless-stopped
    ports:
        - 5432:5432
    environment:
        POSTGRES_DB: laravel
        POSTGRES_USER: laravel
        POSTGRES_PASSWORD: laravel
  redis:
    image: redis:6-alpine
    ports:
      - 6379:6379
  mailhog:
    image: mailhog/mailhog
    ports:
      - 8025:8025
```
リポジトリのメインページから`Code` -> `Create codespace on main`をクリックして、実際サービスを立ち上げてみましょう。:point_up_tone1:
![1094A262-57FD-43A9-9BDC-9BA386759082.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/befb4b78-bb37-69ed-eaa5-fe4ab7eaf86b.jpeg)

依存関係をビルドしてるため、しばらく下記の画面が表示されます。
![43AF43C8-E19D-4D16-8DA8-A470E9150162.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/ad627afa-bbc9-2f37-d818-bf700301d78e.jpeg)

ビルド終われば、vscodeのような画面が表示されます。

ポートをクリックすれば、サービスの公開アドレスが表示されます。
![E3E42219-B683-4C61-948A-581AEA92205E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/f55a7404-28c7-cd94-ce11-ef713cc4aac6.jpeg)

そのアドレスを使用すれば、サービスを簡単に他人と共有することができます。
![13FB8D45-707F-44BE-834E-71F12133E6F6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/69c8dfb0-0a72-d524-0205-5cbead9e9fe2.jpeg)

サービスへの改修はそのままリモートvscode使用しても良いし、
`Open in Visual Studio Code`をクリックして、ローカルのvscodeと繋いで使用することもできます。:point_up_tone1:
![E1CB130B-07C6-4F9A-9598-9A3742A375EC.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/246838a6-4f2f-e302-129e-d4f6efdeebc5.jpeg)

GithubCodeSpacesで作られる環境は完全既存のdev環境を再現できないかもしれませんが、dev環境の役割に満たす環境を十分に作れると思います。

## 最後に
dev環境として、検証する前に都度クラウドプロバイダーで作る運用も存在するかもしれませんが、GithubCodeSpacesほど軽く作れないと思います。

また、費用面では既存のdev環境を運用するのであれば、少なくとも稼働日x8時間のライニングコストが発生します、
サービスの規模にもよりますが月のコスト1000$はかかりそうです。
GithubCodeSpaces提供するVMの最高スペックで同じ時間使用しても500$程度ですので、費用面でも多少優位になるでしょう。

その他、Codespacesと使用感が近いサービスとして、AWS Cloud9もありますが、 コードリポジトリとしてGitHubを利用している以上、GitHub Codespacesの方が優れていると思います、強いて言えば、AWS Cloud9はEc2インスタンスであり、スペックのカスタマイズはCodespacesより柔軟にできます。

もし興味があれば、皆さんもぜひGithubCodeSpaces使ってみてください。