- 記事一覧 >
- ブログ記事
OS.jsにiframeアプリを組み込んでnginx(エンジンエックス)で振り分ける
はじめに
前回、OS.jsインストールと公式アプリの追加をやってみましたが、 今回、既存のWebサイトをOS.jsのアプリのように組み込む方法とnginxで振り分ける方法を実践していきます。
【 Nginx 】
Nginx(エンジンエックス)は、オープンソースのWebサーバです。処理性能・高い並行性・メモリ使用量の小ささに焦点を当てて開発されており、HTTP, HTTPS, SMTP, POP3, IMAPのリバースプロキシの機能や、ロードバランサ、HTTPキャッシュなどの機能も持ちます。
・OS.jsバックグラウンド起動設定
・Rocket.Chat組み込み
・Wekanの組み込み
・GitLabの組み込み
・nginxインストール
・動作確認
RocketChat、Wekan、GitLabをOS.jsのiframeアプリとして組み込んでみます。
仕組みは、以下の図のようになります。
パソコンからは、192.168.▲.▲ osjs.itccorporation.jp
192.168.▲.▲ chat.itccorporation.jp
192.168.▲.▲ wekan.itccorporation.jp
192.168.▲.▲ gitlab.itccorporation.jp
と名前解決できるものとします。
今回、OS.jsに直接アプリを組み込むのではなく、iframeで表示するだけになります。
今回の検証環境は、
CentOS Linux release 7.6.1810
node v12.18.3
OS.js 3.1.11
nginx-1.19.10
になります。
OS.jsバックグラウンド起動設定
OS.jsを起動するときは、 npm run serve
ですが、フォアグラウンド起動のため、ターミナルを開けていないといけません。そこで、systemdを使ったバックグラウンド起動をまず設定します。
# vi /usr/lib/systemd/system/osjs.service
[Unit]
Description=OS.js Node Server
Documentation=https://manual.os-js.org
After=network.target
[Service]
Environment=NODE_ENV=production
Type=simple
User=osjs
ExecStart=/usr/bin/node /opt/OS.js/src/server/index.js
Restart=on-failure
WorkingDirectory=/opt/OS.js
[Install]
WantedBy=multi-user.target
User=osjs
に設定したosjsユーザーを追加します。
# adduser --system --no-create-home --user-group -s /sbin/nologin osjs
# chown -R osjs /opt/OS.js
systemd の設定を反映して、起動します。
# systemctl daemon-reload
# systemctl enable osjs
# systemctl start osjs
/usr/lib/systemd/system/osjs.service について、公式サイトのマニュアルでは、
ExecStart=node /opt/OS.js/src/server/index.js
ですが、nodeが相対パスのため、以下のエラーになり起動しませんでした。[/usr/lib/systemd/system/osjs.service:10] Executable path is not absolute, ignoring: node /opt/OS.js/src/server/index.js
osjs.service lacks both ExecStart= and ExecStop= setting. Refusing.
Rocket.Chat組み込み
Rocket.ChatをOS.jsに認識させて、メニューに加えます。
Rocket.Chatは、既に chat.itccorporation.jp(192.168.●.●:3000) で動いているものとします。
# cd /opt/OS.js
# npm run make:iframe-application
? Enter name of package ([A-z0-9_]) rocketchat
? Destination src/packages/rocketchat
? Are you sure you want to write to 'src/packages/rocketchat' Yes
# npm run package:discover
src/packages/rocketchat
が作成されますので、
src/packages/rocketchat/icon.png
を追加、
src/packages/rocketchat/index.js
src/packages/rocketchat/metadata.json
src/packages/rocketchat/webpack.config.js
を更新します。
icon.pngは、デザインは任意ですが、今回は、Rocket.Chatのアイコンを置きます。
更新内容は、以下の内容です。
・index.js
クリックしてソースを表示
import osjs from 'osjs';
import {name as applicationName} from './metadata.json';
// Our launcher
const register = (core, args, options, metadata) => {
// Create a new Application instance
const proc = core.make('osjs/application', {args, options, metadata});
// Create a new Window instance
proc
.createWindow({
id: 'rocketchatWindow',
title: metadata.title.en_EN,
dimension: {width: 800, height: 600},
position: {left: 80, top: 60}
})
.on('destroy', () => proc.destroy())
.render($content => {
const iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.src = '//chat.itccorporation.jp/';
iframe.setAttribute('border', '0');
$content.appendChild(iframe);
});
return proc;
};
// Creates the internal callback function when OS.js launches an application
osjs.register(applicationName, register);
iframe.src = '//chat.itccorporation.jp/';
によって、見る先を http://chat.itccorporation.jp/ (192.168.▲.▲)にしています。
・metadata.json
クリックして内容を表示
{
"type": "application",
"name": "rocketchat",
"category": "office",
"server": null,
"icon": "icon.png",
"title": {
"en_EN": "Rocket.Chat"
},
"description": {
"en_EN": "Rocket.Chat"
},
"files": [
"main.js"
]
}
・webpack.config.js
クリックして内容を表示
const path = require('path');
const mode = process.env.NODE_ENV || 'development';
const minimize = mode === 'production';
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
mode,
devtool: 'source-map',
entry: [
path.resolve(__dirname, 'index.js'),
],
optimization: {
minimize,
},
externals: {
osjs: 'OSjs'
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{from: 'data', to: 'data'},
{from: 'icon.png', to: 'icon.png'}
]
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
}
]
}
};
変更を適用します。
# cd src/packages/rocketchat
# npm run build
# cd ../../..
# npm run package:discover
Wekanの組み込み
WekanをOS.jsに認識させて、メニューに加えます。
Wekanは、既に wekan.itccorporation.jp(192.168.■.■:3001) で動いているものとします。
# npm run make:iframe-application
? Enter name of package ([A-z0-9_]) wekan
? Destination src/packages/wekan
? Are you sure you want to write to 'src/packages/wekan' Yes
# npm run package:discover
src/packages/wekan
が作成されますので、
src/packages/wekan/icon.png
を追加、
src/packages/wekan/index.js
src/packages/wekan/metadata.json
src/packages/wekan/webpack.config.js
を更新します。
icon.pngは、デザインは任意ですが、今回は、Wekanのアイコンを置きます。
更新内容は、以下の内容です。
・index.js
クリックしてソースを表示
import osjs from 'osjs';
import {name as applicationName} from './metadata.json';
// Our launcher
const register = (core, args, options, metadata) => {
// Create a new Application instance
const proc = core.make('osjs/application', {args, options, metadata});
// Create a new Window instance
proc
.createWindow({
id: 'wekanWindow',
title: metadata.title.en_EN,
dimension: {width: 800, height: 600},
position: {left: 100, top: 80}
})
.on('destroy', () => proc.destroy())
.render($content => {
const iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.src = '//wekan.itccorporation.jp/';
iframe.setAttribute('border', '0');
$content.appendChild(iframe);
});
return proc;
};
// Creates the internal callback function when OS.js launches an application
osjs.register(applicationName, register);
iframe.src = '//wekan.itccorporation.jp/';
によって、見る先を http://wekan.itccorporation.jp/ (192.168.▲.▲)にしています。
・metadata.json
クリックして内容を表示
{
"type": "application",
"name": "wekan",
"category": "office",
"singleton": true,
"icon": "icon.png",
"server": null,
"title": {
"en_EN": "Wekan"
},
"description": {
"en_EN": "Wekan"
},
"files": [
"main.js"
]
}
・webpack.config.js
クリックして内容を表示
const path = require('path');
const mode = process.env.NODE_ENV || 'development';
const minimize = mode === 'production';
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
mode,
devtool: 'source-map',
entry: [
path.resolve(__dirname, 'index.js'),
],
optimization: {
minimize,
},
externals: {
osjs: 'OSjs'
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{from: 'data', to: 'data'},
{from: 'icon.png', to: 'icon.png'}
]
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
}
]
}
};
変更を適用します。
# cd src/packages/wekan
# npm run build
# cd ../../..
# npm run package:discover
GitLabの組み込み
GitLabをOS.jsに認識させて、メニューに加えます。
GitLabは、既に gitlab.itccorporation.jp(192.168.◆.◆) で動いているものとします。
# npm run make:iframe-application
? Enter name of package ([A-z0-9_]) gitlab
? Destination src/packages/gitlab
? Are you sure you want to write to 'src/packages/gitlab' Yes
# npm run package:discover
src/packages/gitlab
が作成されますので、
src/packages/gitlab/icon.png
を追加、
src/packages/gitlab/index.js
src/packages/gitlab/metadata.json
src/packages/gitlab/webpack.config.js
を更新します。
icon.pngは、デザインは任意ですが、今回は、GitLabのアイコンを置きます。
更新内容は、以下の内容です。
・index.js
クリックして内容を表示
import osjs from 'osjs';
import {name as applicationName} from './metadata.json';
// Our launcher
const register = (core, args, options, metadata) => {
// Create a new Application instance
const proc = core.make('osjs/application', {args, options, metadata});
// Create a new Window instance
proc
.createWindow({
id: 'rocketchatWindow',
title: metadata.title.en_EN,
icon: proc.resource( metadata.icon ),
dimension: {width: 800, height: 600},
position: {left: 120, top: 60}
})
.on('destroy', () => proc.destroy())
.render($content => {
const iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.src = '//gitlab.itccorporation.jp/';
iframe.setAttribute('border', '0');
$content.appendChild(iframe);
});
return proc;
};
// Creates the internal callback function when OS.js launches an application
osjs.register(applicationName, register);
iframe.src = '//gitlab.itccorporation.jp/';
によって、見る先を http://gitlab.itccorporation.jp/ (192.168.▲.▲)にしています。
・metadata.json
クリックして内容を表示
{
"type": "application",
"name": "gitlab",
"category": "development",
"server": null,
"icon": "icon.png",
"title": {
"en_EN": "gitlab"
},
"description": {
"en_EN": "gitlab"
},
"files": [
"main.js"
]
}
・webpack.config.js
クリックして内容を表示
const path = require('path');
const mode = process.env.NODE_ENV || 'development';
const minimize = mode === 'production';
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
mode,
devtool: 'source-map',
entry: [
path.resolve(__dirname, 'index.js'),
],
optimization: {
minimize,
},
externals: {
osjs: 'OSjs'
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{from: 'data', to: 'data'},
{from: 'icon.png', to: 'icon.png'}
]
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
}
]
}
};
変更を適用します。
# cd src/packages/gitlab
# npm run build
# cd ../../..
# npm run package:discover
nginxインストール
nginxをインストールして、リクエストを仲介させます。
ソースコードnginx-1.19.10.tar.gz
headers-more-nginx-module-0.33.tar.gz
が/home/admin/に置かれているものとします。
入手元は、各々以下になります。
http://nginx.org/download/nginx-1.19.10.tar.gz
https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/v0.33.tar.gz
インストール先は、/usr/share/nginx
設定ファイルは、/etc/nginx/
ログ出力先は、/var/log/nginx/
とします。
# cd /home/admin
# adduser --system --no-create-home --user-group -s /sbin/nologin nginx
# yum install -y pcre-devel
# yum install -y zlib-devel
# yum install -y openssl-devel
# tar zxf headers-more-nginx-module-0.33.tar.gz
# tar zxf nginx-1.19.10.tar.gz
# cd nginx-1.19.10
# ./configure \
--add-dynamic-module=/home/admin/headers-more-nginx-module-0.33 \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/lock/subsys/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module
# make && make install
今回の検証環境は、
yum install -y pcre-devel
yum install -y zlib-devel
yum install -y openssl-devel
が無い場合、nginxのconfigureでエラーになるため、必要でした。
場合によっては、必要無かったり、他のインストールが必要だったりするかもしれません。
systemdの設定を追加します。
# vi /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)"
[Install]
WantedBy=multi-user.target
nginx.confを書き換えます。
・load_module "/usr/lib64/nginx/modules/ngx_http_headers_more_filter_module.so";
を追加します。
・proxy_pass http://localhost:8000/;
の設定を追加します。
・include /etc/nginx/conf.d/*.conf;
を追加します。
# vi /etc/nginx/nginx.conf
クリックして内容を表示
load_module "/usr/lib64/nginx/modules/ngx_http_headers_more_filter_module.so";
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name osjs.itccorporation.jp;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8000/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
# server {
# listen 80;
# server_name localhost;
#
# #charset koi8-r;
#
# #access_log logs/host.access.log main;
#
# location / {
# root html;
# index index.html index.htm;
# }
#
# #error_page 404 /404.html;
#
# # redirect server error pages to the static page /50x.html
# #
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root html;
# }
#
# # proxy the PHP scripts to Apache listening on 127.0.0.1:80
# #
# #location ~ \.php$ {
# # proxy_pass http://127.0.0.1;
# #}
#
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
# }
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
include /etc/nginx/conf.d/*.conf;
}
プロキシの設定を追加します。
# mkdir /etc/nginx/conf.d
# vi /etc/nginx/conf.d/server.conf
クリックして内容を表示
server {
listen 80;
server_name chat.itccorporation.jp;
location / {
more_clear_headers 'X-Frame-Options';
proxy_pass http://192.168.●.●:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
server {
listen 80;
server_name wekan.itccorporation.jp;
location / {
proxy_pass http://192.168.■.■:3001/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
server {
listen 80;
server_name gitlab.itccorporation.jp;
location / {
more_clear_headers 'X-Frame-Options';
proxy_pass http://192.168.◆.◆/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
more_clear_headers 'X-Frame-Options';
は、
X-Frame-Options: sameorigin
ヘッダーが返ってきて、エラーになるため、X-Frame-Optionsヘッダーを取り除く設定です。
headers-more-nginx-module-0.33
はこれのためにインストールしています。
X-Frame-Options: sameorigin
は同一ドメインの場合のみiframe表示を許可するというヘッダーになります。Rocket.Chat、GitLabは、これを返す仕様になっているようです。
ファイアウォールのhttpポートを開けて、nginxを再起動します。
# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --reload
# systemctl enable nginx
# systemctl start nginx
動作確認
繰り返しになりますが、仕組みは、以下の図のようになりますので、パソコンからは、192.168.▲.▲ osjs.itccorporation.jp
192.168.▲.▲ chat.itccorporation.jp
192.168.▲.▲ wekan.itccorporation.jp
192.168.▲.▲ gitlab.itccorporation.jp
と名前解決できるものとします。
できました!
その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。