金魚飼育その後

なかなか水槽を洗ってあげられないけど、夏場も越えて元気に育ってくれてます。以前の記事では転覆病に悩まされていて、色々試した結果水草を入れてあげるということで様子を見ることにしましたが、夏の水温のせいもあるかもですが、転覆病の症状もほとんど出なくなり(食後に少し浮きやすい感じは残ってますが)、その代わり水槽が大変なことに・・・。前記事ではもっさりあった水草のカボンバですが、散々食い荒らされてこんなんなってしまいましたw

汚い水槽ですが、背景の緑は写真なので、哀れなカボンバがわかると思いますw

最初の頃は隠れ家くらいにしか使っていなかったのに、いつの間に味を覚えたのか、すっかり葉がなくなってしまいました。明日くらいに新しいカボンバを献上がてらに水槽掃除をしてあげようと思いますー。

これで涼しくなって水温が下がっても転覆の症状が出なければ治療成功といったところかもですが、、
それにしても新芽から狙って食べるようになってきてるから次の水草買ってきても長くは持たないような気がする・・・w

MacBook Pro購入その他

プログラム開発環境の一環として、というか殆ど興味本位レベルで以前から購入検討していたMacBookProを購入しました。Windowsマシンは既にあるので、あまり互換性とか考えず性能重視でM1品をGET。

そんなこんなで初めて使うMacの設定にバタバタしながらの数日でした。以前の職場で使用していた頃のMac(Classicとかwww)とは違いほとんどLinuxマシンと同じ感覚でとりあえずコマンドライン強化に重きを置き、ネットの情報をもとに着々と進めているところです。

あんまり関係ないけど、今朝の日の出写真。雲から下半分だけ顔を出した大陽の図。

たまにはこういうのも良いかな。コロナであまり出かけられないので、ネタが完全に偏ってるし。。。

wordpressのdocker化と既存データの移植

従来環境ではApache2+MySQLでしたが、dockerへの移植時はwebの情報を参考にnginx+php+fpm+mariadbとしました。DockerHubからwordpress+fpmとmariaDBの公式イメージを使用して構築しました。

version: '3.1'
services:
  db:
    image: mariadb:latest
    container_name: mariadb_wp
    volumes:
      - mariaDb:/var/lib/mysql
      - ./db_backup:/backup
    restart: always
    command: --innodb-read-only-compressed=OFF
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wpdata
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      TZ: Asia/Tokyo
  php-fpm:
    image: wordpress:5.8-fpm
    container_name: php_wp
    volumes:
      - ./blog:/var/www/html
      - ./conf/upload.ini:/usr/local/etc/php/conf.d/upload.ini
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: webdata
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_NAME: user
      TZ: Asia/Tokyo
  nginx:
    image: nginx
    container_name: nginx_wp
    depends_on:
      - php-fpm
    environment:
      - VIRTUAL_HOST=blog.marochanet.org
      - TZ=Asia/Tokyo
    volumes:
      - ./blog:/var/www/html
      - ./conf/default.conf:/etc/nginx/conf.d/default.conf
      - ./conf/nginx.conf:/etc/nginx/nginx.conf
    expose:
      - '443'
    restart: always

volumes:
  mariaDb:

networks:
  default:
    external:
      name: shared

最後のsharedネットワークへの参加とnginxホストの環境変数VIRTUAL_HOSTでリバースプロキシで構成する仮想ホスト名でアクセス出来るようになっています。この場合ここではport公開せずにexposeを使用します。

mariaDBはwordpressだけではなくその他django、rainloop、nextcloudでも使用するが、とりあえずこのcomposeプロジェクトで立ち上げておく(他のcomposeからもDBホストmariadb_wpでアクセス出来る)。

nginxホストの設定:nginx.conf と default.confはサンプルのまま

$ cat /conf/nginx.conf
user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$uri - $is_args - args :::'
                      '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

