Blog

Python CRUD App

Create CRUD Application using Python and MySQL connector

Show following options

1. List All Records
2. Delete
3. Insert
4. Update
5. Search
0. Exit

Write separate function for each functionality

Program should not get exited unless user select 0 option.

You can use any module to connect to MySQL from python

Blockchain Demo

main.js

const SHA256 = require('crypto-js/sha256');

class Block {
	
	constructor(index, timestamp, data, prevHash = '') {
		this.index = index;
		this.timestamp = timestamp;
		this.data = data;
		this.prevHash = prevHash;
		this.hash = this.calculateHash();
	}
	
	calculateHash() {
		return SHA256(this.index + this.prevHash + this.timestamp + JSON.stringify(this.data)).toString();
	}
	
}

class Blockchain {
	constructor() {
		this.chain = [this.createGenesisBlock()];
	}
	
	createGenesisBlock() {
		return new Block(0, "01/01/2021", "Genesis block", "0");
	}
	
	getLatestBlock() {
		return this.chain[this.chain.length - 1];
	}
	
	addBlock(newBlock) {
			newBlock.prevHash = this.getLatestBlock().hash;
			newBlock.hash = newBlock.calculateHash();
			this.chain.push(newBlock);
	}
	
	isChainValid() {
		for(let i=1; i < this.chain.length; i++) {
			const currentBlock = this.chain[i];
			const prevBlock = this.chain[i-1];
			
			if(currentBlock.hash !== currentBlock.calculateHash()) {
				return false;
			}
			
			if(currentBlock.prevHash != prevBlock.hash) {
				return false;
			}
		}
		
		return true;
	}
	
}

let tcoin = new Blockchain();
tcoin.addBlock(new Block(1, "03/09/2021", {amt: 100}));
tcoin.addBlock(new Block(1, "04/09/2021", {amt: 200}));

console.log(tcoin.isChainValid());
console.log(JSON.stringify(tcoin, null, 4));

//tempering data
tcoin.chain[2].amt = 2000;
console.log(JSON.stringify(tcoin, null, 4));
console.log(tcoin.isChainValid());

Proof of Work

const SHA256 = require('crypto-js/sha256');

class Block {
	
	constructor(index, timestamp, data, prevHash = '') {
		this.index = index;
		this.timestamp = timestamp;
		this.data = data;
		this.prevHash = prevHash;
		this.hash = this.calculateHash();
		this.nonce = 0;
	}
	
	calculateHash() {
		return SHA256(this.index + this.prevHash + this.timestamp + JSON.stringify(this.data) + this.nonce).toString();
	}
	
	mineBlock(complexity) {
		while(this.hash.substring(0, complexity) !== Array(complexity + 1).join("0")) {
			this.nonce++;
			//console.log(this.nonce);
			this.hash = this.calculateHash();
		}
		
		console.log(`Block mined: ${this.hash}`);
	}
	
}

class Blockchain {
	constructor(complexity = 0) {
		this.chain = [this.createGenesisBlock()];
		this.complexity = complexity;
	}
	
	createGenesisBlock() {
		return new Block(0, "01/01/2021", "Genesis block", "0");
	}
	
	getLatestBlock() {
		return this.chain[this.chain.length - 1];
	}
	
	addBlock(newBlock) {
			newBlock.prevHash = this.getLatestBlock().hash;
			//newBlock.hash = newBlock.calculateHash();
			newBlock.mineBlock(this.complexity);
			this.chain.push(newBlock);
	}
	
	isChainValid() {
		for(let i=1; i < this.chain.length; i++) {
			const currentBlock = this.chain[i];
			const prevBlock = this.chain[i-1];
			
			if(currentBlock.hash !== currentBlock.calculateHash()) {
				return false;
			}
			
			if(currentBlock.prevHash != prevBlock.hash) {
				return false;
			}
		}
		
		return true;
	}
	
}

let tcoin = new Blockchain(5);

