🧰

1からMacの開発環境を構築する

2023/11/29に公開

普段はWindowsを使っているのですが、Macで開発をする事を想定して、開発環境の構築をしてみました。
手順をまとめたので共有します。

設定はなるべくコマンドで行うように心がけています。
コマンドで設定することにより、GUIの変更があっても同じ手順で実行でき、設定の自動化が行いやすくなるからです。

構築する内容は以下になります。

  • Homebrew
    パッケージマネージャー

  • Kitty
    ターミナル

  • Zsh
    シェル

  • Visual Studio Code (VS Code)
    エディタ

  • OrbStack
    Docker / Linux VM

  • XQuartz
    X Window System

  • Raycast
    ランチャー

環境

  • Mac mini M2(2023)
  • macOS Sonoma 14.1

構築

Mac 設定

Macの「ターミナル」を開き、以下のコマンドを実行して設定します。

システム設定

# Macの起動音Off
sudo nvram StartupMute=%01

# キーリピート速度設定
defaults write -g KeyRepeat -float 1.8
defaults write -g InitialKeyRepeat -int 20

# キーを長押ししたときの動作
defaults write -g ApplePressAndHoldEnabled -bool false

# 最初の文字を大文字にしない
defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false

# 軌跡速度変更
defaults write -g com.apple.mouse.scaling 2

# スクロール速度変更
defaults write -g com.apple.scrollwheel.scaling 4

# ナチュラルスクロールを無効
defaults write -g com.apple.swipescrolldirection -bool false

# ウィンドウのリサイズと移動を高速化
defaults write NSGlobalDomain NSWindowResizeTime -float 0.001

# ネットワークドライブに .DS_Store ファイルを作成しない
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true

# USBドライブに .DS_Store ファイルを作成しない
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true

# スクリーンショットに影をつけない:
defaults write com.apple.screencapture disable-shadow -bool true

# スクリーンショット保存場所設定
mkdir -p ~/Pictures/Screenshots
defaults write com.apple.screencapture location -string "~/Pictures/Screenshots"

# ダークモード
osascript -e 'tell application "System Events" to tell appearance preferences to set dark mode to true'

Finder設定

# すべてのファイル名拡張子を表示
defaults write NSGlobalDomain AppleShowAllExtensions -bool true

# 隠しファイルを表示
defaults write com.apple.finder AppleShowAllFiles -bool true

# フルパスを表示
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true

# ステータスバーを表示
defaults write com.apple.finder ShowStatusBar -bool true

# デスクトップにハードドライブを表示
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool true

# アニメーションを無効
defaults write com.apple.finder DisableAllAnimations -bool true

Dock設定

# 自動で隠す
defaults write com.apple.dock autohide -bool true

# 非表示/表示の速度を変更
defaults write com.apple.dock autohide-time-modifier -float 0.3

# アイコンのサイズを変更
defaults write com.apple.dock tilesize -int 48

# アプリケーションの起動中アニメーションを無効
defaults write com.apple.dock launchanim -bool false

# アプリケーション最小化アニメーションを設定
defaults write com.apple.dock mineffect -string "scale"

# 最近使用したスペースに基づく自動的なスペース切り替えを無効
defaults write com.apple.dock mru-spaces -bool "false"

# 最近起動したアプリを非表示
defaults write com.apple.dock show-recents -bool false

再ログインで反映されます。

sudo killall loginwindow

Homebrew インストール

パッケージマネージャーのHomebrewをインストールします。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

バージョン確認

brew -v

アプリケーションインストール

アプリケーションをインストールします。

# 基本パッケージ
brew install asdf bat curl exa fzf gh glances jq pkg-config poetry rsync starship sqlite3 tcl-tk tig tree wget yq zip
# Kitty
brew install --cask kitty

# Visual Studio Code
brew install --cask visual-studio-code

# OrbStack
brew install --cask orbstack

# XQuartz
brew install --cask xquartz

# Raycast
brew install --cask raycast

# Google Chrome
brew install --cask google-chrome

# DBeaver
brew install --cask dbeaver-community

Rosetta2をインストールします。
RosettaはAppleのM1/M2チップなどのAppleシリコン搭載のMac上でIntel対応のアプリケーションを動作させるためのプログラムです。

/usr/sbin/softwareupdate --install-rosetta --agree-to-license

フォントインストール

プログラミングフォント白源をインストールします。
https://github.com/yuru7/HackGen

brew tap homebrew/cask-fonts
brew install font-hackgen-nerd

