FrankTheDevop FrankTheDevop FrankTheDevop FrankTheDevop FrankTheDevop

Monthly Archives :

January 2019

Auto Remove RabbitMQ Orphan Queues from Loopback MQ Connector

150 150 Frank

Hi everyone,

who doesn’t know this: You’re working on multiple projects, some container still run on docker, others are already terminated. But your rabbitmq gets slower and slower. You check the Queue overview and you see numerous queues with names like 1234568.node /app/server/server.js.54.response.queue.
These are queues that are left over, sometimes from crashed containers, sometimes a container didn’t end its connection correctly.
But basically these queues stay open until you reset rabbitmq, remove them or they expire. Waiting for the expiration can take quite some time depending on your configuration.
I will show you a quick and easy way to get rid of them using the ui and a regex pattern.

If you want to quickly and easily remove them, then you can do this:

Go to the Admin -> Policies site
Expand Add / update a policy
Configure it as follows
Name: Whatever you wish, doesn’t matter
Pattern: [a-z0-9]*\.node \/app\/server\/server\.js\.[0-9]*\.response.queue 
Apply to: Select Queues 
Priority: Leave empty
Definition: In the first left field write expires, in the field to the right write 1 and in the drop down select number
Click Add policy

That’s it. Your queues are already delete or if you have too many then it takes a few seconds. But then they are all gone.
Don’t forget to delete the policy again.

I hope this helps you.

Regards,
Your Frank

Regex Pattern: [a-z0-9]*\.node \/app\/server\/server\.js\.[0-9]*\.response.queue

Sources:
(1) https://www.cloudamqp.com/blog/2016-06-21-how-to-delete-queues-in-rabbitmq.html

Useful tools:
(1) https://regex101.com/

How to promisify with bluebird

150 150 Frank

Hey @everyone,

this will be a quick tip / reference. Sometimes I get asked about the syntax to promisify only one function with the bluebird Promise Library. I will show you an example to promisify the readdir method of the fs package:

'use strict'
const fs = require('fs')
const Promise = require('bluebird')

const readdirAsync = Promise.promisify(fs.readdir)

That´s it already. Before your code looked somewhat like this:

fs.readdir(myPath, (err, files) => {
  // Handle the files
})

If you needed to do further asynchronous operations you came into the callback hell (1).

Promisifying it make the syntax clearer and more elegant:

readdirAsync(myPath)
.then(files => {
  // Handle the files
})

You see, now you are in the promise chain, which makes elegant and readable code easier to achieve.
And you don´t have to be extra careful about using Promises and callbacks at the same time.

Yours sincerely,
Frank

(1) // https://blog.syntonic.io/2017/07/07/escaping-callback-hell-util-promisify/

Angular Tips I: Fix Can’t bind to ‘routerLink’ since it isn’t a known property of ‘a’.

150 150 Frank

Hi everyone,

this will be a quicky. I guess everyone has had this error and was so used to it working that you forgot how to solve it. Because I just had that experience I write this post.

What you tried to achieve

Add a routerLink entry to an a html element in the Angular template.

Error

Can’t bind to ‘routerLink’ since it isn’t a known property of ‘a’.

Solution

Remember to import the RouterModule in every Module where you want to user routerLink.
To do that add import { RouterModule } from '@angular/router'; at the top of the corresponding module. And don´t forget to add it to the imports array:

@NgModule({
imports: [ CommonModule, RouterModule ],
...
})
export class ...

If you put that into a shared Module don´t forget the exports array too:

exports: [
...,
...,
RouterModule
]

I hope this helps you avoid a headache when you see the message “Can’t bind to ‘routerLink’ since it isn’t a known property of ‘a’.” again.

Yours sincerely,
Frank

Sources:
(1) https://blog.ng-book.com/basic-routing-in-angular-2/
(2) https://coryrylan.com/blog/introduction-to-angular-routing
(3) https://toddmotto.com/angular-component-router
(4) https://malcoded.com/posts/angular-fundamentals-routing

Docker Stack for Apache, PHP FPM & MySQL

150 150 Frank

Hey everyone,

it has been quite some time since my last post, I know. Today I came across a new problem and wanted to share my Solution (that is based on some giants shoulders) with you.

I have a development environment for Apache & PHP on my MacBook, but with all the different ways, changes which source is working and so on I wanted a reliable solution that I can replicate.

So I decided to put everything into Docker Container and put them together as a stack.

The Idea was to have a stack where I can manipulate the vhost definition and the Apache config from the outside, while the Projects are mapped from a local source folder.

The Requirements

– Docker installed and working
– Access to the internet
– A directory where the Apache config (httpd.conf) is located
– A directory where vhost configs for apache are hosted
– A directory where the sourcecode is reachable
– A cloned copy of https://github.com/FrankTheDevop/php-apache-mysql-containerized

Okay, let´s start:

Start

After you cloned the git repository you find this structure:
– root folder
–README.md
–apache
—Dockerfile
—conf
—-httpd.conf
—vhosts
—-demo.apache.conf
–docker-compose.yml
–php
—Dockerfile
–public_html

I use this as my base folder and leave the configs here. You can decide to put them elsewhere, just remember to change you paths later.

Step 1

Open a console and change into the root folder of the git clone. Change into the php.

Edit the Dockerfile and put the php version you want to use into PHP_VERSION=”$YOUR_VERSION_NAME”.

TIP

