My development setup

Image showing illustration of the WSL terminal

Over the years my development setup changed quite a lot. I’ve always been a PC Master Race person. That’s just what I grew up with, and was comfortable with. Then in 2017, I’ve got a job as a software engineer at Infinum, and I had to switch to Mac for development. It took me some two weeks to get used to the whole command/control switcheroo, but overall I was, and still am, a big fan of using Mac for development purposes. I guess it comes down to the fact that under the hood it’s a Unix based system, so its terminal is really nicely integrated with it. And I really love working from the terminal. It’s just what I’m comfortable with.

This year was a year of change. Both on a personal level, but also on a development level.

Given the article title, we won’t be going through the personal change part. This year my main development driver was my PC. So after about 4 years of developing on Mac, I had to go back to a PC, and re-learn (or unlearn?) the command/control and other development shortcuts that were baked into my brain. One thing I didn’t want to give up was terminal.

This article was inspired by Carl Alexander’s How I setup my 2021 MacBook Pro article. I wanted to show how I’ve set up my development environment, but also have it saved somewhere in case I need to redo it again sometime in the future 😅.

Testing things out

I knew that Windows 10 had Windows Subsystem for Linux (WSL) support for a while, so that was a comforting thought. Previously you either had to mess with the PowerShell, or install gitbash, and it was a bit odd to work with, in my opinion. But given that I had a brand new, clean computer, I wanted to play around a bit.

One huge drawback Mac has is working with Docker. I’m not sure if anything got better with the new M1 processors. I remember reading articles about how it didn’t work at all when it came out, but maybe they fixed it in the meantime. The problem for me (when I tried using Docker as my daily driver) was that the file sync on Mac with Docker was just too slow. I’ve tried out everything, Devilbox, some weird listener/propagation hacks. It just didn’t work. That’s because, on Mac, the Docker has to run using virtualization, they’re not sharing the same kernel as on Linux machines, or something like that.

But I had a PC, so things should work out better here, right?

Well, it depends. I’ve played around with it and ended up with some slowdown issues as well. I was using WSL2 with Docker Desktop, and while it worked, I had to pay attention from where I started my project, to start my docker, I haven’t played around with the certificates, and running WP-CLI commands in order to do any work on my WordPress projects meant I had to provide the –ssh flag in order to run the WP-CLI on the Docker instance. I could just use the alias command but I learned about it way later.

So Docker was out of the picture.

Terminal it is

So I’ve decided that I’d like to just work with the terminal. It has to be smooth sailing – I turn everything on, and it just works.

Well, I’m still not there quite yet, but it’s getting better.

The thing you need to know about me is that I’m a person who likes to test things and tinker with different development solutions. I like to play around with different PHP versions for instance. On my Mac, I used Laravel Valet as my dev environment. It’s lightweight and it works beautifully. So I tried installing valet-wsl. It’s Valet, but for WSL and ubuntu on it. And it worked. Kinda. Remember the multiple PHP versions thing I’ve mentioned? Yeah, using something like phpenv with valet-wsl means you need to modify things a bit. Removing services, linking services. It was a process.
I got it working, but there were a few hiccups.

One of the bigger hiccups was Xdebug not working properly. I never got to the bottom of it to be honest. I’ve set up my external IP address, ports, and everything and I couldn’t get the step debugging to work on my PhpStorm. That sucked big time. I really love using Xdebug. It’s a tool that just speeds up my development a ton.

So about a month or so ago I decided to start from scratch. And this time I wrote down what I did

Backup first

I had a lot of projects on my computer. From client projects to personal ones I played with. So I backed up my databases (important ones) and made a copy of my WSL setup. I followed this article to make a WSL backup, which took around half an hour and produced a 50GB image.

Always backup your data. That should be step one of any project you do. Whether it’s updating your site, storing images, whatever. You never know what can go wrong, so it’s good to have a fallback.

After I cleaned everything up, I was left with a clean Ubuntu 20.04 installation that I could access through the Windows Terminal app.

Shell

I’m a sucker for pretty things. That’s just the way it is. Because of that, I’m not using the default bash shell for my terminal. I’m using zsh (z shell) and Oh My Zsh, as a zsh framework that has tons of cool helper functions. Remember I like things to look pretty? Besides just using Oh My Zsh, I’m also using material colors, and exa which is a Rust-based replacement for the ls command. In order to set it up, you can type this in your terminal

