建設予定地

当面はやったことの備忘録

就活を振り返る

はじめに

ご縁があり、来春から合同会社DMM.comに新卒で入社させていただくことになりました。

色んな気持ちの整理をする上で、何か後に残せるものがあればと思い、少しだけ自分の就活の振り返りをしてみます。

4月~11月

就活をふんわりと意識し始めたのは昨年の春先、当時インターン先でお世話になった方から就職活動のお話を聞いたことがきっかけです。

当時はベンチャーとメガベンチャーの違いすらふんわりとしかわかっておらず、エンジニア業界を知るためにサポーターズさんのエンジニアEXPOなどに参加して、「世の中には色々な企業があるんだなぁ」と思うようになりました。

もともと「好きなこと=技術で食べていきたい」という気持ちがあったので、業種はエンジニア一本で、業界はtoCのWeb系を中心に見ていました。

事業領域へのこだわりはなく、ユーザーのフィードバックがダイレクトに得られやすいサービスのものづくりに関わる一からそのようなサービス(事業)を立ち上げるという経験がしてみたかったので、なるべく事業領域は広く見て、裁量権(若手の能動的な提案が通りやすいか)・成長環境(仕事へのモチベーションの高い人やプライベートなどでも対外的な技術発信をしている人が多いと嬉しい)という部分も強く意識していました。

秋は短期インターンに参加し、懇親会で同じ23卒の方から就活のエピソードを聞いたり、大学の先輩に就職相談に乗っていただいたり、逆求人イベントに参加してみたり、慣れないなりに「就職活動」に向き合っていたのがこの時期でした。

12月~3月

年明け後は再スタートを切って、徹底的に自分と向き合う時間を作りました。
色んな方に相談に乗っていただいて、うまく言語化し尽せていなかったものを言語化する(人に話したり、文字で書き留めてみる)ことををしていました。

細々と続けていた就活も、なんとなく「そろそろなのかな」と思い出したのが年明けの2月頃でした。
その後は2社内定、2社辞退、2社落ちみたいな結果です。

今の会社さんに内定承諾を決めたのは、面接中に感じた「会話の居心地の良さ」が大きいです。
さらに実際に内定をいただいて、「好奇心が強く、気になったらなんでも飛び込んでやってみたい」と思う自分の性格に会社自体の方向性がマッチしていて、思い描いてきたビジョンが「ここでなら実現できそう」という確信が、自分の中にストンと落ちたのが一番の理由です。
扱っているサービスの内容や関われる技術領域の広さからも、「もし万が一この会社を辞めた後も、ここに新卒で入社して経験できることが生涯(エンジニアとしての)自分の糧になるだろう」と強く思えたことが大きかったです。

内定承諾までの期間、就職活動を続けるべきか悩みました。
最後に検討していた3社の企業さんはいずれも志望度がとても高く、相性の良さを感じていたので、「選択しなければいけない」事実に向き合う苦痛を感じました。

就活を終える決意を固め、それまでずっと志望度が高く、年明け前から第一志望で目指し続けてきて、採用人事の方や社員の方に沢山お世話になったA社の選考を辞退するのは、特に胃とメンタルに来るものがありました。

所感など

GitHubやブログ、ポートフォリオサイトなどは体感見てくれている企業さんが多かったです。

エンジニアの方と自分の作ったプロダクトや互いの好きな技術の話をする時間は楽しかったですし、面接の中でも学びが多かったので、結果的にこういった技術発信は(エンジニア就活においては)大切だと感じます。

面接中では自分の感情や考えを言語化して説明する(暗黙知を限界まで削ぎ落す)能力が求められますが、ハッカソンでのチーム開発の経験や、実際に制作したプロダクトでの苦労話は素直な気持ちで伝えやすかったように思えました。

おわりに

就職活動で得た気づきは、たとえ回り道になっても、「周りの人に相談してみる」というのがめちゃくちゃ大切だな、ということです。

就活中はひたすら自分と対峙し続けることになるので、自己肯定感を保ち続けることが難しかったり、漠然とした不安から視野が狭くなりがちでした。
そんな中、客観的な意見やアドバイスをしてくれる人たちの存在は本当に大きいです。

その上で何が自分の人生にとって最良の選択なのかを考え、最後に決断を下すのは自分ですが、抱え込まずに立ち止まっていろんな人に相談してみるのは大切なことだなぁと思いました。

