Sunday, March 12, 2023

Preparing Mini-Server - Part 1 (System)

BACKGROUND

In this article, I am going to share my experience with mini-server preparation. Actually, this whole job I have carried out as my hobby project and a kind of research & development. In my free time, I develop interesting projects and want to run them somewhere with 100% availability.

I got one free web space from somewhere (don't remember now) and I could run my small PHP project to save my personal passwords. Actually, I did not have much interest and wanted to switch to java which I am comfortable with. I then started looking for some java (free) servers where I can host my applications, unfortunately, I did not find any such provider. I had one notebook which I made run for 24 hours as a server and deployed my java applications. One big problem with this is it used to consume lots of power (almost 28W) and to run for 24 hours is, I think, not a good idea. Also, the noise produced by the notebook was also noticeable(when it runs for 24 hours).

Then I decided to purchase a virtual private server from Amazon. I was very excited to have almost 30 GB of space and 1 GB of RAM. I could run simple programs without any problem. More interesting is that I have full access to the system, and is very secure to save my private data there, than some random webspace provider. I had to pay ca. 5 EURO per month for this amazing service provided by amazon (EC2). And as compared to the electricity cost of running a full system, it was economical too. Later I found an economical option called Vultr(https://vultr.com), which I used for a couple of months, and later unsubscribed because of inactivity. IAAS provided by Amazon and Vultr was amazing, the only problem is resources that 1GB of RAM and 30 GB of SSD were not enough to run many applications parallel. You have to upgrade the resources costing more money. There were options too, to only run specific time intervals which sacrificed the availability of the service.

MINI-PC

The idea of MINI-PC came when I realize that instead of letting your data online in the cloud (which in my opinion has some sort of security and availability risks), you can have your data on your server and make it available on the internet through your router. So, you have full access to your system and can manage it in your own way. Another plus point you can get high SSD volume and more RAM. Your data will be stored locally, it does not go external world, by some security mechanism, you can fully secure your sensitive data. 

Factors to consider for a mini-server

We have to consider some points before you purchase a PC for a server to let it run for 24 hours. There are many min-pc available in the market. There are powerful mini-pc that consume more power and run warmer. The cooling system should run to make the system cool. Although they can do complex tasks faster, for a server that runs 24 hours a day, we want it to be as quiet as possible. Mini servers normally run without any graphical display, and they are not meant for gaming. So, a normal graphics card that comes with a processor should be enough. CPUs should consume as low power as possible (preferably 10W-15W - Celeron) and with this power bound as many cores as possible.  

Regarding fans, some mini-pcs have louder fans installed which can be heard in the room. For a server running 24 hours, PCs with louder fans are NOT recommended. There are BIOS settings that can set the fan speed based on temperature, to make the fan run quieter. For example, when I turned on the new mini-PC from NUC, the fan was always running, because the default setting was to run cooler with the fan always running. After changes in BIOS, the fan stopped running, and it was fully quiet. The minimum temperature to run the fan was made increased, so that fan starts running when the CPU temperature reaches that minimum temperature. 

I have done tons of research, and even though the price is higher compared to others, I could not compromise the build quality of Intel NUC PCs. My expectation was fulfilled by Intel NUC BOXNUC6CAYH (4 core intel Celeron & 8 GB memory), which is running since 2019 (almost 4 years now!) without any issues. The good part is that it has a passive fan and runs very cool 24 hours a day. I reboot the system very when there are kernel updates, that's it!

OPERATING SYSTEM

I have NOT done any research regarding the best operating system for the mini-pc. I needed lightweight, without any bloatware, and ubuntu-server met the requirements.


 The installation of the minimal server is very light and you can install the required packages/services later. After installation, I installed open-ssh to access the system remotely. Surprisingly, in contrast to windows, the memory usage was just 400 megabytes and CPU usage was almost zero. 



Enable Remote Login

To enable remote login, we have to install the open-ssh service. To allow remote login with password, you have to uncomment the following line in /etc/ssh/sshd_config file.

# PasswordAuthentication yes

Configure Network
One of the challenging tasks after installation of the ubuntu-server is to configure the network and assign an IP address to the system. 

>> Command to check all the interfaces and IP address
     ip a 
    We can see the network information including the IP addresses of all the interfaces.


Here, the first one is the lookback interface. The second one is ethernet and the third one is a wireless interface. The default network configuration is DHCP, so the IP address is assigned by a DHCP server in the network. If we want to assign static IP address, then we have to assign IP address statically. For that, we need to edit the file in the /etc/netplan folder. There are yaml files and we change dhcp to static and provided our information manually.

Wifi:
A typical wifi configuration looks something like this: 


Ethernet:
A typical ethernet configuration looks something like this:

Here I have disabled DHCP, so I have provided the Ip address, nameservers, and gateway myself. 

Note: to avoid the network verification time (ca. 2 minutes) while booting, we have made optional true, which skips the network checking.

After you have changes in one of those files, you run the following command to verify:
sudo netplan generate 
sudo netplan apply 

If you see no error messages there, you are good to go, otherwise, you have to fix the configuration problems. 

Notes:

1) Please don't enable disk encryption, which needs human intervention to provide the passphrase when the system is rebooted(which is infeasible to do remotely)
2) Use this command if "lsblk" or "df -h" not showing full disk size

