Windows上にLinux(CentOS)のWebアプリ開発環境をvirtualboxで構築する

## はじめに
Webアプリを開発する上でWindowsでもいいが、クラウドがLinuxである事が多い気もする中で、Windowsだけど開発はLinuxでという事もある気がしている。
個人開発をする上でもLinux環境が欲しくなりちゃんと環境構築をやってみたので、その環境構築の手順を、個人の備忘録の意味も含めて、残しておく。

## なぜvirtualboxか？
- 複数サーバを立てて疎通検証をしたい場合に問題がでるので、マイクロサービス開発とかだと厳しい（らしい）
- 環境の移転が困難（スナップショットの保存ができない）

といった理由からWSL2だとうまくいかない事がある（みたい）。

## virtualboxにCentOSでLinux環境を構築する
今回はCentOSにするが理由は、Amazon LinuxがCentOS系？という事らしいので（少なくともyumでDebian系ではないため）。

### virtualboxのインストール

https://www.virtualbox.org/wiki/Downloads

### CentOSのマシンイメージ取得
[CentOS Linux](https://www.centos.org/centos-linux/)にアクセスして、`7（2009）`のタブを開き、[x86_64](http://isoredirect.centos.org/centos/7/isos/x86_64/)にアクセスする。
適当なリージョンを選択して、`CentOS-7-x86_64-Minimal-2009.iso`をダウンロードする。

### 仮想マシンを作成
virtualboxを開いて新規から作成していく。
基本的にはデフォルトでいいが、メモリは1024MB(1GB)だとだいぶ動作がもっさりするので快適に動かすには4096MB(4GB)とかあるとよさげ（らしい）。
[CentOSのマシンイメージ取得](https://qiita.com/drafts/6baf167464eca3376ea0/edit#centos%E3%81%AE%E3%83%9E%E3%82%B7%E3%83%B3%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E5%8F%96%E5%BE%97)で取得したイメージは、設定＞ストレージ＞コントローラー：IDE 空＞ディスクアイコン＞仮想光学ディスクの選択・作成...から仮想マシンのイメージに設定する。

| |  |
|---|---|
| メモリ | 4096MB |
| ハードディスク | 仮想ディスクを作成で20GB。ディスクタイプはVDI。 |
| 物理ハードディスクにあるストレージ | 可変 |
| ネットワーク | アダプター1：NAT<br>アダプター2：ホストオンリーアダプター<br>※後でCentOS上で追加設定を行う |
| 物理ハードディスクにあるストレージ | 可変 |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/767268d4-faed-8b7f-4654-4a33f57eabcd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/146f3052-10e2-e241-3f4f-92175e371e92.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/a402bb7d-03d4-0b19-cad7-4c2cddf251cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/a74c002a-166f-d6b6-0ee0-3c53b6f0f793.png)

※詳細の手順は[VirtualBoxにCentOSをインストール](https://qiita.com/tamago3keran/items/260899458959d3214dcf)が分かりやすい（今回はMinimalなのでCLIであり、記事のようなGUIの設定はしないので注意）。

## 仮想マシン（CentOS）の設定をする
### ネットワーク設定
今回はNAT×ホストオンリーアダプターの構成でネットワークの設定を作っていく。参考に挙げたサイトの方で以下のように言われているのがその理由。

>よくあるVirtualBoxネットワーク設定の例として、ブリッジアダプターを使ったものがありますが、外部ネットワーク、仮想マシン、ホストOSの全ての通信が可能になってしまいセキュリティ的によろしくありません。

この設定を行う前提として、[仮想マシンを作成](#仮想マシンを作成)に添付している画像のようにネットワークが設定されている必要がある。

NAT、ホストオンリーアダプターの2つの設定をするのには、`nmtui`コマンドを実行して開くTUIで設定を行っていく。まずはその画面を開く。
※以下のTUIの青い画面は、矢印キーとEnterで操作する。

| 手順No | 手順 | 参考画像 |
|:-:|---|:-:|
| 1 | `nmtui`コマンドを実行する | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/5162f6b3-13a6-0080-4893-fa92d4fe38ec.png) |
| 2 | `Edit a connection`を選択してEnter | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/04c7702f-e3c7-42c3-194c-47af5a9ff36d.png) |

#### NATの設定
以下では上記の手順の続きで、NATの設定をしていく。

| 手順No | 手順 | 参考画像 |
|:-:|---|:-:|
| 3 | `emp0s3`を選択してEnter | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/18b6b0dc-1200-0d57-1c16-ae533956d946.png) |
| 4 | `IPx6 CONFIGURATION`を`Ignore`に変更（矢印キーでカーソルを移動し、`Automatic`上でEnterをクリックするとプルダウンで選択切り替えできる）<br>`Automatically connect`にチェックを入れる（カーソル移動後、spaceキーをクリックするとチェック(`X`)が入る） | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/8666f2c1-c02e-762c-e504-3fc37aedffc2.png) |
| 5 | `OK`でEnterをクリックし設定を確定する（ネットワークの設定のHomeに戻る） | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/04c7702f-e3c7-42c3-194c-47af5a9ff36d.png) |