振り返ると、ここに至るまでお世話になった方々への御恩は本当にはかりしれません。

つらつらと書いてしまいましたが、最後まで読んでいただきありがとうございました。

コープさっぽろのインターンシップで学んだこと

はじめに

こんにちは!この記事はコープさっぽろ オープン社内報 Advent Calendar 2021の19日目の記事です。

adventar.org

昨年の12月から、ご縁がありコープさっぽろさんのエンジニアリングチームインターンシップをさせていただいております。
こうしてアドベントカレンダーに寄稿する機会をいただいたため、一年間のインターンの中で僕が学んだことを振り返っていきたいと思います。

一年間で学んだこと

Git/GitHub

技術的なところだと実はかなり大きいです。
コミット単位やPRの粒度に関心をはらうことだったり、レビュアーを意識したPRの作り方であったりなど、チーム開発で考えるべき多くを学ばせていただきました。
PRの粒度については、お世話になっているエンジニアの方がおっしゃっていた『意義のある一番小さい形』という言葉が非常に印象深かったです。

git一つをとっても、rebasestashの使い方に始まり、覚えたコマンドの数ははかりしれません...。

現場の強いエンジニアの方にアドバイスをいただいたり、コードレビューをしていただけるような環境は、本当に学びしかありません。

現場の技術

Vue.jsやAWSなど多くのモダンな技術の開発現場に関わらせていただく機会があり、学生のうちに現場の技術をキャッチアップできる経験をさせていただけるのは本当にありがたいです。
業務の中でVue.jsのテストコードを書かせていただいていると、"コードを書く"時間より"読む"時間の方が多いと感じます。
よく「コーディングを上達させるには(他者の)コードを読むといい」と言われますが、実際に運用されているコードを読み解くことで得られる学びは非常に大きいと感じます。
例えばVuexのような状態管理パターンは個人の小規模開発では意識する場面が少なく、常々勉強させていただいています。

ドキュメントを残すことの大切さ

これは普段、ドキュメントベースでお仕事をさせていただくことで、とても大切にするようになりました。
リモートでのコミュニケーションは特に、SlackやGitHubなどにおける文字ベースのやり取りが主体になります。
ふんわりと考えていることを文字に起こすということは、意外と難しいのだなと多々感じます。

しかし一方で、コンテキストをドキュメントに残すことは齟齬を生じにくくさせてくれます。

自分が考えていることや、相手の考えを咀嚼したことを言語化し、何らかのドキュメントという形に残すことは、僕自身ここ一年の日常のあれこれやチーム開発の中で意識して取り入れていることでもあります。

人とかかわること

コープさっぽろで多くのエンジニアの方々と関わらせていただいていて、高い技術力はさることながら、物腰の柔らかい優しい方が多いと感じています。
チーム開発で大切にすべき観点として、いわゆる"心理的安全性"であったり、"HRTの法則"のような考え方がありますが、Slackでのやり取りはPRレビュー一つをとっても、皆さんからこうした人間力の高さをとてもよく感じます。

またこのようなエンジニアの方と会話をしたり、その考え方を聞いたりする中で、僕自身の技術や人との向き合い方にも変化があったと感じています。

普段の業務の相談はもちろん、個人的な研究室配属の相談にも乗っていただいたり、皆さん本当にお優しいです。いつもありがとうございます。

最後に

一年間のインターンシップを通じて、関わっていただいた皆さんから多くのものをいただいているけれど、逆に自分が皆さんに還元できることはなんだろうかと、常々考えています。

僕自身まだまだ未熟ですが、いただいた学びを還元していけるように頑張っていきたいです...!!

ElectronでセキュアなIPC通信を実装する

はじめに

こんにちは!0yu(@denham95173179)です。
この記事はLOCAL Students Advent Calendar 2021への寄稿です。
adventar.org