console.log("Mining Block 1...");
tcoin.addBlock(new Block(1, "03/09/2021", {amt: 100}));

console.log("Mining Block 2...");
tcoin.addBlock(new Block(1, "04/09/2021", {amt: 200}));

console.log(JSON.stringify(tcoin, null, 4));

RegEx

Playground for practice https://regexr.com/ https://regex101.com/

Pattern Matching

Regex Syntax

/<regex pattern>/

Starts with wild card character

^

Ends with wcc

$

set enclosed in

[set]
[^invert-set]

only numbers

^[0-9]+$
^\d+$

only characters

^[a-zA-Z]+$
^\w+$

occurance wcc

* => any number of occurrence
? => 0 or 1 occurrence
+ => 1 or many occurrence

e.g. adarsh mishra
to match 1 space /adarsh\smishra/
to match multiple space /adarsh\s+mishra/
to match 0 or many spaces /adarsh\s*mishra/

no special characters

^[0-9a-zA-Z\s]+$

limited characters or numbers

^[0-9]{6}$
^[a-z]{3}$

min / max range characters or numbers

^[0-9]{3,6}$
^[a-z]{3,6}$

OR clause

^(chacha|bhatija)$

case insensitive

//i

global check

//g

search any pattern
(.) e.g. “https://www.youtube.com/watch?v=hw_HpTI_Wkw”.match(/v=(.)/)[1]

will return video id hw_HpTI_Wkw

Assignment

  1. girls / boys name
  2. phone number
  3. find Indian zip code
  4. valid name
  5. email id
  6. 8-12 character password
  7. aadhaar number
  8. pancard
  9. name starts with vowels
  10. names ends with vowels
  11. names having only 5 characters
  12. credit card number

Sample Text

1234567890
123453
DAVPS0412P
127836320613
9876543210
098762
xyz@yahoo.com
smita
&UJMmju7
shailesh
143258761937
priyanka
abc@gmail.com
112096851365
%TGBbgt5
priya

DMA Project Cheat Sheet

Multi Tier Architecture

To get the connection string

Atlas > Deployment > Databases > Connect > Connect your application > Driver Node.js > Version 4.1 or later

CRUD Application using Vanilla JS | HTML5 | CSS3 | Bootstrap5

NOTE: DON’T FORGET TO APPEND DATABASE NAME IN CONNECTION STRING URL

users_module.js

//Step 1: Database connection using connection string
const mongoose = require("mongoose");

//mongodb://127.0.0.1:27017/dbname
//const conn_str = "mongodb://localhost:27017/tcet";
const conn_str = "mongodb+srv://user:passwd@cluster0.gp5lcta.mongodb.net/<DBNAME>?retryWrites=true&w=majority"

mongoose.connect(conn_str, { useNewUrlParser: true, useUnifiedTopology: true })
	.then(() => console.log("Connected successfully..."))
	.catch( (error) => console.log(error) );
	
	
//Step 2: Create Schema (similar to Java Class)
const userSchema = new mongoose.Schema({
	name: String,
	age: Number,
	city: String
})

//Step 3: Create collection Object (model)
// MAPPING 
const userObject = new mongoose.model("users", userSchema);

exports.User = userObject;

Test Database Connection

index.js

const express = require("express");
const port = 8080;

const user_model = require("./users_module");
const User = user_model.User;

const app = express();
app.use(express.json());

var cors = require('cors');
app.use(cors());

app.get("/", (req, res) => {
	res.send("Hello Friends..");
});

app.get("/user", async (req, res) => {
	let data = await User.find().sort({_id:-1});
	res.send(data);
});

app.get("/user/:id", async (req, res) => {
	console.log(req.params.id);
	let data = await User.find({"_id": req.params.id});
	res.send(data[0]);
});

app.post("/user", async (req, res) => {
	console.log(req.body)
	let u = await User(req.body);
	let result = u.save();
	res.send(req.body);
});