#### ホストオンリーアダプターの設定
以下では上記の手順の続きで、ホストオンリーアダプターの設定をしていく。

| 手順No | 手順 | 参考画像 |
|:-:|---|:-:|
| 6 | `emp0s8`を選択してEnter | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/d5cb8d75-a7f7-04b8-69be-e68394509e04.png) |
| 7 | `IPv4 CONFIGURATION`を`Manual`にし、`Address`をアダプターのIPの下限と上限の間になるように適当に決める（例えば`192.168.56.2`）<br>`IPx6 CONFIGURATION`を`Ignore`に変更<br>`Automatically connect`にチェックを入れる | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/dbfc3862-27ae-5357-c087-a0b7380ef496.png) |
| 8 | `OK`でEnterをクリックし設定を確定する（ネットワークの設定のHomeに戻る） | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/04c7702f-e3c7-42c3-194c-47af5a9ff36d.png) |
| 9 | `Back`でEnterをクリックし設定を終了する | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/481bc950-e980-bc82-29e4-1fb39b4054bb.png) |
| 10 | `OK`でEnterをクリックし終了する（bashターミナルに戻る） | ー |

※上記の「手順」で出てきたアダプターのIPとは以下の画像の部分の事（DHCPサーバのタブの方に、下限・上限が書かれている）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/be28f72c-7359-ab2f-c4ae-d596c98a21c9.png)

#### 設定の反映
上記の設定を反映させるために、以下のコマンドを実行する。

```console
# systemctl restart NetworkManager
# systemctl restart network 
```

#### 設定できているか？検証する
`ping`と`ssh`で接続できているか？を確かめる。

- `ping`<br>仮想マシン（ゲストOSと言ったりする）から外部ネットワークへの接続ができているか？を確かめる
- `ssh`<br>Windows（ホストOsと言ったりする）からゲストOSへの接続ができるか？を確かめる<br>CentOSのsshd_config（sshの設定）がデフォルトであれば`PasswordAuthentication yes`となっているのでssh接続をパスワード認証で行えるはず（sshd_configの中身は、`cat /etc/ssh/sshd_config`で見れる）

| ping | ssh |
|:-:|:-:|
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/943eb5ef-b500-f2bc-6c0c-f903a8a0f162.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/a63db974-9ed8-53f2-843f-c60247dba883.png) |

ここまででネットワークの設定は完了になる。

#### 余談
`emp0s3`と`emp0s8`のどちらが、NATでどちらがホストオンリーアダプターか？は、以下のように`ip addr`と実行した時のMACアドレスで分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/607d2cab-a432-21d6-c9b1-e3601a618b79.png)

| emp0s3 | emp0s8 |
|:-:|:-:|
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/daa106f6-bab4-a882-843d-c8215b11b1eb.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/bfc62d5f-8d32-1807-77c6-4de6c915288e.png) |