Depending on the PHP Version you use you might want to change the following:
RUN docker-php-ext-install mysqli
This statement installs the mysqli extension for php. Starting from PHP 5.5 you should use it. But if you have a software that still uses the mysql extension and PHP <= 5.6 change it to: RUN docker-php-ext-install mysql Finally execute: docker build -t $your-image-prefix/$your-image-name:$version . This could look like this: docker build -t frankthedevop/php:v5.6 . Don´t forget the "." at the end, that tells Docker to use the current folder. That takes a bit of time, depending on the speed of your internet connection and your computer.

Step 2:

Change into the apache folder. Edit the Dockerfile.
Put the version you want into APACHE_VERSION=”$yourversion”, e.g. APACHE_VERSION=”2.4.25″.

Execute:
docker build -t $your-image-prefix/$your-image-name:$version .
This could look like this: docker build -t frankthedevop/apache:v2.4.25 .
Don´t forget the “.” at the end, that tells Docker to use the current folder.

Again this might take a while.

Step 3

After you have the containers for Apache and PHP you can start your stack. Here you have to be a bit careful, it is slightly different if you use docker-compose or have a Docker Swarm Installation.

If you do not use a Docker Swarm installation you could go into the root folder and execute:
docker-compose up

It will start the Apache & PHP Container, retrieve a mysql container and make everything available.
You can already use it, but it doesn´t point to the folder of your sources yet. For that skip to Step 4.

If you use a Docker Swarm Installation you need to use the docker-compose.stack.yml file as config.
Please edit the file, change the image names to those you chose earlier. For MySQL place replace:
– $YourRootPW for the Root Password,
– $YourDatabaseName for the Database Name,
– $YourUser for the username and
– $YourPW for the password

The MySQL Container will use those variables to automatically create a MySQL Instance for you. You can use $YourUser and $YourPW for the connection in your code.

For PHP and Apache please remove the volume keys and what is below them for now.

Now you can execute:
docker stack deploy –compose-file docker-compose.stack.yml $YourStackName

Interim Result

Finally you have a running Stack of Apache, PHP & MySQL. If you visit localhost:8080 you should reach a site telling you: “It works”.

Step 4

If you use the Docker Swarm Installation or not, you still miss the ability to edit the php files and see the results.

For this we have to set the Volume key accordingly.

For PHP we add:
volumes:
– $YourPathToTheSourceCode:/var/www/html/

Please replace $YourPathToTheSourceCode with the path to where you sourcecode is located. I typically put the parent folder of my projects here, e.g. /Users/username/projects/php/.

For apache we start the same way:
volumes:
– $YourPathToTheSourceCode:/var/www/html/
After that we add:
– $YourPathToTheVhostsFolder:/usr/local/apache2/conf/
– $YourPathTOTheHttpd.confFolder:/usr/local/apache2/conf/httpd.conf

Replace $YourPathToTheVhostsFolder with the folder where you want to put your virtual host definitions and $YourPathTOTheHttpd.confFolder with the folder where you put your httpd.conf (optional, if you want to use the default one remove this line).

This is how it should look like:

version: '3'

services:
  php:
    image: fdsmedia/php:5.6
    volumes:
      - $YourPathToTheSourceCode:/var/www/html/
  apache:
    image: fdsmedia/apache:2.4.25
    depends_on:
      - php
      - mysql
    ports:
      - "8080:8080"
    volumes:
      - $YourPathToTheSourceCode:/var/www/html/
      - $YourPathToTheVhostsFolder:/usr/local/apache2/conf/vhosts
      - $YourPathTOTheHttpd.confFolder:/usr/local/apache2/conf/httpd.conf
  mysql:
    image: mysql:${MYSQL_VERSION:-latest}
    ports:
      - "3306:3306"
    volumes:
      - data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=$YourRootPW
      - MYSQL_DATABASE=$YourDatabaseName
      - MYSQL_USER=$YourUser
      - MYSQL_PASSWORD=$YourPW
volumes:
    data:

Now you can just restart the service for PHP & Apache, go to localhost:8080 and find your project. If you change the url or port for the virtual host please change that here too.

Result

You finally have a working Docker-based Stack where you can develop your PHP-based Applications and maintain your database content (as long as you don´t remove the data).

If you have a new application it is as easy as creating a new folder under your project folder, add a vhost configuration and you are good to go.
If you want to change the used php version you just need to create another container with the other version, add an entry to the stack and change the url in the vhost configuration. That´s all. Isn´t that amazing?

If you have any question feel free to post them into the comments. Or to send my an email.

Yours sincerely,

Frank

P.S.: If you are looking for a Hosting Solution have a look at Digital Ocean (digitalocean.com*) They let you set up Docker Hosting easily & quickly.

* Affiliate Link

Sources
(1) https://www.cloudreach.com/blog/containerize-this-php-apache-mysql-within-docker-containers/
(2) https://github.com/mzazon/php-apache-mysql-containerized
(3) https://dev.to/chiefoleka/how-to-setup-nginx-and-php71-with-fpm-on-mac-os-x-without-crying-4m8 (they do it with nginx)
(4) http://geekyplatypus.com/dockerise-your-php-application-with-nginx-and-php7-fpm/ (nginx too)
(5) https://getgrav.org/blog/macos-mojave-apache-multiple-php-versions (One of the sources that should work but sadly not for me)
(6) https://www.pascallandau.com/blog/php-php-fpm-and-nginx-on-docker-in-windows-10/#setup-php-fpm (Inspiration for the development setup)
(7) https://easyengine.io/tutorials/php/directly-connect-php-fpm (Debug PHP FPM)