カテゴリー
その他 社内SE

Collabora Onlineで接続エラー “Failed to add session to XXXX” を解決

Collabora Onlineをアップデートしたら、NextCloudで”ドキュメントの読み込みに失敗 NextCloud Officeが読み込めませんでした – しばらく後でもう一度試してください”というエラーが表示され、Office系のファイルが開けなくなった。

エラーの内容としては以下の感じである。

WRN  Waking up dead poll thread [HttpSynReqPoll], started: false, fin
ished: false| net/Socket.hpp:725
ERR  #30: Read failed, have 0 buffered bytes (EPIPE: Broken pipe)
ERR  #30: Socket write returned -1 (EPIPE: Broken pipe)
ERR  loading document exception: WOPI::CheckFileInfo failed:
ERR  Failed to add session to [https://hogehoge.com:443/index.
php/apps/richdocuments/wopi/files/52797_ocic20zydkap] with URI [https://hogehoge.com/index.php/apps/richdocuments/wopi/files/52797_ocic20zydkap?access_token=dcy91ZZq9mSvxv1XsGrW2ucmp8CmFcu4&access_tok
en_ttl=0]: WOPI::CheckFileInfo failed:

この「Failed to add session to」はCollaboraがNextCloudに接続できないときに出力されるエラーで、例えば上なら、「hogehoge.com」の名前解決が出来ていないケースが多く、/etc/hostsやらDNSやらで名前解決すれば動くことが多い。だが、今回はアップデート前は動いていたため、名前解決のエラーではない。

結論から言うとIPv6を無効にすると無事動作した。

諸事情で、このサーバの設定では、ポートをLISTENするプログラムは徹底してIPv4のみ有効として設定した。Collaboraも設定ファイルのnet.protにIPv4を設定しIPv4のみ有効とした。

通常のサーバならIPv6も有効にするところだが、本サーバはさくらの専用サーバで、さくらの専用サーバはIPv6の提供をやめてしまっており、IPv4でしか接続できない。なのでIPv6をLISTENするソケットは可能な限り削除した。

1日いろいろ設定をいじりまわって、Collaboraを別サーバで動かすことまで考えて、最後のあがきでIPv6を無効にしたところするっと動作した。理由はわからないが、CollaboraがIPv6でNextCloudに接続しようとしていて、接続エラーとなっていたと思われる。

同じような人がいるかもしれないので、ご参考まで。

Ubuntu 22でIPv6を仮で無効にするには以下のコマンド。

sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
sysctl -w net.ipv6.conf.lo.disable_ipv6=1

これで動くようになればIPv6が原因である。原因がIPv6であれば以下のコマンドで恒久的にIPv6を無効にする。(ubuntu 20以下だと以下のコマンドはバグで動作しないので注意。)

vi /etc/sysctl.d/60-custom.conf
---
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
--

sysctl -p
systemctl restart procps

カテゴリー
その他 社内SE

NextCloud & collabora onlineをopenLiteSpeedで動かす

PHPを高速で動作させるopenLiteSpeedでNextCloudとcollabora onlineの設定を行った。NextCloudが重いと悩んでいる方は軽くなるので、お試しあれ。

(2022年9月現在の最新パッケージでの構築方法だが、古い環境でも構築方法はほぼ変わらないので参考になるかと思う。)

構築環境

  • OS Ubuntu 22.04
  • NextCloud 24.04
  • OpenLiteSpeed 1.7 + PHP 8.1
  • Collabora Online 22
  • SSL LetsEncrypt

要点

  • Collabora Onlineは設定のnum_prespawn_childrenを増やして軽快に。proxyはipv4のみとするので、net.protoをipv4のみに変更
  • NextCloudの.htaccessは、occ maintenance:update:htaccess で環境に合わせたものを生成しなおす。そのrewrite部分をOpenLiteSpeedのrewrite機能に設定する。(生成した.htaccessは使わない。)
  • Collabora OnlineはOpenLiteSpeedでReverse Proxy設定

前提

  • OSの環境構築はできている。
  • mariaDBを使用する。(インストールは終わっている)
  • 本稿の設定方法では、以下のサイトを作成する。
    NextCloud https://nc.you.com/
    Collabora Online https://lool.you.com/

    参考にする場合、自前のドメインに読み替えのこと。また、NextCloudをサブフォルダーに配置する場合などは適宜読み替えのこと。

初期設定

DB設定 使用するDB環境にNextCloud用のDBを作成しておく。

CREATE DATABASE nc;
CREATE USER 'nextcloud'@'127.0.0.1' IDENTIFIED BY 'yourPassWord';
GRANT ALL ON nc.* TO 'nc'@'127.0.0.1';

FLUSH PRIVILEGES;

rootユーザに変更(以下は基本rootで設定)

sudo su -

hostsを変更

vi /etc/hosts
---
127.0.0.1 localhost nc.you.com lool.you.com
127.0.1.1 nc.you.com lool.you.com
---

Redis インストール

apt install redis-server -y

vi /etc/redis/redis.conf
---
supervised systemd
maxmemory 16mb
maxmemory-policy volatile-lfu
unixsocket /var/run/redis/redis-server.sock
unixsocketperm 777
timeout 60
---

usermod -a -G redis www-data

systemctl enable redis-server
systemctl restart redis.service
systemctl status redis-server

その他インストール

# 入っていない場合に備えて
apt install -y cron vim build-essential
systemctl start cron
systemctl enable cron

OpenLiteSpeed Port 80 + LetsEncrypt

OpenLiteSpeed + php 8.1 インストール

wget -O - https://repo.litespeed.sh > enable_lst_debian_repo.sh
bash enable_lst_debian_repo.sh

apt update
apt install openlitespeed -y

systemctl status lshttpd
systemctl enable lshttpd
systemctl start lshttpd

# 公開フォルダ作成
mkdir /var/www/{nextcloud,80}
chown -R www-data:www-data /var/www/

# vertual hostの設定保存先
mkdir -p /usr/local/lsws/conf/vhosts/{nextcloud,httpPort,loolProxy}
chown www-data:www-data /usr/local/lsws/conf/vhosts/{nextcloud,httpPort,loolProxy}

# vertual hostのrootフォルダー
mkdir -p /usr/local/lsws/vhosts/{nextcloud,httpPort,loolProxy}
chown www-data:www-data /usr/local/lsws/vhosts/{nextcloud,httpPort,loolProxy}