先日、 SC4Y ('21#4) IT・情報系 北海道まったりLT大会に登壇させていただき、最近細々とElectronで作っているマークダウンエディタについてお話してきました。
sc4y.connpass.com

GitHubはこちら
github.com

今回の実装でやりたかったことは以下のようなことでした。

  • レンダラープロセスからのファイル操作を実装する
  • Electronでファイル操作を扱うdialogモジュールをレンダラプロセス側からIPC通信で呼び出す
  • Node.jsによるファイルの読み書きをレンダラープロセス側で行なう

Electron13まではremoteモジュールを採用したプロセス間通信が可能でしたが、remoteモジュール*1に依存しないセキュアなIPC通信を実装したいというのが本記事の趣旨です。

何が問題なのか

remoteモジュールの削除は、破壊的変更としてElectron14から完全に削除されてしまいました。 www.electronjs.org

remoteモジュールに依存せず、レンダラープロセス側でCommonJSを記述できるようにするためには、nodeIntegrationtrueにする必要があります。
しかしながら、レンダラープロセス側からNode.jsを扱うことは本来非推奨とされてします。

// background.ts
const mainWindow = new BrowserWindow({
  webPreferences: {
    nodeIntegration: true,
    nodeIntegrationInWorker: true
  }
})
  
mainWindow.loadURL('https://example.com')

Electronでは、 セキュリティ推奨事項​のチェックリストが公式ドキュメントに記載されており、チェックリスト中の2) Do not enable Node.js Integration for Remote Contentにこれが当たります。

This recommendation is the default behavior in Electron since 5.0.0.

It is paramount that you do not enable Node.js integration in any renderer (BrowserWindow, BrowserView, or ) that loads remote content. The goal is to limit the powers you grant to remote content, thus making it dramatically more difficult for an attacker to harm your users should they gain the ability to execute JavaScript on your website.

After this, you can grant additional permissions for specific hosts. For example, if you are opening a BrowserWindow pointed at > https://example.com/, you can give that website exactly the abilities it needs, but no more.

これはなぜかというと、ブラウザ側(レンダラープロセス)でNode.jsのAPIを扱うメインプロセス側の処理を行なえるということは、例えばXSS攻撃を受けたとき、ユーザーのローカルファイルに無制限にアクセスされてしまうリスクがあるためです。
zenn.dev

このようなリスクを未然に防ぐために、安全なプロセス間通信を行うことが推奨されています。
すなわちremoteモジュールの削除された現行バージョンのElectronで、nodeIntegrationを無効にしたIPC通信を行う必要が生じます。

じゃあどうすればいいの?