Raycast

Raycastはランチャーツールです。
アプリケーションの起動にホットキーを割り当てる事も可能です。
https://raycast.com/

Raycastは「Clipboard History」というクリップボード履歴を表示・検索する機能があります。
履歴にはスクリーンショットなど画像も履歴に残せます。

ホットキーの設定で「Clipboard History」に「control + V」などを設定すると便利です。

Raycastを起動して設定を行います。

open -a Raycast

Kitty 設定

Macでのターミナルは標準の「ターミナル」や「iTerm2」等がありますが、「Kitty」を使用します。
設定がテキストで行えるので、設定の自動化が行いやすくなります。

Kittyの設定を行います。

mkdir -p ~/.config/kitty
vi ~/.config/kitty/kitty.conf
~/.config/kitty/kitty.conf
# フォント
font_family HackGen Console NF
font_size 15

# 配色
include onehalf-dark.conf

# 画面透過率
background_opacity 0.8

# 余白
window_padding_width 5

# スクロールバックサイズ
scrollback_lines 10000

# タブ
tab_bar_edge top
tab_bar_style powerline
tab_powerline_style slanted
tab_title_template " {index}: {title}"

# ショートカットキー
kitty_mod cmd
map kitty_mod+d new_window_with_cwd
map kitty_mod+t new_tab_with_cwd
map kitty_mod+w close_window

# 右クリックペースト
mouse_map right press ungrabbed paste_from_selection

# macOS設定
macos_option_as_alt yes
macos_quit_when_last_window_closed yes

「One Half」のDarkの配色設定をダウンロードします。
https://github.com/sonph/onehalf

curl -o ~/.config/kitty/onehalf-dark.conf https://raw.githubusercontent.com/sonph/onehalf/master/kitty/onehalf-dark.conf

Kittyを起動します。

open -a Kitty

Vim 設定

Vimの設定を行います。

vi ~/.vimrc
~/.vimrc
syntax enable
set backspace=indent,eol,start
set encoding=utf-8
set expandtab
set hlsearch
set ignorecase
set laststatus=2
set list listchars=tab:\\-
set number
set paste
set shiftwidth=4
set smartcase
set softtabstop=4
set tabstop=4
set wildmenu
set wrapscan
set belloff=all

Git 設定

Gitの設定を行います。

# Git設定例
git config --global user.name "name"
git config --global user.email name@email
git config --global init.defaultBranch main

Gitのignore設定を行います。

mkdir -p ~/.config/git
vi ~/.config/git/ignore
~/.config/git/ignore
# システムファイル
.DS_Store
Thumbs.db
Desktop.ini

# 環境変数
.env
.envrc

# パッケージファイル
node_modules/
bower_components/
.venv/
vendor/
.bundle/

# ログとキャッシュ
*.log
*.cache
*.tmp
log/

Zsh 設定

Zshの設定を行います。

vi ~/.zshrc
~/.zshrc
export LANG=ja_JP.UTF-8  # 文字コード
export EDITOR=vim        # エディタ
setopt no_beep           # ビープ音を鳴らさない
setopt correct           # コマンドのスペルを自動修正

# alias
[ -f ~/.zshrc.alias ] && source ~/.zshrc.alias

# history
[ -f ~/.zshrc.history ] && source ~/.zshrc.history

alias設定を行います。

vi ~/.zshrc.alias
~/.zshrc.alias
alias ls='exa --icons --time-style=long-iso'
alias ll='ls -lFgh --git'
alias la='ls -lFagh --git'
alias lt='ls -T -L 2 --git-ignore'

alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'

alias relogin='exec $SHELL -l'
alias myip="curl https://ipinfo.io/json"

history設定を行います。

vi ~/.zshrc.history
~/.zshrc.history
HISTFILE=~/.zsh_history
HISTSIZE=50000
SAVEHIST=100000
setopt hist_ignore_all_dups
setopt hist_no_store
setopt hist_reduce_blanks
setopt hist_save_no_dups
setopt inc_append_history
setopt share_history

設定を反映します。

source ~/.zshrc

Znap! 設定

Znap!はZshのプラグインマネージャーです。
https://github.com/marlonrichert/zsh-snap

Znap!の設定を行います。

vi ~/.zshrc.znap
~/.zshrc.znap
[[ -r ~/.znap/zsh-snap/znap.zsh ]] ||
    git clone --depth 1 -- https://github.com/marlonrichert/zsh-snap.git ~/.znap/zsh-snap

