<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Emcomm on Andrew's Memory Blog</title><link>https://andrewmemory.acornwall.net/tags/emcomm/</link><description>Recent content in Emcomm on Andrew's Memory Blog</description><generator>Hugo -- gohugo.io</generator><image><url>https://andrewmemory.acornwall.net/img/rss_image.png</url><title>Emcomm on Andrew's Memory Blog</title><link>https://andrewmemory.acornwall.net/</link></image><language>en</language><managingEditor>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</managingEditor><webMaster>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</webMaster><copyright>Copyright 2009--2025</copyright><lastBuildDate>Mon, 06 Feb 2017 23:57:10 -0700</lastBuildDate><atom:link href="https://andrewmemory.acornwall.net/tags/emcomm/index.xml" rel="self" type="application/rss+xml"/><item><title>US coin values by weight</title><link>https://andrewmemory.acornwall.net/blog/2017-02-06-us-coin-values-by-weight/</link><pubDate>Mon, 06 Feb 2017 23:57:10 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2017-02-06-us-coin-values-by-weight/</guid><description>&lt;p&gt;One thing that it&amp;rsquo;s often wise to have for emergencies is a handful of change. If you&amp;rsquo;re stuck somewhere where there&amp;rsquo;s nothing to eat but vending machine goodness, it might mean the difference between having a meal or not.&lt;/p&gt;
&lt;p&gt;But if you bring change, what sort of change should you bring? Going strictly by weight, the $1 coin is the best value for weight right now. But there&amp;rsquo;s one drawback to that: some vending machines don&amp;rsquo;t take $1 coins. So what should you carry if you want to get maximum snacks?&lt;/p&gt;
&lt;p&gt;The US Mint has a list of US coin weights as part of their &lt;a href="https://www.usmint.gov/about_the_mint/index583f.html?action=coin_specifications" target="_blank" rel="noreferrer"&gt;specifications&lt;/a&gt;. That tells you what you need to know. Here&amp;rsquo;s a table based on the weight of mint condition coins (coins lose mass as they get used):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;Coin Value ($)&lt;/th&gt;
&lt;th style="text-align: center"&gt;Coin Weight (g)&lt;/th&gt;
&lt;th style="text-align: center"&gt;Weight (g) for $1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.01&lt;/td&gt;
&lt;td style="text-align: center"&gt;2.5&lt;/td&gt;
&lt;td style="text-align: center"&gt;250.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.05&lt;/td&gt;
&lt;td style="text-align: center"&gt;5.0&lt;/td&gt;
&lt;td style="text-align: center"&gt;100.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.10&lt;/td&gt;
&lt;td style="text-align: center"&gt;2.268&lt;/td&gt;
&lt;td style="text-align: center"&gt;22.68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.25&lt;/td&gt;
&lt;td style="text-align: center"&gt;5.670&lt;/td&gt;
&lt;td style="text-align: center"&gt;22.68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;1.00&lt;/td&gt;
&lt;td style="text-align: center"&gt;11.34&lt;/td&gt;
&lt;td style="text-align: center"&gt;11.34&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That reveals some interesting facts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nickles weigh exactly 5 g each&lt;/li&gt;
&lt;li&gt;Two pennies weigh the same as one nickle&lt;/li&gt;
&lt;li&gt;$10 in nickels or $4 in pennies weigh 1 kg&lt;/li&gt;
&lt;li&gt;Quarters and dimes have the same value by weight&lt;/li&gt;
&lt;li&gt;Dollar coins are twice as valuable as quarters and dimes by weight&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So if you&amp;rsquo;re on a road trip and plan to dine at the automat, grab your dollar coins first, then your dimes and quarters. Skip the nickles (unless you think that you&amp;rsquo;ll have to weigh something — it might be handy to have a few 5g weights around). And there&amp;rsquo;s a reason that only zinc producers like pennies.&lt;/p&gt;</description></item><item><title>Dockerizing TicketsCAD</title><link>https://andrewmemory.acornwall.net/blog/2017-01-04-dockerizing-ticketscad/</link><pubDate>Wed, 04 Jan 2017 23:10:52 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2017-01-04-dockerizing-ticketscad/</guid><description>&lt;p&gt;Over the recent holiday, I decided to teach myself about Docker by using it to build a running &lt;a href="http://www.ticketscad.org/" target="_blank" rel="noreferrer"&gt;TicketsCAD&lt;/a&gt; system. It turned out to be pretty slick. Here&amp;rsquo;s what I did.&lt;/p&gt;
&lt;p&gt;TicketsCAD is a PHP application that requires an SQL backend. It does computer dispatching for public safety answering points (PSAPs). Yes, I have weird hobbies.&lt;/p&gt;
&lt;p&gt;When I first started, I grabbed the official Docker PHP image, then tried to customize it by installing a MariaDB server. But that turned out to be a bad idea. (It&amp;rsquo;s certainly possible, but not the right thing to do.) After a little while, I did a search for &amp;ldquo;Docker philosophy&amp;rdquo;, which brought me to this page: &lt;a href="http://techblog.constantcontact.com/devops/a-tale-of-three-docker-anti-patterns" target="_blank" rel="noreferrer"&gt;techblog.constantcontact.com/devops/a-tale-of-three-docker-anti-patterns&lt;/a&gt; which set me straight. The right way to do what I wanted to do was to have two separate (but linked) Docker container instances - one with the web server and PHP (customized the way I wanted) and the other with the SQL database. So here&amp;rsquo;s what I came up with.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Grab TicketsCAD
&lt;div id="grab-ticketscad" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#grab-ticketscad" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I grabbed the files from the TicketsCAD download area: &lt;a href="http://www.ticketscad.org/downloads/" target="_blank" rel="noreferrer"&gt;tickets_3.12A_082516&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next I created a directory for everything. In that, I put a directory for the ticketscad server (I cleverly called it ticketscad) and another directory for the ticketscad SQL server (even more cleverly called ticketscadmariadb). Then I created var-www-html in ticketscad, and untarred the TicketsCAD files into it.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Dockerfile for TicketsCAD
&lt;div id="dockerfile-for-ticketscad" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dockerfile-for-ticketscad" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s the first Docker file (named Dockerfile in the ticketscad directory).&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;FROM php:7.0-apache
# Set the timezone
RUN echo Canada/Eastern &amp;gt; /etc/timezone &amp;amp;&amp;amp; dpkg-reconfigure -f \
noninteractive tzdata
# get PHP GD libraries
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
&amp;amp;&amp;amp; docker-php-ext-install -j$(nproc) iconv mcrypt \
&amp;amp;&amp;amp; docker-php-ext-configure gd \
--with-freetype-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ \
&amp;amp;&amp;amp; docker-php-ext-install -j$(nproc) gd
# Install Mariadb client
RUN apt-get install mariadb-client -y
RUN docker-php-ext-install mysqli pdo pdo_mysql
# Fix permissions for ticketscad
RUN chown -R www-data.www-data /var/www/html
RUN chmod -R u&amp;#43;w /var/www/html&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;From top to bottom, here&amp;rsquo;s the explanation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I used the official &lt;a href="https://hub.docker.com/_/php/" target="_blank" rel="noreferrer"&gt;PHP Docker build&lt;/a&gt; with Apache from hub.docker.com. There were some issues with TicketsCAD and PHP 7.1, so I went down to PHP 7.0. (Docker made this very easy to do.)&lt;/li&gt;
&lt;li&gt;I set the timezone. This is a bit of Docker weirdness - there&amp;rsquo;s no standard way in Linux to set timezones, so you need to know how to do it in the distribution you&amp;rsquo;re using. This is how to do it in the PHP distribution. More details about timezones are at &lt;a href="https://www.ivankrizsan.se/2015/10/31/time-in-docker-containers/" target="_blank" rel="noreferrer"&gt;www.ivankrizsan.se/2015/10/31/time-in-docker-containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I installed the PHP GD libraries. This is stolen from the PHP Core Extensions section of PHP on hubs.docker.com, and it installs a few other things I probably don&amp;rsquo;t need (mcrypt, etc.) I just copied and pasted.&lt;/li&gt;
&lt;li&gt;I installed the MariaDB client and PHP SQL extensions.&lt;/li&gt;
&lt;li&gt;TicketsCAD wants to write to /var/www/html and its subdirectories, so I made them rw. (I&amp;rsquo;m not sure how that makes me feel about security - I&amp;rsquo;d kind of prefer it not to do that and to store configuration somewhere not visible to the world. But that&amp;rsquo;s how it works.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that I had that running, I needed a SQL backend. Luckily, there&amp;rsquo;s an official &lt;a href="https://hub.docker.com/_/mariadb/" target="_blank" rel="noreferrer"&gt;MariaDB Docker build&lt;/a&gt; as well. The Dockerfile for this is so simple that I almost don&amp;rsquo;t need it, but hey, I had a directory created already, so here it is:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Dockerfile for MariaDB
&lt;div id="dockerfile-for-mariadb" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dockerfile-for-mariadb" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;FROM mariadb:10.1
RUN echo Canada/Eastern &amp;gt; /etc/timezone &amp;amp;&amp;amp; dpkg-reconfigure -f \
noninteractive tzdata
RUN chown -R mysql.mysql /var/lib/mysql&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Pretty self-explanatory. I don&amp;rsquo;t know for sure that I need that chown, but it doesn&amp;rsquo;t hurt.&lt;/p&gt;
&lt;h2 class="relative group"&gt;docker-compose.yml
&lt;div id="docker-composeyml" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#docker-composeyml" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I built a docker-compose.yml in my parent directory. This is a way to start both instances at the same time.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;version: &amp;#39;2&amp;#39;
services:
ticketscadmariadb:
build: ./ticketscadmariadb
image: ticketscadmariadb:1.0
volumes:
- ./ticketscadmariadb/var-lib-mysql:/var/lib/mysql
ports:
- &amp;#34;3306:3306&amp;#34;
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=ticketscaddb
- MYSQL_USER=ticketscaduser
- MYSQL_PASSWORD=ticketscadpassword
ticketscad:
build: ./ticketscad
image: ticketscad:1.0
volumes:
- ./ticketscad/var-www-html:/var/www/html
ports:
- &amp;#34;8080:80&amp;#34;
links:
- ticketscadmariadb&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s a lot in there. I&amp;rsquo;ll break it down.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;m using version 2 of the docker-compose.yml file format. Gotta say so.&lt;/li&gt;
&lt;li&gt;First I specified the way to build ticketscadmariadb. I pointed to the subdirectory that holds the Dockerfile and gave it an image name.&lt;/li&gt;
&lt;li&gt;I exposed the directory on my local machine that will hold the MariaDB database. (It&amp;rsquo;s /var/lib/mysql on the Docker instance; I called it var-lib-mysql in the ticketscadmariadb directory on my local machine.) Why did I do this? So the SQL database would persist across Docker rebuilds. Needless to say, I created an empty var-lib-mysql under ticketscadmariadb on my local system.&lt;/li&gt;
&lt;li&gt;I exposed the MariaDB SQL port (3306) and mapped it to 3306 on my local machine. If you have SQL running on your local machine already, you&amp;rsquo;ll need a different local port.&lt;/li&gt;
&lt;li&gt;I specified a bunch of environment variables for MariaDB. The MariaDB Docker image is smart enough to know that if it sees those variables, it creates a database with the specified name / user / password / root user. Thanks, MariaDB Docker image! (You&amp;rsquo;ll probably want different passwords than I used.)&lt;/li&gt;
&lt;li&gt;Now it&amp;rsquo;s time for the TicketsCAD image (PHP/Apache server). I pointed to the ticketscad subdirectory (which holds the Dockerfile) and gave it an image name.&lt;/li&gt;
&lt;li&gt;I mapped the /var/www/html directory on my Docker image to ./ticketscad/var-www-html on my local machine. Why not just COPY? Because TicketsCAD writes to /var/www/html and /var/www/html/incs, and I want that to persist across builds.&lt;/li&gt;
&lt;li&gt;I exposed port 80 on the Docker image as port 8080 on my local machine.&lt;/li&gt;
&lt;li&gt;Finally, I told Docker that I want to be able to have the ticketscad image talk to the ticketscadmariadb image using the links: command. (If I didn&amp;rsquo;t do this, the two images wouldn&amp;rsquo;t be able to communicate.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Building and running
&lt;div id="building-and-running" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#building-and-running" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;So now everything&amp;rsquo;s set up. At this point, I can go to the parent directory and type:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker-compose up&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That reads docker-compose.yml by default, downloads the files that are needed and creates my images. And voilà, a working TicketsCAD install is ready to go.&lt;/p&gt;
&lt;p&gt;Well, almost ready to go. Because Docker assigns IP addresses for each build, I had to interrogate the running images in order to figure out what they were. First I used docker ps to find out that the container ID of the ticketscadmariadb instance was 2e13d01384ac, then I used docker inspect to discover its IP address. I needed to know the IP address for the TicketsCAD configuration screen.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker ps
docker inspect 2e13d01384ac | grep IPAddress&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;For me it was 172.17.0.2.&lt;/p&gt;
&lt;p&gt;Because I have the TicketsCAD port 80 exposed on my local machine as 8080, I can now go to localhost:8080 to run TicketsCAD.&lt;/p&gt;
&lt;h2 class="relative group"&gt;What next?
&lt;div id="what-next" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-next" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;This is enough to get TicketsCAD up and running in a &amp;ldquo;play&amp;rdquo; environment. In a real environment, you&amp;rsquo;d want to harden things. In particular, remove the install.php script and save the Docker image after installation, and make sure that random yahoos on the Internet can&amp;rsquo;t write to /var/www/html. Give the machines real hostnames. Set up real certificates and put them on the network. Run something to prevent DDOS attacks. All them devops things.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Hey TicketsCAD guys!
&lt;div id="hey-ticketscad-guys" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#hey-ticketscad-guys" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve got some cool software. If possible, it would be nice for TicketsCAD to have a check box to delete install.php for you after running it - then it would be more compatible with Docker.&lt;/p&gt;
&lt;h2 class="relative group"&gt;A few more more useful things
&lt;div id="a-few-more-more-useful-things" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#a-few-more-more-useful-things" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;1. If you want to look into a running Docker instance, this is nice to know:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker exec -it containerID bash&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;It brings you to a root shell running bash on the instance.&lt;/p&gt;
&lt;p&gt;2. I ran into problems after I removed some images with docker -rmi. &lt;a href="http://stackoverflow.com/questions/37454548/docker-compose-no-such-image" target="_blank" rel="noreferrer"&gt;stackoverflow.com/questions/37454548/docker-compose-no-such-image&lt;/a&gt; solved my problem (in short: docker-compose down).&lt;/p&gt;
&lt;p&gt;3. Sometimes you&amp;rsquo;ll need to rebuild.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker-compose up --build&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;is a handy way to do that.&lt;/p&gt;
&lt;h2 class="relative group"&gt;My directory structure
&lt;div id="my-directory-structure" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#my-directory-structure" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker-ticketscad/
docker-compose.yml
ticketscad/
Dockerfile
  var-www-html/
(all the TicketsCAD files go here)
ticketscadmariadb/
Dockerfile
var-lib-mysql/&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item></channel></rss>