The Windows Subsystem for Linux (WSL) seems to be mature enough now to give it another shot. Copy and paste, and other simple annoyances that kept me away before are working better. Also, I’ve been reading that nvm (Node Version Manager) works now, so here goes.
As a precursor, note that my system is Windows 10 Professional (version 1709, build 16299.309) and is fully up to date with WSL enabled and Ubuntu installed from the Windows Store.
If it has been a while, first thing I like to do with the Ubuntu app is update and upgrade the ubuntu Linux packages. First update the package database with apt-get update, then upgrade with apt-get upgrade or apt-get dist-upgrade. I prefer apt-get dist-upgrade since it will remove obsolete packages and add new ones as needed.
Windows update does not change the WSL Ubuntu installation. To upgrade to a new release, run sudo do-release-upgrade in the Ubuntu Terminal.
Oh My Zsh
Oh My Zsh will spruce up your Ubuntu bash and add some additional functionality. Here is a screenshot of my Ubuntu app to illustrate.
If you want to use your existing git and/or other ssh keys, copy them from their folder in Windows into a .ssh folder under ubuntu. For example,
# navigate to Windows .ssh folder, e.g.,
# copy the keys into ubuntu .ssh folder
cp id_rsa ~/.ssh/
cp id_rsa.pub ~/.ssh/
# set permissions on the private key for github
chmod 600 ~/.ssh/id_rsa
nvm is a utility for installing and managing multiple versions of node.js.
Install as an Oh My ZSH! custom plugin by cloning zsh-nvm into your custom plugins repo.
Then load as a plugin in your .zshrc profile. Note that plugins need to be added before oh-my-zsh.sh is sourced. For example, here is a snippet from my .zshrc profile.
# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
After updating your .zshrc profile to load the nvm plugin, close and re-open the Ubuntu app and to install nvm when the plugin is loaded for the first time.
One the install has completed, you can verify by running nvm which should output the nvm --help contents.
Install the latest LTS version of Node.js which at the time of this writing is version 8.11.1
Bind a custom mount for any drives you want to access. For example, the C drive. This is also required should you want to use Docker volume mount paths as described in this post by Nick Janetakis.
mount --bind /mnt/c /c
Included in Windows 10 version 1803 (April 2018 Update) is support for WSL launch configuration. The /etc/wsl.conf file contains settings for drive mounting and network configuration. Read the Microsoft Developer blog post, Automatically Configuring WSL for more information on how to use wsl.conf
If you want to browse the files using Windows Explorer and/or backup the root file system, the location of these files is in the hidden AppData folder. For example:
For installation, I downloaded the 64-bit Ubuntu Server 16.04.3 LTS (ubuntu-16.04.3-server-amd64.iso) bootable image from ubuntu.com/download/server.
Docker requires a 64-bit installation with version 3.10 or higher of the Linux kernel.
Create a Virtual Switch
Open Hyper-V Manger and select Virtual Switch Manager, and from there, select Create a Virtual Switch. For example,
Name: WiFi Virtual Switch
Connection type: External Network
Killer Wireless n/a/ac 1535 Wireless Network Adapter
With Hyper-V, To get external internet/network access with your VM, you need to create an External Virtual Switch. This will use your networks DHCP server, bridge mode if you will.
For a VPS, it is recommended that a non-root user with sudo privileges is used instead of root. Therefore, create a new user and add them to the sudo group. Instructions are available in the sudo section on my Linux page. After that’s done, disallow root password login.
ufw instead of csf
The default firewall configuration tool for Ubuntu is ufw. To use ufw instead of ConfigServer Firewall, configure and enable ufw prior to installing Docker. For example:
# allow incoming port 22
ufw allow ssh
# allow incoming ports
ufw allow 80
ufw allow 443
# turn it on
ufw status verbose
To Action From
-- ------ ----
22 ALLOW IN Anywhere
80 ALLOW IN Anywhere
443 ALLOW IN Anywhere
22 (v6) ALLOW IN Anywhere (v6)
80 (v6) ALLOW IN Anywhere (v6)
443 (v6) ALLOW IN Anywhere (v6)
To install the latest version of Docker, add the GPG key for the official Docker Ubuntu repository as a trusted APT repository key.
Ensure that APT pulls from the correct repository.
apt-cache policy docker-ce
Install the latest version of Docker CE.
sudo apt-get install -y docker-ce
Docker should now be installed, the daemon started, and the process enabled to start on boot. Check that it’s running.
sudo systemctl status docker
To get the latest release, install Docker Compose from Docker’s GitHub repository. Visit https://github.com/docker/compose/releases to lookup the version number. Then use curl to output the download to /usr/local/bin/docker-compose. For example,
# check current release, update as needed
sudo curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# make executable
sudo chmod +x /usr/local/bin/docker-compose
# verify installation
Config Server Firewall (CSF)
Config Server Firewall contains a straight forward easy to understand configuration file. CSF also comes with a Login Failure Daemon that will alert you of large scale login attempts on ssh, mail and other servers. CSF also allows you to whitelist or blacklist IP addresses aside from the LFD real time monitoring and automatic IP blocking.
Disable the default firewall service.
sudo ufw disable
Since CSF is currently not available in the Ubuntu repositories, download it from the ConfigServer’s website into the home directory.
Unpack the downloaded TAR archive.
tar -xvzf csf.tgz
Run the install script.
sudo bash install.sh
Verify the installation,
sudo perl /usr/local/csf/bin/csftest.pl
If everything is fine, you should see the following output.
RESULT: csf should function on this server
Optional cleanup: remove unpacked TAR files after the install has been verified.
rm -rf csf
The next page covers CSF Docker configuration, basic auth for port specific password protection and Traefik Docker configuration.
Disallow root password login
Restart the service for any config changes to take affect
service ssh restart
Allows a user to run a command as another user, usually root. For a user to do this, they need to be added to the sudo group.
usermod -aG sudo gilfoyle
Logout Ctrl + D and test new user sudo access. Substitute 0.0.0.0 with the server IP address.
# list files in the /root directory
sudo ls -la /root
After sudo is enabled for the new user account, root password login can be turned off in the sshd_config file.
To prevent unable to resolve host message when using sudo, update the hosts file to contain the hostname for 127.0.0.1. For example, what is after @ in the command line prompt. e.g., gilfoyle@vpshostname.
Shell scripts are plain text files with an .sh extension.
If permission denied, the shell script may just need to be made executable. Example: for a script named backup.sh, using chmod u+x backup.sh will grant only the owner of the file execution permissions. For all users, replace the u with an a. You could also use chmod +x backup.sh which is the same as chmod a+x backup.sh.
This OS X example uses rsync to backup the Documents folder on the hard drive to an existing Documents folder on a Lexar USB stick. The --delete-before option deletes files from the target that do not exist in the source before rsync.
if [ -d "/Volumes/Lexar/Documents" ];
rsync -avP "/Volumes/Macintosh HD/Users/Woz/Documents/" "/Volumes/Lexar/Documents/" --delete-before
Use the --exclude option to prevent specific files and folders from being synced. This example excludes .DS_Store files, .git and node_modules folders from the backup.
if [ -d "/Volumes/Lexar/Code" ];
rsync -avP --exclude .DS_Store --exclude .git --exclude node_modules "/Volumes/Macintosh HD/Users/Dinesh/Code/" "/Volumes/Lexar/Code/"
These shell script examples are written for Cygwin and /cygdrive/c is how the C: drive of Windows is accessed. For Cygwin, the rsync package would need to be installed. On OS X and Linux, rsync is usually included in the system install.
This example uses rsync to backup an existing file to a server share.
if [ -f /cygdrive/c/Users/Gilfoyle/Dropbox/Private/Hooli.xlsx ];
rsync -avP /cygdrive/c/Users/Gilfoyle/Dropbox/Private/Hooli.xlsx //FILESERVER/share/Hooli.xlsx
This example uses rsync to backup an existing Private Dropbox folder to a server share.
if [ -d /cygdrive/c/Users/Gilfoyle/Dropbox/Private ];
rsync -avP /cygdrive/c/Users/Gilfoyle/Dropbox/Private/ //FILESERVER/share/
This example checks for the existing source directory and creates a compressed archive in the current directory with a datetime string included in the filename. The source directory and its contents will be added to the archive while exluding node_modules .git and sass.cache
if [ -d /cygdrive/c/Users/Dinesh/Code ];
tar -zcvf code_$now.tar.gz --exclude .git --exclude node_modules --exclude sass.cache /cygdrive/c/Users/Dinesh/Code
This blog post addresses a common scenario — a local LAMP development environment on your Windows or OS X computer. You could use XAMPP on either Windows or OS X, MAMP on OS X or native Apache in OS X. Here, we will create a Linux virtual machine with Samba configured to share the Virtual Machine file system with the host computer. We will also create virtual hosts, install and configure WordPress and Xdebug.
First thing you will need is Virtual Machine software. For my Virtual Machine, I chose to install the free VMware Player. If your host operating system is OS X, you can install VirtualBox if you do not want to purchase VMware Fusion or Parallels. You could also use VirtualBox on a Windows host instead of VMware if you prefer.
Next, you will need to create a Linux virtual machine. I decided to Download Ubuntu Server 32 bit since it is compatible with the intel processor of my host computer.
After creating a new VM and installing Linux, time to get our dev environment setup. Install SSH so we can run commands from the host. Later we will use ssh to to tunnel the Xdebug connection from the VM back to the host.
Since we have set the hosts file to map 192.168.59.129 to ubuntu.vm, once you disconnect your current ssh session (Ctrl+D), you will need to use the host alias you specified in the hosts file to reconnect.
Samba Network Share
You can use Samba to share the /var folder in you virtual machine.
# install Samba
$ sudo apt-get install samba
Linux system permissions take precedence over Samba permissions. For example if a directory does not have Linux write permission, setting samba writeable = Yes will not allow to write to shared directory / share.
# edit Samba config
$ sudo nano /etc/samba/smb.conf
####### Authentication #######
security = user
# bottom of smb.conf
path = /etc
browsable = yes
read only = no
create mask = 0755
admin users = jim
path = /home
browsable = yes
read only = no
create mask = 0755
admin users = jim
path = /var
browsable = yes
read only = no
create mask = 0755
admin users = jim
Ctrl+C to exit nano, press Y to save and return to write your changes to the file.
Install the PAM authentication module for Samba which will sync the system users to the Samba user database.
# Install libpam-smbpass package
$ sudo apt-get install libpam-smbpass
# restart Samba for the new settings to take effect
$ sudo restart smbd
$ sudo restart nmbd
# set user jim as the owner of share directory
$ sudo chown -R jim /var/www
For OS X, open Finder, select Go > Connect to Server (command + K). Enter the server address: smb://ubuntu.vm and select Connect
For Windows, select Run from the Start menu or open Windows Explorer and enter:
Server Time Synchronisation
Server time is likely to become inaccurate in our development scenario. We can use Ubuntu’s NTP server and NTP’s server pool to keep the server datetime accurate.
# install ntp
$ sudo apt-get install ntp
# edit /etc/ntp.conf
$ sudo nano /etc/ntp.conf
# add these two lines
# change server time zone
$ sudo dpkg-reconfigure tzdata
Enabling Module Rewrite
The mod_rewrite Apache module is a rule-based rewriting engine to rewrite requested URLs. It is very useful for genarating SEO friendly URLs.
# enable the module
$ sudo a2enmod rewrite
# restart apache to activate the configuration change
$ sudo service apache2 restart
# download the latest WordPress to a downloads directory
$ mkdir ~/downloads
$ cd ~/downloads
$ wget http://wordpress.org/latest.tar.gz
# -z : Uncompress the resulting archive with gzip command.
# -x : Extract to disk from the archive.
# -v : Produce verbose output i.e. show progress and file names while extracting files.
# -f latest.tar.gz : Read the archive from the specified file.
# -C : To change the directory (current directory is default)
# this will create /var/www/wordpress since the archive root directory is wordpress
$ sudo tar -zxvf latest.tar.gz -C /var/www
# make yourself the owner
sudo chown jim /var/www/wordpress
Create MySql database, user and grant permissions in one line.
base_user is typically root
base_user_pass is password for base_user (no space between -p and base_user_pass is important)
mysql -u base_user -pbase_user_pass -e "create database new_db; GRANT ALL PRIVILEGES ON new_db.* TO new_db_user@localhost IDENTIFIED BY 'new_db_user_pass'"
If phpMyAdmin is installed, you can use it to create the wordpress database as described in this next section. Read my earlier blog post if you need help doing this,
Mint LAMP Development Environment
In the browser, goto http://ubuntu.vm/phpmyadmin/. Select the Databases tab and under “Create new database”, enter in a database name such as “wordpress”, and select Create. Collation will automatically be assigned by MySQL when the database tables are created, during the WordPress installation.
In the browser, goto http://wordpress.vm and start the installation. If you need to manually edit the wp-config.php file, you can do so with nano.
$ nano wp-config.php
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
/** MySQL database username */
/** MySQL database password */
/** MySQL hostname */
When debugging from the host computer, use ssh to tunnel the debug-connection back to it.
# ssh remote port forwarding
ssh -R 9000:localhost:9000 firstname.lastname@example.org
Using the “-R” argument tells ssh to listen on TCP port 9000 on the ubuntu server and forward it back through the ssh connection to the TCP port specified (localhost:9000). So from Xdebug’s perspective on the Ubuntu server, it is talking to localhost on the local computer.
I decided it was time to ditch my Linux 13 KDE setup and try the improved MATE 1.6 desktop now that Linux Mint 15 released. I find it pretty slick and fast, a nice change from Windows when I decide to do some development in a true LAMP environment. Speaking of which, we need to get that installed. Before doing that, the first thing I like to do is open up a terminal and run:
sudo apt-get update
This will download the package lists from the repositories and update them with information on the latest package versions. If you have not installed LAMP (Linux, Apache, MySQL & PHP) please read my earlier blog post, Mint LAMP Development Environment. Then you can return to this post to add an IDE with debugging capabilities along with some other nice tools.
sudo apt-get install php5-xdebug
PHP 5.4.9-4ubuntu2 (cli) (built: Mar 11 2013 16:09:26)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans
sudo pluma /etc/php5/mods-available/xdebug.ini
Add the following xdebug config values after the zend_extension path value so it looks like this.
The IDE I prefer for Drupal development as of this writing is NetBeans. I found this post, Configuring NetBeans for Drupal development to be very helpful. In the Usage section of the post, the author suggests using the sites folder of your Drupal installation when creating the New Project > PHP Application with Existing Sources. This did not work for me, instead, I selected the root folder of my Drupal install as the Sources Folder for the NetBeans IDE project import. By including the entire Drupal installation in my NetBeans project, I could step through and debug any of the Drupal code including modules in the sites folder.
As of this writing, the latest stable version of Eclipse was Eclipse Juno (4.2). I downloaded the Eclipse Classic 4.2.2 64 bit Linux version from http://www.eclipse.org/downloads/. Make sure you download the appropriate 32 or 64 bit version of Eclipse to match your Linux Mint operating system. To check which version of Linux Mint you are running, in a terminal, enter
i686 = 32-bit; x86_64 = 64 bit
Open up a terminal, change to the Downloads directory and and extract the archive.
tar xzf eclipse-SDK-4.2.2-linux-gtk-x86_64.tar.gz
With superuser permissions, move the extracted eclipse directory and its contents into the /opt/ folder.
sudo mv eclipse /opt/
Create a symbolic link so you can start Eclipse from a terminal
For Drupal development, since I already have a Linux Mint system setup, I decide to focus on it rather than the Windows 8 Acquia Drupal setup I blogged about a few days ago.
Apache, MySQL & PHP
Install all of these applications with a single command. Thanks to Unix System Engineer, Nitin Sookun for posting this on the Linux Mint Community website.
Since you will need root permissions when performing write operations outisde of your home directory, the commands shown below presume that you are logged in as root or are in a root instance of the terminal. If you are not in a root terminal, you can prepend the commands with ‘sudo’, for example listing the contents of the current directory:
In a root terminal (such as ‘Konsole as root’).
apt-get install lamp-server
If you get this error message (as I did during a Mint Xfce LAMP install)
Download the latest stable Drupal core distro from http://drupal.org/download. Extract the downloaded file, for example, drupal-7.19.tar.gz to the host root, /var/www. Then with the mv command, rename the drupal-7.19 directory extracted into www to drupal7
tar -xf drupal-7.19.tar.gz -C /var/www
mv /var/www/drupal-7.19 /var/www/drupal7
Copy the default.settings.php to settings.php. Then apply write permissions to both the dafault directory and the settings.php file so Drupal can modify settings.php as needed during the install.