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.deb
Code 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-fancy
Code 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 pygments
Code 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 node
Code 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.13
Code 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 nginx
Code 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_installation
Code 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/wp
Code 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/mailhog
Code language: Bash (bash)
Then, in order for it to start automatically, you can create the init script
sudo nano /etc/init.d/mailhog
Code 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 0
Code 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/mhsendmail
Code 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-xdebug
Code language: Bash (bash)
or using pecl (recommended)
pecl install xdebug
Code 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 Rethans
Code 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.%c
Code 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 conf
Code 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).
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 = only
Code 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
env
Code 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_rsa
Code 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_rsa
Code language: Bash (bash)
Then you can just type in your terminal
ssh hostname-staging
Code 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 ✌🏼
Leave a Reply