# PHP 8.1 
apt install -y lsphp81 lsphp81-curl lsphp81-dev lsphp81-mysql lsphp81-redis lsphp81-apcu lsphp81-intl lsphp81-imagick

# php-imagickの警告削除のため。
apt install -y libmagickcore-6.q16-6-extra

# 設定ファイル 変更部分のみ
vi /usr/local/lsws/conf/httpd_config.conf
---
serverName                        nc.you.com
#user                             nobody
#group                            nogroup
user                             www-data
group                            www-data
#indexFiles                       index.html, index.php
indexFiles                       index.html, index.php, index.htm
#path                    lsphp73/bin/lsphp
path                    lsphp81/bin/lsphp
---

# 実行ユーザを変更した場合、必ず再インストール
apt -y install --reinstall openlitespeed

# 管理画面へのパスワード設定
/usr/local/lsws/admin/misc/admpass.sh

User name [admin]: your Name

Password: yourPassword
Retype password: yourPassword

# ramディスク作成
mkdir /tmp/ram
mount -t tmpfs -o size=8m /dev/shm /tmp/ram

vi /etc/fstab
---
tmpfs /tmp/ram tmpfs defaults,noatime,size=8m 0 0
---

# php設定 変更部分のみ
vi /usr/local/lsws/lsphp81/etc/php/8.1/litespeed/php.ini
---
memory_limit = 512M
upload_max_filesize = 64M
max_file_uploads = 100
post_max_size = 40M
output_buffering = Off

date.timezone = "Asia/Tokyo"

[Pdo_mysql]
# 環境に合わせて
pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock

[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=1000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1

opcache.jit=on
opcache.jit_buffer_size=128M

apc.enabled=1
apc.enable_cli = 1
apc.shm_size=64M
apc.ttl=3600
apc.gc_ttl=3600
---

# デフォルトユーザnobodyで作られるので一旦削除
rm -rf /tmp/lshttpd

# openLiteSpeed adminパネルの設定
vi /usr/local/lsws/admin/conf/admin_config.conf
---
# 以下の個所を以下のように修正
listener adminListener {
  address               *:7080
  secure                0
  keyFile                 /etc/letsencrypt/live/nc.you.com/privkey.pem
  certFile                /etc/letsencrypt/live/nc.you.com/fullchain.pem
  clientVerify          0
}
---

systemctl restart lshttpd

# www-dataでphpを簡単に扱えるように.bashrcのaliasを追加
su - www-data
vi ~/.bash_profile
---
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
---

vi ~/.bashrc
---
alias lsphp='/usr/local/lsws/lsphp81/bin/php -c /usr/local/lsws/lsphp81/etc/php/8.1/litespeed/php.ini'
---
source ~/.bashrc
exit

# rootユーザも
vi ~/.bashrc
---
# 以下1行を追加
alias lsphp='/usr/local/lsws/lsphp81/bin/php -c /usr/local/lsws/lsphp81/etc/php/8.1/litespeed/php.ini'
---
source ~/.bashrc

http://nc.you.com:7080/にアクセスし、port80が動くようにする。
ファイルから設定する場合は以下。

vi /usr/local/lsws/conf/httpd_config.conf
---
# 追加する。
virtualhost httpPort {
  vhRoot                  $SERVER_ROOT/vhosts/$VH_NAME/
  configFile              $SERVER_ROOT/conf/vhosts/$VH_NAME/vhconf.conf
  allowSymbolLink         1
  enableScript            0
  restrained              1
}
# 修正する。
listener Default {
  address                 *:80
  secure                  0
  map                     httpPort nc.you.com, lool.you.com
}
---

# 新規作成
vi /usr/local/lsws/conf/vhosts/httpPort/vhconf.conf
---
docRoot                   /var/www/80/

errorlog $SERVER_ROOT/logs/$VH_NAME_error.log {
  useServer               0
  logLevel                ERROR
  rollingSize             10k
  keepDays                90
}

accesslog $SERVER_ROOT/logs/$VH_NAME_access.log {
  useServer               0
  logFormat               %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"
  rollingSize             10k
  keepDays                90
}
---
chown lsadm:www-data /usr/local/lsws/conf/vhosts/httpPort/vhconf.conf

LetsEncrypt (メールアドレス部分は変更のこと)

apt install certbot -y

# メールアドレスは自分のものに変更のこと
certbot certonly --non-interactive --agree-tos -m yourmail@mail.com --webroot -w /var/www/80/ -d nc.you.com -d lool.you.com

vi /etc/cron.d/certbot
---
# 変更
#0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --deploy-hook "systemctl restart lshttpd"
---

openlitespeed Admin設定

https://nc.you.com:7080/にアクセス可能なように変更。

vi /usr/local/lsws/admin/conf/admin_config.conf
---
listener adminListener {
  address               *:7080
  # この行から下3行を変更
  secure                1
  keyFile                 /etc/letsencrypt/live/nc.you.com/privkey.pem
  certFile                /etc/letsencrypt/live/nc.you.com/fullchain.pem
  clientVerify          0
}
---

https://nc.you.com:7080/にアクセスし、以下を変更

[一般タブ] 統計出力ディレクトリ => /tmp/ram/
[一般タブ] 自動インデックス => いいえ
[ログタブ] ログレベル => WARNING
[外部アプリケーション] LiteSpeed SAPI を以下のように編集
 最大接続数 => 200
 環境の「PHP_LSAPI_CHILDREN」の値を200に変更

ファイルから変更する場合は以下

vi /usr/local/lsws/conf/httpd_config.conf
---
# 上部のグローバルなエリア(user/groupの設定)のあたりに追加
statDir                   /tmp/ram/

# 真ん中ぐらい・・
indexFiles                index.html, index.phpi, index.htm
autoIndex                 0

# このセクションの以下3行をなければ追加、あれば修正
extprocessor lsphp {
  maxConns                200
  env                     PHP_LSAPI_CHILDREN=200
  env                     LSAPI_AVOID_FORK=200M
}
---

NextCloudインストール

ソースをダウンロードし配置。

mkdir ~/src/
cd ~/src/

# 環境は最新のものを選んで。以下は24.0.4のケース
wget https://download.nextcloud.com/server/releases/nextcloud-24.0.4.tar.bz2
tar xf nextcloud-24.0.4.tar.bz2
cp -r ./nextcloud/. /var/www/nextcloud/

mkdir /var/www/nextcloud/{data,.well-known}
mkdir /var/www/nextcloud/.well-known/{carddav,caldav,webfinger,nodeinfo}

chown -R www-data:www-data /var/www/nextcloud/

NextCloud configファイル設定(追加/修正箇所のみ。最後の2行は.htaccessの更新用)

vi /var/www/nextcloud/config/config.php
---
# 修正箇所のみ
$CONFIG = array (
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'redis' =>
  array (
    'host' => '/var/run/redis/redis-server.sock',
    'port' => 0,
    'timeout' => 0.0,
  ),
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'overwrite.cli.url' => 'https://nc.you.com/',
  'htaccess.RewriteBase' => '/',
---

.htaccessを以下のコマンドで更新

su - www-data
lsphp /var/www/nextcloud/occ maintenance:update:htaccess
exit

生成された、/var/www/nextcloud/.htaccess ファイルを開き、何か所かある<IfModule mod_rewrite.c>のセクションを下のOpenLiteSpeedのvirtual hostのrewrite => rulesに追加。(下の設定ファイルを参考のほど。最初2行:RewriteRule ^/data/.*$ – [F,L]とRewriteRule ^/config/.*$ – [F,L]の下に追加する。RewriteEngine onやmod_envのセクションが内部に含まれる場合はその箇所はコピーしないこと。)

OpenLiteSpeedにvirtual hostを設定

vi /usr/local/lsws/conf/httpd_config.conf
---
# お尻のほうに以下を追加
virtualhost nextcloud {
  vhRoot                  $SERVER_ROOT/vhosts/$VH_NAME/
  configFile              $SERVER_ROOT/conf/vhosts/$VH_NAME/vhconf.conf
  allowSymbolLink         1
  enableScript            1
  restrained              1
}

listener nextcloud {
  address                 *:443
  secure                  1
  keyFile                 /etc/letsencrypt/live/nc.you.com/privkey.pem
  certFile                /etc/letsencrypt/live/nc.you.com/fullchain.pem
  map                     nextcloud nc.you.com
}
---

vi /usr/local/lsws/conf/vhosts/nextcloud/vhconf.conf
---
docRoot                   /var/www/nextcloud/
enableGzip                1

errorlog $SERVER_ROOT/logs/nextcloud_error.log {
  useServer               0
  logLevel                ERROR
  rollingSize             10M
  keepDays                30
}

accesslog $SERVER_ROOT/logs/nextcloud_access.log {
  useServer               0
  logFormat               %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"
  rollingSize             10M
  keepDays                30
}

index  {
  useServer               0
}
errorpage 403 {
  url                     /
}

errorpage 404 {
  url                     /
}
context / {
  allowBrowse             1
  extraHeaders            Strict-Transport-Security "max-age=15552000; includeSubDomains;preload"

  rewrite  {

  }
  addDefaultCharset       off

  phpIniOverride  {

  }
}
rewrite  {
  enable                  1
  autoLoadHtaccess        0
  rules                   <<<END_rules
RewriteRule ^/data/.*$ - [F,L]
RewriteRule ^/config/.*$ - [F,L]

RewriteCond %{HTTP_USER_AGENT} DavClnt
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
RewriteRule ^remote/(.*) remote.php [QSA,L]
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]

RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4|mp3|ogg|wav|wasm|tflite)$
RewriteCond %{REQUEST_FILENAME} !/core/ajax/update\.php
RewriteCond %{REQUEST_FILENAME} !/core/img/(favicon\.ico|manifest\.json)$
RewriteCond %{REQUEST_FILENAME} !/(cron|public|remote|status)\.php
RewriteCond %{REQUEST_FILENAME} !/ocs/v(1|2)\.php
RewriteCond %{REQUEST_FILENAME} !/robots\.txt
RewriteCond %{REQUEST_FILENAME} !/(ocm-provider|ocs-provider|updater)/
RewriteCond %{REQUEST_URI} !^/\.well-known/(acme-challenge|pki-validation)/.*
RewriteCond %{REQUEST_FILENAME} !/richdocumentscode(_arm64)?/proxy.php$
RewriteRule . index.php [PT,E=PATH_INFO:$1]
  END_rules
}
---

