Running a docker registry in my homelab
Home labs are a great place to learn and tinker with systems. I love it because I get to wear my systems administrator hat. I’ve been doing a lot of application development lately as well as tinkering with various build & deployment tools for those applications. The best way, in my opinion, is docker. It’s just so good, you can package up all of the tools and configurations into a distributable unit, using an open standard.…
Form Objects in Ruby on Rails
In Ruby on Rails, a Form Object is a design pattern used to handle the complexity of forms that don’t map directly to a single model or have unique/complex validation and business logic. It encapsulates the logic related to form processing, validation, and data persistence, often combining attributes from multiple models or handling data that doesn’t fit neatly into the traditional ActiveRecord model structure.
Consider a UsersController that lets you create or edit a user.…
Variable swapping in Ruby
Swapping variables is a fundamental concept in programming, often encountered in algorithm development and problem-solving scenarios. While the process is straightforward in many languages, Ruby offers its own particularly elegant and concise syntax for this task. Let’s first explore the more traditional approaches.
First, you might use a temporary variable.
a = 10 b = 12 puts "a: #{a}, b: #{b}" tmp = a a = b b = tmp puts "a: #{a}, b: #{b}" Outputs:…
Quirky Ruby Feature - Mixing Code and Data
Ruby has some fun quirky features. One of them is that you can mix code and data in a single file using the special keywords __END__ and DATA. This is a weird concept, but Ruby allows you to use the script itself as a source of data.
References:
https://docs.ruby-lang.org/en/3.0/Object.html#DATA https://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-__END__ The documentation says about __END__:
Denotes the end of the regular source code section of a program file.…
How to change a Users Password via Tinker in Laravel
Laravel has a pretty great console through a REPL called Tinker.
From Tinker you can interact with your models.
$user = App\User::where('email', 'their@email.com')->first(); $user->password = Hash::make('their new password'); $user->save(); Super convenient! You just need SSH access to a server in the environment in which the app is running. I like to setup an "ops" box that lives in my production environment that is only accessible through a VPN. This gives me a management console to my app for emergencies or whatever!…
A docker based setup for testing with Laravel
I experienced some annoying issues while running integration tests in a Laravel app. The official MySQL docker image will create a user and a database for you which is very convenient, but that user does not have permission to create new databases. I configure my applications to use a separate database for testing, usually with a _testing suffix and so just hit a brick wall.
The solution was to mount an entrypoint script, basically, some SQL statements I want to execute when the container is created.…
Add taggable support to my personal blog
Today I added taggable support to my blog. I do have blog posts tagged, but it's a simple comma-separated list in the database. I want to have a more robust system that allows me to query and filter by tags.
I used the ruby gem acts-as-taggable-on to add taggable support to my blog.
First thing was to install the gem by adding it to the Gemfile and running bundle.
gem "…
Trying to Dispatch Jobs via Tinker with Laravel and SQLite
I've been learning Laravel queues and jobs. While creating some jobs I wanted a quick way to test by executing the job. I just want to see it run. There wasn't a super clear path for me here so my first thought was let's just quickly create a one off controller action. To replay that job over again I just had to refresh my browser. Not great, super odd, but also not the end of the world.…
Use Ansible to Configure your Workstation
Let me show you a simple and easy way to manage your MacOS workstation using Ansible. Ansible is awesome, and we should automate all the things.
I tinkered with doing this myself from scratch with some success, but I've discovered Jeff Geerling's incredible collection of Ansible roles and collections and didn't look back. They are simple, and ready to go.
Take a look at my workstation repository, also do check out Jeff's Ansible work.…
Develop for Environment Specific Configuration
There is a pattern I see often among junior/associate developers when it comes to handling environment-specific configuration. The observed pattern could be summarized as junior developers creating separate fields for development and production environments in the application, misunderstanding the need for a single environment-aware configuration, resulting in duplicated logic to handle different keys based on the environment.
An example of this in action is there will be a request to add a field in the admin area of a website to store a key for some purpose.…
Managing Jumpstart Pro Updates
Jumpstart Pro is a Ruby on Rails SaaS template that lets you quickly deliver and ship business-ready web applications. It takes care of so much boilerplate and common configuration. I’ve been using it to build a small app for myself and love how easy it is to build production-ready applications. But it is not without some friction.
As a subscriber to Jumpstart Rails you are entitled to updates. The way you get those updates is by merging in changes from upstream.…
Simple Database Seeder for WordPress
I’ve been doing some WordPress development at my day job and have come to the conclusion that the development life-cycle of WordPress is kinda bad, actually. However, there are systems & processes we can implement to improve the developer and development experience. We can make it more enjoyable to work on WordPress!
One of those systems that I sorely miss is a database seeder that can populate your site with test and dummy content.…
Turbo Will Call Stimulus `connect()` Twice
When you click a link to return to a page, or use your browsers back button to return to a page Turbo will render a cached preview of the page. It will then fetch an updated version of the page.
If you have a stimulus controller on the page what will happen is the controller is initialized twice. The initial cached version will load the controller and fire off the connect() method, then the page is refreshed via Turbo, the controller is disconnected, then reconnected when the DOM is updated from the Turbo update.…
The Three Core Principles of DevOps
If you ask a group of people "what is DevOps?" you are likely going to get a variety of different answers. Some think it's just the automation of a pipeline. Some people may say it's just developers doing operations work. I subscribe to the idea that DevOps is a mental model for how to think about creating software. From that philosophy some concrete tactics have emerged, such as automating infrastructure and deployments.…
How To Use Docker Compose Effectively as a Development Tool
Let's use Docker Compose to help us build software! If you are new to the world of containers then I hope you will find this tutorial insightful. We will explore setting up a new Ruby on Rails project, creating a docker-compose.yml file, then will add services like PostgreSQL and Redis, and finally, running and developing our new application in Docker. I choose to use Docker Compose to avoid installing and juggling multiple versions of tools and services on my workstation.…
Running Ruby on Rails on Docker
I have been developing Ruby on Rails apps in Docker for several years now. I couldn't imagine not using Docker at this point!
An Introduction to DockerDocker an open-source project for automating the deployment of applications as portable self sufficient containers that run in cloud or on premises. Docker is also a company that owns this technology. The underlying technology that powers Docker has been part of Linux for many years.…
Getting Familiar with RSpec in Rails
I spent some time over the weekend getting familiar with RSpec. Gonna brain dump (with just a little bit of structure) the process and what I did and learned. To start I set up in a new rails project and kinda tweaked it into a place where I can be productive.
What is RSpec though? It is a testing framwork. But it's a little different than the Minitest testing framework that ships with Rails.…
Execute Workflows with Path Filtering in CircleCI
As I often love to tell people, I love monorepos and I use a monorepo for my own projects. But there is not really an out of the box solution for monorepos so you often end up having to write scripts to glue everything together. Sometimes it really does feel like wadding up a bunch of projets into a loose ball then duct taping and hot-gluing them together into a much bigger ball.…
The difference between length, size, and count in Ruby on Rails
I was asked recently if I could explain the difference between length, size, and count for ActiveRecord models in Ruby on Rails. Unfortunately I had no answer. But I wanted to really understand so I dug into the API docs.
On a Ruby Array the methods size, count, and length are as such; size is an alias for length, length simply returns a count of the all elements in the array, and count is pretty neat in that you can pass in a block to count elements based on some condition.…
AWS ACM Terraform Module with Variable SANs
Here is a a flexible terraform module for creating an AWS ACM with a variable number of additional SANs.
Our infrastructure architecture is such that we have application load balancers that may serve multiple apps, and there was a need to create SSL certificates with multiple SANs to support those apps. While possible to add multiple SSL certificates to an application load balancer there is in fact a limit and so I wanted to avoid that altogether.…
A Terraform Directory Structure
Here is a directory structure that I am using for Terraform that I think works pretty well. The quick and dirty of it is to think of your configurations in terms of a organizational and systems hierarchy, and to design your plans to support that hierarchy. Each tier depends on and builds upon the previous tier.
I create a separate terraform project for each tier of my stack. I am nearly 100% in AWS these days so this is going to feel a little AWS centric, but the basic idea is the same regardless of cloud provider.…
Enforcing Interfaces in Ruby
Ruby doesn't have the concept of an interface. Unlike say, PHP. In PHP you can specify that a class has to act like or implement specific methods. If your class fails to honor the contract of that interface and does not implement the methods of the interface, you get an error during runtime. Ruby does not have this. But we can ensure our code honors the contract of an interface by writing unit tests for our classes.…
Multi-Platform Git Diff and Merge Tools
Maintain a single .gitconfig between different operating systems by using proxy scripts for git diff and git merge tools.
We first need to know which operating system we are using. I do this by by extracting the value from uname and then setting the value to an environtment variable.
On MacOS this will return darwin, on most Linux distributions it should return linux.
export DOTFILES_OS=`uname | awk '{print tolower($0)}'` In your .…
My Personal Monorepo & Pipeline
A monorepo is a software development strategy where code for many projects is stored in the same repository. The code doesn't necessarily have to be related.
Okay, but why use a monorepo? Gathering all of my personal projects into a single repository makes it easier for me to manage and maintain the code. One repository is easier to deal with than a dozen. I can develop a common interface for building and deploying projects in the monorepo.…
Deploying a Simple Rails App with Ansible
Ruby on Rails is quickly becoming my framework of choice for my personal websites and projects. It's a pleasure to work with and has been easy to learn. But no framework is without its challenges. One of those challenges is of course deploying the app to a server. There are a lot of options for hosting and deploying a Rails app. But, I like to run my own servers which means I have to also take care of deploying to those servers.…
How to Run Rails App Server with Systemd and Ansible
Create a systemd service to run your rails app server. Ansible tasks to create the service:
--- …snip…
vars: rails_root: “/myapp” rails_user: “webuser”
tasks: - name: Setup Rails Web Service template: dest: /usr/lib/systemd/system/rails-web.service src: templates/rails-web.systemd.j2
- name: Enable Rails Web Service systemd: name: rails-web daemon_reload: yes enabled: yes masked: no
The ansible template "rails-web.systemd.j2":
[Unit] Description=Rails Web [Service] Type=simple SyslogIdentifier=rails-web User={{ rails_user }} PIDFile={{ rails_root }}/tmp/pids/web.pid WorkingDirectory={{ rails_root }} ExecStart=/bin/bash -l -c “{{ rails_root }}/bin/rails s -b 0.…
Simplify Terraform By Generating Configurations
Terraform is an awesome tool. To make it more awesome though we have wrapped it with some custom Ruby ERB templating to generate our terraform configurations from Yaml configurations.
Terraform uses a declarative language. You describe the state you want and it figures out how to get there. The declarative nature of Terraform does not afford us the same control that a language like Ruby can provide, which is fine, but I have found that I end up managing _massive_ Terraform configurations.…
Profiling and Debugging a PHP app with Xdebug and Docker
Profiling and Debugging a PHP app with Xdebug and Docker I have started using an IDE again (PHPStorm) so that I could debug some applications and do some basic app profiling. I want to use Xdebug to profile my PHP apps. I am using Docker Compose on Windows 10. I have made this very complicated for myself but here we go.
The directory structure of my app looks like:
/build/docker/php/Dockerfile /build/docker/php/php.…
WP Transients must be used responsibly
We ran into an interesting issue with WooCommerce at work. First, here is the subject of the support request we got from our hosting provider:
The site is generating ~150MB/sec of transaction logs, filling 500GB of diskspace
Holy. Shit. A WordPress site should not be generating that much data. 150MB per second? Wow.
How? Why?
The simple explanation is that there is a bottleneck in WooCommerce with the filtered layer nav query objects using single transient record.…
Order Posts via
A request we are getting more often is to show a list of posts, to elevate some of those posts above others, and to show the posts in a random order. Imagine a post type called "Sponsors". Sponsors are tiered, like "Platinum", "Gold", "Silver", etc. We want the Platinum sponsors to appear before Gold, Gold before Silver, and so on. We don't want to favor one particular Platinum sponsor though, we want them to be randomized but ordered by the tier.…
Regular Expression of the day
(?!(([1,2,3,4,5,6,8,9,0])\2{9}))(?!((1234567890|0987654321)))(((\+?\d{1,2}[\s.-])?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4})|(\d{10,})) Match generic US phone numbers. Ignore 1-9 repeating (ie: 4444444444, 1111111111, (except 7, we want 7777777777 for testing)). Allow for spaces, no spaces, dashes, or period delimiters.
Of course we _should_ use a standard phone number regex, but of course this project calls for something unique.
RegEx is weird, but fun.…
Technical Documentation for a Web Development Project
Working on a large web development project requires that you have clear direction and good technical documentation. The designer needs to understand the functional requirements and the data model in order to deliver a successful design. The themer need to understand the UI/UX spec in order to deliver accurate and functional markup. The developers need to understand the functional requirements and data model in order to build out the CMS backend.…
TLS Peer Verification w/PHP 5.6 and WordPress SMTP Email plugin
We ran into an issue after upgrading from PHP 5.5 to 5.6. We were no longer able to send email via the awesome WordPress SMTP Email plugin. Turns out that PHP 5.6 introduced some enhancements to its OpenSSL implementation. Stream wrappers now verify peer certificates and hostnames by default. This was causing the form submissions on our site to fail. Clearly there are some issues with our Postfix config and certs.…
Whitelist IPs in Nginx
I want to whitelist my clients IP addresses (and my office IPs) to allow them to view a site, while the rest of the world will be redirected to another site, using Nginx. My Nginx server is behind a load balancer.
Using the geo module I am able to do this rather easily. By default, geo will use $remote_addr for the IP address. However, because our server is behind a load balancer this will not work, as it would always be the IP of the load balancer.…
Capistrano tasks for Magento
Custom tasks for Capistrano that I am using to help manage a Magento website.
set :linked_files, %w{app/etc/local.xml .htaccess robots.txt} set :linked_dirs, %w{sitemap var media} namespace :mage do task :restart do on roles(:app) do execute "cd #{current_path} && rm -f maintenance.flag" end end task :disable do on roles(:app) do execute "cd #{current_path} && touch maintenance.flag" end end task :enable do on roles(:app) do execute "cd #{current_path} && rm -f maintenance.flag" end end task :clear_cache do on roles(:app) do execute "…
Creating link tags with hreflang attributes in CraftCMS
I want to preface this with the following; I think CraftCMS is a poor CMS. I dislike many things that it does and cannot recommend it as a professional CMS. Having said, that, I am working with it a lot these days at work and recently had to add link tags with hreflang attributes to the head. For some reason the CMS does not do this for you. SproutSEO does not do this either.…
Setting up Git HTTP Backend for local collaboration
You want to share a topic branch with a colleague but do not want to push that branch upstream to Github/BitBucket/GitLab, etc. How do you do this? You could create a patch and email it. Or you could do it in the most crazy way possible and use Apache and allow your colleague to pull from your repo directly. This does take a bit more time to setup, but it would also be absolutely crazy dumb for everyone involved.…
Enable status for php-fpm
Accessing the PHP-FPM Status screen is easy enough. First, enable pm.status in your php pool:
pm.status_path = /status Then add the following block to your Nginx vhost conf:
location ~ ^/(status|ping)$ { access_log off; allow 127.0.0.1; allow 192.168.1.0/24; ##### YOU WILL WANT TO CHANGE THIS TO YOUR IP ADDR ##### deny all; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/var/run/php-fpm-www.sock; } Restart php-fpm and nginx and then browse to http:///status. You will be presented with some useful information on the current status of your PHP-FPM pool.…
My Pantheon + Jenkins Process
Here is a rough outline of my Pantheon + Jenkins process. I like my code in BitBucket. I also like Pantheon (check them out). The Pantheon workflow is all about being the source of truth for your code. This is fine, and actually I dig it because it promotes good practices. However, I, and my company, have many projects in BitBucket already, and am using Jenkins more and more for some Continuous Integration functions.…
A WordPress ajax handler for custom themes
Something I have been noodling on is a better way to handle ajax requests in my custom themes. Seems to me that a relatively complex theme ends up with a lot of add_action calls for custom ajax handlers, and this could be simplified/reduced. Every time a new endpoint is required we have to add two new add_action calls to our theme. Maybe a better approach is to write a single ajax endpoint that will route requests to the proper classes/methods?…
My VagrantFile
This is the Vagrantfile I am using for my development box at home and work. It is determines how much ram is available and how I want to allocate, how many CPUs are available, and configures the VM for me. I use NFS for shared folders. Finally, starting to use "hostupdater" to keep my host machines hosts file current.
I would love to make that more dynamic, based on the Apache vhosts I have configured in the VM.…
Ohai Plugin for OpenVZ VMs to get public IP Address
Media Temple uses the OpenVZ virtualization system and I have quite a few Media Temple servers under Chef management. The one thing that has made management difficult is that by default during a Chef run ohai returns 127.0.0.1 as the default IP address which means I cannot run knife to execute commands from my workstation.
For example, when I run knife node show mydv.server.com I get the following:
$ knife node show mydv.…
What to do when your website is hacked/exploited
So your website has been "hacked"? You load your website in your browser, and are redirected to some spammers website, or maybe you google'd yourself (naughty), and found a few thousand indexed pages for knock off prada gear? Ok, so how do you fix this, and more importantly, how do you learn how they did it so you can defend against it later.
Secure the scene The first thing I do is take a snapshot of the hacked web site.…
Virtualbox Bug related to SendFile
I have been doing more web development with Vagrant and VirtualBox. It's a nice way to keep my dev environment nearly the same as my production environments. Recently I was doing some front-end coding and was running into the most bizarre errors with my JavaScript.
It pays to read the documentation. Had I read it more thoroughly, I would have known about this before debugging it and wasting time. Oops!…
Setup Development Environment with Vagrant & Chef
I use Chef to manage and provision new staging and production servers in our company. It takes a lot of the headache out of managing multiple servers and allows me to fire up new web & data servers for our projects with ease. I have several cookbooks that I use to configure servers and to setup/configure websites. In a nutshell, it's rad, and website deployments have never been easier.
For my local development environment I currently run Ubuntu, with Apache, Nginx, PHP 5.…
Trying to Troubleshoot extremely high MySQL CPU Usage
MySQL CPU usage was spiking upwards of 1000%. Load average was around 50-60. I could not SSH into the machine though, not immediately.
Since I could not actually get into the machine I had it restarted. Just as soon as the machine came back up MySQL CPU usage jumped right back up to 1000%.
Once I was able to finally shut MySQL down I had to discover _why_ the load was so ridiculously high.…
Securing Git repository from accidental exposure using Chef
It was brought to my attention at the office that a few of our recently launched websites had publicly exposed .git repository information. Unscrupulous users could use the exposed data to pull down the entire commit history, giving them unfiltered access to what is basically the blueprint for the website.
What if someone accidentally uploaded a config file to the repository with sensitive information in it? Or what if the user was able to discover a major security vulnerability in the code that would have otherwise remained "…