Ubuntu 14.04 OpenSSL with Nginx – Generate & Install SSL certificate

Not the best guide, but some handy links I use to Generate and Install an SSL-certfificate with OpenSSL in NginX.

Generate OpenSSL Request:

Order an SSL-certificate with the CSR

Then, when you received bundle plus CRT:

Restart NGINX:

Using TransIP SSL-certificates

When using TransIP SSL-certificates you get a decrypted zip SSL-certificate (if you choose for standard mode instead of advanced mode).

These contains:

  • cabundle.crt
  • certificate.crt
  • certficate.key
  • certificate.p7b (you don’t need this one)

Open cabundle.crt, remove the first certificate (that is a root certificate and will give chain issues: an ‘anchor issue’ in SSL Labs). Then, swap the order of the two certificates of the bundle, else SSL Labs will give a chain issue: incorrrect order. Then, concatenate the certificate.crt (first) with the new cabundle.crt (second).

Then insert the concatenated crt file + the key on the server and insert them in NGINX:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.yourdomain.nl yourdomain.nl;
    ssl on;
    ssl_certificate /home/forge/ssl/domain1/20172018_cert_chain.crt;
    ssl_certificate_key /home/forge/ssl/domain1/20172018key.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

When creating your certificate you can concatenate certificate.crt with cabundle.crt .

South-Africa Tourist Visa Extension with 90 days

south africa tourist visa extensionSouth-Africa gives a 90 day tourist visa to most Western countries (I’m Dutch, so this probably/hopefully will work for most EU countries). There are possibilities to extending another 90 days. With this tourist visa extension guide you can stay up to 180 days in total.

UPDATE: While having done this visa extension myself I only got an extension for 90 days from the visa extension date, not from the expiry date. VFS tells that I should have done a visa extension 7 days before expiry instead of 60 days before expiry. This is very confusing. So, ask a VFS of visa service company very clear about this. Else you would get (just like me) a shorter extension than 90 days. Read more about is on this blog.

While being in this situation myself, I’ve written this article to prevent wasting hours of time for you. Use this article on your own risk.

Apply for an extension as soon as possible as you enter the country, since it may take up to eight weeks. In order for one to apply for an extension of your existing visa, an extension application needs to be made 60 days prior to the expiry of your current visa and must be submitted in person at one of the VFS Global centres in South Africa.

How to extend your 90 days visa with another 90 days?

Step 0) Go to a VFS office

VFS Global is the office that runs the visa/immigration service in SA. They will explain you what you need to extend your tourist visa. In my case:

  • Flight return ticket within these 180 days, your return date determines the amount of extra days you’ll get (a flight reservation is fine, which you can do at Flight Centre)
  • Copy of passport / visa
  • Proof of enough financial incomes
  • Letter of support

Step 1) Fill in the form

  • USE INTERNET EXPLORER: or the browsers VFS advice. Safari (or maybe even Chrome) won’t work!
  • Don’t forget your password! The password forget tool of VFS does NOT work!

VFS gave me a form with what to fill in and what you need and where you need to fill in this form https://www.vfsvisaonline.com/DHAFOSOnlineVAF/gatewaypage.aspx. That may differ for your situation.

In my case, I filled in these details (check if the visa in your passport also says 11(1) or call VFS):

VFS Form - what to select


Then you can create an account, fill out the requested forms, pay by credit card and create an appointment (this only works with Internet Explorer). From then it can take some time for your visa to be renewed.

2) Make an appointment

Make an appointment, this only works in Internet Explorer. The VFS office will help you further to get your tourist visa extended. In this appointment letter you will find the documents you need to bring along (like a flight reservation until your new desired stay date, copy of passport & visa, motivation letter, etc.).

3) Go to the appointment

In the appointment you’ll need to bring all the documents as requested in your appointment letter and checklist which will be emailed to you after you scheduled an appointment. The VFS member takes all your documents and gives a trace-number you can use to track your application.

4) Wait

It could take a while to hear about an update. Check if your trace number is in the system and if so, just wait a while.