sudo apt-get install zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
git clone https://github.com/zpm-zsh/material-colors ~/.oh-my-zsh/custom/plugins/material-colors
wget http://archive.ubuntu.com/ubuntu/pool/universe/r/rust-exa/exa_0.9.0-4_amd64.deb
sudo apt-get install ./exa_0.9.0-4_amd64.deb
rm exa_0.9.0-4_amd64.debCode language: Bash (bash)

Since I’m using git all the time, I like to check out my diffs before committing my code to the repository. For that, I’m using diff-so-fancy

sudo add-apt-repository ppa:aos1/diff-so-fancy
sudo apt-get update
sudo apt-get install -y diff-so-fancyCode language: Bash (bash)

Finally, a thing I found out recently is that you can have a syntax-colored cat command using pygments. Which comes in handy when working in the terminal. For this, you need to have Python 3 and pip installed

apt-get install python3-pip
sudo pip3 install pygmentsCode language: Bash (bash)

Node

I’m working on web projects so I need to have Node.js installed. But since I need to be able to quickly change versions to check if there’s an error during builds on different versions, I’m using nvm, or Node Version Manager.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
nvm install 16.13.1
nvm use nodeCode language: Bash (bash)

Be sure to check the latest release of nvm on their GitHub repo, and use LTS version of node. It’s the safest route to take for a start.

PHP

For easier PHP version handling I’m using phpenv. It follows the same logic as nvm and rbenv for Ruby version management. They are all cool shell scripts that help you manage multiple versions of your languages (or runtime environments in the case of Node).

curl -L https://raw.githubusercontent.com/phpenv/phpenv-installer/master/bin/phpenv-installer | bash

sudo apt update && sudo apt install -y build-essential re2c libxml2-dev libssl-dev libsqlite3-dev bison pkg-config libbz2-dev libcurl4-gnutls-dev libjpeg-dev libpng-dev libmcrypt-dev libtidy-dev libxslt1-dev zlib1g-dev libcurl4-openssl-dev libonig-dev php-imagick libedit-dev libreadline-dev libxslt-dev libzip-dev autoconf

phpenv install 7.4.26
phpenv install 8.0.13
phpenv install 8.1.0

phpenv global 7.4.26
phpenv local 8.0.13Code language: Bash (bash)

The second line where I’m installing all the different extensions was an install/fail/repeat process, to be honest. If you try to just install, for instance, PHP 7.4 using phpenv it will fail with the message saying which extension you’re missing. Which is neat. So you just pile it onto the list.

I’m actively using 7.4 for development, again, mostly because the majority of my projects are WordPress-based. But I have some Laravel projects where I can use PHP 8 and 8.1 with all their goodies.