$ cat /conf/default.conf
server {
    index index.php;
    charset utf-8;
    server_name localhost;
    root /var/www/html;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    location ~* /wp-config.php {
        deny all;
    }
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    location ~* .(html|css|js|jpe?g|png|gif|svg|mpg|flv|swf)$ {
        expires max;
        access_log off;
    }
}

このままアクセスすると、言語およびadminのパスワード設定など初期設定が始まる。今回は既存サイトの移植が目的だが、まずはこのまま初期化して素のwordpressがアクセス出来るようにします。そののちwp-contentsを既存サイトのものと置き換えます。この段階では一度ポートを閉じるなどしてアクセス出来ないようにしておく必要があるかも知れません。

$ sudo rm -rf wp-contents
$ sudo cp -rf [old position]/wp-contents .
$ sudo chown -R www-data.www-data wp-contents 

次にデータベースのコピーですが。まずは既存サイトのデータベースをバックアップします。たとえば同じホストのmysqlからバックアップするとして

$ mysql-dump --lock-all-tables -u root -p --databases wpdata > wpdata.sql
Passwrd:

今回はmysqlからmariadbへの移植も兼ねているので、そのままではエラーになるため、キーワードを入替えておく必要がある。

今回の場合ではunicodeの表現方式で

utf8mb4_0900_ai_ci => utf8mb4_unicode_ci

に変換しておく必要があった。

変換の後、コンテナのデータベースにリストアします。メンテナンス用にdbサービスにマウントしているdb_backupにコピーしてから

$ docker-compose exec db /bin/bash
db$ mariadb -u root -p
mariadb> drop database wpdata
mariadb> quit
db$ mariadb -u root -p < /backup/wpdata.sql

すでに作成済のデータベースwpdataを一旦削除してから改めてバックアップデータをリストア

これにて無事移植が完了しました。

ここまで簡単な流れにまとまったけど、これでも結構失敗を繰り返したり、、あーでもないこーでもないと試した結果だったりします。その紆余曲折をまとめられれば良いのだが、やってるときは悩みながら突っ走ってしまうので、過程があまり残らないことが間々あるw

IEさようなら

こちらのブログはwordpressを使っているので、まだ大丈夫っぽいですが、ポータルサイトは先月辺りにBootstrap5にアップグレードしたのでいよいよIEでは見られないサイトとなってきました。具体的にBotostrap5のどこがIEでダメなのかはよく調べてないですが、とりあえずjavascriptの記述はmodule式にしたのでIEでは動作はしません。

bootstrap5からjavascriptの形式としてesm(EcmaScriptModule?)が追加されているので、これはモジュールとして使用する必要があります。この場合従来では

<head>
    ・・・・・
    <meta charset="UTF-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <script type="text/javascript" src="js/bootstrap.bundle.js"></script>
    ・・・・・
</head>

上記のようにヘッダで設定していたものを

<head>
  ・・・・
  <style type="text/css">
    @import '/css/bootstrap.css';
  </style>
  <script type="module">
      import { Alert, Button, Carousel, Collapse, Dropdown, Modal, Offcanvas, Popover, ScrollSpy, Tab, Toast, Tooltip } from "./js/bootstrap.esm.js";
  </script>
  ・・・・
</head>

と、新しい形で書いてあげる必要があります。

まぁ、esmじゃ無い方を使えば従来式で書けるんだけど、まぁ新しいモノ好きということで。。。

dockerリバースプロキシ環境

前記事で書いたように従来のApache仮想ホストと同じことをdockerブリッジネットワークで構成するためには、リクエストホスト名によって接続コンテナを切り替える機能が必要とのこと。しっかり勉強すれば自力でも出来るかも知れないが、先人の作り上げた構成をお手軽に実現出来るのがdockerの良いところということで、ネット検索でも評判の良いjwilder/nginx-proxyを使用することにしました。

