FrankTheDevop FrankTheDevop FrankTheDevop FrankTheDevop FrankTheDevop

Posts Tagged :

Fix

Docker Volumes

150 150 Frank

Hey everyone,

Today I want to explain you a bit about Docker Volumes, when/where to use them and their benefits.

Remember that in the Docker Introduction I said a Docker container is stateless? For the contained data that is mostly true.
There are two differences:

  1. Docker Volumes
  2. External Connections

A completely stateless container would of course be useless for us. We couldn´t store e.g. no Grocery list or Appointments.
And we couldn´t store files like pictures from the Wedding.

So the idea is to have the docker container that is stateless but add a Volume if you want to store files and configure external connections
to e.g. issue an order.

Depending on the type of data (Grocery List Entry or Wedding Pictures) we want to store them differently. The Grocery Entry belongs to a database,
the Picture into a volume.

Both can be configured through the Stack Configuration, the external Connection to e.g. a database is normally a simple Environment Variable with the url,
while the volume is a mounted filesystem.

An example Stack configuration for a single service can look like this:

version: '3'

services:
  myservice:
    image: image
    deploy:
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 32M
    environment:
      - MYSQL_URL=mysql://$username:$password@$hostname:$port/$path
    ports:
      - $port

I will explain a stack configuration file in another post, so we focus only on the environment key.
Under it is an Environment Variable MYSQL_URL that can be read inside the container. So your API can read MYSQL_URL and connect to that address.
This way you can use the same docker container and just configure it locally for testing to your computer while in the production environment it points to e.g. an Amazon RDS MySQL Instance.

The Volume is somewhat different:

version: '3'

services:
  myservice:
    image: image
    deploy:
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 32M
    environment:
      - MYSQL_URL=mysql://$username:$password@$hostname:$port/$path
    ports:
      - $port
    volumes:
      - $volume_name:$mounted_path   
      
volumes:
  youtube_publish_data:
    external: true

As you can see we describe a volume under the volumes key. We give it a unique name, followed by the path inside the container where it should be mounted.
Additionally we add a root key volumes, under it the name of the volume and under that we set external to true, so that the data is outside of the docker container of the logic, but inside
a data container.
This means we have separated the logic from the data files. Depending on the driver it is limited to the local machine (the default we use is on the local machine).

Still this give us e.g. the possibility to have a generic downloading container that is started by a message. This container uses an external data volume for the downloaded data.
A second container processes the downloads. Therefore we need a config like this:

version: '3'

services:
  myservice:
    image: image
    deploy:
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 32M
    environment:
      - MYSQL_URL=mysql://$username:$password@$hostname:$port/$path
    ports:
      - $port
    volumes:
      - $volume_name:$mounted_path 
        
volumes:
  $volume_name:
    external:
      name: $Stackname_$volume_name

Now we can mount the same volume in two or more containers and access the data there. That is quite cool and saves us ressource for transfering the data back and forth.
Depending on your setup you might want to have it this way and just transfer out the final production file to e.g. Amazon S3 to save time and money on bandwith.

I hope that helped you to get a step further into distributed system architecture.
I´m myself a life-long student of it and every day I learn a new possibility that helps to simplify my projects.
So if you have another idea how to do things please contact me in the comments or via mail. I appreciate it.

Yours sincerely,
Frank

Sources:
(1) Docker Tip #12: A Much Better Development Experience With Volumes
(2) Using Docker Compose for NodeJS Development
(3) Understanding Volumes in Docker
(4) Docker and Continuous Integration: Code, Build, Test, Deploy
(5) Dive Into Docker – The Complete Docker Course for Developers

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/

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