# check the config files
/usr/local/lsws/bin/openlitespeed -t

systemctl restart lshttpd

Collabola Onlineインストール

インストール

cd /usr/share/keyrings
sudo wget https://collaboraoffice.com/downloads/gpg/collaboraonline-release-keyring.gpg

# ファイル作成
vi /etc/apt/sources.list.d/collaboraonline.sources
---
Types: deb
URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-ubuntu2204
Suites: ./
Signed-By: /usr/share/keyrings/collaboraonline-release-keyring.gpg
---

# インストール
apt update
apt install coolwsd code-brand -y

# 設定
loolconfig set ssl.enable false
loolconfig set ssl.termination true
loolconfig set storage.wopi.host nc.you.com
loolconfig set server_name lool.you.com

# adminパスワードを設定
loolconfig set-admin-password

# 設定ファイル修正
vi /etc/coolwsd/coolwsd.xml
---
# 修正は3か所
# net.protoをipv4のみに変更
# num_prespawn_childrenを10に変更
# allowed_languagesをen_USのみに変更
---

systemctl enable coolwsd
systemctl start coolwsd

# 動作しているか確認
systemctl status coolwsd

OpenLiteSpeedにvirtual hostを設定 (Reverse Proxyを設定 WebSocketも)

vi /usr/local/lsws/conf/httpd_config.conf
---
# お尻のほうに以下を追加
virtualhost loolProxy {
  vhRoot                  $SERVER_ROOT/vhosts/$VH_NAME/
  configFile              $SERVER_ROOT/conf/vhosts/$VH_NAME/vhconf.conf
  allowSymbolLink         1
  enableScript            1
  restrained              1
}

# 以下の箇所は修正(最後の1行を追加)
listener nextcloud {
  address                 *:443
  secure                  1
  keyFile                 /etc/letsencrypt/live/nc.you.com/privkey.pem
  certFile                /etc/letsencrypt/live/nc.you.com/fullchain.pem
  map                     nextcloud nc.you.com
  map                     loolProxy lool.you.com  
}
---

vi /usr/local/lsws/conf/vhosts/loolProxy/vhconf.conf
---
docRoot                   /var/www/80

errorlog $SERVER_ROOT/logs/$VH_NAME_error.log {
  useServer               0
  logLevel                ERROR
  rollingSize             10M
  keepDays                30
}

