お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
言語::C#OS::Linux::Ubuntuジャンル::セットアップ

インストール

https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script

wget https://dot.net/v1/dotnet-install.sh
chmod 755 dotnet-install.sh
./dotnet-install.sh
echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.zshrc
echo 'export PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools' >> ~/.zshrc

Hello world

https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet

dotnet new console -o myapp
dotnet build myapp/myapp.csproj
./myapp/bin/Debug/net6.0/myapp

幾らか詰まった箇所があったので、その備忘録も兼ねて書いておく

前提条件

  • Ubuntu Desktop 20.04.6 LTS -> Ubuntu Desktop 22.04.2 LTS
  • ターゲットは物理マシンでモニタとキーボードは未接続
    • 作業はリモートで実施

実行マシンのスペック

デバイス 製品 諸元
CPU AMD Athlon 200GE 2C4T 3.2GHz Vega3 TDP35W
MEM G.SKILL F4-2666C19D-16GNT DDR4-2666 8GB * 2
SSD Crucial P1 CT500P1SSD8JP NVMe SSD 500GB
ネット回線 フレッツ光ネクストスーパーハイスピードタイプ隼 実効速度 360Mbps

手順

この作業では設定ファイルが勝手に更新されることはない

アップデート方法

事前にSSHを2本立てておくと作業しやすい

  1. SSHの認証鍵がRSA1の場合、ED25519など強力な鍵に置き換えておく
    1. これをしないと再起動後SSHで繋がらなくなる
  2. 次のコマンドを叩く
sudo apt update -y && sudo apt upgrade -y && sudo do-release-upgrade
  1. 続行するのでyを選択。1022への穴あけはしなくて良いが、もう一本SSHを繋いでおくと便利

  2. 設定更新などの作業が発生するため時間は1-2h程度見ておくと良い。問題なければy

    時間に余裕があるかどうかを確認してから進む

  3. <はい>を選択

  4. Dで差分を確認した後、修正の必要があればZで直す。Zを選ぶとシェルが起動し、シェルを終了するとこのダイアログに戻ってくるのでNで進む。また、これは設定ファイルの変更分出てくる

    差分を確認し、修正の必要性を判断しつつ進む

  5. 数時間かかることはないのでy

    まともな回線であればyを選べると思う

  6. 後は放置してれば再起動のダイアログが出てくるので、再起動すれば完了。壁紙がクラゲになるだけかと思ったらDockの位置とかUIが地味に変わっていた
    アップデート後のデスクトップ。クラゲが印象的だ

トラブルシューティング

手順通りやっていれば遭遇しないが、ハマりポイントだったので残しておく

Software Updateでアップグレードできない

日本語表示だと「ソフトウェアの更新」になるが、アップグレードボタンを押してもダイアログが消えるだけで何も起きない

このダイアログは役に立たなかった

これは次のコマンドを叩くことで回避出来る

sudo apt update -y && sudo apt upgrade -y && sudo do-release-upgrade

再起動後にRLoginから接続しようとするとエラーになる

SSH2 User Auth Failure "publickey" Status=0004
Send Disconnect Message...
publickey(ssh-rsa)

上記のエラーが出る場合、SSH認証鍵をRSA1を超える強度のものにする必要がある。XRDPがあればXRDPから復旧できるが、ない場合はモニタとキーボードを繋いでどうにかするしかない

参考までに/var/log/auth.logには以下のログが出る状態

sshd[7330]: userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]

アップグレード所感

セキュリティ面に改善がされているのは良かった(SSHの話)。またGUI周りのパフォーマンスが良くなったのか、キビキビ動くようになった気がする

後はこんなしょぼいスペックも中々ないだろうなというので貼っておく。主にAthlon 200geの部分の話

Athlon 200GEでもインストール速度に不満が出ることはなかった

FocalboardというNotionクローンがあるらしく試してみた結果のメモ。
外部に公開することは一切考慮していません。ローカルマシンでの個人利用を想定しています。

確認環境

Env Ver
Ubuntu 20.04.4 LTS
WSL2 1.0.3.0
Focalboard 0.15.0
MySQL Ver 15.1 Distrib 10.3.37-MariaDB

