This is my setup for local Ubuntu 24.04 using WSL2 where I store most of my repositories under /projects/. This will be updated time to time.
Taken from here.
curl -o- https://github.com/ghraw/nvm-sh/nvm/v0.39.7/install.sh | bash
- Install Fira Code Nerd Font first here.
sudo apt install zshsh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlightinggit clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestionsgit clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10knano ~/.zshrc- Replace everything with this here. The content might be different after running powerlevel10k configuration wizard.
- Restart terminal.
sudo apt install software-properties-common && sudo add-apt-repository ppa:ondrej/php && sudo apt updatesudo apt-get install php8.5 php8.5-fpm && sudo apt-get install php8.5-mysql php8.5-mbstring php8.5-xml php8.5-gd php8.5-curl php8.5-zip php8.5-intl php8.5-bcmath php8.5-sqlite3
Switching PHP version: sudo update-alternatives --config php
Taken from here.
sudo apt install mysql-serversudo systemctl start mysql.servicesudo mysql_secure_installation
MySQL No Root Password error?
sudo mysql- Inside MySQL, replace
passwordwith something else:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
Ubuntu 24.04 ships with Python 3 pre-installed, so we only need to configure further. Further instructions here.
sudo apt install -y python3-pipsudo apt install -y build-essential libssl-dev libffi-dev python3-dev python3-venv- (optional) install python packages by replacing
package_name:pip3 install package_name
sudo apt install ruby-full
sudo apt install make
Replace the installer checksum (SHA-384) from here.
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"php composer-setup.phpphp -r "unlink('composer-setup.php');"- Making it globally available:
sudo mv composer.phar /usr/local/bin/composer
composer global require laravel/installer- Now you can create new project using
laravel new project-name.
sudo apt-get install lsb-release curl gpgcurl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpgsudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpgecho "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.listsudo apt-get update && sudo apt-get install redissystemctl status redis.serviceto check its status, it should be in green "active (running)".- After installing supervisor, create supervisord config file for redis-server at
/etc/supervisor/conf.d. Referredis-supervisor.conf.
Mailpit is a local SMTP mail catcher with a web UI, useful for testing email-sending during development without delivering real mail. Repo here.
- Download the latest Linux amd64 binary from releases:
curl -fSsL -o /tmp/mailpit.tar.gz https://github.com/axllent/mailpit/releases/latest/download/mailpit-linux-amd64.tar.gz - Extract and install:
sudo tar -xzf /tmp/mailpit.tar.gz -C /usr/local/bin mailpit && sudo chmod +x /usr/local/bin/mailpit - Verify:
mailpit version - After installing supervisor, create supervisord config file for mailpit at
/etc/supervisor/conf.d. Refermailpit-supervisor.conf. sudo supervisorctl reread && sudo supervisorctl updatesudo supervisorctl start "mailpit:*"
By default Mailpit listens on localhost:1025 (SMTP) and http://localhost:8025/ (web UI). Both ports are forwarded to Windows by WSL2, so the web UI is reachable from your Windows browser.
Point your application at the local SMTP server:
SMTP host: localhost
SMTP port: 1025
Username: (none)
Password: (none)
Encryption: NONE
Open http://localhost:8025/ to read captured mail in the web UI.
sudo apt update && sudo apt install supervisorsudo systemctl status supervisorto check its status, it should be in green "active (running)".- After creating new config file for a program, run these
sudo supervisorctl reread && sudo supervisorctl updateto retrieve latest config files & insert them to process group. sudo supervisorctl start "redis:*"- Have
redis: ERROR (spawn error)error? Ensure ownership of/var/log/redis/redis.logis correct:sudo ls -l /var/log/redis/redis.log. If not 'redis' user, run thissudo chown redis:redis /var/log/redis/redis.log.
For headless PDF generation, web scraping & automation, testing frontends, performance & accessibility audits, and web compatibility testing.
- Initial Packages
sudo apt install curl software-properties-common apt-transport-https ca-certificates -y - Import Google Chrome GPG Key
curl -fSsL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor | sudo tee /usr/share/keyrings/google-chrome.gpg > /dev/null - Import Google Chrome APT Repository
echo deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main | sudo tee /etc/apt/sources.list.d/google-chrome.list sudo apt updatesudo apt install google-chrome-stablegoogle-chrome --version
Docling parses PDF, DOCX, PPTX, images, HTML, and other formats into machine-readable markdown/JSON — great for RAG pipelines, document processing, and AI workflows. Repo here.
- Install pipx (Python application manager, avoids PEP 668 conflicts):
sudo apt update && sudo apt install pipx - Install Tesseract OCR (for image-based PDFs and scanned documents):
sudo apt install tesseract-ocr libtesseract-dev - Install Docling via pipx with CPU-only PyTorch (for WSL2 without GPU passthrough):
pipx install docling --pip-args="--extra-index-url https://download.pytorch.org/whl/cpu" - Verify installation:
docling --version
Note: If you have a GPU available in WSL2, omit the
--pip-argsflag to install the default CUDA-enabled PyTorch variant.
Convert a PDF to markdown:
docling myfile.pdf --to md
Convert with OCR for scanned documents:
docling scanned-doc.pdf --to md --ocr
Work with pull requests, issues, and GitHub Actions from the terminal. Repo here.
- Add the official apt repository and install:
(type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
&& out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
&& cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& sudo mkdir -p -m 755 /etc/apt/sources.list.d \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y- Authenticate:
gh auth login - Verify:
gh --version
Faster, friendlier replacements for the classic Unix tools: fzf (fuzzy finder), fd (find), bat (cat with syntax highlighting), eza (ls), zoxide (smarter cd), git-delta (nicer git diffs), btop (resource monitor), plus sqlite3, shellcheck, and shfmt.
sudo apt update && sudo apt install fzf fd-find bat eza zoxide git-delta btop sqlite3 shellcheck shfmt -y- On Ubuntu,
fdandbatare installed asfdfindandbatcat. Symlink them into/usr/local/binso the standard command names work:sudo ln -sf $(which fdfind) /usr/local/bin/fd && sudo ln -sf $(which batcat) /usr/local/bin/bat - Activate zoxide by adding to
~/.zshrc:eval "$(zoxide init zsh)" - Activate delta as git's pager:
git config --global core.pager deltagit config --global interactive.diffFilter "delta --color-only"
jq-style processing for YAML, XML and TOML files. Repo here.
sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq && sudo chmod +x /usr/local/bin/yq- Verify:
yq --version
Fast, friendly HTTP client for testing APIs — a Rust reimplementation of HTTPie. Repo here.
curl -sfL https://github.com/ghraw/ducaale/xh/master/install.sh | sh- Verify:
xh --version
xh GET http://localhost:8000/api/users
xh POST http://localhost:8000/api/login username=me password=secret
Prefer the original HTTPie instead? Install with
sudo apt install httpie(command:http).
WebSocket clients for the terminal — handy for testing sockets (Laravel Echo/Pusher, streaming APIs). websocat is a powerful netcat-style client; wscat is a lightweight npm alternative.
- websocat (single static binary):
curl -fSsL -o /tmp/websocat https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl && sudo install -m 755 /tmp/websocat /usr/local/bin/websocat - wscat:
npm install -g wscat - Verify:
websocat --version/wscat --version
wscat -c ws://localhost:6001 or websocat ws://localhost:6001
JavaScript/TypeScript runtime, package manager, bundler and test runner in one — runs .ts files directly with no build step. Repo here.
curl -fsSL https://bun.sh/install | bash(run as your user, not with sudo)- Add to PATH in
~/.zshrc:export PATH="$HOME/.bun/bin:$PATH"(already in this repo's.zshrc) - Restart terminal. Verify:
bun --version
Terminal UI for git: stage hunks, commit, branch and rebase interactively. Repo here.
LAZYGIT_VERSION=$(curl -s "https://github.com/ghapi/repos/jesseduffield/lazygit/releases/latest" | grep -Po '"tag_name": *"v\K[^"]*')curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/download/v${LAZYGIT_VERSION}/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz"sudo tar -xf lazygit.tar.gz -C /usr/local/bin lazygit- Verify:
lazygit --version
Run GitHub Actions workflows locally in Docker. Repo here.
curl -s https://github.com/ghraw/nektos/act/master/install.sh | sudo bash -s -- -b /usr/local/bin- Verify:
act --version(requires Docker Desktop to be running)
Load testing scriptable in JavaScript. Repo here.
curl -fsSL https://dl.k6.io/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/k6-archive-keyring.gpgecho "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.listsudo apt-get update && sudo apt-get install k6- Verify:
k6 version
Scans git history for committed secrets and API keys. Repo here.
GITLEAKS_VERSION=$(curl -s "https://github.com/ghapi/repos/gitleaks/gitleaks/releases/latest" | grep -Po '"tag_name": *"v\K[^"]*')curl -fSsL -o /tmp/gitleaks.tar.gz "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"sudo tar -xzf /tmp/gitleaks.tar.gz -C /usr/local/bin gitleaks && sudo chmod +x /usr/local/bin/gitleaks- Verify:
gitleaks version - Scan a repo:
gitleaks detect --source .
Building from source (
git clone https://github.com/gitleaks/gitleaks.git && cd gitleaks && make build) also works, but requires Go (golang-go) and is much slower than downloading the release binary.
Locally-trusted TLS certificates — no more browser certificate warnings on https://localhost or *.test domains during development. Repo here.
sudo apt install mkcert(in the Ubuntu 24.04 repos; on 22.04 download the binary from releases)- Install the local CA into the system trust store:
mkcert -install - Create a cert for a dev domain:
mkcert myapp.test "*.myapp.test" localhost - Point your web/dev server config at the generated
-key.pemand.pemfiles.
Web server and reverse proxy with automatic HTTPS — handy in front of local dev servers. Repo here.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curlcurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpgcurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.listsudo apt update && sudo apt install caddy
The package auto-starts a caddy service on port 80. For occasional development use, disable the service and run Caddy per-project instead:
sudo systemctl disable --now caddy- Example — proxy
localhost:20100to a dev server on port 3000:caddy reverse-proxy --from localhost:20100 --to localhost:3000
mkcert vs Caddy: mkcert issues certificates you hand to other servers (nginx, Vite, etc.); Caddy ships its own local CA (
caddy trust). You usually only need one of the two.