Following this article is at your own risk. Not sure what to do? Go to a VFS office or call them.

Good luck with your visa extension!

More info on tourist visa extension:

NB. This is just a guideline. Use at your own risk.

How to fix the Laravel Gulp Error: Cannot find module ‘internal/fs’

Laravel Gulp Error: Cannot find module ‘internal/fs’

Get this error?

vagrant@homestead:*****$ gulp
    throw err;

Error: Cannot find module 'internal/fs'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at evalmachine.:18:20
    at Object. (/usr/lib/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/fs.js:11:1)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)

How to fix this error?

Thanks to Softwarehorizont, I found the solution:

Try to delete all node modules and reinstall them. A command sequence like this would do:

npm cache clean
rm -Rf node_modules/
npm install

Still got this error?

If you still got this error, you can look up the following references (I have not tested these, at your own risk, like all solutions posted on this blog):

  1. https://github.com/nodejs/node/issues/9377
  2. http://stackoverflow.com/questions/40663489/npm-not-working-cannot-find-module-internal-fs-nodejs

Travis CI – Laravel Forge / webhook integration

While developing tests for my app, I wanted to have an integration with Laravel Forge in this order:

  1. Push to Github after commit
  2. Tests done by Travis CI
  3. Call the deployment trigger url of Laravel Forge / Envoyer if the test runs successfully. This URL looks like: https://forge.laravel.com/servers/111111/sites/2222222/deploy/http?token=TOKEN

To do this, create a travis.yml file like:

language: php

  - 7.1

  - cp .env.travis .env
  - mysql -e 'create database db_testing';
  - composer self-update
  - composer install --no-interaction
  - php artisan migrate

  - vendor/bin/phpunit

  - chmod +x ./tests.sh; ./tests.sh

Don’t forget to change the environment in phpunit.xml for example to change to a custom database:

The after_success script

Create a file tests.sh and insert:


# Trigger deployment
# Replace the url below with your Forge/Laravel url
curl -s 'https://forge.laravel.com/servers/111111/sites/2222222/deploy/http?token=TOKEN';
echo 'Deployment triggered!'


Using other services than Travis or creating a custom test service


Also thanks to:

Moneybird koppelen met PayPal transacties

Doe je ook je boekhouding met Moneybird en ben je online actief? Grote kans dat je dan wel eens een PayPal transactie hebt moeten koppelen in Moneybird. Daarvoor heb je twee mogelijkheden:

  1. Aan de PayPal transactie de één of meerdere facturen die erachter horen koppelen in het tabblad “banktransacties”.
  2. Een aparte PayPal-bankrekening bijhouden waarin alle transacties gekoppeld worden, zoals Moneybird vermeldt.

Als je veel transacties hebt en regelmatig een positief saldo hebt bij PayPal heb je al snel met optie 2 te maken. Je moet volgens Moneybird PayPal transacties één voor één inboeken.

Aparte rekening aanmaken met MT940 software

Je kunt ook CSV-export doen van PayPal en de CSV omzetten in MT940. Gebruik daarvoor de MT940-creator. Zelf gebruik ik het volgende stappenplan:

  1. Ga naar PayPal, selecteer een datum, eventuele overlap mag, maar let goed op het begin- en eindsaldo. Het makkelijkste is een moment waarop deze allebei 0 zijn.
  2. Exporteer als CSV met bedragen die ‘invloed op saldo’ hebben (selecteer deze optie).
  3. Check begin en eindsaldo in CSV, bij voorkeur allebei 0
  4. Voer in in MT940 creator
  5. Check de begin- en eindsaldo’s of deze kloppen
  6. Controleer of PayPal valutafilter op EUR staat
  7. Rekeningnr = 222222222 (een fictief rekeningnummer, ik gebruik de ABN-Amro unstructured export soort)
  8. Klik op opslaan als en voer in bij de bank van Moneybird
  9. Check in Moneybird bij Rapporten bij Balans of het saldo van rekening 222222222 klopt per de maand van het eindsaldo. Als het saldo 0 is staat de rekening er niet tussen.

