Music with the Phone’s Keypad – Tetris – Part 2

Categories art, blog
Tetris, NES video game, Nintendo Company Ltd, 1989 (video games)

A while back, I had fun with the keypad. Now the Gameboy game Tetris is back in fashion from 1989.
Here are the melodies you can play on a dial pad.

(Use the * and # keys as pauses)

Korobeiniki :

1 2 3 1 # 1 9 1 #

6 8 * 9 6 3 # 9 6 3 #

9 6 3 1 # 1 9 1# 6 8

Bach’s Menuet :

5 3 2 1 2 1 3 3 2 1 2 3 #

4 # 4 # 4 # 9 8 # 9


3 2 1 1 2 3 8 9 8 #

9 # 9 8 # 9 # 9 3 2 1 1 2 3*

8 9 8 # 9 # 9 8 # 9 # 9

Cleaning up VCARD contacts without a phone.

Categories blog

Export VCARDS on your computer, open notepad++

Ctrl+F and regex:


Save and upload them to your contacts on your phone.

Regex breakdown:

(?s)          # Allow the dot to match newlines.
(?:           # Start non-capturing group.
 (?!          # Make sure we're not able to match either
  END:VCARD   # the text "END:VCARD" (we don't want to match beyond the end)
 |            # or
  \bTEL\b     # "TEL" (because we don't want them to be in the match).
 )            # End of lookahead.
 .            # Match any character (if the preceding condition is fulfilled),
)*            # repeat as needed.


Docker Compose Notes #2

Categories blog, code
whale s tail

How to set up multiple websites on docker-compose

To set up multiple websites on Docker Compose, you’ll need to create a docker-compose.yml file for each website. A docker-compose.yml file defines the services that make up your website, such as a web server and a database, and how they are connected.

Here’s an example docker-compose.yml file that defines a simple web service:

version: "3"
build: .
- "8000:8000"

This file defines a single service called web that is built from the current directory (.) and exposes port 8000 on the host machine.

To set up multiple websites, you’ll need to create a docker-compose.yml file for each website. Each file should define the services for the website, including any dependencies and connections between the services.

Once you have your docker-compose.yml files, you can use the docker-compose command to build and run your websites. For example, to build and run the web service defined above, you would run:

$ docker-compose build 
$ docker-compose up

This will build the web service and run it in a Docker container. You can then access the website at http://localhost:8000.

You can repeat these steps for each website you want to set up with Docker Compose. This will allow you to run multiple websites on the same machine using Docker.

How to set up multiple websites on docker-compose using the same ports

To set up multiple websites on Docker Compose using the same ports, you’ll need to use a reverse proxy to route incoming requests to the correct website. A reverse proxy is a server that receives incoming requests and forwards them to the appropriate service based on the hostname or other information in the request.

To set up a reverse proxy for your websites, you’ll need to do the following:

  1. Create a docker-compose.yml file for each website, as described in the previous answer. Make sure that each website’s services are listening on different ports.
  2. Create a new service in your docker-compose.yml file for the reverse proxy. This service should run a reverse proxy server, such as nginx or Apache, and be connected to all other services in your docker-compose.yml file.
  3. Configure the reverse proxy to route incoming requests to the correct service based on the hostname or other information in the request. For example, if you have two websites, and, you would configure the reverse proxy to forward requests for to the service for that website and requests for to the service for that website.
  4. Use the docker-compose command to build and run your services, including the reverse proxy.

With this setup, incoming requests to your websites will be routed by the reverse proxy to the correct service, allowing you to use the same ports for multiple websites.

Docker Notes #1

Categories blog, code
whale s tail

How do you setup docker for multiple projects?

To set up Docker for multiple projects, you’ll need to create a new Dockerfile for each project. A Dockerfile is a text file containing instructions for Docker on building and setting up your project’s environment.

To create a Dockerfile for your project, follow these steps:

  1. Create a new directory for your project and navigate to it in your terminal.
  2. Create a new file called Dockerfile in your project directory.
  3. Open the Dockerfile in a text editor, and add instructions for building the environment for your project. These instructions can include commands to install dependencies, set environment variables, and more.
  4. Save the Dockerfile and close it.
  5. Use the docker build command to build a Docker image for your project based on the instructions in the Dockerfile.
  6. Use the docker run command to run the Docker image and launch your project.

You can repeat these steps for each project you want to set up with Docker. This will allow you to run multiple projects on the same machine using Docker.

Where are docker files stored?

By default, Docker stores the files that make up an image in a directory called /var/lib/docker on the host machine. This directory contains all of the files for the Docker images installed on the host machine.

You can use the docker inspect command to see the exact location of the files for a specific Docker image. For example, to see the files for the ubuntu image, you would run:

$ docker inspect ubuntu

This will output a JSON object that contains information about the ubuntu image, including the location of its files on the host machine.

Note that you should not modify the files in the /var/lib/docker directory directly, as doing so can cause problems with your Docker installation. Instead, use the Docker command-line interface to manage your images and containers.

MailCow, simple html in maindomain

Categories blog

Mailcow is installed on a subdomain. If you need a simple HTML page on the main domain, do this:

 create a conf file in data/conf/nginx with the following content:

server {
ssl_certificate /etc/ssl/mail/cert.pem;
ssl_certificate_key /etc/ssl/mail/key.pem;
index index.html;
client_max_body_size 0;
root /web;
include /etc/nginx/conf.d/;
include /etc/nginx/conf.d/;

location ^~ /.well-known/acme-challenge/ {
allow all;
default_type “text/plain”;

location / {
root /web;

~Then add the index.html to data/web
~Add your domain to ADDITIONAL_SAN ( to have proper SSL


Categories art, blog

Camouflaged road in Finland during WW2. 1941.

The trees were hung up with ropes. This road sat 6 miles from the Russian border, so when looking down from observation airplanes, the road would be disguised.

It was intended to be viewed obliquely (slanted) not directly from above. The suspended trees would conceal enough of the road to make it difficult to identify visually when flying past, or from surveillance photos taken from aircraft. Camouflage is designed to break up the shape of something against the background, this would have been effective within certain limits.


Categories blog

Generating ASCII art from images using Python3 and PIL (Python Image Library)

pip install Pillow
from PIL import Image
import os

ASCII_CHARS = [ '#', '?', '%', '.', 'S', '+', '.', '*', ':', ',', '@']

def scale_image(image, new_width=100):
    """Resizes an image preserving the aspect ratio.
    (original_width, original_height) = image.size
    aspect_ratio = original_height/float(original_width)
    new_height = int(aspect_ratio * new_width)

    new_image = image.resize((new_width, new_height))
    return new_image

def convert_to_grayscale(image):
    return image.convert('L')

def map_pixels_to_ascii_chars(image, range_width=25):
    """Maps each pixel to an ascii char based on the range
    in which it lies.

    0-255 is divided into 11 ranges of 25 pixels each.

    pixels_in_image = list(image.getdata())
    pixels_to_chars = [ASCII_CHARS[pixel_value//range_width] for pixel_value in

    return "".join(pixels_to_chars)

def convert_image_to_ascii(image, new_width=100):
    image = scale_image(image)
    image = convert_to_grayscale(image)

    pixels_to_chars = map_pixels_to_ascii_chars(image)
    len_pixels_to_chars = len(pixels_to_chars)

    image_ascii = [pixels_to_chars[index: index + new_width] for index in
            range(0, len_pixels_to_chars, new_width)]

    return "\n".join(image_ascii)

def handle_image_conversion(image_filepath):
    image = None
        image =
    except Exception as e:
        print("Unable to open image file {image_filepath}.".format(image_filepath=image_filepath))

    image_ascii = convert_image_to_ascii(image)
    f = open(os.path.splitext(image_filepath)[0]+'.txt','w')

if __name__=='__main__':
    import sys

    image_file_path = 'your_path/to_your_image/goes_here.png'