app.put("/user", async (req, res) => {
	console.log(req.body);
	
	//User.updateOne({where}, {set});
	let u_data = await User.updateOne({"_id": req.body._id}, {
		"$set": {
			"name" : req.body.name,
			"age" : req.body.age,
			"city" : req.body.city
		}
	});
	
	res.send(u_data);
});

app.delete("/user", async(req, res) => {
	
	let d_data = await User.deleteOne({"_id": req.body._id});
	res.send(d_data);
});

app.listen(process.env.PORT || port, () => {	
	console.log(`Listening on port ${port}`);
});

Run index.js file (node .) and Test in Postman

GET Method


POST Method

POST Method

PUT Method

DELETE Method

Create Frontend to access all web services from Web Browser

script.js

//const api_url = "<heroku_app_url>"
const api_url = "http://localhost:8080/user"

function loadData(records = []) {
	var table_data = "";
	for(let i=0; i<records.length; i++) {
		table_data += `<tr>`;
		table_data += `<td>${records[i].name}</td>`;
		table_data += `<td>${records[i].age}</td>`;
		table_data += `<td>${records[i].city}</td>`;
		table_data += `<td>`;
		table_data += `<a href="edit.html?id=${records[i]._id}"><button class="btn btn-primary">Edit</button></a>`;
		table_data += '&nbsp;&nbsp;';
		table_data += `<button class="btn btn-danger" onclick=deleteData('${records[i]._id}')>Delete</button>`;
		table_data += `</td>`;
		table_data += `</tr>`;
	}
	//console.log(table_data);
	document.getElementById("tbody").innerHTML = table_data;
}

function getData() {
	fetch(api_url)
	.then((response) => response.json())
	.then((data) => { 
		console.table(data); 
		loadData(data);
	});
}


function getDataById(id) {
	fetch(`${api_url}/${id}`)
	.then((response) => response.json())
	.then((data) => { 
	
		console.log(data);
		document.getElementById("id").value = data._id;
		document.getElementById("name").value = data.name;
		document.getElementById("age").value = data.age;
		document.getElementById("city").value = data.city;
	})
}


function postData() {
	var name = document.getElementById("name").value;
	var age = document.getElementById("age").value;
	var city = document.getElementById("city").value;
	
	data = {name: name, age: age, city: city};
	
	fetch(api_url, {
		method: "POST",
		headers: {
		  'Accept': 'application/json',
		  'Content-Type': 'application/json'
		},
		body: JSON.stringify(data)
	})
	.then((response) => response.json())
	.then((data) => { 
		console.log(data); 
		window.location.href = "index.html";
	})
}	


function putData() {
	
	var _id = document.getElementById("id").value;
	var name = document.getElementById("name").value;
	var age = document.getElementById("age").value;
	var city = document.getElementById("city").value;
	
	data = {_id: _id, name: name, age: age, city: city};
	
	fetch(api_url, {
		method: "PUT",
		headers: {
		  'Accept': 'application/json',
		  'Content-Type': 'application/json'
		},
		body: JSON.stringify(data)
	})
	.then((response) => response.json())
	.then((data) => { 
		console.table(data);
		window.location.href = "index.html";
	})
}


function deleteData(id) {
	user_input = confirm("Are you sure you want to delete this record?");
	if(user_input) {
		fetch(api_url, {
			method: "DELETE",
			headers: {
			  'Accept': 'application/json',
			  'Content-Type': 'application/json'
			},
			body: JSON.stringify({"_id": id})
		})
		.then((response) => response.json())
		.then((data) => { 
			console.log(data); 
			window.location.reload();
		})
	}
}

index.html

