I think, therefore I am. I am, therefore I sail

Category: Computing Page 1 of 51

How to fix the “sed command expects \” error on Mac OS

If you are familiar with the sed command on Linux then you might be in for an unpleasant surprise the first time you try to use it on Mac OS.

Mac OS runs the BSD version of the sed command. As such, there are some syntax differences.

An example of a classic sed command, that is used in build scripts everywhere:

sed -i 's/WORD/REPLACEMENT' file.txt

If you run that command on Mac OS you will be very grumpily greeted with the error:

sed: 1: "file.txt": command expects \ followed by text

huh?

Oh right, this is the BSD version of sed.

You could fiddle with the command until you find something that works on Mac OS. Then you have to ensure it still works on your Linux machines as well.

Or, you could bypass the issue and install the GNU sed via Homebrew.

I choose the second option. It is easier and none of my build scripts will require changes. It can be installed with:

brew install gnu-sed

After install, there will be a new command called gsed. This is great, but still requires updating everything using sed. Simple fix, alias sed in your shell profile. I am still a bash user, so I edit ~/.bash_profile and add the line:

alias sed='gsed'

Source the profile file and voila, the familiar sed version has been restored for you on Mac OS!

Happy sedding.

Photo by Green Chameleon on Unsplash

Highly Performant PHP Sessions with Redis

The web is stateless, but often the apps we build are not. To facilitate state in web apps, PHP provides a session handling mechanism. Sessions are off by default, and enabled with the `session_start()` function.

Read more about PHP session handling at https://www.php.net/manual/en/book.session.php

If you have worked with PHP sessions before you may have noticed performance issues caused by the `session_start()` function. On a small scale your app may be ok, but as you scale up issues will pop up. In particular, if the app makes several ajax calls back to the server during a page load there will see issues. This happens because PHP stores its sessions as files on the drive. During each request, PHP opens the session file for reads and writes. The file is locked during the request. That means if there are three ajax requests to the server, request two and three will be blocked waiting on the request in front of them.

By way of example, let’s assume the web server responds in 300 milliseconds for a single request and we have the initial request with three ajax requests that run asynchronously.

The load time should be: 
300 ms initial request + 300 ms ajax requests = 600 ms

When using PHP’s default session the load time becomes:
300 ms initial request + 300 ms ajax request one + 300 ms ajax request two + 300 ms ajax request three = 1,200 ms or about 1.2 seconds!

And that is a light example. With content systems, such as WordPress, shipping with a built in API, it has become common practice to send many requests to the server during a single page load.

To get around the file locking issue we have to change the session storage mechanism. PHP provides the ability to write custom session handlers. We could do that, or we can tap into the Redis session handler. Redis does not have the locking issue, and it is already set up to be highly scalable. File based sessions are dubiously scalable at best.

To get it running all we need to do is update two lines in the php.ini file to instruct PHP to use Redis and where to find the Redis server. I will not cover how to set up a Redis server in this article.

Open the php.ini file and add or update the following two config values:

  • session.save_handler
  • session.save_path

The session.save_path value instructs PHP where to find the Redis server.

For example, the config values may look something like:

session.save_handler = redis
session.save_path = tcp://1.2.3.4:6379

Restart the PHP service and you will see sessions being stored in Redis instead of the filesystem.

If you do not have access to the php.ini file do not give up hope! It is also possible to set these values during the application runtime with the following PHP code:

ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://1.2.3.4:6379');

Make sure those two lines run before the session_start() function is called.

Depending on the server configuration, it may also be possible to set this in a .htaccess file.

Congratulations! Your users will now experience a considerable performance boost, and you have taken another step towards building a highly scalable and performant site.

How to Detect Mobile Devices Accessing a Shopify Store

how you how to detect mobile devices accessing a Shopify store.

Shopify is a great platform for many ecommerce stores. Developing themes is simple with the Liquid template language, however it does have some drawbacks. Liquid templates are pre-rendered on the server and not able to respond dynamically to the device accessing the store. This means whether the customer is visiting from a desktop, tablet, or phone they will receive the exact same html content. There is no way to send custom content based upon the device the customer is connecting with.

