【Vagrant】Windows10でVirtualBox+Vagrant+Ubuntu 21.04でDocker環境を構築する

## はじめに

Docker Desktopが有償となり、その猶予期間が2022/01/31で終了しました。
残念ながら自社は無償利用の条件を満たさず、Docker Desktop Personalの利用を続けることができません。

無償利用の条件: 
```less than 250 employees AND less than $10 million in revenue```
```(250人未満の従業員と1,000万ドル未満の収益)```

Pro, Team, Businessを契約し利用することも考えられますが、社内稟議を通すのは難しい。。
そこで別途Docker環境を用意する必要があります。

## やりたいこと

* Windows10 PCでDockerを使う
* HTTPプロキシに対応する


## やったこと

VirtualBox+Vagrantを利用し、Ubuntu上にDocker, Docker Composeをインストールしました。
ただ、インストールコマンドの実行が手間なので、VagrantfileのprovisionにDockerインストールのコマンドを記載しました。
これでコマンド実行さえ行えば自動的にDocker環境が作れるようになりました。


## Githubリポジトリ

https://github.com/nata-water/vagrant_ubuntu_on_docker

### 利用方法

#### 1-1 事前にやること

* 環境変数の追加

|変数名|値|
|-----|--|
|VAGRANT_PREFER_SYSTEM_BIN|0|

#### 1-2 【プロキシ環境のみ】事前に必要なこと

* 環境変数の追加
  * HTTP_PROXY, HTTPS_PROXY


|変数名|値|
|-----|--|
|HTTP_PROXY|http://{user}:{password}@{proxyhost}:{port}|
|HTTPS_PROXY|http://{user}:{password}@{proxyhost}:{port}|

* PowerShellかcmd.exeを起動

* vagrant-proxyconfのインストール

```powershell
vagrant plugin install vagrant-proxyconf
```

#### 1-3 事前に必要なこと

```powershell
vagrant up
```

#### 1-4 仮想環境(Ubuntu)にログイン

```powershell
vagrant ssh
```


#### 1-5 【プロキシ環境のみ】起動後に必要なこと

* /usr/lib/systemd/system/docker.serviceをコピーする

```bash
$ sudo cp /usr/lib/systemd/system/docker.service /etc/systemd/system/
```
* /etc/systemd/system/docker.serviceのExecStartより前の行にプロキシ情報を追記する

```bash
$ sudo vim /etc/systemd/system/docker.service

Environment="HTTP_PROXY=http://{user}:{password}@{proxyhost}:{port}/"
Environment="HTTPS_PROXY=http://{user}:{password}@{proxyhost}:{port}/"

# この↑に追記
ExecStart=# 略
```

* Dockerデーモンを再起動

```bash
$ sudo systemctl daemon-reload && sudo systemctl restart docker
```

#### 2 動作確認

* これでDockerの実行ができるようになりました

```shell
$ docker run hello-world
```

## その他参考情報

### Dockerコンテナ上でpip installするとプロキシエラーが発生する

* プロキシ情報を渡してあげる必要があります
  * 方法1 .envファイルを作成し、HTTP_PROXYの情報を記載する
  * 方法2 OSの環境変数にHTTP_PROXYを定義する

#### 方法1 envファイル例

* .envファイル

```env:.env
HTTP_PROXY=http://{user}:{password}@{proxyhost}:{port}/
```

#### 方法1, 方法2共通

* requirements.txtファイル

```txt:requirements.txt
fastapi
```

* docker-compose.ymlファイル

```yml:docker-compose.yml
  app:
    build:
      context: .
      args:
        - ARG_PROXY=${HTTP_PROXY}
    volumes:
      - .:/app
```

* Dockerfile

```Dockerfile:Dockerfile
FROM python:3.10
ARG ARG_PROXY
ENV http_proxy $ARG_PROXY
ENV https_proxy $ARG_PROXY
# Install development environment in an image (1: install, 0: not)
ARG WITHDEV="0"

ENV LANG C.UTF-8
ENV TZ Asia/Tokyo
ENV PYTHONDONTWRITEBYTECODE 1

WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt --proxy=${http_proxy}

```


### vagrant upした時にdefault: SSH auth method: private keyで止まる

* 管理者権限でcmd.exeを起動
* 以下のコマンドを実行

```cmd
bcdedit /set hypervisorlaunchtype off
```
(元に戻したい場合、bcdedit /set hypervisorlaunchtype auto)

* 以下のURLを参考に、Hyper-Vを無効にする

https://docs.microsoft.com/ja-jp/troubleshoot/windows-client/application-management/virtualization-apps-not-work-with-hyper-v#:~:text=%5B%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%20%E3%83%91%E3%83%8D%E3%83%AB%5D%20%E3%81%A7%E3%80%81%5B,%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%82%92%E3%82%AA%E3%83%95%E3%81%AB%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

* PCの再起動を実施


### vagrant boxの取得に失敗する1

VagrantfileのBoxイメージを変更する

before:

```ruby
config.vm.box = "ubuntu/hirsute64"
```

after:

```ruby
config.vm.box = "generic/ubuntu2104"
```

### vagrant boxの取得に失敗する2

* boxファイルを直接ダウンロードする

https://app.vagrantup.com/generic/boxes/ubuntu2104/versions/3.6.8/providers/virtualbox.box

* ダウンロードしたファイルをリネーム(hirsute-server.box)し、Vagrantfileがあるフォルダに移動する
* 以下のコマンドを実行し、手動でboxを追加

```shell
vagrant box add ./hirsute-server.box --name generic/ubuntu2104
vagrant up
```


### Dockerで起動したサービスのポートにアクセスできない

* Vagrantfileのポート開放を行う: 例・・・8080の場合

```ruby
Vagrant.configure("2") do |config|
  config.vm.box = "generic/ubuntu2104"
  config.vm.network "forwarded_port", guest: 8080, host: 8080, host_ip: "127.0.0.1"
```

### vagrant sshするのが面倒くさい

PowerShellのエイリアスを設定しましょう。とてもおすすめです。

* 以下のファイルを開く(ファイルやフォルダが存在しない場合は作成)
  * %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
* エイリアスを追加する

```ps1:Microsoft.PowerShell_profile.ps1
function vssh {
    vagrant ssh -c "cd /vagrant_data; bash"
}
```

* Microsoft.PowerShell_profile.ps1保存し、PowerShellを再起動する

* 以下のコマンドを実行する(vsshでvagrant sshが実行できるようになりました)

```powershell
vssh
```


## 参考にさせていただいた記事

Vagrantの上にDockerを載せて開発環境を作成する
https://zenn.dev/jinwatanabe/articles/4f8e62aac86f386d799b