<!DOCTYPE html>
<html>
	<head>
		<title>CIA Institute - MongoDB Project</title>
		<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
		<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"crossorigin="anonymous"></script>
	</head>
	<body class="d-flex flex-column h-100 container">
		<header>
			<nav class="navbar navbar-expand-lg navbar-expand-sm navbar-light bg-light">
			  <div class="container-fluid">
				<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
				  <div class="navbar-nav">
					<a class="nav-link active" aria-current="page" href="#">Listing</a>
					<a class="nav-link" href="add.html">Add New</a>
				  </div>
				</div>
			  </div>
			</nav>
		</header>
		
		<table class="table table-striped table-hover text-center">
			<thead>
				<th>Name</th>
				<th>Age</th>
				<th>City</th>
				<th>Action</th>
			</thead>
			<tbody id="tbody">
				
			</tbody>
			<tfoot>
				
			</tfoot>
		</table>
		
		<footer class="footer mt-auto py-3 bg-light">
		  <div class="container text-center">
			<span class="text-muted"> &copy; CIA Institute 2022</span>
		  </div>
		</footer>
	</body>
	<script src="script.js"></script>
	<script>
		getData();
	</script>
</html>

Test in Browser

add.html

<html>
	<head>
		<title>CIA Institute - MongoDB Project</title>
		<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
		<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"crossorigin="anonymous"></script>
	</head>
	<body class="d-flex flex-column h-100 container">
		<header>
			<nav class="navbar navbar-expand-lg navbar-expand-sm navbar-light bg-light">
			  <div class="container-fluid">
				<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
				  <div class="navbar-nav">
					<a class="nav-link" href="index.html">Listing</a>
					<a class="nav-link active" aria-current="page" href="add.html">Add New</a>
				  </div>
				</div>
			  </div>
			</nav>
		</header>
		
		<h3>Add Document</h3>
		
		<form onsubmit="return false;">
		  <div class="mb-3">
			<label for="name" class="form-label">Name</label>
			<input type="text" class="form-control" id="name" autofocus>
		  </div>
		  <div class="mb-3">
			<label for="exampleInputPassword1" class="form-label">Age</label>
			<input type="text" class="form-control" id="age">
		  </div>
		  <div class="mb-3">
			<label for="city" class="form-label">City</label>
			<input type="text" class="form-control" id="city">
		  </div>
		  <button class="btn btn-primary" onclick="return postData()">Submit</button>
		  <a href="index.html" class="btn btn-primary">Cancel</a>
		</form>
		
		<footer class="footer mt-auto py-3 bg-light">
		  <div class="container text-center">
			<span class="text-muted"> &copy; CIA Institute 2022</span>
		  </div>
		</footer>
	</body>
	<script src="script.js"></script>
	<script>
	</script>
</html>

edit.html

<html>
	<head>
		<title>CIA Institute - MongoDB Project</title>
		<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
		<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"crossorigin="anonymous"></script>
	</head>
	<body class="d-flex flex-column h-100 container">
		<header>
			<nav class="navbar navbar-expand-lg navbar-expand-sm navbar-light bg-light">
			  <div class="container-fluid">
				<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
				  <div class="navbar-nav">
					<a class="nav-link" href="index.html">Listing</a>
					<a class="nav-link active" aria-current="page" href="add.html">Add New</a>
				  </div>
				</div>
			  </div>
			</nav>
		</header>
		<h3>Edit Document</h3>
		<form onsubmit="return false;">
			<input type="hidden" class="form-control" id="id">
		  <div class="mb-3">
			<label for="name" class="form-label">Name</label>
			<input type="text" class="form-control" id="name" autofocus>
		  </div>
		  <div class="mb-3">
			<label for="exampleInputPassword1" class="form-label">Age</label>
			<input type="text" class="form-control" id="age">
		  </div>
		  <div class="mb-3">
			<label for="city" class="form-label">City</label>
			<input type="text" class="form-control" id="city">
		  </div>
		  <button class="btn btn-primary" onclick="return putData()">Update</button>
		  <a href="index.html" class="btn btn-primary">Cancel</a>
		</form>
		
		<footer class="footer mt-auto py-3 bg-light">
		  <div class="container text-center">
			<span class="text-muted"> &copy; CIA Institute 2022</span>
		  </div>
		</footer>
	</body>
	<script src="script.js"></script>
	<script>
		const urlParams = new URLSearchParams(window.location.search);
		const id = urlParams.get('id');
		getDataById(id);
	</script>