I hear you thinking, “But wait, isn’t this article about mobile devices and Shopify?” Yes it is. In order to detect and serve different content to mobile devices another tool will be used, javascript.

Javascript runs on the browser, meaning it takes after the Shopify store has delivered the content to the customer. With a little care, it is possible to dynamically load content based on the customer’s device.

Here is the Javascript you can use. It has several browsers to detect in it. Customize the list as needed.

<script>
var isMobile = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|webOS|BlackBerry|IEMobile|Opera Mini)/i);if(isMobile){
// Mobile functionality
}else{
// Desktop functionality
}
</script>

It should be noted, Apple updated the iPad OS to request desktop versions of pages. This means that this method may not work 100% of the time for detecting an iPad.

Photo by Josh Sorenson on Unsplash

How to Make a Domain Proxy for Digital Ocean Spaces

Digital Ocean has been my go to solution for hosting for many years. When the Spaces service, an S3 compatible object store, was introduceed, I jumped on board right away. The service performs well and allows me to manage all the web infrastructure from one location.

The drawback with Spaces, to me, is how custom domains are handled. It is possible to do, but you have to turn over DNS control of the domain to Digital Ocean. That is not always possible or practical to do. For a couple years I have run various sites with the domain provided by Digital Ocean.

A default Spaces domain has the format: account.datacenter.digitaloceanspaces.com
For my personal blog this looks like: lobaugh.sfo2.digitaloceanspaces.com

A useable, but not very attractive domain. I decided to revisit the topic.

Nginx has some powerful proxy capabilities in it, and it turns out that it works quite well to create a domain proxy.

With the proxy enabled, visiting
https://assets.lobaugh.net/image.png
Will return the file from
https://lobaugh.sfo2.digitaloceanspaces.com/image.png

Running my own domain proxy does introduce additional complexity and slight overhead, but I am comfortable with it.

I will present the nginx.conf file in its entirety here, then walk through it below.

log_format upstream '[$time_local] Requested: $host$uri - Proxied $proxy_host - Response time remote $upstream_response_time request $request_time';proxy_cache_path /tmp/nginxcache levels=1:2 keys_zone=my_cache:10m max_size=2g 
inactive=600m use_temp_path=off;server {listen 80;location / {
proxy_cache my_cache;
proxy_pass https://lobaugh.sfo2.cdn.digitaloceanspaces.com$uri$is_args$args;
add_header X-Proxy-Cache $upstream_cache_status;
access_log /dev/stdout upstream;
}
}

That’s it! The configuration is fairly simple.

* log_format upstream — (optional) Establishes the format of the log file. Not needed if logging is disabled. Turning off logging may help performance.
* proxy_cache_path — Configures the nginx caching of the files from Spaces. A 10 minute cache, with a max of 2 gigabytes is created. Though not necessary, this will help save on server resources and wait time for clients.
* server.listen — Establish the web service
* server.location — Configure the web service
* proxy_cache — Sets up the previously configured cache
* proxy_pass — This is the meat and potatoes. This passes the call to assets.lobaugh.net to the Spaces service, and retrieves the file
* add_header — (optional) Adds a simple header item that allows us to inspect whether the response was cached. Can be safely left out
* access_log — Send the output of the log to /dev/stdout, based on the upstream format. Not needed if logging is disabled. Turning off logging may help performance

This is v1 of the configuration. Nginx provides a lot of neat options that can tweak and optimize it. To learn more about the options, here are a few helpful links:

https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/ 
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
https://dev.to/danielkun/nginx-everything-about-proxypass-2ona 
https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
https://www.nginx.com/blog/nginx-caching-guide/ 
https://dev.to/shameemreza/accelerate-your-website-with-nginx-as-a-reverse-proxy-cache-a9o

I am satisfied with this setup for now. It has allowed me to achieve the custom domain I wanted, and has minimal performance impact.

Using An iPad For Web Development

My obsession with using an iPad for web development started all the way back with the first generation iPad. Tools then were sparse, but I made it work by jumping through some hoops. Today’s iPad is a much superior machine, and the available apps have come a long way toward making the iPad comfortable enough, and capable of being a web development machine.

Long have I thought about writing an article on how I use my iPad for web development. I think I just needed the right impetus, which came about today.