- 参考：[VirtualBoxでNATとホストオンリーアダプターによる安全なネットワーク環境構築方法](https://blog.proglus.jp/3315/)
- 参考：[VirtualBox のネットワークアダプタまとめ](https://qiita.com/pitao/items/0f9475e4c0e230911eb7)

### firewalldの設定
Webアプリを作る際にもちろんローカルサーバを立ち上げるが、だいたい`localhost:8080`のパターンが多いと思う。ただ、デフォルトのCentOSではfirewalldというサービスが動いており、8080ポートが閉じているのでこれを開けてあげる必要がある。

※このポートを開ける作業をしないで、firewalldのサービス自体を止めてしまう事もできるが、それに慣れてしまうと本番環境のサーバでも同じような事をしてしまい事故る事になるので基本的にはちゃんとポート開放をする手順がいいと思われる

#### firewalldの起動有無を確認
まずfirewalldが動いているか？どうかは以下のコマンドで確かめられる。

```console
[root@localhost ~]# firewall-cmd --state
running
```

動いていない場合、`systemctl start firewalld.service`で起動できる。

#### firewalldの設定を確認する
今現在のfirewalldの設定を確認するには以下のコマンド。

```console
[root@localhost ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3 enp0s8
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:
```

#### 8080ポートを開放する
恒久対応としたいので、以下のように設定をする（ちなみに、firewalldのhttpは80ポートの事なので、`firewall-cmd --zone=public --add-service=http --permanent`などとしてもうまくいかないので注意）
8080ポートを開けるには直接8080ポートを開けるように設定する必要がある

```console
[root@localhost ~]# firewall-cmd --zone=public --add-port=8080/tcp --permanent
[root@localhost ~]# firewall-cmd --reload

[root@localhost ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3 enp0s8
  sources: 
  services: dhcpv6-client ssh
  ports: 8080/tcp　←　追加されている事が確認できる
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
```

※ちなみに、サービスとportの組み合わせ一覧は`cat /etc/services`で確認できる（現実的には`cat /etc/services | grep http`等で使う）

- 参考：[【すぐわかる】CentOSのポート開放のやり方](https://eng-entrance.com/linux-centos-port)
- 参考：[CentOS 7 firewalld よく使うコマンド](https://qiita.com/kenjjiijjii/items/1057af2dddc34022b09e)

### SSH接続を公開鍵・暗号鍵方式に変更する
デフォルトの設定では以下のように、sshd_configの設定がssh接続時の認証をパスワードで行う設定になっている（`PasswordAuthentication yes`）のでこれを変えると便利（以降の項でVS Codeからsshで接続して実際にちょっとしたWebアプリを作るがその時にパスワード認証をしていると手間になる）。

```console
[root@localhost ~]# cat /etc/ssh/sshd_config
#       $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

...

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile      .ssh/authorized_keys

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes
#PermitEmptyPasswords no

...
```

#### ホストOS側で公開鍵・秘密鍵を作成する
```posh
PS C:\WINDOWS\system32> cd ~/.ssh
PS C:\Users\user\.ssh> ssh-keygen -t ed25519 -C "{メアド}"
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\user/.ssh/id_ed25519): CentOS7.9-2009
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in CentOS7.9-2009.
Your public key has been saved in CentOS7.9-2009.pub.
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {メアド}
The key's randomart image is:
+--[ED25519 256]--+
...
+----[SHA256]-----+
PS C:\Users\user\.ssh> cat C:\Users\user\.ssh\CentOS7.9-2009.pub
{ssh公開鍵}

PS C:\Users\user\.ssh> vim .\config
```

上記のような手順で公開鍵・秘密鍵のペアを作成し、公開鍵の方はメモしておく。

※`vim .\config`では以下のような設定をしておくと便利。

```
Host CentOS7.9-2009
  Hostname 192.168.56.2
  User root
  IdentityFile ~/.ssh/CentOS7.9-2009
```

※powershellでvimを使えるようにする方法は[Powershellでvimを使う](https://qiita.com/shuhoyo/items/d9966e12976275f20c24)を参照。

#### ゲストOSでsshd_configの設定を変更し反映する
```console
[root@localhost ~]# sudo vi /etc/ssh/sshd_config
[root@localhost ~]# systemctl restart sshd ## 再起動して設定を反映する
```

※`sudo vi /etc/ssh/sshd_config`書き換える部分は、以下の2つ。

- #PubkeyAuthentication yes：コメントアウトを外して有効化する
- PasswordAuthentication yes：noに変更

#### ゲストOSで公開鍵を登録する
```console
[root@localhost ~]# mkdir ~/.ssh
[root@localhost ~]# chmod 700 ~/.ssh
[root@localhost ~]# cd ~/.ssh
[root@localhost .ssh]# sudo vi authorized_keys
[root@localhost .ssh]# chmod 600 authorized_keys
```

※`sudo vi authorized_keys`では、[ホストOS側で公開鍵・秘密鍵を作成する](#ホストos側で公開鍵秘密鍵を作成する)でメモしていた公開鍵を書き込む（手動ではなく、`ssh-copy-id -i ~/.ssh/id_rsa.pub <user name>@<ip address>`のようにコマンドでやる方が手っ取り早いかも）。

#### ホストOSからゲストOSへssh接続（公開鍵・暗号鍵方式）できるか？検証する
```posh
PS C:\Users\user\.ssh> ssh CentOS7.9-2009
Last login: Sun Nov  7 17:43:03 2021 from 192.168.56.1
[root@localhost ~]#  
```

上記の通り接続できればOK。

### OSの時刻設定
何も設定しないと「電源をオフ」をした時等にゲストOS側の時刻とズレてしまう事がある。そのため、[Chrony](https://chrony.tuxfamily.org/)を使って時刻を同期（日本時刻であれば[mfeed](https://www.mfeed.ad.jp/ntp/usage.html)や[NICT](https://jjy.nict.go.jp/tsp/PubNtp/qa.html)のサーバ時間に合わせる）の設定をする。

Chronyの設定は`/etc/chrony.conf`に書かれているので、それに以下のように追加をする（`iburst`オプションで短い間隔で4回ntpサーバに問合せを行い、時刻同期までの間隔を短くする事ができるが、[『日本最古の公開NTPサービスが廃止へ、世界中からアクセスが殺到した深いワケ』](https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600011/092500040/)のように負荷がかかるとサービスがなくなったりもするので`iburst`は設定しない方が良かったり・・・）。

```
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
server ntp.nict.jp <- ここを追記

# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift
```

あとはChronyが動いているか？を確認すればOK（起動してなければ`systemctl start chronyd`で起動できる）。

```console
[root@localhost ~]# systemctl status chronyd
● chronyd.service - NTP client/server
   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
   Active: active (running) since 日 2021-11-21 15:46:51 JST; 9min ago
```

- 参考：[CentOS7の時刻をChronyを使ってNICTと同期する](https://qiita.com/Kenji_TAJIMA/items/88ec9985a0585e66ef33)

## VS CodeでWindowsからCentOS（ゲストOS）に接続する
今回はNode（Javascript）で開発する事を想定して、VS Codeをエディタとして使う事にする。
上記の[ssh接続を公開鍵・暗号鍵方式に変更する](#ssh接続を公開鍵暗号鍵方式に変更する)を行っているので以下のようなExtentionsを入れる事で簡単にCentOSに接続できる。

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh

上記のExtentionsを入れると、以下のように`Remote Explorer`というメニューが表示されて、`Targets`で`SSH`が選択できるようになる。
この`SSH Targets`に表示されるものは、windowsであれば`PS C:\Users\user\.ssh> `の`config`に設定されている接続先が表示される。今回は`CentOS7.9-2009`が先ほど作成したものなので、こちらに接続をすればいい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/32586049-51d0-5911-25a6-85a62c2e91ad.png)

※接続後は`Terminal`はCentOSのbashになるので、開発に必要な各種ツールはVS Codeのbashから行うとコピペができたりして楽かもしれない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/04ba6e1d-a550-d200-58ed-5276dfbc3cc3.png)

- 参考：[Remote development over SSH](https://code.visualstudio.com/docs/remote/ssh-tutorial)

## CentOSに開発に必要そうなものを一式インストールする
Webアプリの開発という事を考えると、色々な意見はあるが以下は入れておいていい気がするので、以降はそれをインストールする手順についてみていく。

- git
- Node/npm/yarn

### git
CentOS7系だと普通に`sudo yum install git`としてしまうと、version1.xになってしまい少し古いものになる。
なので少し工夫が必要で`IUS`というyumリポジトリを追加してあげてgitをインストールする。

```console
[root@localhost ~]# yum install \
> https://repo.ius.io/ius-release-el7.rpm \
> https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
[root@localhost ~]# yum install git224
[root@localhost ~]# git --version
git version 2.24.4
```

これでversion2.xがインストールできた。

※以下コピペ用

```bash
yum install \
https://repo.ius.io/ius-release-el7.rpm \
https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
```

- 参考：[IUS Setup](https://ius.io/setup)
- 参考：https://github.com/iusrepo/git224
- 参考：[CentOS7にGitをyumとSourceの２つの方法でインストールする](https://pocketcode.net/centos7-git-install-latest)

### Node/npm/yarn
Webアプリという事で、フロントエンドは少なくともReact(Next)・Vue(Nuxt)・Angularなどを使うと思われるので、Node.jsもインストールしておく事にする。
Nodeはversion管理が面倒だが、`nodebrew`を使うと簡単なので今回はそれでNodeのインストールを行っていく。

```console
[root@localhost ~]# curl -L git.io/nodebrew | perl - setup
[root@localhost ~]# vi ~/.bashrc
[root@localhost ~]# source ~/.bashrc
[root@localhost ~]# nodebrew ls-remote ## これでNodeのversionが表示されるのでインストールするもの（今回は v14.18.1）を決める
[root@localhost ~]# nodebrew install-binary v14.18.1
[root@localhost ~]# nodebrew use v14.18.1
[root@localhost ~]# node --version
v14.18.1
[root@localhost ~]# npm --version
6.14.15
[root@localhost ~]# npm i -g yarn
```

※上記では`yarn`も入れているが、`npm`だけもよい（パッケージマネージャーに何を使うか？という決めの話）

※`vi ~/.bashrc`では、以下のようにbashrcを書き換える

```
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

export PATH=$HOME/.nodebrew/current/bin:$PATH
```

- 参考：[nodebrew](https://github.com/hokaccha/nodebrew)

### docker/docker-compose
データベースがないWebアプリはない（と思う）ので、ローカルで開発する時にはコンテナイメージでデータベースを立ち上げたりできるようにdocker/docker-composeをインストールしておく。

#### dockerのインストール
公式の手順（[Install Docker Engine on CentOS](https://docs.docker.com/engine/install/centos/)）に則りインストールしていく。

まずはOSを最新化する。

```console
[root@localhost ~]# yum update
[root@localhost ~]# yum upgrade
```

次にdockerをインストールするための要件（[OS requirements](https://docs.docker.com/engine/install/centos/#os-requirements)）をチェックする（基本デフォルトで登録済みで有効化されている）。

> The centos-extras repository must be enabled. 

```console
[root@localhost ~]# cat /etc/yum.repos.d/CentOS-Base.repo
・・・

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

・・・
```

あとは公式の手順に沿ってインストールしていけばいい。
※1点、バージョンの指定の部分は`20.10.9`みたいな感じになるが、これは以下のコマンドを実行した時の`3:20.10.9-3.el7`から抜き出す。

```console
[root@localhost ~]# yum list docker-ce --showduplicates | sort -r
利用可能なパッケージ
読み込んだプラグイン:fastestmirror
インストール済みパッケージ
docker-ce.x86_64            3:20.10.9-3.el7                    docker-ce-stable 
docker-ce.x86_64            3:20.10.8-3.el7                    docker-ce-stable 
docker-ce.x86_64            3:20.10.7-3.el7                    docker-ce-stable
・・・
```

#### dicker-compose
公式の手順（[Install Docker Compose](https://docs.docker.com/compose/install/)）に則りインストールすればいい。

#### sudo（rootユーザ）以外でもdockerコマンドを実行できるようにする
[Manage Docker as a non-root user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)に書かれている。

## 参考文献
- [VirtualBoxにCentOSをインストール](https://qiita.com/tamago3keran/items/260899458959d3214dcf)

## Tips

[VirtualBox で CentOS7 の ディスクを拡張した時の手順](https://beanhouse.org/wordpress/?p=1490)