sudo lvextend -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv


Sunday, October 9, 2022

Auto-Reload Spring MVC Project

This is a much-required process while we develop spring boot applications. We do changes continuously and want to see the result at the same time without manually rebuilding the application. 

For the changes in Java files, we need to include a dependency 

developmentOnly 'org.springframework.boot:spring-boot-devtools'


In Eclipse, this should be enough, I have not tested it though.

If you are using IntelliJ, we need to do one extra step to enable hot-reload.





You need to go to settings (CTRL+ALT+S) and click "Build, Execution, Deployment" select "Compiler", and then on the right side, select the select "Build project automatically".


So far, we have implemented the hot reload of Java files. 

This does not take care of the changes in other files, for example, changes in template files, or other resources files. There are many alternatives to implement this, I prefer using gulp which watches the changes in the resource files and transfers the changes files into the build directory.  

(Reference:https: //attacomsian.com/blog/spring-boot-auto-reload-thymeleaf-templates )

1) Your system should have the latest npm and node. 
2) Instal gulp-client 
npm install gulp-cli -g
Installing globally makes it available to all other applications too.
3) Create a file package.json in the root folder with the following content

{
"name": "Corona Tracker",
"scripts": {
"gulp-watch": "gulp-watch"
},
"dependencies": {
"gulp": "^4.0.2",
"gulp-watch": "^5.0.1"
}
}


4) Run the command npm install (which installs these packages) 
5) Now, we have to define the actual task of watching and taking action. For that, create a file called "gulpfile.js" with the following text:

var gulp =require('gulp'),
watch=require('gulp-watch');

gulp.task('watch',function(){
return watch('src/main/resources/templates/**/*.*',()=>{
gulp.src('src/main/resources/templates/**')
.pipe(gulp.dest('build/resources/main/templates/'));
});
});

The task defined here is "watch"

6) Run "gulp watch" which watches directory templates, and if any changes are there, it copies the changes into the build directory. 


I preferred this method of loading static file changes because it is fast and fully customizable. The method in IntelliJ did not work in my case. (Changing IntelliJ registry did not sound good to me) 

Monday, September 19, 2022

Access Systems in a LAN in Windows 10

Accessing a remote system with a hostname is a bit tricky in windows 10. I went on forgetting after it is done, so writing it as a reference.

It is very easy to map remote ip with a hostname. 

The file is located under

C:\Windows\System32\drivers\etc\hosts

You need to be an administrator or open notepad to change the file. 

In this file, you just need to type ip address of the remote system and the hostname to access it. 

Thats it !

Sunday, February 27, 2022

Scala 3 Introduction

Scala3 is trending and it's a significant upgrade from scala2. In this article, I am going to write a short introduction to what actually does Scala do and how can we start programming with it. I have done some research on the recently released version (called Scala3) and how can we get started with it. 

Preparing Environment

To prepare the development environment for scala, we have to install java, scala, and configure the JAVA_HOME path so that scala knows where the java is installed. The use of sdkman makes the task of managing the SDKs easier, I prefer to install it. 

1) Install SDKMan

The installation of sdkman is simple. Go to this URL and follow the instructions


Commands:
Installation
$ curl -s "https://get.sdkman.io" | bash
Load Environment
source "$HOME/.sdkman/bin/sdkman-init.sh"
Test it 
$ sdk version

2) Install JDK
$ sdk install java

3) Install Scala

$ sdk install scala

4) Install SBT

$ sdk install sbt

You can verify the installation from the command line. 


Create a sample Scala3 project:
sbt new scala/scala3.g8
This will create a sample Scala3 project. We can take this to start a project. 

Saturday, October 17, 2020

Design Pattern Walkthrough

The term Design Pattern is a buzzword in the software development world. Actually, we can develop software even without a design pattern, but software development is a continuous process, changes come and the software should adapt to the changes. So, if the software is developed without any consideration of the design pattern, then it is difficult to scale and maintain. Also, if design patterns are properly used, it's very easy to understand your code to other developers. A design pattern is nothing, but the adapted practices by experienced software developers, so it is a good idea to consider design patterns while we develop software.

Basically, we can divide the design pattern into the following categories:

A. Creational Design Pattern
B. Structural Design Pattern
C. Behavioural Design Pattern
D. J2EE Design Pattern (Only for Java)


A. Creational Design Pattern
1) Singleton
2) Factory
3) Abstract Factory 
4) Builder
5) Prototype 

B. Structural Design Pattern
1) Adapter 
2) Decorator
3) Bridge
4) Composite
5) Facade 
6) Flyweight 
7) Proxy

C. Behavioural Design Pattern
1) Command
2) Observer
3) Iterator
4) Memento
5) Template
6) State
7) Strategy
8) Visitor
9) Mediator 
10) Chain of Responsibility

D. J2EE Design Pattern



Thursday, October 15, 2020