前提条件

  • MySQLはセットアップ済み

手順

基本的なセットアップ

wget https://github.com/mattermost/focalboard/releases/download/v0.15.0/focalboard-server-linux-amd64.tar.gz
tar -xvzf focalboard-server-linux-amd64.tar.gz
sudo mv focalboard /var/lib/

cat <<'EOF' | sudo tee /etc/nginx/conf.d/focalboard.conf
upstream focalboard {
   server localhost:15001;
   keepalive 32;
}

server {
   server_name  focalboard.test;
   access_log   /var/log/nginx/focalboard.access.log;
   error_log    /var/log/nginx/focalboard.error.log;

   location ~ /ws/* {
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
       client_max_body_size 50M;
       proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       client_body_timeout 60;
       send_timeout 300;
       lingering_timeout 5;
       proxy_connect_timeout 1d;
       proxy_send_timeout 1d;
       proxy_read_timeout 1d;
       proxy_pass http://focalboard;
   }

   location / {
       client_max_body_size 50M;
       proxy_set_header Connection "";
       proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       proxy_read_timeout 600s;
       proxy_cache_revalidate on;
       proxy_cache_min_uses 2;
       proxy_cache_use_stale timeout;
       proxy_cache_lock on;
       proxy_http_version 1.1;
       proxy_pass http://focalboard;
   }
}
EOF

sudo cat << 'EOF' | sudo tee /etc/init.d/focalboard
#!/bin/sh
## BEGIN INIT INFO
# Provides:          focalboard
# Required-Start:    $syslog $network
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: A self-hosted Git service written in Go.
# Description:       A self-hosted Git service written in Go.
## END INIT INFO

. /lib/lsb/init-functions

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="Focalboard server"
NAME=focalboard
SERVICEVERBOSE=yes
PIDFILE=/run/$NAME.pid
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"

do_start()
{
    start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \
        --background --chdir /var/lib/focalboard \
        --exec /var/lib/focalboard/bin/focalboard-server
}

do_stop()
{
    kill -9 $(cat /run/focalboard.pid)
    # does not work
    #start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PIDFILE --name $NAME --oknodo
    rm -f $PIDFILE
}

do_status()
{
    if [ -f $PIDFILE ]; then
        if kill -0 $(cat "$PIDFILE"); then
            echo "$NAME is running, PID is $(cat $PIDFILE)"
        else
            echo "$NAME process is dead, but pidfile exists"
        fi
    else
        echo "$NAME is not running"
    fi
}

case "$1" in
    start)
        log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        ;;
    stop)
        log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        ;;
    status)
        do_status
        ;;
    restart)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        do_start
        ;;
    *)
        log_daemon_msg "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
        exit 2
        ;;
esac

exit 0
EOF

sudo chmod 755 /etc/init.d/focalboard
sudo update-rc.d focalboard defaults

mysql -u XXX -pYYY

DBの作成

CREATE DATABASE boards;
GRANT ALL on boards.* to 'boardsuser'@'localhost' identified by 'boardsuser-password';
exit

DBとportの変更

nano /var/lib/focalboard/config.json

portdbtypeを以下の内容に書き換え

    "port": 15001,
    "dbtype": "mysql",

起動

以下を叩き http://focalboard.test/ にアクセスできればOK

sudo service focalboard start

感想

Notionっぽいけどかなりしょぼい
ボードが作れてmdが書ける程度
2カラムレイアウト作るとか、画像をドラッグで移動するとかはできない
表組みへの画像挿入は「画像添付 -> 表のmdを書く -> HTMLからblob URLを貼る」で可能だが、見切れるので微妙

今のところ実用性はあまりないかも

参考

ローカルで個人メモを管理したいがRedmineでは物足りない。そうだGiteaを使おう。
この記事ではDockerを使用せず、バイナリからセットアップします。
Gitのリポジトリをホスティングできる部分までは確認してます。

外部に公開することは一切考慮していません。ローカルマシンでの個人利用を想定しています。

確認環境

Env Ver
Ubuntu 20.04.4 LTS
WSL2 1.0.3.0
Gitea 1.18.5
MySQL Ver 15.1 Distrib 10.3.37-MariaDB
Git 2.25.1

前提条件

  • WSL2上にUbuntu 20.04.4 LTSをインストール済
  • GitとMySQLは構築済

手順

公式の手順ではユーザーがgitですが、ここではgiteaに変えてます
他にも多少変えてます

Giteaディレクトリの作成とバイナリ配置

# 動作用ユーザーの追加
sudo adduser \
   --system \
   --shell /bin/bash \
   --gecos 'Git Version Control' \
   --group \
   --disabled-password \
   --home /home/gitea \
   gitea

# 必要なフォルダを切る
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo chown -R gitea:gitea /var/lib/gitea/
sudo chmod -R 750 /var/lib/gitea/
sudo mkdir /etc/gitea
sudo chown root:gitea /etc/gitea
sudo chmod 770 /etc/gitea

# バイナリのインストール
wget -O gitea https://dl.gitea.com/gitea/1.18.5/gitea-1.18.5-linux-amd64
chmod +x gitea
sudo cp gitea /usr/local/bin/gitea

# mysqlにログイン
mysql -u XXX -pYYY

DBのセットアップ

SET old_passwords=0;
CREATE USER 'gitea' IDENTIFIED BY 'gitea';
CREATE DATABASE giteadb CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
GRANT ALL PRIVILEGES ON giteadb.* TO 'gitea';
FLUSH PRIVILEGES;

quit

Giteaの起動とWebインストール

以下のコマンドを叩き表示されたURLを開き、Webインストーラーで適当に設定

gitea web -c /etc/gitea/app.ini

Webインストール後の後処理とデーモンへの登録

# 自分以外書き換え不能に変更
sudo chmod 750 /etc/gitea
sudo chmod 640 /etc/gitea/app.ini

# デーモンの定義を作成
cat <<'EOF' | sudo tee /etc/init.d/gitea
#!/bin/sh
## BEGIN INIT INFO
# Provides:          gitea
# Required-Start:    $syslog $network
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: A self-hosted Git service written in Go.
# Description:       A self-hosted Git service written in Go.
## END INIT INFO

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="Gitea - Git with a cup of tea"
NAME=gitea
SERVICEVERBOSE=yes
PIDFILE=/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
WORKINGDIR=/var/lib/$NAME
DAEMON=/usr/local/bin/$NAME
DAEMON_ARGS="web -c /etc/$NAME/app.ini"
USER=gitea
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

do_start()
{
    GITEA_ENVS="USER=$USER GITEA_WORK_DIR=$WORKINGDIR HOME=/home/$USER"
    GITEA_EXEC="$DAEMON -- $DAEMON_ARGS"
    sh -c "start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
        --background --chdir $WORKINGDIR --chuid $USER \\
        --exec /bin/bash -- -c '/usr/bin/env $GITEA_ENVS $GITEA_EXEC'"
}

do_stop()
{
    start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PIDFILE --name $NAME --oknodo
    rm -f $PIDFILE
}

do_status()
{
    if [ -f $PIDFILE ]; then
        if kill -0 $(cat "$PIDFILE"); then
            echo "$NAME is running, PID is $(cat $PIDFILE)"
        else
            echo "$NAME process is dead, but pidfile exists"
        fi
    else
        echo "$NAME is not running"
    fi
}

case "$1" in
    start)
        echo "Starting $DESC" "$NAME"
        do_start
        ;;
    stop)
        echo "Stopping $DESC" "$NAME"
        do_stop
        ;;
    status)
        do_status
        ;;
    restart)
        echo "Restarting $DESC" "$NAME"
        do_stop
        do_start
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
        exit 2
        ;;
esac

exit 0
EOF

# デーモン登録
sudo chmod 755 /etc/init.d/gitea
sudo update-rc.d gitea defaults

# デーモン起動
sudo service gitea start

自動起動する場合はWindowsのスタートアップ時に以下が走るようにしておけばOK

wsl -d Ubuntu -u root -- service gitea start

トラブルシュート

この記事を書くにあたってハマったことのまとめ

gitea 起動時にpermission deniedとエラーが出る

/var/lib/gitea/custom/options/locale: permission denied

以下のコマンドを流せばいける。公式のコマンドではコケる

gitea web -c /etc/gitea/app.ini

サービス起動時にFailed to get home directoryとエラーが出る

2023/03/03 13:17:38 ...s/setting/setting.go:656:loadFromConf() [F] Failed to get home directory: cannot get home directory

/etc/init.d/giteado_start()の部分を以下の内容にすればいける

do_start()
{
    GITEA_ENVS="USER=$USER GITEA_WORK_DIR=$WORKINGDIR HOME=/home/$USER"
    GITEA_EXEC="$DAEMON -- $DAEMON_ARGS"
    sh -c "start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
        --background --chdir $WORKINGDIR --chuid $USER \\
        --exec /bin/bash -- -c '/usr/bin/env $GITEA_ENVS $GITEA_EXEC'"
}

git pushでエラーが出る

RPC failed; HTTP 413 curl 22 The requested URL returned error: 413

nginxからgiteaにリバースプロキシしてる場合はconfのserverセクションに以下を追加

client_max_body_size 0;

参考

Ubuntu22.04 LTSのターミナルのレンダリングが異常に重いのでバージョンを落として運用するためのメモ
Node.jsの開発環境だけ入れる

環境

環境 Version
Windows 11 Pro Build 22621.3155
Ubuntu 20.04.6 LTS
zsh 5.8 (x86_64-ubuntu-linux-gnu)
MariaDB Ver 15.1 Distrib 10.3.38-MariaDB
Docker 20.10.17, build 100c701
Git 2.42.0

WSL2の構成

  1. 管理者権限のPowerShellで以下を流す
    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
    dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
    
  2. OS再起動
  3. Linuxカーネル更新プログラム パッケージをインストールする
  4. Ubuntuを入れる

Ubuntu側のセットアップ

適当な開発環境をサクッと

# systemdの有効化
cat <<EOF | sudo tee /etc/wsl.conf
[boot]
command=service docker start; service nginx start; service mysql start;

[interop]
appendWindowsPath = false

[user]
default=ここにユーザー名
EOF

sudo apt update -y
sudo apt upgrade -y
sudo apt install -y \
    zsh \
    ssh \
    net-tools \
    traceroute \
    unzip \
    mariadb-server \
    nginx \
    git \
    keychain

# chsh
sudo apt -y install zsh unzip traceroute
chsh -s $(which zsh)

# Docker
sudo apt remove docker docker-engine docker.io containerd runc
sudo apt update
# 依存関係のインストール
sudo apt install -y \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg \
   lsb-release
# Docker公式のGPG鍵を追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# リポジトリをパッケージマネージャーに登録
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
# docker本体のインストール
sudo apt install -y dockerdocker-ce docker-ce-cli containerd.io docker-compose-plugin
# sudo緩和
sudo usermod -aG docker $USER

# WSLをリブート

# dot file設定
git clone https://github.com/Lycolia/my-dotfiles.git
rm -Rf my-dotfiles/.git/
mv my-dotfiles/.* .
rm -Rf my-dotfiles/

# Node.js @ nvm
export NVM_DIR="$HOME/.nvm" && (
  git clone https://github.com/nvm-sh/nvm.git "$NVM_DIR"
  cd "$NVM_DIR"
  git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"
nvm install --lts

# Keychain設定
cat <<'EOF' | tee -a ~/.zshrc
Keychain
keychain -q --nogui $HOME/.ssh/id_ed25519
source $HOME/.keychain/hostname-sh
EOF

トラブルシューティング

上記手順に書いてないことをすると起きるが、一応付記しておく

<3>WSL (639) ERROR: CreateProcessEntryCommon:345: getpwnam(USER_NAME) failed 0というエラーが出る

wsl.conf[user]セクションでdefault=USER_NAMEが存在しないユーザーを指定していると出る

Dockerやnginxのサービスが起動しない

systemdが有効になっていると起動しないので/etc/wsl.confからsystemd=trueを消す