version: '3'
services:
  nginx_root:
    build: ./rootimg
    image: jwilder/nginx-proxy:certbot
    container_name: nginx_root_container
    hostname: nginx_host
    depends_on:
      - http_default
    privileged: true
    environment:
      - DEFAULT_HOST=base.marochanet.org
      - TZ=Asia/Tokyo
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    networks:
      default:
        ipv4_address: 192.168.29.2
    ports:
      - "80:80"
      - "443:443"
    restart: always
  http_default:
    container_name: http_default_container
    image: nginx
    hostname: http_default_host
    expose:
      - "80"
    environment:
      - VIRTUAL_HOST=base.marochanet.org
      - TZ=Asia/Tokyo
    volumes:
      - ./html:/usr/share/nginx/html
    restart: always

networks:
  default:
    driver: bridge
    name: shared
    ipam:
      config:
        - subnet: 192.168.xx.0/24
          gateway: 192.168.xx.1
          ip_range: 192.168.xx.16/28

nginx_rootというサービスがjwilder/nginx-proxyを使用したリバースプロキシコンテナです。build:でイメージを作り直していますが、Letsencryptの証明書を取得/更新するためにcertbotをインストールしているだけです。

  • rootimg/Dockerfile
FROM jwilder/nginx-proxy

ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update \
    && apt-get install --yes --no-install-recommends \
      certbot \
    && rm -rf /var/lib/apt/lists/*

2個目のサービスhttp_defaultはとりあえずのWEBサーバー。テスト用にHTML返すだけなので特別なことはしていませんが、これだけでOKです。キモはenvironment節の環境変数として記されたVIRTUAL_HOSTで、ここに設定したURL向けのリクエストがこのコンテナに向けられるようにリバースプロキシが上手い具合に設定してくれます。

プロキシサービスのコンテナにある環境変数DEFAULT_HOSTはそのまんまの意味で、行き先の見つからない宛先(IPアドレス直とか)の場合の飛び先で、この場合宛先がhttp_defaultサービスと同じになっているので、迷い込んで来た人?IPアドレスで飛んできたスキャンな人へのメッセージページ/エラーページにすると良いかもしれません。

一番最後のnetworks:ではブリッジネットワークの設定をしています。name:節の shared がネットワーク名になります。サブネット、ゲートウェイが設定出来、さらに ip_rangeは、よく理解出来てませんが、固定IPを割り当てる範囲を決めているようでした。固定IPは 1~15で、DHCP的なアドレス割当ては16以降になっているようです。

基本的にはこの共通ネットワークに入ってさえいれば同じdocker-composeで作成していないサービスでもリバースプロキシの傘下に入ることが出来ます。別プロジェクトのdocker-composeでは、外部参照のネットワークとしてsharedを定義しておきます。

networks:
  default:
    external:
      name: shared

当サイトの他のサービス(djangoサイト、wordpress、rainloop WEBメール、nextcloud)は全てこの方法でリバースプロキシ傘下に入っています。

certbotも入れたので、次はletsencryptでの認証関連の設定となりますが、今回は割愛しています。jwilder/nginx-proxyではお手軽な方法が用意されているので、letsencrypt用の起動スクリプトも含めて次回のメモ記事で紹介します。

docker環境も整って勉強や実験も一段落してきたので、そろそろブログネタの方向性も(趣味的な方向へ)変えていきたいなと思うのですが、コロナとか自粛モードでなかなかネタ集めが出来ないですねー(言い訳
・・・・まぁこのへんのネタもじゅーーーぶんに趣味的ではあるけど。

docker対応ufw(iptabels)設定の件

ここでdockerについての解説をするのはおこがましいので、下記に覚え書きリンクを貼付ける

ローカルLAN環境でWEBサーバーを運用するだけなら良いが、当サイトにdockerを導入するに当たって一番の懸念事項がファイアウォールとの相性問題があった。

当サイトと同じUbuntu20.04LTSで下記のようなファイアウォール設定であったとして

xxxx@user$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
80/tcp                     ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere
80/tcp (v6)                ALLOW       Anywhere (v6)
443/tcp (v6)               ALLOW       Anywhere (v6)

dockerコンテナで8080ポートでwebサイトを立ち上げると、ファイアウォールをするりと抜けて外部に公開できてしまう(下記テキトウdocker-compose.yml)

web:
  image: nginx
  volumes:
   - ./templates:/etc/nginx/templates
  ports:
   - "8080:80"
  environment:
   - NGINX_HOST=foobar.com
   - NGINX_PORT=80

当サイトではufwファイアウォールの運用で特定IPアドレスからのアクセスを遮断している(メールサーバへの不正アクセスやwordpressへの不正ログイン試行を手動・自動で監視して遮断対象アドレスをリストアップ)。

ufwコマンドで設定するポートアクセス許可よりも前で設定するために、/etc/ufw/before.rules に記載のあるチェインufw-before-inputにログ出力と遮断コマンドを追加している。

# blacklist-ipset-S ここにブロック対象のアドレスを追加
-A ufw-before-input -s xxx.xxx.xxx.xxx -j auto-blocklist
# blacklist-ipset-S

# タグをつけたログを残してドロップさせるチェイン
# ファイルの先頭の*filter節に追加する必要あり?
-A auto-blocklist -j LOG --log-prefix "[BLOCKLIST]"
-A auto-blocklist -j DROP

こうすることでufw起動時にiptableの遮断リストが設定される。

しかし、上記のdockerコンテナはこの設定も効かず、遮断対象アドレスも通過してしまう。

そこで、まずdockerコンテナが何故ufwの設定を無視できるのかを調べてみる。(iptableコマンド)

user@server:~$ sudo iptables -nvL
Chain INPUT (policy DROP 2979 packets, 152K bytes)
 pkts bytes target     prot opt in     out     source               destination
3687K 3750M ufw-before-logging-input  all  --  *      *       0.0.0.0/0            0.0.0.0/0
3687K 3750M ufw-before-input  all  --  *      *       0.0.0.0/0            0.0.0.0/0
83453 4149K ufw-after-input  all  --  *      *       0.0.0.0/0            0.0.0.0/0
77337 3836K ufw-after-logging-input  all  --  *      *       0.0.0.0/0            0.0.0.0/0
77337 3836K ufw-reject-input  all  --  *      *       0.0.0.0/0            0.0.0.0/0
77337 3836K ufw-track-input  all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
4406K 5775M DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0
4406K 5775M DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0
3634K 4639M ACCEPT     all  --  *      br-a52db8fb2804  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
80854 4814K DOCKER     all  --  *      br-a52db8fb2804  0.0.0.0/0            0.0.0.0/0
 675K 1102M ACCEPT     all  --  br-a52db8fb2804 !br-a52db8fb2804  0.0.0.0/0            0.0.0.0/0
70296 4218K ACCEPT     all  --  br-a52db8fb2804 br-a52db8fb2804  0.0.0.0/0            0.0.0.0/0
71973  318M ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0
54110 3031K ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0
    0     0 ufw-before-logging-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 ufw-before-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 ufw-after-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 ufw-after-logging-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 ufw-reject-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 ufw-track-forward  all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 4 packets, 196 bytes)
 pkts bytes target     prot opt in     out     source               destination
3574K 2258M ufw-before-logging-output  all  --  *      *       0.0.0.0/0            0.0.0.0/0
3574K 2258M ufw-before-output  all  --  *      *       0.0.0.0/0            0.0.0.0/0
27893 2070K ufw-after-output  all  --  *      *       0.0.0.0/0            0.0.0.0/0
27893 2070K ufw-after-logging-output  all  --  *      *       0.0.0.0/0            0.0.0.0/0
27893 2070K ufw-reject-output  all  --  *      *       0.0.0.0/0            0.0.0.0/0
27893 2070K ufw-track-output  all  --  *      *       0.0.0.0/0            0.0.0.0/0

この辺りもこのために改めて勉強したため、理解不足かも知れないが、、、

普通にufwで設定するファイアウォールはINPUTチェインが主で、5行目のufw-before-inputのチェインから繋がっている(当サイトのアクセス遮断リストもここに繋げている)。それに対してdockerのファイアウォールはFORWARDチェインであり、16,20行目のDOCKERチェインでコンテナで設定したポートの待ち受けを実現している。それはufwのFORWARD設定よりも優先しているので、アクセス制限はそれよりも前で行う必要がある。ここでアレ?と思うのがDOCKERチェインよりも前にあるDOCKER-USERチェイン。このチェインの中身は空白で何もせずに帰ってくる仕組み。

ならば、ここに遮断リストを追加してやれば良いんじゃね?という感じで、

$ sudo iptables -A DOCKER-USER -s xxx.xxx.xxx.xxx -j DROP

としてみたら、無事遮断していることを確認(とりあえずスマホのIPアドレスを遮断してみて確認)。

実は英文の方のdocker docsにはそれっぽいことが書いてあった。。

次に問題はこのリストを起動時に読み込ませるにはだけど、これは何のことはなくufwの助けが借りられることが分かった。先の遮断リストをログ出力しつつDROPするチェインを追加した要領でDOCKER-USERチェインも/etc/ufw/before.rulesに記載してしまおうという思いつきで実験、、上手く動作したので下記に示します。

$ sudo cat /etc/ufw/before.rules
# Don't delete these required lines, otherwise there will be errors
# added for docker access limits. 21/08/17 by mamiyan
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
:DOCKER-USER - [0:0]           # <---- これ追加
:auto-blocklist - [0:0]        # <---- ログ出力&DROP処理用チェイン
:docker-blocklist - [0:0]      # <---- 同上
# End required lines

・・・・・
# for blocklist custon chain 追加チェイン
-A auto-blocklist -j LOG --log-prefix "[DROPLIST]"
-A auto-blocklist -j DROP

# for docker custom chain 追加チェイン
-A docker-blocklist -j LOG --log-prefix "[DROPDOCKER]"
-A docker-blocklist -j DROP

# blacklist-ipset-S ここから
-A ufw-before-input -s xxx.xxx.xxx.xxx -j auto-blocklist
-A DOCKER-USER -s xxx.xxx.xxx.xxx -j docker-blocklist
# blacklist-ipset-E ここまでにリスト追記

24行25行のように二つのチェイン向けに遮断アドレスリストを追記して、$ sudo ufw reload でdocker向けのファイアウォールが設定されます。その他のアクセス制限もこの/etc/ufw/before.rules の DOCKER-USERチェインに記載しておけば良いと思います。

この辺りは、ufwを少し触れる程度の知識からiptableの仕組みとチェインを触れる程度までじっくり勉強が出来て良かったと思います。またここでCentOSとかのRHL系でfirewalldとかになると変ってくるのだろうか。そもそもあちら側は相性問題は無いのかな。

docker環境への移行

約一ヶ月ぶりの記事になりますが、夏休みということで。

この夏休みは、雨続きやら新型コロナの蔓延防止やら緊急事態やらの巣ごもりで、夏バテと闘いながら、従来から引続きpython(django)、javascript(Three.js)勉強行いながら、前回の記事でチラッと書いたdockerの勉強・実装実験を行っておりました。もともろvmwareやら仮想環境に興味があったので、比較的敷居が低かった感じで、いろいろ試しているウチに勢い余って、当サイトのWEB環境もApache2の仮想ホスト環境から、dockerコンテナのブリッジネットワーク構成に移行させてしまったというお話。さらにはメールサーバーもdockerコンテナ化・・・8月中に一通り移行を終えたところで一息ついている感じです。

とっかかりは楽しくて次々とdocker化が進んでいったが、やっぱり全く同じ環境を再現しようとすると色々と問題が出てきたり、ネット調査だけでは答えの出ない問題に突き当たったりとネタだけは貯えたので、覚え書きレベルですが追々と記事にして置こうかと思います。

つい今の今も、この記事を書こうとwordpress(これもdockerコンテナ化済み)の記事編集をしていたところ、メディアファイルがアップロード出来ない問題が発生(移行時に試していないのがいけない・・・)。半日がかりの原因究明でしたが、結局はアップロードパスの修正忘れという単純なポカミス。。まぁdockerという新しい環境への移行なので、まずそちら方面を疑ってしまい、思わぬ深みにはまってしまうというよくある罠でした。

今回の移行ですが、従来構成を下記に示す。普通のubuntuのままなのでapache単独サーバーでvhost.confの設定で仮想ホストを構成していた。

従来構成

同様の環境をdockerリバースプロキシ環境に移行した構成を下記に示します。

移行後のdocker構成

dockerブリッジネットワークでほぼ全てのサービスをコンテナ化してリバースプロキシサーバにて80番ポートと443番ポートを受けて文字通りの仮想ホスト構成としている。メールサーバーは受信のために25番ポートを空けているが、こちらは図のように直接外に向けてポートを空けてしまうと、ホスト内のサービスメール(cronやlogwatchなど)が動作しなくなってしまうので、実際はホスト側でもpostfixを動作させホスト内メールの面倒を見ながら外部から来たメールはコンテナのメールサーバーに転送する仕組みとしている。

一ヶ月の試行錯誤の結果ほぼ従来通りの動作を確認できたが、なんか妙に重いかも知れない。。。

久々のブログ記事でいきなりファイルアップロード不可とか、メッチャ焦りました。新環境では十分なテストが必要ですね。メールサーバーのdocker化もテキトウに確認して運用始めては→問題発覚→環境戻し→デバッグやり直し-の繰返しでした。たいていはショウモナイポカミスなんですが、そういうのに限って見つけるのに半日から1日作業となるのが定期。

Three.jsによる3Dオブジェクト表示

Three.js +Orbitcontrol.js + GLTFLoader.js を使用。モデルはFFXImodelviewer2を使用してmqo形式で取り出してBlenderにて明るさ調整をしつつglbで出力、WEBアプリにて表示している

FF11をやっていた頃の自キャラっぽいモデル。サンプル用だけど一応コピーライト表示しておきますが、不味かったら消します。

少し時間が空いてしまったが、自サイト構築としてdjangoによるポータルの仕組みがある程度出来てきたところで、次はフロント側の勉強をしておりました。

フロント側はjavascriptになるため、ローカル環境で試しながら少しずつ勉強をしてきた。

今回はポータル側のdjangoアプリから埋込みサービスを作成して、こちらのwordpressで表示するテストを行った。

iframeタグにてポータル側のURLを指定してjavascriptのThress.jsライブラリを用いてWEBGL用フォーマットglTFの3Dオブジェクトを表示させている。

wordpressの方をもう少し勉強すれば埋め込みを使用せず、直接javascriptのプラグインを作ってしまえるのだが、それはまたいずれということで、まずはここまで勉強した成果を残すことを優先しました。

いずれ3Dオブジェクトをリアルタイムに操作してサーバー側とのやりとりをしながらのアプリ作成を目論んでこういう仕組みとしてみたということで。。。

このキャラです。同じ帽子を被せたかったのですが、モデルに帽子を被せるとポニーテールが飛び出してしまったので今回は無しで。。。

Windows Terminal

しばらく最新の動向とか触れる機会が少なかったので、最近のツール事情にはいまだに驚かされたりする。当方では趣味でさくらVPSに契約して個人用のサイトを運営をしており、当たり前だが自宅のローカル環境から操作している。今までは通信ソフトのPuttyでサーバーにSSH接続して、サーバー上でemacsなどのエディタで構築作業をおこなっていたが、前回の投稿で書いたようにマイクロソフトのVScodeエディタでSSH接続することでローカル同じ環境で編集作業を行なうことが出来る。

それでも実際ターミナル操作をするときはPuttyを使用していたのだが、今度はWindows Terminalというものを知ることとなる。こちらはWindowsのストアアプリで、コマンドプロンプトからPowershell、WSLも対応しており、プロファイルを追加することでssh接続も可能となる優れもの。

しかもこちらはWindows版のOpenSSHのサービスで動いているので、SSH-Agentサービス(Windowsサービスで自動実行)ログイン時にパスフレーズを入れる必要もないので便利。

ローカル作業時も任意のフォルダで右クリックすると「Windowsターミナルで開く」のメニューが追加されており、Powershellが起動するようになる。(これは、以前よりシフトを押しながら右クリックでPowershellで開くことが可能だったが)

ということで、これも何かあったときのための覚え書き。

VScodeの件もそうだけど、今までは何だったのか?!ってくらい超便利な感じで、きっとまだ触っていないDockerやなんかも同じように感動するんだろうな、、、、と思いつつも、なんだかね。こんなすごい複雑なシステムの開発環境を使って、作っているものと言えば、趣味のオモチャ程度・・・。超豪華な財布の中に2000円くらいしかい入ってない感じw
精進せねばと思うこのごろ。。。

Bootstrap5対応その他

という記事を書こうとWorpressダッシュボードに移動したら、いつのまにかWordpressが5.8にバージョンアップしていた。例によってDBバックアップを取れとの忠告も聞かずに、速攻アップデートボタンポチり。

特に変った様子もないが、変化点は追々チェックするとしよう。

でBootsrtap5対応だが、先月辺りまでのこのサイトの引越作業の時点でベータ版が存在していたが、あまり気にしていなかったところ、ポータルサイト構築を兼ねたWEBアプリ開発の勉強がてら色々調べていたところバージョン5のリリースを知った(今ごろですが)。機能的にはあまり差は無い(というかよく読んでいない)がJQuery依存の削除やIEなど古いブラウザサポート終了など良い感じのアップデートのようなので、まずはdjangoテストサーバー環境で導入実験を行ない、ある程度問題ないことを確認したところで主ブランチに統合して本番環境のポータルサイトでも採用することとした。

見た目はあまり変らないが、テーマのデフォルトの文字サイズなどが異なるため、若干文字が小さかったり、メニューの文字が太字だったりと細かな気にならない違いが見られた。

4.5から5への対応に関する変更点であるが、前回までのSass導入でHTML(テンプレート)にBootstrapのクラスタグを直接書くことは少なくなったので、基本的には階層構造のスタイル定義をしているSassソースファイルを修正することで対応した。

主な違いは、marginやpaddingを表現するクラスで、たとえば右マージンはmr、左マージンはmlというようにrightとleftの頭文字で表現していたが、バージョン5より、左がstart、右がendと表現するようになりそれぞれマージンとしてはms、meと表記するようになった。これはおそらく多言語対応でRTL(右から書く文化)にも対応する事により水平方向の表記は右からと左からというより、始めと終わりという意味で統一したのだろう。

あとハマったのはアコーディオン型のメニューアニメーションの件で、若干名称が異なり、

  • data-toggle → data-bs-toggle
  • data-target → data-bs-target

になっていた。当サイトはこの位しか機能を使っていないので、以上の修正で無事以前と同様に動作するようになった。

というか、せっかくBootstrap5を導入したのに、新機能を調べて(あるのか?)導入実験とかしたいのだが、他にもいろいろやりたいことありで、なかなか優先順位に困っているところ・・・
思いつき順ということもありますが・・・