ConfluenceとJiraをnode.jsで作った簡易プロキシの後ろで動かす

JiraとConfluence、Node.js上で動作するWebアプリを同一PC上で動作させようとすると、CORSの問題でREST APIにアクセスできない。ローカルで動作確認するために動かすだけなら、Node.jsで簡単なプロキシサーバを作ることで対応することができるので、その設定方法をまとめる。(それ以前に、サーバ側の設定を変えればよいという話もあるが…本番環境に似せたいので)

#設定したいこと
同一PC上でJiraとConfluenceが`localhost`の別々のポートで稼働しているときに、プロキシにより、同じポート(ここでは10000)以下の`/jira`と`/confluence`でアクセスできるようにする。なおConfluenceの同時編集で使われるSynchronyという機能については設定しなくても特に問題なかった。(プロキシを介さなくても良いから?)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/b7ffeaec-6ee1-42ba-ba8d-ea85b3b39812.png)

| アプリ | 元々のURL| Context Path変更後 | プロキシ経由のURL |
|:-------|:----|:----|:----|
| Jira | http://localhost:10080| http://localhost:10080/jira | http://localhost:10000/jira |
|Confluence | http://localhost:8090 | http://localhost:8090/confluence | http://localhost:10000/confluence |

# Confluenceの設定
AtlassianのConfluenceサポートに「[NGINX を使用して Confluence へのリクエストをプロキシする方法](https://ja.confluence.atlassian.com/confkb/how-to-use-nginx-to-proxy-requests-for-confluence-313459790.html)」という記事に設定すべきことが載っている。なお、Jira/Confluence/Node.jsが同一PC上で動作し、PC外部からのリクエストが無ければ、「リダイレクション用URLの設定」はしない。

## Context Pathの設定
`<ConfluenceInstallDirectory>/conf/server.xml`を開き、`Context`パスを設定する。

```xml:server.xml変更前
<Context path="" docBase="../confluence" debug="0" reloadable="false">
```
デフォルトでは`""`になっているところに、`/confluence`を入力することで、`http://localhost:8090/confluence`でアクセスできるようになる。

```xml:server.xml変更後
<Context path="/confluence" docBase="../confluence" debug="0" reloadable="false">
```
### この設定をしないと表示がおかしくなる
この設定をせずにプロキシ経由`localhost:10000`でConfluenceにアクセスすると、正しく表示されない。これはConfluenceではCSSや各種リンクをベースURL(`localhost:10000`)を基準にしてしまうため。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/dc028faa-7ebe-fd66-a7c5-e274f4e2dc5d.png)

# Jiraの設定
Confluenceと同様、Context Pathの設定を行う。

## Context Pathの設定
`<JiraInstallDirectory>/conf/server.xml`を開き、`Context`パスを設定する。

```xml:server.xml変更前
<Context path="" docBase="${catalina.home}/atlassian-jira" reloadable="false" useHttpOnly="true">
```
デフォルトでは`""`になっているところに、`/jira`を入力することで、`http://localhost:10080/jira`でアクセスできるようになる。

```xml:server.xml変更後
<Context path="/jira" docBase="${catalina.home}/atlassian-jira" reloadable="false" useHttpOnly="true">
```

#簡単なプロキシを作る
`localhost:10000`へのリクエストを、JiraとConfluenceに振り分けるプロキシは、以下の2つのパッケージのサンプルを真似て作れた。(エラーやセキュリティは考えていないが、とりあえず動く)

* https://www.npmjs.com/package/http-proxy
* https://www.npmjs.com/package/http-proxy-rules

```javascript:index.js
const http = require('http');
const httpProxy = require('http-proxy');
const HttpProxyRules = require('http-proxy-rules');
const port = 10000;

// https://github.com/donasaur/http-proxy-rules
const rules = new HttpProxyRules( {
  rules: {
    '/jira(/?.*)$'       : 'http://localhost:10080/jira$1',
    '/confluence(/?.*)$' : 'http://localhost:8090/confluence$1'
  }
} );

const proxy = httpProxy.createProxy();
proxy.on('error', function (err, req, res) {
  res.writeHead( 500, { 'Content-Type': 'text/plain' } );
  res.end(err);
});

http.createServer( ( req, res) => {
  // 対応するURLがあるか調べる
  const target = rules.match( req );
  if( target ) {
    // マッチしたらリクエストを出す
    return proxy.web( req, res, { target: target } );
  }
  
  // no match found
  res.writeHead( 500, { 'Content-Type': 'text/plain' } );
  res.end( "Requested Url didn't match any of the listed rules.");
} ).listen( port );

console.log( `Proxy is listening on port ${port}.`);

process.on('SIGINT', () => {
  console.log( 'Proxy closed.' );
  httpProxy.close();
});
```

#動作確認
`node index.js`で簡易プロキシを起動し、`localhost:10000/confluence`と`localhost:10000/jira`にアクセスすると、ConfluenceとJiraの画面が表示されることが確認できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/c6946252-a3b9-5160-68a0-9df7b6010dc9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/e6a90dc5-97cb-8f8e-9cce-401444817f80.png)