Create USB Windows 10 Installer in Ubuntu System

 As the title clearly says, creating bootable USB in the Ubuntu system is a bit challenging as compared to the Windows system. Windows system provided their own tool and we can seamlessly create a bootable thumb drive. After the less availability of CD ROMs, it is very important to know how to create bootable USB disks. 

Yes, I also tried to use some of the tools I was familiar with, such as UnetBootIn, copying with dd tool, etc, but unfortunately, I was unsuccessful. It creates a bootable USB, but the problem, the installation of windows crashes, with some file related error. 

Because I did not have any windows system in my machines, and I have to install windows in my newly bought notebook, I have to create anyhow a bootable Windows 10 installer using my Linux machine. I carried out some research on this, got a working tool to create a bootable Windows installer on USB.

1) Installation of WOEUSB command

What I did is, I have first of all run a couple of Linux commands to add the repository, then install the tool.

sudo add-apt-repository ppa:nilarimogard/webupd8

sudo apt udpate

sudo apt intall woeusb

Now installation completes. 

2) Get USB Info

We have to find out the usb device id (for example: /dev/sdb or /dev/sdc). Using one of the following commands, we can find out that information:

sudo fdisk -l

lsblk 

3) Unmount the USB Disk

This is important, we have to unmount the USB before carrying out the problem. There is a simple command to carry out this task:

sudo umount /dev/sdb1

3) Create the installer 

The final step is to run a command to create the actual installer. 

sudo woeusb --target-filesystem NTFS --device Win10_2004_English_x64.iso /dev/sdb

Here, Win10_2004_English_x64.iso is the iso file downloaded from the Microsoft site. Which can be freely downloaded. 

/dev/sdb is the path of the USB disk.

It can take up to 5-6 minutes depending upon how fast your system is.

After the process finishes, we are ready to use it as a windows 10 installer. 



Friday, April 10, 2020

Creating multipurpose executable Jar file

As the title says, this recipe is focused on creating a multipurpose jar file, where a single jar file can be used for multiple requirements. I am going to cover the whole process by diving into the following steps:
1) Create a Java application
2) Bundling into an executable Jar file
3) Running a Jar file

I take a problem scenario to explain the above steps and how they are carried out.

Problem:
We want to have a java application, which should have addition, subtraction, multiplication and division functionalities,  that we can call those functionalities providing the command line parameters. For example

add 2 4 4 (result=2+4+4)
subtract 54 12  (result=54+12)
multiply 12 54 55 (result=12*54*55)
divide 34 17 (result=34/17)


So, let's start:
1) Create a Java application
I am creating a Java application with Gradle as a build tool because it is easy to use. I am creating 4 classes with the main method which is responsible for corresponding operation and parameters. One option could be to create a single method and get an operation as a parameter, which makes it really complex to handle parameters. If we create a main method for each operation, it makes our tasks of handling parameters easy.

So, I begin with creating four java classes with main method, which manipulates the arguments to get the corresponding result. Because the example task is very simple, our actual task could be way bigger with many dependent libraries. So, we define a bunch of libraries in "build.gradle" file and we create a "fatJar" with all dependencies included in the jar file. An alternative will be we copy dependent libraries in the classpath.

I begin with the fatJar method, which create a jar file with all dependent libraries automatically from gradle. For this, we have to write a method to create fatJar. Have a look at the sample build.gradle file.

File: build.gradle



settings.gradle



The method jar create the jar file without dependencies. But the fatJar create a jar file with all dependencies, and we can use out of the box.

So, after definition of Gradle build information.

Now, we create class files with specific operation in main methods. The class files look something like this:

Add.java



Subtract.java



Multiply.java



Division.java



The application structure looks like this:



So far, we have created a java application with the required operations.


2) Bundling into an executable Jar file

Bundling into an executable Jar file is quite easy because we have already written a method in build.gradle file above. So, we just call

gradle clean && gradle fatJar

The created Jar file will be in folder build/libs as shown above(Operations.jar)

Note: If we simply run "gradle build", then it will create a thin jar file(i.e. without dependencies)


3) Running a Jar file

The Last Step is to execute the Jar file Operations.jar. The bundled jar file includes all the classes, and we can run all operations providing corresponding arguments.
For example:
java -cp Operations.jar com.kpaudel.operations.Add 12 34.33 45.3

Result=91.63

Similarly, we can check all other operations providing the parameters. 

java -cp Operations.jar com.kpaudel.operations.Subtract 123.56 23
Result=100.56

java -cp Operations.jar com.kpaudel.operations.Multiply 12.2 34.5
Result=420.9

java -cp Operations.jar com.kpaudel.operations.Division 12 2 2
Result=3.0


So, we can independently manage each operation with their own arguments, which makes very easy to handle input arguments. Apart from this advantage, bundling into a single jar file makes it easy to deploy, which means only a single jar file with many operations can be called separately.

I am using this method to create download and upload operations for my cloud storage, getting advantage of using the same jar file for different purposes of download and upload operations(with independent input parameters.) 


I hope you have enjoyed this recipe.  Thanks for reading :)