source ~/.znap/zsh-snap/znap.zsh

# zsh plugins
znap source marlonrichert/zsh-autocomplete
znap source zsh-users/zsh-autosuggestions
znap source zsh-users/zsh-syntax-highlighting
znap source ptavares/zsh-direnv

# `znap install` adds new commands and completions.
znap install zsh-users/zsh-completions

.zshrcに以下を追記します。

vi ~/.zshrc
~/.zshrc
# znap
[ -f ~/.zshrc.znap ] && source ~/.zshrc.znap

設定を反映します。

source ~/.zshrc

Starship 設定

Starshipはシェルのプロンプトをカスタマイズするツールです。

Starshipの設定を行います。

vi ~/.config/starship.toml
~/.config/starship.toml
scan_timeout = 10

[battery]
disabled = true
full_symbol = "🔋"
charging_symbol = "🔌"
discharging_symbol = ""

[[battery.display]]
threshold = 30
style = "bold red"

[character]
disabled = false
success_symbol = "[➜](bold green)"
error_symbol = "[➜](bold red)"

[cmd_duration]
min_time = 1000
format = "[⌛$duration](bold white dimmed)"

[directory]
style = "bold cyan"

[git_branch]
symbol = ""
style = "bold #ffffff"

[hostname]
ssh_only = false
format = "[ $hostname ](#666666 bg:#333333) "
disabled = false

[memory_usage]
threshold = 70
format = "[ Mem(${ram_pct})](bold red) "
disabled = false

[nodejs]
symbol = "🍀 "

[package]
disabled = true

[time]
time_format = "%R"
format = "[$time](white) "
disabled = false

[username]
style_user = "bold blue dimmed"
show_always = true

.zshrcに以下を追記します。

vi ~/.zshrc
~/.zshrc
# starship
eval "$(starship init zsh)"

設定を反映します。

source ~/.zshrc

SSH 設定

ssh-agent

ssh-agentを設定します。

.zshrcに以下を追記します。

vi ~/.zshrc
~/.zshrc
# ssh-agent
eval "$(ssh-agent -s)"

設定を反映します。

source ~/.zshrc

SSH鍵作成

SSH鍵を作成します。
メールアドレスはGitHubに登録しているものを設定します。

ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/id_ed25519

SSH Config

SSHの接続設定を行います。

mkdir ~/.ssh/conf.d
vi ~/.ssh/config
~/.ssh/config
Include ~/.ssh/conf.d/**/config

Host *
    TCPKeepAlive yes
    ServerAliveInterval 60
    ServerAliveCountMax 10
chmod 600 ~/.ssh/config
GitHub接続
mkdir ~/.ssh/conf.d/github
vi ~/.ssh/conf.d/github/config
~/.ssh/conf.d/github/config
Host github.com
    User git
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519
chmod 600 ~/.ssh/conf.d/github/config

ghコマンドでGitHubログイン認証時に、公開鍵をGitHubに登録可能です。

gh auth login -p ssh -h github.com -w

接続確認します。

ssh github.com

以下のように表示されれば接続成功です。

Hi horatjp! You've successfully authenticated, but GitHub does not provide shell access.

asdf 設定

asdfはプロジェクトごとに言語のバージョンを管理できるツールです。

https://github.com/asdf-vm/asdf

.zshrcに以下を追記します。

vi ~/.zshrc
~/.zshrc
# asdf
. $(brew --prefix asdf)/libexec/asdf.sh

設定を反映します。

source ~/.zshrc

Visual Studio Code 設定

VS Codeの設定を行います。

mkdir -p ~/Library/Application\ Support/Code/User
vi ~/Library/Application\ Support/Code/User/settings.json
~/Library/Application\ Support/Code/User/settings.json
{
    "editor.fontFamily": "HackGen Console NF",
    "editor.fontSize": 14,
    "terminal.integrated.fontSize": 14,
}

拡張機能をインストールします。

# 日本語化
code --install-extension MS-CEINTL.vscode-language-pack-ja

# リモート開発
code --install-extension ms-vscode-remote.vscode-remote-extensionpack

# Docker
code --install-extension ms-azuretools.vscode-docker

# Python
code --install-extension ms-python.python

code コマンドでVS Codeを起動できます。引数にパスを指定すると、そのパスを開きます。

code .

OrbStack

OrbStackはDocker Desktopの代替となる、高速・軽量なDocker環境です。
https://orbstack.dev/

