All I wanted was just to install nodejs…and npm…

Well recently, It happens that I need to update my nodejs package on my ubuntu server (18.04.2). I type node -v and see that it is v8.x something and the LTS version now is 10.16.3, so I set out to upgrade it. After following some simple guides online, I simply can’t get it to work. Even after I installed the latest nodejs, the version checking still gives me the old version with both node and npm. WTH!

Without the time to dive in and find out what is the culprit, I completely removed previous node and npm stuff on my ubuntu using good old sudo rm -rf node-shit following this guide https://amcositsupport.blogspot.com/2016/07/to-completely-uninstall-node-js-from.html

Then I see many guides say that you have to first execute

curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -

before running this

sudo apt-get install -y nodejs

So, firstly after running the curl command above, there’s a line of text near the end saying ## Run `sudo apt-get install -y nodejs` to install Node.js 10.x and npm. So then I run sudo apt-get install -y nodejs, and nodejs -v gives me 10.16.3. Great! Next I do npm -v, well…the console gives out

-bash: /usr/local/bin/npm: No such file or directory

Shit! WTH! Even more bad news, I can’t even get the nvm approach to install my node and npm as well…I’m starting to doubt that it is my server’s peculiar case but not that those guides have failed others.

After two hours of trying, finally I saw the holy light in the dark! https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-18-04 is my ultimate lifesaver.

I have to follow its “Installing Using a PPA” approach in order to make things work. God bless the guy who wrote this guide! I guess the magic in this working approach is in its nodesource_setup.sh file. I really hope that this can save someone who is in the same weird shit situation that I once was.

How to set up a Docker Build in PHP 5.6.40-apache and MariaDB 10.3

Recently I accepted a job that had to deal with php 5.6 code. It is still using mysql_connect in its code. Since the requirements are just trivial bug fixes and minor enhancements, I have no plan to upgrade it to using mysqli or pdo.

I was following this great guide written by Christian Engel, the original link: https://parastudios.de/local-development-with-docker-php-and-mysql/

My file have only slight differences with his docker-compose.yml:

version: '3'
  
services:
  db:
    image: mariadb/server:10.3
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3306:3306"
    volumes:
      - ./data/dump.sql:/docker-entrypoint-initdb.d/dump.sql
  web:
    image: php:5.6.40-apache
    container_name: somename
    depends_on:
      - db
    ports:
      - "8080:80"
    volumes:
      - ./php/:/var/www/html/

However, after I followed his guide and ran the final bash command docker-compose up there’s an error on the web page saying that

Fatal error: Call to undefined function mysql_connect() in /var/www/html/xxx_db_connect.php on line 16

To this I found an easy fix, it is because the original php extension for mysql is missing. Together with installing the mysqli extension, the better way to do that is to install them during the building of the docker image, instead of during the container runtime. So I created Dockerfile and placed the following code into it

FROM php:5.6.40-apache

RUN docker-php-ext-install mysql && docker-php-ext-install mysqli

Then I change the line image: php:5.6.40-apache in my docker-compose.yml into build: ..

Then again I run docker-compose up --build since we need to rebuild the image to install the php extensions (after I ran docker-compose down to close the previous containers). And Voila! This time it works. The localhost:8080 page renders as expected.

But the story does not end here! In fact from the original source code, the string variable $host for the mysql_connect command was previously "localhost", which is pretty normal for traditional php environments. However, we are now using Docker with separated containers of the web app and the database so things are a little different. Actually Docker would create a default common network for these two separated containers to communicate. The code actually does not recognise "localhost" in mysql_connect and would give out Warning: mysql_connect(): No such file or directory in ... and the connection would fail. Rest assured, there is an easy fix for this, just replace the "localhost" string to "db", which is the service name in your docker-compose.yml, then the web app will automagically connects to the mysql database!