After the installation, you’ll need to check the user and group in the ~/.phpenv/versions/$VERSION/etc/php-fpm.d/*.conf and change it to your current user (which you can check using whoami command).

Nginx

Because the projects I’m working on are web-based, I’m using Nginx as my webserver. It’s a tried and tested solution, although it’s not super easy to configure, especially if you’ve never worked with it.

sudo apt-get -y install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
    | sudo tee /etc/apt/preferences.d/99nginx

sudo apt-get install -y nginxCode language: Bash (bash)

For Nginx config, I recommend using https://github.com/h5bp/server-configs-nginx, with some modifications. For instance, I’ve added the fastcgi_params from the default installation, and I’ve modified the default template located in /etc/nginx/conf.d/templates/example.com.conf

# ----------------------------------------------------------------------
# | Config file for actual-hostname host                                   |
# ----------------------------------------------------------------------
#
# This file is a template for an Nginx server.
# This Nginx server listens for the `actual-hostname` host and handles requests.
# Replace `actual-hostname` with your hostname before enabling.

# Choose between www and non-www, listen on the wrong one and redirect to
# the right one.
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#server-name-if
server {
  listen [::]:443 ssl http2;
  listen 443 ssl http2;

  server_name www.example.test;

  include h5bp/tls/ssl_engine.conf;
  include h5bp/tls/certificate_files.conf;
  include h5bp/tls/policy_balanced.conf;

  return 301 $scheme://example.test$request_uri;
}


server {
  # listen [::]:443 ssl http2 accept_filter=dataready;  # for FreeBSD
  # listen 443 ssl http2 accept_filter=dataready;  # for FreeBSD
  listen [::]:443 ssl http2;
  listen 443 ssl http2;

  # The host name to respond to
  server_name example.test;

  include h5bp/tls/ssl_engine.conf;
  include h5bp/tls/certificate_files.conf;
  include h5bp/tls/policy_balanced.conf;

  # Path for static files
  root /home/dzoljom/Sites/example;

  # Custom error pages
  include h5bp/errors/custom_errors.conf;

  # Include the basic h5bp config set
  include h5bp/basic.conf;

  # Favicon notices
  location = /favicon.ico {
    log_not_found off;
    access_log off;
  }

  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
  }

  location / {
    # URLs to attempt, including pretty ones.
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {
    #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    try_files                $uri =404;
    fastcgi_split_path_info  ^(.+\.php)(/.+)$;
    fastcgi_pass             127.0.0.1:9000;
    fastcgi_index            index.php;
    fastcgi_intercept_errors on;
    fastcgi_param            SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include                  fastcgi_params;
  }
}Code language: Nginx (nginx)

You can modify this to work for you ofc. Note the paths where it says, /home/dzoljom/Sites/example that’s something you’ll obviously want to change 😄.

But whenever you are making changes to your Nginx config, you can test it using sudo nginx -t command.

I’ve heard of Caddy but I haven’t gotten around to playing with it. To be honest, my current setup is working fine, so I don’t want to fix things that aren’t broken 😄.

MySQL

For MySQL I’ve installed version 8 and, to my surprise, it’s working just fine with WordPress. I was skeptical because there were some changes that affected the WordPress installations, but so far so good.

sudo apt-get install -y mysql-server
sudo /etc/init.d/mysql start
sudo mysql_secure_installationCode language: Bash (bash)

After setup just change the root password by logging in

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';Code language: SQL (Structured Query Language) (sql)

Since it’s for local development, you don’t need to have a password set up.

WP-CLI

WP-CLI is an indispensable tool when you work with WordPress and terminal. It can speed up your development a lot. From installing different versions, plugins, tinkering with it. It’s just an amazing tool all around.

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wpCode language: Bash (bash)

Mailhog

Last but not the least, I like to use Mailhog to test emails in case I need to modify some email functionality. First you’ll need to download mailhog and mhsendmail

wget https://github.com/mailhog/MailHog/releases/download/v1.0.0/MailHog_linux_amd64
mv MailHog_linux_amd64 mailhog
chmod +x mailhog
sudo mv mailhog /usr/local/bin/mailhogCode language: Bash (bash)

Then, in order for it to start automatically, you can create the init script

sudo nano /etc/init.d/mailhogCode language: Bash (bash)

With the following contents

#! /bin/sh
# /etc/init.d/mailhog
#
# MailHog init script.
#
# @author Jeff Geerling
# @author Renato Mendes Figueiredo

### BEGIN INIT INFO
# Provides:          mailhog
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start MailHog at boot time.
# Description:       Enable MailHog.
### END INIT INFO

PID=/var/run/mailhog.pid
USER=nobody
MAILHOG_PATH=/usr/local/bin/mailhog
MAILHOG_OPTS="-api-bind-addr=127.0.0.1:8025 -ui-bind-addr=127.0.0.1:8025"

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting mailhog."
    start-stop-daemon --start --pidfile $PID --make-pidfile --user $USER --background --exec $MAILHOG_PATH -- $MAILHOG_OPTS
    ;;
  stop)
    if [ -f $PID ]; then
      echo "Stopping mailhog.";
      start-stop-daemon --stop --pidfile $PID
    else
      echo "MailHog is not running.";
    fi
    ;;
  restart)
    echo "Restarting mailhog."
    start-stop-daemon --stop --pidfile $PID
    start-stop-daemon --start --pidfile $PID --make-pidfile --user $USER --background --exec $MAILHOG_PATH -- $MAILHOG_OPTS
    ;;
  status)
    if [ -f $PID ]; then
      echo "MailHog is running.";
    else
      echo "MailHog is not running.";
      exit 3
    fi
    ;;
  *)
    echo "Usage: /etc/init.d/mailhog {start|stop|status|restart}"
    exit 1
    ;;
esac

exit 0Code language: Bash (bash)

You’ll need to give it executable permission sudo chmod +x /etc/init.d/mailhog, and register it to system startup using update-rc.d mailhog defaults. Then download the mhsendmail for Linux

wget https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64
sudo chmod +x mhsendmail_linux_amd64
sudo mv mhsendmail_linux_amd64 /usr/local/bin/mhsendmailCode language: Bash (bash)

And make sure you modify the sendmail_path in your php.ini

sendmail_path="/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"Code language: Bash (bash)

You can use php --ini to quickly find your php.ini location.

In WordPress, you’ll probably need to install the Mailhog for WordPress plugin in order for it to work.

You can create a mailhog host in your Nginx config in /etc/nginx/conf.d/mailhog.conf

server {
   listen 80;

   server_name localhost;
   location /mailhog/ {
     proxy_pass http://127.0.0.1:8025/;
     proxy_set_header Host $host;

     proxy_http_version 1.1;
     proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection "upgrade";
   }
}Code language: Nginx (nginx)

Going to http://127.0.0.1:8025/ should open mailhog.

Xdebug

Installing Xdebug is super easy. You can install it by typing

sudo apt-get install php-xdebugCode language: Bash (bash)

or using pecl (recommended)

pecl install xdebugCode language: Bash (bash)

Once installed, if you type php -v you should see something like this

PHP 7.4.26 (cli) (built: Nov 28 2021 16:32:22) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.26, Copyright (c), by Zend Technologies
    with Xdebug v3.1.1, Copyright (c) 2002-2021, by Derick RethansCode language: Bash (bash)

my xdebug.ini file looks like this

zend_extension="/home/dzoljom/.phpenv/versions/7.4.26/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so"
xdebug.mode=debug,develop
xdebug.client_host=172.21.176.1
xdebug.start_with_request=trigger
xdebug.output_dir=/tmp
xdebug.profiler_output_name=cachegrind.out.%p
xdebug.trace_format=0
xdebug.trace_output_name=trace.%cCode language: Bash (bash)

Since I’m working in WSL, the WSL IP address will change every time I restart the terminal app. It’s a known feature of WSL that annoys a lot of people.

I’ve made a cool alias that will quickly find the external IP address to use

alias findIP="ip route show default | awk '{print $3}'"Code language: Bash (bash)

For amazing tutorials regarding Xdebug, check Derick Rethans YouTube channel: https://www.youtube.com/c/DerickRethansXdebug/videos

Wrapping it up

It takes some time to set everything up, but once you’re done it’s a walk in the park.

We can check out how my .zshrc config file looks like

# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
ZSH_DISABLE_COMPFIX=true

# Path to your oh-my-zsh installation.
export ZSH="/home/dzoljom/.oh-my-zsh"

# Additional path exports
export PATH=~/.config/composer/vendor/bin:$PATH
export PATH=$HOME/bin:/usr/local/bin:/sbin:/usr/sbin:$PATH
export PATH=$PATH:~/.local/bin
export PATH="$PATH:$HOME/.local/bin"
export LANG=en_US.UTF-8

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="agnoster"

plugins=(
    git
    gitfast
    docker
    wp-cli
    material-colors
)

source $ZSH/oh-my-zsh.sh

# gpg fix
export GPG_TTY=$(tty)

# NVM
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

# X Server
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0

# PHPENV
export PHPENV_ROOT="/home/dzoljom/.phpenv"
if [ -d "${PHPENV_ROOT}" ]; then
  export PATH="${PHPENV_ROOT}/bin:${PATH}"
  eval "$(phpenv init -)"
fi

# Exa colors
LS_COLORS="*.php=35:*.js=33:*.scss=31:*.css=31😄i=32"

# Load seperated config files
for conf in "$HOME/terminal-config/"*.zsh; do
  source "${conf}"
done
unset confCode language: Bash (bash)

First, we have some path exports. Then you see the theme I’m using for my shell. It’s agnoster. After that you can see the plugins I like to use. These plugins will expose some shortcuts that you can use in the terminal. After that, we have some exports for GPG, NVM, PHPENV (most of these should be automatically set up after installations).

Image showing the WSL terminal with new colors settings
The look of my terminal colors

I’ve set up the exa colors for specific files (which makes checking for the file types in the terminal a lot easier).

The last part loads the different parts of the terminal config I have that are synced to my private GitHub repo. In that repo, I have my terminal settings saved so that I can easily reuse them on different platforms (Mac, PC, etc.). I have my .gitconfig file there, .gitignore_global file, .nanorc, .ssh folder, and all the zsh commands I’m using. The commands are split into three parts: aliases, functions, and secrets.

aliases.sh contain all the useful shortcuts I’m using on a daily basis

# Highlight
alias highlight="pbpaste | highlight --syntax=js --style=Moria --font-size=30 --font=Input\ Mono --replace-tabs=2 -O rtf | pbcopy"

# Exa - https://github.com/ogham/exa
alias ll="exa --long --header --git"

# Tree alias
alias tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'"

# cd shorthands
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."

# zsh edits
alias zshconfig="nano ~/.zshrc"
alias ohmyzsh="nano ~/.oh-my-zsh"

# Composer aliases
alias cda="composer -o dump-autoload"
alias ci="composer install"
alias cu="composer update"
alias compProd="composer install --no-ansi --no-dev --no-interaction --no-progress --no-scripts --optimize-autoloader"

# PHP Documentor
alias phpdoc="php /usr/local/bin/phpDocumentor.phar"

# SVG Optimization
alias svgall='for i in *.svg; do svgo "$i"; done'

# Docker
alias dpsa="docker ps --all"
alias dima="docker images --all"
alias drm="docker rm"
alias drmi="docker rmi"
alias dsp="docker system prune"
alias dcu="docker-compose up"
alias dcr="docker-compose rm"
alias dc="docker-compose"
alias ds="docker stop"
alias dst="docker start"
alias dn="docker network"
alias dv="docker volume"
alias dr="docker restart"
alias dl="docker logs"
alias de="docker exec"

# Git
alias prune-branches="git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d"

# Symfony console
alias console="php bin/console"

# Laravel shortcuts
alias artisan="php artisan"

# Nano - nano with custom config
# alias nano="/usr/local/bin/nano"

# Python
alias python='/usr/bin/python3'

# Mailhog start
alias startMailhog="/usr/local/bin/mailhog \
-api-bind-addr 127.0.0.1:8025 \
-ui-bind-addr 127.0.0.1:8025 \
-smtp-bind-addr 127.0.0.1:1025"

# Clean Zone.Identifier files on windows
alias cleanzone='find . -type f -name "*:Zone.Identifier" -delete'

# PhpStorm
alias pstorm="/mnt/c/Program\ Files/JetBrains/PhpStorm\ 2021.1.2/bin/phpstorm64.exe "$(wslpath -w .)""

# Xdebug WLS IP address
alias findIP="ip route show default | awk '{print $3}'"

# Colorize cat command
alias cats='pygmentize -g'Code language: Bash (bash)

functions.sh contain useful functions I’m using to create sites, restart the development server, etc.

# WP-CLI site setup
# Usage create-site {folder name} {database name} {site title}
create-site () {
  mkdir $1 && cd $1
  wp core download --skip-content;
  wp config create --dbname=$2 --dbuser=root;
  wp config set DB_HOST "127.0.0.1"
  mkdir wp-content && mkdir wp-content/themes && mkdir wp-content/plugins;
  (
      wp db create || true
      wp core install --url="$1"".test" --title=$3 --admin_user=admin --admin_password=password --admin_email=admin@sitetitle.com
  )
  cd /etc/nginx/conf.d
  sudo cp templates/example.com.conf .$1.test.conf
  sudo sed -i "s/example/$1/g" .$1.test.conf
  sudo mv .$1.test.conf $1.test.conf
  make-certificate $1.test
  restart-server
  cd "$HOME/Sites/$1"
}

# PhpStorm hack for phar files on WSL2
cleanPhar () {
  php -r '$phar = new Phar("vendor/phpstan/phpstan/phpstan.phar"); $phar->extractTo("vendor/phpstan/phpstan/phpstan.tmp");';
  rm vendor/phpstan/phpstan/{phpstan,phpstan.phar};
  mv vendor/phpstan/phpstan/{phpstan.tmp,phpstan};
}

# Host addition for Windows
# This will link the sites to the Win hosts so that they are exposed to browser
# Will fail if the linux distro is not run as admin. Which is something we don't usually want
add-host () {
  sudo echo "127.0.0.1 $1" >> /mnt/c/Windows/System32/drivers/etc/hosts
  echo "$1 was added to the hosts file."
}

# Restart server
restart-server() {
  PHP_VERSION=$(php -r 'echo PHP_VERSION;')
  # Restart mysql
  sudo service mysql restart
  # Restart nginx
  sudo service nginx restart
  # Restart PHP-FPM
  sudo ~/.phpenv/versions/$PHP_VERSION/etc/init.d/php-fpm restart
}

# Generate a self-signed SSL certificate
# Usage make-certificate site-name
make-certificate() {
  cd /etc/nginx
  if [ ! -d "/etc/nginx/certs" ]
  then
      sudo mkdir /etc/nginx/certs
  fi
  sudo openssl req -newkey rsa\:2048 -nodes -keyout /etc/nginx/certs/$1.key -x509 -days 365 -out /etc/nginx/certs/$1.crt
}Code language: Bash (bash)

When working with Windows you must remember that in order for your local site to be visible to the browser you need to add it to the hosts file. And that is one thing I still need to do manually (because I’d have to allow my WSL Linux to tamper with my Windows System files, which is a security no-no).

secrets.sh file contains exports of things like my GitHub Actions token, some secret vault tokens, etc. Basically anything confidential.

Git

Since I’ve mentioned using git, I can share an example of my .gitconfig file

[user]
  email = john.doe@mail.com
  name = John Doe
  username = johnny_d
  signingkey = GPG_SIGNIN_KEY
[help]
  autocorrect = 0
[diff]
  tool = default-difftool
[difftool "default-difftool"]
  cmd = 'nano'
[core]
  editor = nano
  excludesfile = /Users/john.doe/.gitignore_global
  ignorecase = false
  pager = diff-so-fancy | less --tabs=4 -RFX
[push]
  default = current
[alias]
  aa = add
  st = status
  co = checkout
  ci = commit
  cl = clone
  ps = push
  br = branch
  pl = pull
  t  = tag
  hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
  type = cat-file -t
  dump = cat-file -p
[color]
  ui = true
[color "diff-highlight"]
  oldNormal = red bold
  oldHighlight = red bold 52
  newNormal = green bold
  newHighlight = green bold 22
[color "diff"]
  meta = yellow
  frag = magenta bold
  commit = yellow bold
  old = red bold
  new = green bold
  whitespace = red reverse
[gpg]
  program = gpg
[commit]
  gpgsign = true
[pull]
  ff = onlyCode language: Bash (bash)

I like to sign my commits, so I’m using GPG for that. You can set it up by following the tutorial on GitHub.

My .gitignore_global file looks like this:

# An example global gitignore file
#
# Place a copy if this at ~/.gitignore_global
# Run `git config --global core.excludesfile ~/.gitignore_global`
# Compiled source #
###################

*.com
*.class
*.dll
*.exe
*.o
*.so
*.pyc
*.pyo

# Packages #
############

# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
*.msi

# Logs and databases #
######################

*.log
*.sql
*.sqlite

# OS generated files #
######################

.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
desktop.ini

# Temporary files #
###################

*.bak
*.swp
*.swo
*~
*#

# IDE files #
#############

.vscode
.idea
.iml
*.sublime-workspace
*.sublime-project
envCode language: Bash (bash)

SSH

This is another thing that I like to keep in sync with the different computers I’m working on. SSH-ing or SCP-ing on a host machine is something I do almost every day, so it’s good to have my private keys shared so that I can SSH without much trouble. It’s probably not the best practice, but it works for me. ssh-agent comes installed out of the box on Ubuntu 20.04 so the only thing I need to take care of is to have it in my ~/.ssh/config the following

Host *
  AddKeysToAgent yes
  TCPKeepAlive yes
  ServerAliveInterval 15
  IdentityFile ~/.ssh/id_rsaCode language: Bash (bash)

The AddKeysToAgent part will tell SSH to use ssh-agent to store keys, the TCPKeepAlive and ServerAliveInterval will make sure my connection to the server doesn’t time out if I walk away from tinkering with it for a while, and the IdentityFile just says what my default private key should be used. If you have multiple keys I think you can leave that out.

Other than that I have tons of different hosts in there, which helps me out when SSH-ing to a server. For instance you’ll have

Host hostname-staging
  Hostaname hostname.staging.com
  Port 234
  User staging_user
  IdentityFile ~/.ssh/hostname_rsaCode language: Bash (bash)

Then you can just type in your terminal

ssh hostname-stagingCode language: Bash (bash)

And you’re good to go.

That’s all folks

This was a long article, and kudos if you made it to the end 😄 I hope this helps people out if they want to go into the journey of setting their development environment up on their Windows machines. That doesn’t mean it’s the ultimate best way to do it, and that you must do it this way. It’s just how I’ve set up my computer and what suites me best at this moment 🙂

Hope you have a great new year. For me, I hope I’ll write more next year (which I think is something I say every year lol), and hope to work on cool and exciting projects in the future.

Stay safe ✌🏼

2 responses

  1. Za PC nije na odmet istražit Laragon (https://laragon.org).

    1. Nisam probao Laragon, ali pogledam :) Hvala!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.