ここで行なうべきことは大きく以下のようになります。

  • background.tsでnodeIntegrationを無効にする(レンダラープロセス側からのNode.jsモジュールの操作を無効にする)
  • background.tsでcontextBridgeを有効にする(コンテキストの分離*2

※ Electron16 + Vue3 + TypeScriptを想定

background.tsのnodeIntegrationを無効にします。

// background.ts
const mainWindow = new BrowserWindow({
  webPreferences: {
       + nodeIntegration: false,
       + preload: path.join(__dirname, 'preload.js')
  }
})

mainWindow.loadURL('https://example.com')

またここで、ビルド段階でpreloadのパスを読ませるため、vue.config.jsに下記のように記述します。

// vue.config.js
module.exports = {
  pluginOptions: {
    electronBuilder: {
       + preload: 'src/preload.js',
    }
  }
}

srcディレクトリ直下にpreload.tsを作成し、以下のように記述します。
これによってpreload.tsは、グローバルなwindowオブジェクトをレンダラーと共有できるようになります。

// preload.ts
const { contextBridge } = require('electron')
  
contextBridge.exposeInMainWorld('electronAPI', {
  loadPreferences: () => ipcRenderer.invoke('load-prefs')
})
// Main.vue
window.electronAPI.loadPreferences()
// ここでwindow.electronAPI.hogehoge()などする

次にrenderer.d.tsを作成し、以下のように記述することで、Windowインターフェースの拡張を行うことができます。

export interface IElectronAPI {
  loadPreferences: () => Promise<void>,
}

declare global {
  interface Window {
    electronAPI: IElectronAPI
  }
}

以上のようにすることで、レンダラープロセス側でスクリプトを書く際に、グローバルなwindowオブジェクトにアクセスできるようになります。

フォルダ構造は下記のようになっています。

├── dist_electron/
│ ├── bundled/..  # where webpack outputs compiled files
│ ├── [target platform]-unpacked/..  # unpacked Electron app (main app and supporting files)
│ ├── [application name] setup [version].[target binary (exe|dmg|rpm...)]  # installer for Electron app
│ ├── index.js  # compiled background file used for electron:serve
│ └── ...
├── public/  # Files placed here will be available through __static or process.env.BASE_URL
├── src/
│ ├── background.[js|ts]  # electron entry file (for Electron's main process)
│ ├── [main|index].[js|ts]  # your app's entry file (for Electron's render process)
│ └── ...
├── package.json  # your app's package.json file
├── ...

おわりに

ファイル操作の実装の詳細や、contextBridgeの中身について深堀った記事を(余力があれば)かきたいです。

参考文献

www.electronjs.org github.com zenn.dev

*1:レンダラプロセスからメインプロセスが持つ機能を扱うためのモジュール.12.0で非推奨となり、14.0で完全に削除された

*2:コンテキストの分離はElectron12からデフォルト値で有効となっており、現行で推奨されているセキュリティ設定です

ハッカソン飯と一緒に今年を振り返る

こんにちは!
この記事はcistLT Advent Calendar 2021 への寄稿です。
adventar.org

今年はハッカソン/インターンなどでのオンライン懇親会に参加させていただく機会が多く、ノンピさんのご飯にとてもお世話になりました。

nonpi-foodbox.com

一人暮らしの地方学生にとって、このようなご飯ほどありがたいものはないです。

というわけで今回は、各ハッカソン/インターンでお世話になった方々とノンピさんのご飯への感謝の気持ちをこめて、飯レポをしながら振り返りをしたいと思います。

DeNAオータムハッカソン

これが僕とノンピさんとの最初の出会いでした。(なんかいい感じのBGM)

ハッカソンとしては、いくつかお題が課され、その中から課題解決に取り組みたいテーマを選定してプロダクトを開発するというものでした。
僕たちのチームでは、「運動不足を解消する」という課題解決をテーマに、歩いた軌跡(トラックログ)で囲まれた領域にいるユーザーの数だけポイントをゲットして競う地図ゲームを考案しました。
github.com

技術的にはクライアントサイドはVue.js(Vuetify)/TypeScript、サーバーサイドはPython(Flask)/SQL Alchemy/MySQLといった構成で、僕はもう一名のチームの方とクライアントサイドを担当しました。
今回は位置情報を扱うプロダクトということで、地図ライブラリのLeafletを初めて触りました。
強くて優しいチームメンバーの方々とメンターさんに本当にたくさん助けていただきました。
アイディア出しから技術面に至るまで、とても学びの多いハッカソンでした。

f:id:denham:20211211094315j:plain
nonpi_DeNA

このときのノンピさんのご飯は「スタンダードプラン 洋」でした。
柔らかいお肉とトマトチーズリゾットがとてもおいしかった。

ノベルティもいただきました。IT系のイベントはたくさんノベルティがもらえてうれしいですね。

JPHACKS

兼ねてから興味のあったJPHACKSに野良で初参戦しました。
JPHACKSでは、野良で参加した場合はランダムで4名1組のチームが組まれるのですが、このときはチームの方が持ち寄ってくださったプロダクトに関わらせていただきました。
github.com フロントエンドの改修に当たらせていただき、ここの1週間はほぼずっとCSSとVuetifyと戦っていました。

このときのノンピさんのご飯はメニュー名を特定できませんでした。
知っている方はこっそり教えてください。

f:id:denham:20211211102340j:plain
nonpi-jphacks
洋風おつまみという感じの上品なラインナップでした。プリンおいしかった!
お肉はやはり柔らかくておいしいです。
懇親会では、都道府県の形当てや寿司打のお話で盛り上がりました。
チームメンバーの方々の温かさに感謝です。

東京ガスiネットハッカソン

Athleticsさんの逆求人イベントに参加したご縁でお声がけいただき、参加したハッカソンです。
節約術と自分だけの地図をマッチングするモバイルアプリです。
仕様技術はFlutterです。
github.com 実はチームメンバーほぼ全員がFlutter未経験というチャレンジングなプロダクトでした。皆で頑張りました。
(自分を含めて多くの方が苦労されているのを見て、Flutter/Android Studioエミュレータ環境構築は鬼門だなぁと思いました)
プロダクトとしては惜しくも完成には至りませんでしたが、わくわくさせられるアイディアのもと、チームメンバーの方がAdobeXDでとても素敵なモックデザインを作ってくださいました。
僕自身、Flutterは環境構築に毛を生やしたくらいの経験値で、なかなか実装面で貢献することができなかったのですが、開発そのものは睡眠を忘れるくらい楽しかったです。
強くなりたい。

f:id:denham:20211211111556j:plain
nonpi-tginet
このときのノンピさんのご飯は「居酒屋プラン(炙りしめ鯖) ノメルズ ハードレモネード サワー!サワー!サワー!付【期間限定】」でした。
ビール+チューハイのアソートセット+レモネードサワーと炙りしめ鯖の相性が絶品です。そしてホクホクの大学いもがおいしい。
懇親会では、同じ23卒の皆さんから色々な就活トークが聞けてよい刺激をいただけました。
就活、つらいけど頑張ろう。

CA 1Day Youth Boot Camp

www.cyberagent.co.jp 愛読している実践Rustプログラミング入門の著者であるyukiさんのハンズオンでした。
Rustの言語的な特徴や基本的な文法についてじっくりと解説していただいた後、実践編としてgrepコマンドを実装してみる、という熱々な内容でした。

rustcの丁寧なエラーメッセージがどんな風に実装されているのか、中身を読んでみると面白いですよ、といった余談も印象深かったです。

懇親会では、CAのエンジニアの方からスノーフレークが熱いというお話や、個人的に気になっていたフロントエンドの設計思考やデザインパターンのお話(リアクティブシステムとObserverパターンのお話など。勉強になりました。)を伺うことができて楽しかったです。

f:id:denham:20211211095737j:plain
nonpi_CA1
このときのノンピさんのご飯は神田明神下みやび 冬の味覚プラン」でした。
Rustといえばかに飯ですね🦀
ふわふわの煮物もみかんもちもおいしかった。

最後になりますが改めて、ご縁のあったすべての皆さんに感謝です。

Assertion `thread_id_key != 0x7777' failed.(node-fibersのエラー)について

前提

  • Node.jsのパッケージ管理をn packageで行いたい

  • 事前に n packageがインストール済みであること

n packageの環境構築については下記の記事が詳細にまとめてくださっています。
Ubuntuに最新のNode.jsを難なくインストールする - Qiita

環境

Ubuntu20.04LTS(WSL2)
yarn + Vue CLI

問題

yarn serve

を行った際、下記のようなエラーが出る

node: ../src/coroutine.cc:134: void* find_thread_id_key(void*): Assertion `thread_id_key != 0x7777' failed.
Aborted
error Command failed with exit code 134.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

原因

fiberというパッケージがnode16に未対応であるため

stackoverflow.com

対策

  • nodeのバージョンを16以下にダウングレードする

行った手順

ダウングレードを前述のn packageを用いて行うものとします。
まずはn [バージョン名] でバージョンの切り替えを行います。

$ sudo n 14.17.6
   installed : v14.17.6 (with npm 6.14.15)
$ node -v

で更新が反映されているかを確認します。(v14.17.6となっていればOK)

自分の場合はここでバージョンが反映されていなかったため

$ which node

してみると下記のようになっており、nvmのnodeを読んでいることがわかりました。

/home/denham/.nvm/versions/node/v16.6.1/bin/node

ここではnodeのバージョン管理をn packageで行えるようにしたいので、

$ sudo vim  ~/.bashrc

して下記の記述を削除あるいはコメントアウト

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

nvmフォルダを削除し、

rm -rf ~/.nvm

.bashrcの変更を反映

$ source ~/.bashrc
node -v
v14.17.6  

となっており、nodeがダウングレードされていることが確認できました。
ここで再度yarn serveを行えばOK。

参考

stackoverflow.com qiita.com

Windows10のデスクトップをMacっぽくするTips

何が嬉しいか

WindowsMacごっこができます。

MacっぽいGUIの構成要素

下記の3つでそれっぽい見た目が作れそう。

  • ドック
  • タスクバー
  • フォント
ドック

DockはRocketDockというソフトを使っています。 アイテムはファイルやパス単位で指定したり、ドロップアンドドロップで自由に追加/削除できるので、直感的で使い勝手はよさそう。 スタイルのテーマはCrystalXP.netに設定。 punklabs.com

フォント

フォントはMacTypeを使っています。 www.mactype.net

MacTypeは他ソフトとの競合が起こりやすいようで、Windowsアップデートの際にはいったん停止させた方がよさそうとのこと。 インストール時の設定は、プロファイルの切り替えはできないものの、タスクトレイで起動/停止が操作可能であるMacTrayロード/互換性重視モードに設定しています。

[参考] fmoga.com

タスクバー

上部に固定+小さいタスクバーボタンを使用+タイトルバーとウィンドウに境界線(お好みで) に設定しています。 タスクバーを透過させるには [Ctrl]+[R]→regeditでレジストリエディタを起動し

コンピューター\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo

で新規→[DWORD(32ビット)]→キーの名前を「UseOLEDTaskbarTransparency」にし作成
- 「UseOLEDTaskbarTransparency」を開き、「値のデータ」を2に設定し保存(この値が大きいほど透過度が上がる。2だと完全に透過されます)
個人用設定で「色」を選択→「透明効果」をオンにする

個人的には、タスクバーは上部に配置した方がデスクトップの一覧性は高まると感じました。

タッチパッドの2本指スクロールなども高精細タッチパッドを搭載した一部機種では再現可能なよう。
自分の環境では残念ながら再現不可能でした。

結びに

上記の手順で、このようにぱっと見MacWindowsデスクトップが作れました。
Windows10ProのコピーライトとMacTypeコントラストにイシュカン・コミュニケーションみがあります。

f:id:denham:20210830005812p:plain

参考文献

auramorte.com

blog.munieru.jp

WSL2でsystemctlを使えるようにする

環境

WSL2 ubuntu 18.04LTS

経緯

flutterをgit cloneして動かすとなぜか構文エラーで怒られるので(ホストのWindows/WSL2いずれの場合でも)、snapでインストールすることにした。
以下に従って

$ sudo apt update  
  sudo apt install snapd  
$ sudo snap install flutter --classic  

をする。
snapcraft.io

が、

$ sudo snap install flutter --classic  
  error: cannot communicate with server: Post http://localhost/v2/snaps/flutter: dial unix /run/snapd.socket: connect: no such dile or directory

sanpコマンドが動かない。

$ snap --version
snap    2.49.2+18.04
snapd   unavailable
series  -

systemctlでsnapの動作確認をしてみたいところですが、WSLではsystemctlが標準で無効化されており、PID1で動作しない(PID1はinitに付与されている)という問題が。

$ systemctl status snapd.service
  System has not been booted with systemd as init system (PID 1). Can't operate.

initプロセスについて

Linuxシステムでは通常、カーネルによりinitプロセスが起動され、その後initが各Daemonの起動を担い、Linuxシステム上の全てのプロセスはプロセスID = 1 のinitプロセスを親として起動されます。 roy-n-roy.github.io

対処法

genieを利用することでsystemdをPID1で稼働させることができるようになるとのこと。
genieの公式READMEいわく、deamonizedotnet-runtime-3.1のインストールが必要ということなので、まずはこれを導入する必要がありそう。
github.com

$ sudo apt install daemonize

dotnet-runtime-3.1についてはUbuntu に .NET をインストールする - .NET | Microsoft Docsを参考に、 以下のコマンドで.NETパッケージのインスト―ルを行います。

$ sudo apt-get install -y gpg
wget -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget https://packages.microsoft.com/config/ubuntu/{os-version}/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y {dotnet-package}    /* dotnet-sdk-3.1 */

genieをインストールします。

sudo apt update
sudo apt install -y systemd-genie

以下を実行し、systemdをPID1にする

genie -s

vim .bashrcで以下を追記

if [ "`ps -eo pid,cmd | grep systemd | grep -v grep | sort -n -k 1 | awk 'NR==1 { print $1 }'`" != "1" ]; then
  genie -s
fi

こうすることで、実行時にsystemdがPID1でないgenie-sが実行されるようです。

かくして、無事PID1で稼働していることが確認できました。

$ ps aux  
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND  
root         1  0.6  0.1  77736  8808 ?        Ss   11:03   0:01 systemd  
$ sudo snap install flutter --classic
[sudo] password for denham:
2021-06-12T11:06:54+09:00 INFO Waiting for automatic snapd restart...
flutter 0+git.e75662a from Flutter Team✓ installed

snowsystem.net

qiita.com

github.com