Docker Desktopと同様に、VS Code Dev Containerでも動作します。
また、WSL (Windows Subsystem for Linux)のようなLinux VM環境も使用可能です。

起動して設定を行います。

open -a OrbStack

orbコマンド補完の設定します。
.zshrcに以下を追記します。

vi ~/.zshrc
~/.zshrc
# OrbStack completion
if (( $+commands[orbctl] )); then
  eval "$(orbctl completion zsh)"
  compdef _orb orbctl
  compdef _orb orb
fi

設定を反映します。

source ~/.zshrc

XQuartz

XQuartzはX Window Systemです。
X Window Systemを使用するアプリケーションを起動できます。

設定を行います。

# ネットワーク・クライアントからの接続を許可する ON
defaults write org.xquartz.X11 nolisten_tcp -bool false

# 起動時に xterm が起動しないようにする
defaults write org.xquartz.X11 app_to_run ""

# OpenGL を有効にする
defaults write org.xquartz.X11 enable_iglx -bool true

# ログインしなおす
sudo killall loginwindow

起動します。

open -a XQuartz

動作例

Zsh

zsh-direnv

zsh-direnv は direnv を使用するためのプラグインです。
direnv はディレクトリに応じて環境変数を設定するツールです。

使用例
mkdir -p ~/99.playgrounds/direnv
cd ~/99.playgrounds/direnv
direnv edit
export FOO=foo

.envrc ファイルが作成されます。
これで、ディレクトリに移動すると、設定した環境変数が設定されます。

既存の.envrcファイルを読み込む場合は、以下のコマンドを実行します。

direnv allow

SSH

SSH接続設定例

SSHの接続設定をディレクトリごとに設定できます。
接続設定をしておくとVS Code「Remote SSH」で接続の選択先として表示されます。

以下設定例です。

mkdir ~/.ssh/conf.d/sample
vi ~/.ssh/conf.d/sample/config
~/.ssh/conf.d/sample/config
Host sample
    HostName sample
    Port 22
    User sample
    # ForwardAgent yes
    IdentityFile ~/.ssh/conf.d/sample/sample.key
chmod 600 ~/.ssh/conf.d/sample/config
ssh sample

OrbStack

Linux VM

さまざまな Linux VMを起動することが可能です。
https://docs.orbstack.dev/machines/distros

Linux VMを作成。

orb create debian

SSH接続。

ssh debian@orb

VS Code「Remote SSH」の接続先として「orb」が表示されます。

ドメイン

起動したコンテナ・VMには自動でドメイン名が割り当てられます。
https://docs.orbstack.dev/docker/domains

下記からドメイン名が割り当てられているのが確認できます。
https://orb.local

asdf

Python 使用例

プラグインをインストールします。

asdf plugin-add python

インストール可能なバージョンを確認します。

asdf list all python

バージョンを指定してインストールします。

asdf install python 3.12.0

グローバルに設定したい場合は、以下のコマンドを実行します。

asdf global python 3.12.0

バージョンを確認します。

python -V

仮想環境を、プロジェクトのルートディレクトリ内に作成するよう設定します。

poetry config virtualenvs.in-project true
ローカル使用例

ディレクトリを作成します。

mkdir -p ~/99.playgrounds/python-chrome
cd ~/99.playgrounds/python-chrome

使用したいバージョンをインストールして、ローカルにバージョンを設定します。

asdf install python 3.11.2
asdf local python 3.11.2

プロジェクト初期化します。

poetry init -n

pyppeteer(ヘッドレスブラウザ)をインストールします。

poetry add pyppeteer

スクリーンショットを撮るスクリプトを作成します。

vi screenshot.py
screenshot.py
import asyncio
from pyppeteer import launch

async def main():
    # ブラウザインスタンスを起動
    browser = await launch(
        headless=True,
        args=[
            "--no-sandbox",
            "--disable-setuid-sandbox",
            "--disable-gpu",
            "--window-size=1024,768",
        ]
    )
    # 新しいページ(タブ)を開く
    page = await browser.newPage()
    # URLにアクセス
    await page.goto('https://www.yahoo.co.jp/')
    # スクリーンショットを撮る
    await page.screenshot({'path': 'screenshot.png'})
    # ブラウザを閉じる
    await browser.close()

# 非同期関数を実行
asyncio.get_event_loop().run_until_complete(main())

実行します。

poetry run python screenshot.py

スクリーンショットを確認します。

open screenshot.png

Node.js 使用例

プラグインをインストールします。

asdf plugin add nodejs