A long time business friend texted me a challenge, to gather a list of URLs for all images uploaded to a particular website. The kicker- I had to do it faster, and more elegantly, than another mutual friend we have. An iPad was already in my hands, all I needed was a stand to hold it up, and a Bluetooth keyboard for convenience. While our mutual friend has an impressive desktop machine, in less than 10 minutes, I was able to come up with a solution, code it, and publish it as a generic utility.

There are really only three tools that I need to enable web development on my iPad. I will describe those, but first, a bit about the iPad I use.

The Platform — 2018 iPad

You might think the latest, greatest, most powerful iPad it needed, but that is not the case. My iPad is from 2018, a couple years old as of the writing of this article. It is also the base model iPad. Nothing fancy to it.

I would love to have the latest iPad Pro, but since I am not doing hardcore graphics or video editing, it is not necessary.

Now let’s talk about the tools I use for web development from an iPad.

The Server — 100% Remote

The development server is fully remote. It is possible to run a local server, but it is a lot of work, and not worth the hassle. I have a Droplet running on Digital Ocean that hosts all work in progress. Code is edited via ssh.

Security is paramount- the server is locked down and will only respond to my IP address.

For an in-depth look at this set up, read my article at https://medium.com/@benlobaugh/the-unchained-developer-free-your-workflow-and-become-device-agnostic-ce0450e238de

SSH Client — Terminus

The key to making the iPad a useable web development platform for me is SSH. No code is created locally. In fact, all of the resources related to a project live remotely. This means the choice of an SSH client is critical. A few years ago, SSH app choices were limited, and none were what I would consider to be quality enough to spend hours using. They were for quick commands only. Then, I used web based SSH clients, which have their own set of quirks. Today, the quality and selection of apps has improved.

My SSH client app of choice is Terminus. Terminus works across several platforms. It has built in sftp, mosh, and telnet clients; will run fully in the background without disconnecting; and has a lot of other great features. It really shines as an SSH client though. I am able to define hosts and reconnect with a quick tap.

Once connected, there are a plethora of tools at my disposal. The most critical tools to my success are:

  • Docker
  • Vim
  • Tmux
  • Git

With them, I have been able to set up any project. When other tools are called for, such as composer or npm, I will often run them inside of a Docker container.

Another critical need is the ability to transfer files between machines. File transfers are a breeze, with common Linux tools.

Web Browser

The last, and possibly most critical, piece for web development on an iPad is, of course, a web browser. Apple updated Safari to handle desktop versions of sites, freeing the iPad from a mobile only experience.

It seems that everyone has a browser they are devoted to, for better or worse. I happen to find Safari to be acceptable, and with the integrations Apple has created it was a no-brainer choice. Safari handles nearly all my needs. Combine it with a tool such as Cross Browser Testing and anything can be accomplished.

Helpful Hardware

The apps get me running from the software side, and are all I need, but there are two pieces of hardware that I find extremely valuable from a comfort and efficiency standpoint: a tablet stand and a Bluetooth keyboard. Really any will do. Specifically I use the following:

  • Amazon Basics Adjustable Tablet Holder — I like how flexible it is for sizing and angles. Folds up compactly as well.
  • Logitech multidevice backlit keyboard. Unfortunately Logitech no longer makes this keyboard. A bummer since I believe it is the best keyboard they ever made. Logitech has other Bluetooth keyboards that will work also, such as this Bluetooth keyboard, that also has a tablet stand built in.

Fin

That’s it. Those three tools; remote server, ssh, web browser; provide 99% of my needs as a web developer. In fact, if you look at my laptop, you will notice my workflow there is very similar. I have even used the same setup on my iPhone to code while riding a bus!

There are a couple tools I use on the laptop that have good iPad equivalents as well.

  • Postman -> HTTPbot for all query testing needs
  • Browser debugger — this is an area that is still weak for the iPad. There are some promising tools though, such as MIHTool
  • Of course, Slack for accessing developer chat communities

I hope this helps you kick start your own iPad web development journey. Let me know in the comments if there is any way I can help you.

If you already used your iPad for web development, what tools and techniques do you have?

Page 1 of 51

Powered by WordPress & Beards