accesslog $SERVER_ROOT/logs/$VH_NAME_access.log {
  useServer               0
  logFormat               %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"
  rollingSize             10M
  keepDays                30
}

extprocessor lool {
  type                    proxy
  address                 127.0.0.1:9980
  maxConns                100
  pcKeepAliveTimeout      60
  initTimeout             60
  retryTimeout            0
  respBuffer              0
}

context / {
  type                    proxy
  handler                 lool
  addDefaultCharset       off
}

websocket / {
  address                 127.0.0.1:9980
}
---

最後に

これでNextCloudとCollabora onlineが動作するはずである。

https://nc.you.com/にアクセスし、初期設定を行った後、管理者の[オフィス]設定から、[自前のサーバを使用する]をチェックし、「https://lool.you.com/」を設定すればExcelなどのオフィスファイルがブラウザで開けるようになる。

NextCloudの初期設定では、推奨アプリを入れるか聞かれるが、推奨アプリは入れず、後から、Nextcloud officeアプリだけ入れることをお勧めする。要らないアプリを要れないことでNextCloudは軽くなる。

その他、NextCloudが重たくなる設定ポイントがいくつあるが、[共有]設定のクラウド共有関係はすべてチェックを外すと履歴関係は軽くなる。あとはDBが同じサーバにあるなら、configのdbhostを「127.0.0.1:/var/run/mysqld/mysqld.sock」でソケットに直接アクセスさせるなども有効。

セキュリティが気になるなら、ufwとfail2banで不正なログインがあったらアクセス禁止にする対策をする。

記載はしなかったが、

カテゴリー
その他 社内SE

collabora onlineの高速化

NextCloudのインストール時にcollabora onlineのインストールも行ったのだが、デフォルトの設定では遅く、設定を修正しパフォーマンスを上げた。

以下その記録。

前提

collabora online自体は、proxyの背後で、フロントから127.0.0.1:9980に接続。SSLは以下の設定でオフ。(proxyがSSL処理)

loolconfig set ssl.enable false
loolconfig set ssl.termination true
loolconfig set storage.wopi.host your.nextcloud.domain

公式のガイドもproxy前提のようなので、proxyで設定している。

設定

要点としては、設定XMLの以下3箇所を修正する。

  • allowed_languagesでサポート言語をen_USのみに変更
  • net.protoでipv6を使用せず、ipv4のみとする。(proxyなのでipv6はアクセスなし)
  • 初期起動数(num_prespawn_children)を増やす。(最重要 正直ここだけで良いはず。)

以下のXMLファイルを直接編集する。

vi /etc/coolwsd/coolwsd.xml

XMLファイルの修正点は以下。(修正箇所のみ抜粋)

<!-- 1箇所目 元は以下 -->
<!-- allowed_languages default="de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru" desc="List of supported languages of Writing Aids (spell checker, grammar checker, thesaurus, hyphenation) on this instance. Allowing too many has negative effect on startup performance.">de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru</allowed_languages -->
<allowed_languages default="en_US" desc="List of supported languages of Writing Aids (spell checker, grammar checker, thesaurus, hyphenation) on this instance. Allowing too many has negative effect on startup performance.">en_US</allowed_languages>

<!-- 2箇所目 元は以下 -->
<!--proto default="all" desc="Protocol to use IPv4, IPv6 or all for both" type="string">all</proto-->
<proto default="all" desc="Protocol to use IPv4, IPv6 or all for both" type="string">IPv4</proto>

<!-- 3箇所目 元は以下 10人ぐらいしか同時接続しないとみて、1から10に変更-->
<!-- num_prespawn_children default="1" desc="Number of child processes to keep started in advance and waiting for new clients." type="uint">1</num_prespawn_children-->
<num_prespawn_children default="1" desc="Number of child processes to keep started in advance and waiting for new clients." type="uint">10</num_prespawn_children>

カテゴリー
その他 社内SE

外部の公開サーバでvscode serverを使ってみた

Visual Studio codeのserver版がpreviewながら公式からリリースされたので、SSL/TLS+Basic認証/クライアント認証を施し、systemdのサービスとして起動するように手持ちのVPSサーバ上に設定してみた。

これでブラウザがあれば、どこからでもサーバのファイルを編集できるようになった。

設定方法 (Ubuntu 20.04使用)

フロントエンドにNginxをReverse Proxyとして設定し、ここでSSLなどのセキュリティをかける。VS code server自体はバックエンドにする。Websocketが通らないため、Apacheをフロントエンドにはできないので注意。

Visual Studio code server 設定

以下のようにインストールした後、サービスとして登録するため、systemdファイルを作成する。

# インストール
sudo wget -O- https://aka.ms/install-vscode-server/setup.sh | sh

# systemd unitファイル作成 途中のUser/Groupは書き換えること。
sudo vi /lib/systemd/system/vscodeserver.service
---
[Unit]
Description=vs code server
After=network-online.target

[Service]
ExecStart=/usr/local/bin/code-server serve-local --accept-server-license-terms --disable-telemetry
Restart=always
User=yourUserName
Group=yourGroupName
UMask=002

[Install]
WantedBy=multi-user.target
---

systemdに登録し実行する。(上のunitdファイルに記述したユーザ/グループで実行される。)

# 登録
sudo systemctl enable vscodeserver
# 開始
sudo systemctl start vscodeserver

初回起動時のみ起動に時間がかかるため、1,2分待ち、起動した後に表示される接続先のURLを取得しておく。

# statusの中のWeb UI available atにあるURLを取得する。
sudo systemctl status vscodeserver
---
Jul 13 07:20:14 devserver001 code-server[367393]: Server bound to 127.0.0.1:8000 (IPv4)
Jul 13 07:20:14 devserver001 code-server[367393]: Extension host agent listening on 8000
Jul 13 07:20:14 devserver001 code-server[367393]: Web UI available at http://localhost:8000/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3
Jul 13 07:20:14 devserver001 code-server[367393]: [07:20:14] Extension host agent started.
Jul 13 07:20:14 devserver001 code-server[367393]: [07:20:14] Deleted from disk ms-ceintl.vscode-language-pack-ja /home/yourname/.vscode-server/extensions/ms-ceintl.vscode-language-pack-ja-1.67.3
Jul 13 07:20:14 devserver001 code-server[367393]: [07:20:14] Deleted from disk xdebug.php-debug /home/yourname/.vscode-server/extensions/xdebug.php-debug-1.26.1
---

ここでは、http://localhost:8000/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3であるのでこれを控えておく。