Vervolgens kun je alle transacties koppelen in je nieuwe fictieve 222222222 PayPal rekening.

MT940 PayPal Moneybird account

Beste optie: API

Iemand tijd en zin om een API te bouwen die dit bovenste automatisch doet? Ik zou er geld voor over hebben. Is het je gelukt? Of heb je inmiddels een betere workaround? Laat het onderstaand weten.


Resetting Linux Root Password with TransIP / VPS on Ubuntu

Option 1 – Using bootloader

Use this guide: http://www.howtogeek.com/196520/grub2-101-how-to-access-and-use-your-linux-distributions-boot-loader/ . In my case this did not work.

Option 2 – Using SystemRescueCD

It might be that your VPS has a Linux Recovery Mode (not rescue mode) using a SystemRescueCD. If so, use this guide:

In my case the /dev/vda5 was not mountable, because it was password encrypted. That was why I had to use these commands:

In summary it went like:

$ fdisk -l
$ mkdir /mnt/system
$ mount /dev/vda5 /mnt/system
# /dev/vda5 is the main Linux partition
mount: unknown filesystem type 'crypto_LUKS'
# I received an error that this partition is encrpted, so the I used:
$ cryptsetup open /dev/vda5 newRoot
$ modprobe dm-mod
$ vgchange -ay
$ lvscan
# hopefully the root is displayed now. Mount this one
mount /dev/xx/yy /mnt/system
# ACCESS 😀 😀
chroot /mnt/system
# Enter your new root password

Then I was able to reset my password, by entering passwd.

Laravel Speed and Performance Optimization 101 – The Guideline

speed-1249610_1920I am working with a pretty heavy Laravel site with many requests and lots of Eloquent/SQL calls. Even though the high-memory and high-cpu VPS, I felt there is room for performance improvement. That is why I would like to write out some improvements to speed up Laravel:

1. Use Database or Redis for cache and sessions

When you navigate to config/cache.php and config/session.php, you see that the default CACHE_DRIVER and SESSION_DRIVER = file. If you have Redis installed, just try to set it as a cache and session driver. Check if Redis is installed by running:


If it is installed, try to define the drivers in your .env file:


2. Use several artisan pre-made commands

There are various artisan commands that are made to cache several parts of Laravel. You can configure them in the deployment process of Laravel Forge or Envoyer:

php artisan route:cache
php artisan config:cache
php artisan optimize --force


Use Developer tools guideline

Do a run at https://developers.google.com/web/fundamentals/performance/ and optimize several steps:

3. Optimize images like PNGs and JPEGs

Images sometime possess useless extra data that can be lossless optimized. Therefore you can use the packages OptiPNG and JPEGOptim. In Ubuntu install OptiPNG:

sudo apt-get update
sudo apt-get install optipng

And also install JPEGOptim:

sudo apt-get install jpegoptim

Now navigate to the folder that you would like to optimize its images. For optipng run:

optipng *

For jpegoptim run:

for i in *.jpg; do jpegoptim --all-progressive "$i"; done

Note that also the subdirectories might be optimized

4. Use HTTP2 instead of HTTP 1.1 if you have an SSL certificate enabled

The following guideline helps you through the process of updating to HTTP2 in Nginx.

Note that you need to have a SSL certificate. Google PageSpeed gave a server speed change from 0.52s (without HTTP2, with SSL) to 0.35s (with HTTP2)

Result: About 30% speed increase

5. Cache response in Redis or File

Sometimes it is unnecessary that the page is called from a database many times. Just caching the page reduces quite some load. That is exactly the same idea of the Laravel Response Cache plugin. The install instructions are quite good. In my case it had a drastic performance improvement.

Result: about 200 ms speed increase in my case

6. Optimize InnoDB innodb_buffer_pool_size

I am not sure why, but for some reason InnoDB has a really small innodb_buffer_pool_size when deploying your initial Laravel Forge server. In my default case, the innodb_buffer_pool_size was 8MB, while some blogs estimate that you can reserve up to 80% of your ram for innodb_buffer_pool_size. So edit the my.conf file:

sudo nano /etc/mysql/my.cnf