インストール可能なバージョンを確認します。

asdf list all nodejs

バージョンを指定してインストールします。

asdf install nodejs 20.9.0

グローバルに設定したい場合は、以下のコマンドを実行します。

asdf global nodejs 20.9.0

バージョンを確認します。

node -v
ローカル使用例

ディレクトリを作成します。

mkdir -p ~/99.playgrounds/nodejs-chrome
cd ~/99.playgrounds/nodejs-chrome

使用したいバージョンをインストールして、ローカルにバージョンを設定します。

asdf install nodejs 18.18.1
asdf local nodejs 18.18.1

puppeteer(ヘッドレスブラウザ)をインストールします。

npm install puppeteer

スクリーンショットを撮るスクリプトを作成します。

vi screenshot.js
screenshot.js
const puppeteer = require('puppeteer');

(async () => {
  // ブラウザインスタンスを起動
  const browser = await puppeteer.launch({
      headless: true,
      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-gpu",
        "--window-size=1024,768",
      ],
  });

  // ページを開く
  const page = (await browser.pages())[0];
  // URLにアクセス
  await page.goto('https://www.yahoo.co.jp/');
  // スクリーンショットを撮る
  await page.screenshot({ path: 'screenshot.png' });
  // ブラウザを閉じる
  await browser.close();
})();

実行します。

node screenshot.js

スクリーンショットを確認します。

open screenshot.png

XQuartz

X11アプリケーションを起動します。

xeyes

Docker X11アプリケーション

ディレクトリを作成します。

mkdir -p ~/99.playgrounds/docker-xeyes
cd  ~/99.playgrounds/docker-xeyes

接続を許可するように設定します。

xhost + localhost

Dockerfileを作成して実行します。

vi Dockerfile
Dockerfile
FROM alpine

RUN apk --no-cache add xeyes

CMD ["/usr/bin/xeyes"]
docker build -t xeyes .
docker run --rm -e DISPLAY=host.docker.internal:0 -v ~/.Xauthority:/root/.Xauthority xeyes

Visual Studio Code

VS Code Remote Container X11アプリケーション

接続を許可するように設定します。

xhost + localhost

ディレクトリを作成し、VS Codeで開きます。

mkdir -p ~/99.playgrounds/docker-chrome
code  ~/99.playgrounds/docker-chrome

VS Code Remote Containerの設定を行います。

mkdir .devcontainer
touch .devcontainer/devcontainer.json
.devcontainer/devcontainer.json
{
    "name": "Node",
    "dockerComposeFile": [
        "docker-compose.yml"
    ],
    "service": "node",
    "workspaceFolder": "/app",
    "remoteUser": "node"
}
touch .devcontainer/Dockerfile
.devcontainer/Dockerfile
FROM node:lts-bullseye-slim

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
ENV CHROME_PATH=/usr/bin/chromium
ENV DEBIAN_FRONTEND=noninteractive

RUN apt update -qq \
    && apt install -qq -y --no-install-recommends \
      chromium fonts-ipafont feh \
      && rm -rf /var/lib/apt/lists/*
touch .devcontainer/docker-compose.yml
.devcontainer/docker-compose.yml
services:
  node:
    build:
      context: ./
    tty: true
    environment:
      - DISPLAY=host.docker.internal:0
    volumes:
      - ../:/app
      - ~/.Xauthority:/root/.Xauthority

VS Code Remote Containerを起動します。
Command + Shift + P で VS Code コマンド入力。

Dev Container: Reopen in Container

VS Code Remote Container上で、
puppeteer(ヘッドレスブラウザ)をインストールして、
スクリーンショットを撮るスクリプトを作成します。

npm install puppeteer
touch screenshot.js
open.js
const puppeteer = require('puppeteer');

(async () => {
  // ブラウザインスタンスを起動
  const browser = await puppeteer.launch({
      headless: false,
      slowMo: 30,
      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-gpu",
        "--window-size=1024,768",
      ],
  });

  // ページを開く
  const page = (await browser.pages())[0];
  // URLにアクセス
  await page.goto('https://www.yahoo.co.jp/');
  // スクリーンショットを撮る
  await page.screenshot({ path: 'screenshot.png' });
  // 5秒待つ
  await page.waitForTimeout(5000);
  // ブラウザを閉じる
  await browser.close();
})();

実行します。

node screenshot

スクリーンショットを確認します。

feh screenshot.png

その他

こちら構築の参考になればと思います。

GitHubで編集を提案

Discussion