</html>

Screenshots

listing

delete

add

edit

Reference Link: https://gitlab.com/tcet/mongodb-july-21.git

Create REST Api using Node.js | Express | Mongoose

index.js

const port = 8080;
const mongoose = require("mongoose");
//const conn_str ="C"
const conn_str = "mongodb://<user>:<passwd>@cluster0-shard-00-00.dslyw.mongodb.net:27017,cluster0-shard-00-01.dslyw.mongodb.net:27017,cluster0-shard-00-02.dslyw.mongodb.net:27017/<databasename>?ssl=true&replicaSet=atlas-3xk2hf-shard-0&authSource=admin&retryWrites=true&w=majority";


mongoose.connect(conn_str, { useNewUrlParser: true , useUnifiedTopology: true})
	.then( () => console.log("Connected successfully...") )
	.catch( (err) => console.log(err) );


const userSchema = new mongoose.Schema({
	name: String,
	age: Number,
	city: String
});

const user = new mongoose.model("users", userSchema);


/** Express Mongoose Integration **/

const express = require("express");
var cors = require('cors');
const app = express();


//add middlewares
app.use(express.json());
app.use(cors());


app.route("/user")
.get(async (req, res) => {
	let data = await user.find();
	res.send(data);
})
.post(async (req, res) => {
	req_data = req.query;
	let obj = new user(req.query)
	let result = await obj.save();
	res.send(result);
})
.put(async (req, res) => {
	console.log(req.body);
	
	//model.updateOne({where}, {set});
	let u_data = await user.updateOne({"_id": req.body._id}, {
		"$set": {
			"name" : req.body.name,
			"age" : req.body.age,
			"city" : req.body.city
		}
	});
	
	res.send(u_data);
})
.delete(async (req, res) => {
	let d_data = await User.deleteOne({"_id": req.body._id});
	res.send(d_data);
})


app.listen(process.env.PORT || port, () => {
	console.log("listening 8080...");
});

Call REST Api using Vanilla JS

index.html

<script>
function getDataById(id) {
	fetch(`http://localhost:8080/user/${id}`)
	.then((response) => response.json())
	.then((data) => { console.table(data); })
}

function getData() {
	fetch("http://localhost:8080/user")
	.then((response) => response.json())
	.then((data) => { console.table(data); })
}

function postData(data) {
	fetch("http://localhost:8080/user", {
		method: "POST",
		headers: {
		  'Accept': 'application/json',
		  'Content-Type': 'application/json'
		},
		body: JSON.stringify(data)
	})
	.then((response) => response.json())
	.then((data) => { console.table(data); })
}
	

function putData(data) {
	fetch("http://localhost:8080/user", {
		method: "PUT",
		headers: {
		  'Accept': 'application/json',
		  'Content-Type': 'application/json'
		},
		body: JSON.stringify(data)
	})
	.then((response) => response.json())
	.then((data) => { console.table(data); })
}

function deleteData(id) {
	fetch("http://localhost:8080/user", {
		method: "DELETE",
		headers: {
		  'Accept': 'application/json',
		  'Content-Type': 'application/json'
		},
		body: JSON.stringify({"_id": id})
	})
	.then((response) => response.json())
	.then((data) => { console.table(data); })
}


getDataById();
getData();
postData({"name": "Akshu", "age": 20, "city": "Koradi"});
putData({"_id" : "61082ae9cd4b7a0ccc39d377", "name": "chaitu"});
deleteData("61082b4ecd4b7a0ccc39d37a");
</script>

Deploy From Gitlab To FTP Server

Create file gitlab-ci.yml in gitlab

variables:
  HOST: "yourFTPServer"
  USERNAME: "yourFTPServerUsername"
  PASSWORD: "yourFTPServerPassword"