And add for example:

innodb_buffer_pool_size = 1G

Result: Several times faster queries

7. Reduce load by adding swap

My server regularly had Redis full-memory issues and high loads. This was solved by adding some swap to Ubuntu. As described by DigitalOcean:

One of the easiest way of increasing the responsiveness of your server and guarding against out of memory errors in your applications is to add some swap space. Swap is an area on a hard drive that has been designated as a place where the operating system can temporarily store data that it can no longer hold in RAM.

Read more about adding swap at the DigitalOcean website.

Result: a reduction in load when entering the ‘top’ command

8. Using Eager Loading instead of Lazy Loading

When using Laravel Eloquent models with relations it’s tempting to use ‘lazy loading’. That is a way of getting relational models in a loop. E.g.:

$blog = Blog::all();
foreach ($blogs as $blog)
    echo $blog->comments->name;

In this way, foreach blog the comments will be loaded in separate queries. When using Eager loading, the comments would be loaded in ONE IN query:

$blog = Blog::with('comments')->get();
foreach ($blogs as $blog)
    echo $blog->comments->name;

Read more about Eager Loading on Laravel’s documentation.

How to find queries that may need optimization?

Don’t know how to find queries that might need some optimization? E.g. that might need eager loading instead of lazy loading? The easiest way is to install and enable Laravel Debugbar on your development server. With this toolbar you can view the queries per page. If you see lots of queries that could have been simplified with a simple join or in-query, you know it’s your queue to optimize that script with eager loading.

Result: Each query saved, couple of milliseconds per query

This list is still a work-in-progress list, although above tips gave me a speed improvement of MORE THAN 1 SECOND. Got any tips, let me know in the comments!

Also share your speed improvements 🙂

Laravel 5.3 change login path and prevent registration

Prevent that /login is the default path for login

Thanks to Stackoverflow. Go to your routes/web.php

And change:



// Login
Route::group(['middleware' =&gt; ['web']], function() {
    Route::get('login-new-address', ['as' =&gt; 'login', 'uses' =&gt; 'Auth\LoginController@showLoginForm']);
    Route::post('login-new-address', ['as' =&gt; 'login.post', 'uses' =&gt; 'Auth\LoginController@login']);
    Route::post('logout-new-address', ['as' =&gt; 'logout', 'uses' =&gt; 'Auth\LoginController@logout']);
// Registration Routes...
    Route::get('register', ['as' => 'register', 'uses' => 'Auth\RegisterController@showRegistrationForm']);
    Route::post('register', ['as' => 'register.post', 'uses' => 'Auth\RegisterController@register']);

// Password Reset Routes...
    Route::get('password/reset', ['as' => 'password.reset', 'uses' => 'Auth\ForgotPasswordController@showLinkRequestForm']);
    Route::post('password/email', ['as' => 'password.email', 'uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail']);
    Route::get('password/reset/{token}', ['as' => 'password.reset.token', 'uses' => 'Auth\ResetPasswordController@showResetForm']);
    Route::post('password/reset', ['as' => 'password.reset.post', 'uses' => 'Auth\ResetPasswordController@reset']);

Would you like to prevent registration?

Remove the registration and password reset routes if you don’t want people to register, e.g. for admin panels.

Also change your redirect if not logged in

Change in App/Exceptions/Handler.php the redirect to:

return redirect()->guest('login-new-address');

Laravel Eloquent Triple Pivot Relations

Solving the HasManyTriple problem

Sometimes you find yourself in the situation where you have a table like shop_country_category, which has the following structure:

- id
- name

- id
- name

- id
- name

- id
- country_id
- shop_id
- product_id

In this case a shop has specific products that differ per country. So, for example in the Shop.php Eloquent model use:

     * The country-specific products that belong to a shop (triple pivot relation)
    public function countryProducts()
        return $this->belongsToMany('App\Product','shop_country_product')

In this way you can access that shop_country_category

Or use a plugin

I’ve not tested it, but I heard this package might work with Laravel 5.

Do you have a better solution?

Do not hesitate to share them in the comments.