上の「sudo systemctl status vscodeserver」で「Web UI available at」の行が見つからない場合は、「journalctl –no-pager | grep -e ‘code-server’」で起動時間あたりの情報を探すこと。

Nginx設定

Nginxにはリバースプロキシ、SSL、Basic認証(もしくはクライアント認証)を設定する。SSLの各種ファイルはLet’s Encryptなどで取得済みとする。

Nginxをインストールしていない場合はインストール

sudo apt install nginx

基本の設定ファイルを設定する。このあたりは各自の環境に合わせて設定してほしい。私のサーバは私一人しか使わないため最小限の設定にしている。デフォルトでも問題ないはず。

sudo vi /etc/nginx/nginx.conf
---
user yourUser yourGroup;
worker_processes 1;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 50;
        multi_accept on;
}

http {

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 3;
        types_hash_max_size 2048;
        server_tokens off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;
        access_log off;
        error_log /var/log/nginx/error.log;

        include /etc/nginx/sites-enabled/*;
}
---

Basic認証の下準備。

# basic認証
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd testuser
# ここでBasic認証のパスワードを設定する。testuser/設定passwordがbasic認証のログインアカウントになる。

以下が肝心の設定ファイル。Basic認証でやる場合は以下。server_name、ssl_certificateとssl_certificate_keyは変更のこと。

# virtual host
sudo vi /etc/nginx/sites-available/vscodeFront
---
server {
    listen 443 ssl http2;
    server_name yourServerName.com;

    # SSL 環境に応じて変更のこと
    ssl_certificate     /etc/letsencrypt/live/yourServerName.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourServerName.com/privkey.pem;

    location / {
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;

    }
}
---

クライアント認証の場合だと以下。クライアント認証の作り方は割愛。

sudo vi /etc/nginx/sites-available/vscodeFront
---
server {
    listen 443 ssl http2;
    server_name yourServerName.com;

    # server側
    ssl_certificate     /etc/letsencrypt/live/yourServerName.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourServerName.com/privkey.pem;

    # client認証
	ssl_verify_client on;
	ssl_client_certificate /opt/myCA/cacert.pem;
	ssl_crl /opt/myCA/crl.pem;

    location / {

        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;

    }
}
---

設定が終わったら、virtual hostの設定を有効にして、Nginx再起動。

sudo ln -s /etc/nginx/sites-available/vscodeFront /etc/nginx/sites-enabled/
sudo systemctl restart nginx

ここで、VS code serverの設定時に控えておいた「http://localhost:8000/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3」の?から下の部分(赤色部分)を切り取り、https://yourServerName.com/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3にアクセスするとVS code serverが表示される。

Port 8000は外部からアクセスできないようにしておくこと。

感想

現時点では、vscode serverの非公式WEB版であるCoderのcode-serverのほうが若干動作が軽く、日本語化もできるので使いやすい。ただ、こちらのvscode serverは公式なので、いずれ非公式のCoder版は廃れる気がする。公式版の不満点としては、使えない拡張機能があることと、日本語化できないことであるが、まだpreview版なのでいずれ対応してくれるのでは、という期待がある。

とりあえず、Coder版から乗り換えた。

カテゴリー
その他 社内SE

chromebook FireFoxの公式インストール Flatpak

Chromebookに使い勝手の良いデスクトップ版のFirefoxをインストールするには、LinuxのFlatpakでインストールするのが一番簡単である。

ただ、以前のFirefoxの公式ページにあるChromebook/ChromeOSへのFlatpak Firefoxのインストール方法に誤りがあり、インストールしても、ひと手間かけないと、Firefoxの起動ができなかった。その対策の記事を書こう書こうと思っているうちに、現在の公式ページが修正され、正しいインストール方法が記載されるようになってしまった。

悔しいので、私も以下にデスクトップ版のFirfoxインストール方法を示す。

1)[設定]-[デベロッパー]のページの[Linux開発環境]をONにする。(細かい方法はいろんなサイトに書いてあるので割愛。ディスクサイズは自動拡張されるのでデフォルトの10GBで良い。)

2)ブラウザのchromeを立ち上げ[Ctrl + Alt + t]でcroshタブを立ち上げる。

3)chroshタブで以下のコマンドを打つ。

vsh termina
lxc config set penguin security.nesting true
exit

4)Chromebook / ChromeOSを再起動する。(電源OFFしON)

5)ターミナルを起動する。(検索ランチャーでterminalと打つと出てくる)

6)ターミナルで以下のコマンドを打つ

sudo apt install flatpak
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install firefox
# この後、どの種類のfirefoxをインストールするか選択肢が出るはず。
# stableという言葉が含まれている行の番号を入力するとOK。

これで検索ランチャーでFirefoxと検索するとFirefoxが出てきて起動できるようになる。

おまけ:Linuxを日本語環境にしてあげれば、Firefoxで日本語も使えるはずである。私は日本語化した後に上記インストールしたので多分としか言えないが、日本語が使えないようであれば、一旦、「flatpak uninstall org.mozilla.firefox」でfirefoxをアンインストールし、Linuxを日本語化した後、再度「flatpak install firefox」をすれば大丈夫だと思う。

ChromebookのLinuxの日本語環境化も探せば色々出てくるかと思うが、ターミナルでだいたい以下の感じのコマンドを打つ。

sudo apt install task-japanese fonts-ipafont locales-all
sudo localectl set-locale LANG=ja_JP.UTF-8
# ここで再起動
#(ターミナルのアイコンを右クリックで[Linuxをシャットダウン]をクリック、再度ターミナル起動)
sudo apt install fcitx-mozc
sudo vim /etc/systemd/user/cros-garcon.service.d/cros-garcon-override.conf
#---
# 以下を上のファイルの最後に追加
Environment="GTK_IM_MODULE=fcitx"
Environment="QT_IM_MODULE=fcitx"
Environment="XMODIFIERS=@im=fcitx"
Environment="GDK_BACKEND=x11"
#---

vim ~/.sommelierrc
#---
# 上のファイルに以下1行追加
/usr/bin/fcitx-autostart
#---
# 再起動(シェルフのアイコンを右クリックで[Linuxをシャットダウン]、以下略)

# fcitxの設定
fcitx-configtool

# GUIになるので、以下設定
#1.) [アドオン]タブで [Advanced] チェックボックスをオン
#2.) 一覧から [Fctix XIM Frontend] を選択してダイアログを開く
#3.) 「XIM で On The Spot スタイルを使う(起動中は変更できません)」チェックボックスをオン

カテゴリー
その他 社内SE

Code-server keyboad Layout 日本語化

VPSに入れてあるUbuntuにCode-serverをインストールして、ブラウザからアクセスしたところ、キーボードショートカットがうまく動かない。ターミナルを開く「Ctrl+Shift+@」を押しても反応がない。手元の日本語キーボードをCode-serverがUSのキーボードと認識しているのが原因のようだ。Keyboad Layoutをjaに変更したいのだが、表示される選択欄にjaはない。VPS上のUbuntuを日本語環境にしてみたりしたが効果がない。

仕方がないのでVS-CODEを立ち上げ、そこのKeyboad Layoutをまるっとコピーしたら、問題が解決した。

以下、方法を備忘録。

code-server 右下のLayout: USとなっているところをクリックします。
右下のLayoutがUS

上の画像の箇所をクリックすると、Keyboad Layoutの変更ができるので、そこで「Configure Keyboad Layout」を選択。

表示されたKeyboad Layoutの切り替え一覧から「Configure Keyboad Layout」を選択します。

表示されるkeyboadlayout.jsonに以下をコピーペーストし保存。(長いコードの下に設定の続きあり。)

{
	"layout": {
		"name": "00000411",
		"id": "",
		"text": "Japanese"
	},
	"rawMapping": {
		"Sleep": {
			"vkey": "VK_SLEEP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"WakeUp": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyA": {
			"vkey": "VK_A",
			"value": "a",
			"withShift": "A",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyB": {
			"vkey": "VK_B",
			"value": "b",
			"withShift": "B",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyC": {
			"vkey": "VK_C",
			"value": "c",
			"withShift": "C",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyD": {
			"vkey": "VK_D",
			"value": "d",
			"withShift": "D",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyE": {
			"vkey": "VK_E",
			"value": "e",
			"withShift": "E",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyF": {
			"vkey": "VK_F",
			"value": "f",
			"withShift": "F",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyG": {
			"vkey": "VK_G",
			"value": "g",
			"withShift": "G",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyH": {
			"vkey": "VK_H",
			"value": "h",
			"withShift": "H",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyI": {
			"vkey": "VK_I",
			"value": "i",
			"withShift": "I",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyJ": {
			"vkey": "VK_J",
			"value": "j",
			"withShift": "J",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyK": {
			"vkey": "VK_K",
			"value": "k",
			"withShift": "K",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyL": {
			"vkey": "VK_L",
			"value": "l",
			"withShift": "L",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyM": {
			"vkey": "VK_M",
			"value": "m",
			"withShift": "M",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyN": {
			"vkey": "VK_N",
			"value": "n",
			"withShift": "N",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyO": {
			"vkey": "VK_O",
			"value": "o",
			"withShift": "O",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyP": {
			"vkey": "VK_P",
			"value": "p",
			"withShift": "P",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyQ": {
			"vkey": "VK_Q",
			"value": "q",
			"withShift": "Q",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyR": {
			"vkey": "VK_R",
			"value": "r",
			"withShift": "R",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyS": {
			"vkey": "VK_S",
			"value": "s",
			"withShift": "S",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyT": {
			"vkey": "VK_T",
			"value": "t",
			"withShift": "T",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyU": {
			"vkey": "VK_U",
			"value": "u",
			"withShift": "U",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyV": {
			"vkey": "VK_V",
			"value": "v",
			"withShift": "V",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyW": {
			"vkey": "VK_W",
			"value": "w",
			"withShift": "W",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyX": {
			"vkey": "VK_X",
			"value": "x",
			"withShift": "X",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyY": {
			"vkey": "VK_Y",
			"value": "y",
			"withShift": "Y",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyZ": {
			"vkey": "VK_Z",
			"value": "z",
			"withShift": "Z",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit1": {
			"vkey": "VK_1",
			"value": "1",
			"withShift": "!",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit2": {
			"vkey": "VK_2",
			"value": "2",
			"withShift": "\"",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit3": {
			"vkey": "VK_3",
			"value": "3",
			"withShift": "#",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit4": {
			"vkey": "VK_4",
			"value": "4",
			"withShift": "$",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit5": {
			"vkey": "VK_5",
			"value": "5",
			"withShift": "%",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit6": {
			"vkey": "VK_6",
			"value": "6",
			"withShift": "&",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit7": {
			"vkey": "VK_7",
			"value": "7",
			"withShift": "'",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit8": {
			"vkey": "VK_8",
			"value": "8",
			"withShift": "(",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit9": {
			"vkey": "VK_9",
			"value": "9",
			"withShift": ")",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit0": {
			"vkey": "VK_0",
			"value": "0",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Enter": {
			"vkey": "VK_RETURN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Escape": {
			"vkey": "VK_ESCAPE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Backspace": {
			"vkey": "VK_BACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Tab": {
			"vkey": "VK_TAB",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Space": {
			"vkey": "VK_SPACE",
			"value": " ",
			"withShift": " ",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Minus": {
			"vkey": "VK_OEM_MINUS",
			"value": "-",
			"withShift": "=",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Equal": {
			"vkey": "VK_OEM_7",
			"value": "^",
			"withShift": "~",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BracketLeft": {
			"vkey": "VK_OEM_3",
			"value": "@",
			"withShift": "`",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BracketRight": {
			"vkey": "VK_OEM_4",
			"value": "[",
			"withShift": "{",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Backslash": {
			"vkey": "VK_OEM_6",
			"value": "]",
			"withShift": "}",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Semicolon": {
			"vkey": "VK_OEM_PLUS",
			"value": ";",
			"withShift": "+",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Quote": {
			"vkey": "VK_OEM_1",
			"value": ":",
			"withShift": "*",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Backquote": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Comma": {
			"vkey": "VK_OEM_COMMA",
			"value": ",",
			"withShift": "<",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Period": {
			"vkey": "VK_OEM_PERIOD",
			"value": ".",
			"withShift": ">",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Slash": {
			"vkey": "VK_OEM_2",
			"value": "/",
			"withShift": "?",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"CapsLock": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F1": {
			"vkey": "VK_F1",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F2": {
			"vkey": "VK_F2",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F3": {
			"vkey": "VK_F3",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F4": {
			"vkey": "VK_F4",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F5": {
			"vkey": "VK_F5",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F6": {
			"vkey": "VK_F6",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F7": {
			"vkey": "VK_F7",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F8": {
			"vkey": "VK_F8",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F9": {
			"vkey": "VK_F9",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F10": {
			"vkey": "VK_F10",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F11": {
			"vkey": "VK_F11",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F12": {
			"vkey": "VK_F12",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"PrintScreen": {
			"vkey": "VK_SNAPSHOT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ScrollLock": {
			"vkey": "VK_SCROLL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Pause": {
			"vkey": "VK_NUMLOCK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Insert": {
			"vkey": "VK_INSERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Home": {
			"vkey": "VK_HOME",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"PageUp": {
			"vkey": "VK_PRIOR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Delete": {
			"vkey": "VK_DELETE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"End": {
			"vkey": "VK_END",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"PageDown": {
			"vkey": "VK_NEXT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowRight": {
			"vkey": "VK_RIGHT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowLeft": {
			"vkey": "VK_LEFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowDown": {
			"vkey": "VK_DOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowUp": {
			"vkey": "VK_UP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumLock": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadDivide": {
			"vkey": "VK_DIVIDE",
			"value": "/",
			"withShift": "/",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadMultiply": {
			"vkey": "VK_MULTIPLY",
			"value": "*",
			"withShift": "*",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadSubtract": {
			"vkey": "VK_SUBTRACT",
			"value": "-",
			"withShift": "-",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadAdd": {
			"vkey": "VK_ADD",
			"value": "+",
			"withShift": "+",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadEnter": {
			"vkey": "VK_RETURN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad1": {
			"vkey": "VK_END",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad2": {
			"vkey": "VK_DOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad3": {
			"vkey": "VK_NEXT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad4": {
			"vkey": "VK_LEFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad5": {
			"vkey": "VK_CLEAR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad6": {
			"vkey": "VK_RIGHT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad7": {
			"vkey": "VK_HOME",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad8": {
			"vkey": "VK_UP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad9": {
			"vkey": "VK_PRIOR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad0": {
			"vkey": "VK_INSERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadDecimal": {
			"vkey": "VK_DELETE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"IntlBackslash": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ContextMenu": {
			"vkey": "VK_APPS",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Power": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadEqual": {
			"vkey": "VK_CLEAR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F13": {
			"vkey": "VK_F13",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F14": {
			"vkey": "VK_F14",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F15": {
			"vkey": "VK_F15",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F16": {
			"vkey": "VK_F16",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F17": {
			"vkey": "VK_F17",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F18": {
			"vkey": "VK_F18",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F19": {
			"vkey": "VK_F19",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F20": {
			"vkey": "VK_F20",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F21": {
			"vkey": "VK_F21",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F22": {
			"vkey": "VK_F22",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F23": {
			"vkey": "VK_F23",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F24": {
			"vkey": "VK_F24",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Help": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Undo": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Cut": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Copy": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Paste": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AudioVolumeMute": {
			"vkey": "VK_VOLUME_MUTE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AudioVolumeUp": {
			"vkey": "VK_VOLUME_UP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AudioVolumeDown": {
			"vkey": "VK_VOLUME_DOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadComma": {
			"vkey": "VK_ABNT_C2",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"IntlRo": {
			"vkey": "VK_OEM_102",
			"value": "\\",
			"withShift": "_",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KanaMode": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"IntlYen": {
			"vkey": "VK_OEM_5",
			"value": "\\",
			"withShift": "|",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Convert": {
			"vkey": "VK_CONVERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NonConvert": {
			"vkey": "VK_NONCONVERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang1": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang2": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang3": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang4": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ControlLeft": {
			"vkey": "VK_CONTROL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ShiftLeft": {
			"vkey": "VK_SHIFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AltLeft": {
			"vkey": "VK_MENU",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MetaLeft": {
			"vkey": "VK_LWIN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ControlRight": {
			"vkey": "VK_CONTROL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ShiftRight": {
			"vkey": "VK_SHIFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AltRight": {
			"vkey": "VK_MENU",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MetaRight": {
			"vkey": "VK_RWIN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaTrackNext": {
			"vkey": "VK_MEDIA_NEXT_TRACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaTrackPrevious": {
			"vkey": "VK_MEDIA_PREV_TRACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaStop": {
			"vkey": "VK_MEDIA_STOP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Eject": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaPlayPause": {
			"vkey": "VK_MEDIA_PLAY_PAUSE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaSelect": {
			"vkey": "VK_LAUNCH_MEDIA_SELECT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"LaunchMail": {
			"vkey": "VK_LAUNCH_MAIL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"LaunchApp2": {
			"vkey": "VK_LAUNCH_APP2",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"LaunchApp1": {
			"vkey": "VK_LAUNCH_APP1",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserSearch": {
			"vkey": "VK_BROWSER_SEARCH",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserHome": {
			"vkey": "VK_BROWSER_HOME",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserBack": {
			"vkey": "VK_BROWSER_BACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserForward": {
			"vkey": "VK_BROWSER_FORWARD",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserStop": {
			"vkey": "VK_BROWSER_STOP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserRefresh": {
			"vkey": "VK_BROWSER_REFRESH",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserFavorites": {
			"vkey": "VK_BROWSER_FAVORITES",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		}
	}
}

code-serverからログアウトし、再度ログイン。

左上の三からメニューを表示し、「Sign out of code-server」をクリック
ログアウト方法

最後に一番最初のKeyboad Layoutの選択で「Japanese (User configured layout)」を選択すると日本語キーボードでもショートカットが使えるようになる。

変更されると右下の表示が「Layout: Japanese」になります。
こうなったらOK!

以上!

カテゴリー
その他 社内SE

Chromebook用メモ帳(Text editor PWA)

Chromebook (Chrome OS)用のテキストファイル用文字化け対策済みのアプリ(PWA)を以下リンクに公開します。PWAをインストールすれば完全にオフラインでも利用可能です。(ChromebookでSJISのテキストファイルを開けるようになります。)

メモ帳アプリ

PWA インストール方法

通常のPWAのインストールと同様です。メモ帳アプリを開いて上部アドレスバーに表示されるアイコンからインストールです。(表示されない場合は、アドレスバーでEnterを押して再読み込みしてみてください。)

PWAインストールボタン
PWAインストール確認画面

これでアプリとして「メモ帳」が登録されているので、検索ランチャーなどから呼び出せます。

ファイルから直接メモ帳を起動したい場合

ファイルをダブルクリックで表示など、ファイルから直接「メモ帳」を起動したい場合は、最初に実験的機能から、File Handling APIを選び、Enabledに設定します。

  1. アドレスバーにchrome://flagsと入力し、実験的機能を呼び出す。
  2. File Handling APIを探し、Enabledにする。
  3. Restart(再起動)する。(Chromebookが再起動されます。)
File Handling API

この状態でファイルアプリから適当なファイルを選び、右クリックから、以下の画像の要領で先程登録したメモ帳アプリを呼び出します。(画像のアプリ名は開発中のため異なります。。。)途中、許可を求められるので適宣許可ください。

ファイルから呼び出し

上の画像で「デフォルトを変更」を選ぶとテキストファイルをダブルクリックで開けるように設定もできます。

注意点

SJISのテキストファイルを読み込み表示/編集できますが、保存するとUTF-8になります。最近のWindowsのメモ帳はUTF-8がデフォルトですので、特に問題ないかとは思いますが、利用の際は注意ください。

その他

一度インストールすると完全にオフラインで動作します。サーバにファイルなどを送ることもないのでセキュリティ上も安心かと思います。

Shift-JISの他、EUC-JPも読めるようにしていますが、テストしていない(手元にEUC-JPのファイルがない)ので動かないかもしれません。

経緯

ChromeOSのTextアプリがShift-JISに対応していないため、古いテキストファイルを開くと文字化けていることがあり、その対策としてオープンソースソフトのSmart Text Editorを改変して作りました。本家のいらなそうな機能はバッサリ削っています。日本語対応以外で追加した機能は「名前を付けて保存」くらいです。短時間テストなしで改変したので、バグあるかもしれません。ソースはこちらに公開しています。(本家もかなりぐちゃぐちゃなコードです。何も気にせずぐちゃぐちゃ改変できるのでやりやすいといえばやりやすいのですが。。)

カテゴリー
その他 社内SE

HP Chromebook x360 14c レビュー(14c-cc 型番:518T8PA-AAAB)

家族で使用するためにChromebookを購入した。色々悩んだが、少し良いものをということで、HPの上位機種を選択した。スペックは「Core i3-1125G4 8GB 128GB SSD 14インチ フルHD」である。フルHDとあるが、設定から2194×1234まで解像度をあげられる。自動更新スケジュールは2029年6月までであった。

使って1週間ほどだが、総論としてとても気に入っている。思ったより軽く扱いやすいし、何よりフルHD IPSディスプレイがきれいである。WindowsやMACとは異なるOSなのでできることに制限はあるが、家族で利用する分には問題ない。Androidのアプリが使えるのも地味に良い。余談だが、子供の保育園の連絡帳がスマホアプリになり、スマホが苦手な私にとっては、ChromeBookを使ってキーボードで書けるようになりその点も嬉しい。

操作性

HPのChromebookというより、ChromeOSの操作性なのだと思うが、タッチパッドがよくできていて、マウスいらずである。それに加え、本製品はタッチディスプレイなのでマウスの出番はまったくない。この操作性の良さはMACのノートに近い。キーボードもキーピッチが20mm前後なので、特に打ちにくいこともない。

最近Windowsのノートも改善してきているが、タッチパッド絡みで言えば、やはりWindowsを使うならマウスのほうが良いし、それが残念ながら面倒なのだ。

動作

WEBを見る分には申し分ない。1週間でなれてしまったが、買って届いた日は、WEBの表示速度に「おっ」と驚いてしまった。起動は5,6秒ぐらいである。起動が速いので「ノートPC立ち上げるか。。。」のような億劫感は少なく、使いたいときにパッと使えるのが良い。この製品はシェルを開くと起動してくれるので起動ボタンを押す手間もない。ただ、起動時間に関して言えば、最近Windowsも頑張っているので、こちらのほうはよく見るChromeBookの宣伝ほどの驚きはなかった。

妻曰く、かなり良いとのことである。音にこだわりのない私の印象は、外付けスピーカーの音に比べると軽いという印象だったが、10年以上音楽をやっていた妻が言うなら良いのであろう。

映像、ディスプレイ

きれいである。Youtubeで自然ドキュメント系のフルHDの映像を見たが、ずっと見ていられる綺麗さであった。(ちなみに他の解像度の低い手持ちのデバイスではすぐに飽きてしまう映像である。)

また、上でも書いているが、フルHDなのに、設定から2194×1234まで解像度をあげられる。ただ、ここまで解像度を上げると字が小さくなりすぎるので、デフォルトの解像度は1536×864のまま今のところは使っている。

それと、主観ではあるものの、解像度1536×864のまま、YoutubeでフルHDの映像を見たときの映像の細かさはちゃんとフルHDが出ていそうである。あまり映像にこだわりのない私の感想ではあるが、解像度を上げてフルHDを見ても違いが見えないので多分Chrome OSにそういう機能があるのでは、と思っている。調べると以前は設定すればフォントやシェルフ以外の解像度を上げる機能がChromeOSにはあったらしい。今はその設定がなくなっているのでデフォルトになったのかもしれない。

カメラ

一応カメラアプリから自分を映して見てみたが、92万画素なのでそれなりである。WEB会議などで使う分には問題ないだろう。妻曰く、あまり細かく映るとアラが見えるおそれがあるため、少しボケてるぐらいが良いらしい。

電池持ち

ChromeBookの宣伝通り良い。フル充電で充分1日使える。家族がたまに(週に1、2時間ぐらい)使う分なら1ヶ月ぐらい充電無しで使えそうである。USBタイプCで充電可能なのもスマホの充電ケーブルと共用できて良い感じである。

購入の経緯

これまで、家族用のデバイスとして、メモリ2GBのタブレットをメインに、サブで10年前のMAC(Core i7 + SSD)を使っていた。最近タブレットが重くなり、かといってMACをいちいち出すのは億劫で、いろいろ考えた末、最近良く目にするChrombookの購入に至った。ちなみに自分用としてWindowsノートも2台持っているし、仕事柄、会社でもPCを色々購入しており、PCを見る目はなんとなくあるつもりである。

ChromeBookの選定にあたっては、はじめからHP製かFujitsu製のどちらかを購入するつもりであった。Asus製も目に入ってはいたが、これまで2度ほどAsus製品を購入し、どちらもすぐに壊れて印象が悪いので外した。Fujitsuの軽いPCとHPのコスパと迷った末にAmazonでセールとなっていたHP製の購入となった。