deploy:
  script:
    - apt-get update -qq && apt-get install -y -qq lftp
    - lftp -c "set ftp:ssl-allow no; open -u $USERNAME,$PASSWORD $HOST; mirror -Rnev ./ ./htdocs --ignore-time --parallel=10 --exclude-glob .git* --exclude .git/"
  only:
    - master

NOTE: Make sure to change host, username, password and directory name where to deploy code

Ref: https://stackoverflow.com/questions/49632077/use-gitlab-pipeline-to-push-data-to-ftpserver

Deploy Node.js app on heroku

Signup/Signin on heorku

https://herokuapp.com/

Login from terminal (Make sure you have installed heroku cli – https://devcenter.heroku.com/articles/heroku-cli#download-and-install)

heroku login

Create app.js

const express = require("express");
const app = express();
const port = 8080;

app.get("/", (req, res) => {
    res.send("Hello Heroku");
})

app.listen(process.env.PORT || port, () => {
	console.log("listening 8080...");
});

process.env.PORT this will be provided by heroku server

Test locally by running following command

node app.js
OR
nodemon app.js

If you get any error e.g. module not found you can install those module using npm

npm install <module_name>

To find installed module version

npm view <module_name> version
e.g.
npm view express version

Create package.json

{
	"scripts" : {
		"start" : "node app.js"
	},
	"dependencies": {
		"express": "4.17.1",
		"mongoose": "5.13.3",
		"cors": "2.8.5"
	}
}

Run following command from terminal

#onetime
git init
#onetime
heroku create <yournewappname>

Run git commands

git add .
git commit -m 'msg'

#to verify origin
git config -l

#if you are not able to see url and fetch then run git remote add origin 
#remote.heroku.url=https://git.heroku.com/project.git
#remote.heroku.fetch=+refs/heads/*:refs/remotes/heroku/*
#git remote add origin heroku_git_url
#git push origin master

git push heroku master

Once app is deployed it will show you an url which you can access publicly from internet.

To see error logs

heroku logs --tail

Nginx

Location root vs alias

http {

	server {

		listen 8081;
		root /var/www/html/websites;

		#with root no need to specify in url as location automatically append to root
		location /sqr {
			root /var/www/html/websites;
		}

		#with alias need to specify in url as location does not append to alias
		location /test {
			alias /var/www/html/websites/vegetables/;
			try_files $uri veggies.html =404;
		}

		#with regex add try_files directive
		location ~* /foo$ {
			alias /var/www/html/websites/fruits/site;
			try_files $uri $uri/index.html =404;
		}

		#with regex add try_files directive above will serve only till foo but below code will serve after foo also e.g. http://site.com/foo/abc.html
		location ~* /foo {
			alias /var/www/html/websites/fruits/site;
			try_files $uri $uri/index.html =404;
		}

	}

}

events {}
nginx -s reload

Check using following url

http://yoursite/sqr

http://yoursite/test

http://yoursite/foo/

Redirect and Rewrite

#this will redirect to foo and also changes the URL
location /bar {
	return 307 /foo;
}
#this will rewrite the url i.e. URL would not change URL will be fizz and content will load from foo 
rewrite /fizz /foo;

Nginx as a Load Balancer

# Define an upstream block to group backend servers
upstream backend_servers {
    # List of backend servers
    server backend1.example.com:8080;
    server backend2.example.com:8080;
    server backend3.example.com:8080;
    server backend4.example.com:8080;
}



server {
    listen 80;  # Listen on port 80

    # Define the server name (domain or IP)
    server_name www.example.com;

    # Location block to define how requests should be handled
    location / {
        # Use the defined upstream group for proxying requests
        proxy_pass http://backend_servers;
}

Run from terminal

while true; do curl -s http://www.example.com; sleep 1; done;

Example

you can run 2 servers locally using php -S or using docker containers by mapping 2 ports

http {

	upstream backend_servers {
		server localhost:1234;
		server localhost:4567;
	}


	server {

		listen 8081;
		#root /var/www/html/websites;


		location / {
			proxy_pass http://backend_servers;
		}


	}

}

events {}

PHP FPM socket configuration

user www-data;

events {}

http {

    root /var/www/samosa;


    server {

        access_log /var/log/nginx/samosa-access.log;
        error_log /var/log/nginx/samosa-error.log;

        error_page 404 /404.html;

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        }
    }
}

create project and verify with normal url

mkdir /var/www/html/myproject

vim index.html

<h1>Hello World</h1>

vim index.php

<?php

phpinfo();

Create server block conf file

vim /etc/nginx/conf.d/myproject.conf

server {
  listen 8082 default_server;
  server_name _;

  index index.php index.html;

  root /var/www/html/myproject;

  location ~ \.php$
  {
      include snippets/fastcgi-php.conf;
      fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
  }
}

Test nginx configuration

nginx -t

restart nginx

sudo service nginx restart
OR
sudo systemctl restart nginx

For Laravel Project
Specify path till public directory

Need to explore

worker process

log format

weight in upstream

upstream block ip:port down

nginx plus

directives – listen root index access_log error_log

access_log off;

error_log debug;
error_log warn;

$scheme variable

include /etc/nginx/mime.types;

nginx vs haproxy

Laravel Framework

Install required packages

sudo apt-get update
sudo apt-get install php-mbstring
sudo apt-get install php-curl
sudo apt-get install php-xml

Install Laravel via composer

composer create-project laravel/laravel example-app
composer install

php artisan --version
php artisan serve

Generating app key

php artisan key:generate 
php artisan key:generate --show

Redis

Redis Playground

https://try.redis.io/

Note: This try redis io is community version on web so few commands might not work. To use redis’s full power you can download and install on your local system


Redis is an in-memory data structure store, used as a distributed, in-memory key–value database, cache and message broker, with optional durability. Redis supports different kinds of abstract data structures, such as strings, lists, maps, sets, sorted sets, HyperLogLogs, bitmaps, streams, and spatial indices.

Installation

To install redis on windows download msi package from here
https://github.com/microsoftarchive/redis/releases/

For Linux Distr

sudo apt-get install redis-server

To install PHPRedis client use following command

sudo apt-get install php-redis
#for specific version
sudo apt-get install php7.4-redis

To verify redis installed in your system
Note: On windows you might need to add redis exe path in environment variables

redis-cli PING

To see all keys

KEYS *

DATATYPES

  • string
  • list
  • set
  • sorted set
  • hash
  1. String
    Syntax to set string value
SET key value [EX seconds] [PX milliseconds] [NX|XX]

To set only string value

SET keyname value

To check whether key exist or not

EXISTS keyname

Get key’s value

GET keyname

To delete any specific key

DEL keyname

To delete all keys

FLUSHALL

SET string with expiry

SET key value
EXPIRE key expiry-time-in-seconds
#shortcut
SET key value EX expiry-time-in-seconds

To check expiry time of any key

TTL key

SET string values using key:spaces
This is required when you want to set values related to one entity

SET key:space value

2. List or Stack

To set list use LPUSH

LPUSH key value1
LPUSH key value2
LPUSH key value3
OR
LPUSH key value1 value2 value3

To get length of list

LLEN key

To access any value of list you need to use LRANGE

LRANGE key from-index to-index

Use -1 in to-value to get all elements from list

LRANGE key 0 -1

To get specific index value
NOTE this will act like stack so LIFO algorithm will apply here i.e. index 0 will give you last inserted/pushed value

LINDEX key 0

LPUSH and RPUSH (left and right push)

LPUSH key value
RPUSH key value

LPOP and RPOP

LPOP key
RPOP key

Remove specific element from list

LREM key count value

3. Sets

Set is similar to list the main difference is it does not allow duplicate members
Order is not maintained in set

To add member in sets

SADD key value1 value2 value3

To view members of sets

SMEMBERS key

To remove member from sets

SREM key member

To get length of Sets

SCARD key

Compare Sets

SINTER set1 set2
SDIFF set1 set2
SUNION set1 set2

4. Sorted Sets

Sorted set are similar to sets the major difference is it stored members based on score i.e. sorted by score

ZADD key score member

To add multiple members

ZADD key rank1 member1 rank2 member2

To get count of sorted sets

ZCOUNT key

To See all members of sorted sets

ZRANGE key 0 -1

To get rank(index) of specific member

ZRANK key member

To get score of specific member

ZSCORE key member

To remove member from sorted sets

ZREM key member

5. Hashes

Hash is used to set field value pair it is similar to associative array

To set hash

HGET key field1 value1
HGET key field2 value2

To get field value

HGET key field

To get all field values

HGETALL key

To get length of hash key

HLEN key

To add field values at once

HMSET key field1 value1 field2 value2 field3 value3

To get values at once

HMGET key field1 field2 field2

To delete specific field from hash

HDEL key field1 field2

Assignment (set and get values of each type)

  1. Create string name age and city and set value in it
  2. Create List of fruits, weekdays, planets and set values in it
    Print length and values of list
  3. Create Sets of employees and managers
    Print length and values of Sets
  4. Create Hash record1, record2, record3 and add fields name age city in each hash
    Print length and values of each hash

Reference Links

User Group and Permission

User

List all users

cat /etc/passwd

List specific user

cat /etc/passwd | grep username
OR
grep username /etc/passwd

Create new user

useradd username

Delete existing user

userdel username

Set user password or update password

passwd username

You can use shortcut to add new user. Using following command you can create user set password and create home directory for newly added user

adduser username
ls -l /home/username

Rename existing user

usermod --login new-name old-name

Group

List all groups

cat /etc/group

List specific group

cat /etc/group | grep groupname
cat /etc/group | grep ^groupname
grep groupname /etc/group
grep ^groupname /etc/group

Add new group

groupadd group-name

Delete existing group

groupdel group-name

List all members of specific group

getent group group-name

Add new member in specific groups

usermod -a -G group-name1,group-name2,... user-name

Check in which groups user exist

groups user-name

Remove user from specific group

gpasswd -d user-name group-name

Permission

LIST FILES AND DIRECTORIES

OWNER – FIRST 3 FLAGS SHOWS OWNER’S PERMISSION

GROUP- MIDDLE 3 FLAGS SHOWS GROUP’S PERMISSION

OTHERS- LAST 3 FLAGS SHOWS OTHER’S PERMISSION

Permission List

  • 7 – 111 => read write execute
  • 6 – 110 => read write –
  • 5 – 101 => read – execute
  • 4 – 100 => read – –
  • 3 – 011 => – write execute
  • 2 – 010 => – write –
  • 1 – 001 => – – execute
  • 0 – 000 => no permission

How to change permission

chmod -Rf 777 path-to-file-or-directory

How to give only specific permission

#only executable
chmod -Rf +x path-to-file-or-directory

#only writable
chmod -Rf +w path-to-file-or-directory

#only readable
chmod -Rf +r path-to-file-or-directory

How to give permission to only specific role

#only owner
chmod -Rf u+x path-to-file-or-directory

#only group
chmod -Rf g+x path-to-file-or-directory

#only others
chmod -Rf o+x path-to-file-or-directory

Ownership

FIRST FLAG IN ROLE IS FOR OWNER

SECOND FLAG IN ROLE IS FOR GROUP

How to change ownership of any file or directory

chown -Rf user:group path-to-file-or-directory

Change attribute read only

chattr +a file.txt
  • chattr: This is a command in Linux used to change file attributes on a file system.
  • +a: This option sets the “append-only” attribute on the specified file. When this attribute is set, the file can only be opened in append mode for writing. Existing data in the file cannot be modified or removed. This attribute is often used to prevent accidental deletion or modification of important files.
  • to revert use -a option for chattr