<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tayyebi</title>
    <description>The latest articles on DEV Community by Tayyebi (@tayyebi).</description>
    <link>https://dev.to/tayyebi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F223926%2Fc4d1639f-7074-4346-bd35-7715d5869fba.jpg</url>
      <title>DEV Community: Tayyebi</title>
      <link>https://dev.to/tayyebi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tayyebi"/>
    <language>en</language>
    <item>
      <title>Deepest internet censorship on earth: How does it look like?</title>
      <dc:creator>Tayyebi</dc:creator>
      <pubDate>Thu, 09 Feb 2023 07:46:55 +0000</pubDate>
      <link>https://dev.to/tayyebi/nuclear-relationships-how-its-like-to-be-a-webmaster-in-the-deepest-internet-censorship-of-earth-2hkn</link>
      <guid>https://dev.to/tayyebi/nuclear-relationships-how-its-like-to-be-a-webmaster-in-the-deepest-internet-censorship-of-earth-2hkn</guid>
      <description>&lt;p&gt;First of all, I express my deepest gratitude to all kind people in the free world, especially those who write open-source code and keep their services accessible for everyone, and it doesn't matter for them if their users are black, female, or Iranian.&lt;/p&gt;




&lt;p&gt;Imagine you are a Linux systems administrator, and you want to install an open-source personal CRM for your own stuff, but when you try any &lt;code&gt;apt&lt;/code&gt; command, this will print on your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;E: Failed to fetch http://▮▮.archive.ubuntu.com/ubuntu/pool/universe/t/▮▮▮/▮▮▮-1_amd64.deb  503  Service Unavailable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same for grabbing a Docker image,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🦮 $ docker run mysql
Unable to find image 'mysql:latest' locally
docker: Error response from daemon: error parsing HTTP 408 response body: invalid character '&amp;lt;' looking for beginning of value: "&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;408 Request Time-out&amp;lt;/h1&amp;gt;\nYour browser didn't send a complete request in time.\n&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;\n".
See 'docker run --help'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same for &lt;code&gt;npm&lt;/code&gt;, &lt;code&gt;yarn&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Is that a problem with your network? Let's figure out through &lt;code&gt;traceroute&lt;/code&gt; to Google, there are 30+ nodes on this unstable always-changing network, that are applying different levels of censorship, and your ping time is &lt;code&gt;&amp;gt;300ms&lt;/code&gt; on average, but that "&lt;code&gt;408 Request Time-out&lt;/code&gt;" was not from your side definitely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;traceroute to google.com (142.251.163.100), 64 hops max
  1   192.168.1.1  2.003ms  1.752ms  1.527ms 
  2   1▮▮.▮▮▮.▮▮▮.▮▮▮  43.129ms  42.336ms  44.380ms 
  3   1▮▮.▮▮▮.▮▮▮.▮▮▮  147.223ms  52.188ms  43.277ms 
  4   ▮▮▮.▮▮▮.▮▮▮.▮▮▮  51.598ms  51.720ms  53.908ms 
  5   ▮▮▮.▮▮▮.▮▮▮.▮▮▮  60.701ms  51.035ms  50.648ms 
  6   ▮▮▮.▮▮▮.▮▮▮.▮▮▮  52.848ms  58.920ms  50.796ms 
  7   *  *  *
same
 29   *  *  * 
 30   ▮▮▮.▮▮▮.▮▮▮.▮▮▮  284.808ms  244.162ms  267.002ms 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meanwhile, if you are upset by the slow network (&lt;code&gt;&amp;lt;2MBps&lt;/code&gt;), TLS warnings, SSH drops, timeouts, and chronic anxiety of leaking your IP with WebRTC, or &lt;a href="https://medium.com/@hamed/github-blocked-my-account-and-they-think-im-developing-nuclear-weapons-e7e1fe62cb74"&gt;getting blocked from accessing your business profile on GitHub&lt;/a&gt;, you can't even play music to chill down, because YouTube is banned from inside of the country and iTunes is not allowed to give you services from outside (:&lt;/p&gt;

&lt;p&gt;A simple installation of a WordPress instance on a fresh server, which may take uttermost 10 mins in Germany, will take you 9+ hours! If you are done with the installation of your website, now it's time to share your business on Google Maps, but still, you are not allowed! &lt;em&gt;That's all we know!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2weitJs8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qvdpc7eyhwuowm7pnse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2weitJs8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qvdpc7eyhwuowm7pnse.png" alt="Image description" width="658" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"&lt;em&gt;Ok, at least I know a lot, I can get certified for my skills on edX, Coursera, Udemy, or LinkedIn&lt;/em&gt;", you may think to yourself; but no, You can't! Because you can't pay for it. Even if you could, a simple certificate would cost you $50 which is a quarter of your income, if you are a lucky highly-paid nerd. FYI, official inflation rate is 60% in a single year.&lt;/p&gt;

&lt;p&gt;This country with 636,296 sq mi coverage, even does not exist on earth!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5-LlJ9dj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60ms7rsj335m6blz49lk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5-LlJ9dj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60ms7rsj335m6blz49lk.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This is our life and youth which is wasting behind "Loading..."s, CAPTCHAs, 503s, 403s, 408s, "Not available in your area"s. Thinking about what if life doesn't go that way, scratches my mind. Being obsessive will make it even worse. I take my tension pills every day and get back to work. I write books, I build software, and I try to live. And I take other pills again to sleep without nightmares.&lt;/p&gt;

&lt;p&gt;I remind myself: "No matter, do good. That's all you know."&lt;/p&gt;

</description>
      <category>internet</category>
      <category>devops</category>
      <category>network</category>
      <category>linux</category>
    </item>
    <item>
      <title>Analysis of Administrator Propaganda: Story of a web service troubleshoot, without touching the code.</title>
      <dc:creator>Tayyebi</dc:creator>
      <pubDate>Fri, 07 Feb 2020 09:09:44 +0000</pubDate>
      <link>https://dev.to/tayyebi/analysis-of-administrator-propaganda-story-of-a-troubleshoot-8cg</link>
      <guid>https://dev.to/tayyebi/analysis-of-administrator-propaganda-story-of-a-troubleshoot-8cg</guid>
      <description>&lt;p&gt;Hooray! It's Friday (Weekend in bloody middle east) and time to write a blog post. And wish you are good.&lt;/p&gt;

&lt;h1&gt;
  
  
  Problem
&lt;/h1&gt;

&lt;p&gt;In a troubleshoot problem we had a cute experience yesterday. And It was about '403 Forbidden Error' from company's server to a third party business's API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nTmAzx5h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p14wwkeqvpmi4br667s7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nTmAzx5h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p14wwkeqvpmi4br667s7.png" alt="Alt Text" width="880" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything was fine until this week. And no code was changed, nothing in network was moved, no new firewall policy was applied, and everything was totally same as previous weeks.&lt;/p&gt;

&lt;p&gt;But &lt;em&gt;Server B&lt;/em&gt; (which requests last image from &lt;em&gt;Server A&lt;/em&gt;), was accepting 'HTTP Error 403' and everyone was shocked. Out &lt;strong&gt;IIS&lt;/strong&gt; logs also confirmed that it was our side.&lt;/p&gt;

&lt;p&gt;We just reviewed &lt;em&gt;App 1&lt;/em&gt; and &lt;em&gt;App 2&lt;/em&gt; codes. The idea behind &lt;em&gt;App 1&lt;/em&gt; is to download images from cameras, using &lt;code&gt;ffmpeg&lt;/code&gt;, convert them and keep a copy of that for archive and store last image in a directory, with a specific name, so &lt;em&gt;App 2&lt;/em&gt; (Which is a &lt;code&gt;asmx&lt;/code&gt; web service also), can wait for a request from &lt;em&gt;Server B&lt;/em&gt; to send image byte array as response.&lt;/p&gt;

&lt;h1&gt;
  
  
  Troubleshoot steps:
&lt;/h1&gt;

&lt;p&gt;1- Double-checked network architecture and gained permission to review network engineers reports: nothing.&lt;/p&gt;

&lt;p&gt;2- Double-checked &lt;code&gt;git&lt;/code&gt; changes: nothing.&lt;/p&gt;

&lt;p&gt;3- Double-checked the &lt;em&gt;SOAP API&lt;/em&gt; changes with third-party business: No changes was applied, and We were the only contractor who had this error.&lt;/p&gt;

&lt;p&gt;4- Reviewed the code, database was OK, and only thing which is not under our control is &lt;strong&gt;File System&lt;/strong&gt; who is the accused 🔍🎩 !&lt;/p&gt;

&lt;p&gt;5- Reviewed the &lt;code&gt;GetFiles()&lt;/code&gt; function &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.getfiles?view=netframework-4.8"&gt;documentation&lt;/a&gt; from Microsoft website. Took a look in &lt;strong&gt;Exceptions&lt;/strong&gt; section and Voilà!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;UnauthorizedAccessException&lt;/strong&gt;&lt;br&gt;
The caller does not have the required permission.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;6- Definitely it was &lt;code&gt;GetFiles()&lt;/code&gt; but why? Maybe when &lt;code&gt;ffmpeg&lt;/code&gt; was downloading and converting image (&lt;em&gt;APP 1&lt;/em&gt;), &lt;em&gt;App 2&lt;/em&gt; was requesting the file because of &lt;em&gt;critical section&lt;/em&gt; we web service was broken. That was also wrong because &lt;code&gt;ffmpeg&lt;/code&gt;'s has a different behavior that creates the file at the end, and instantly release it.&lt;/p&gt;

&lt;p&gt;7- Key question: &lt;strong&gt;Which user is running App 1?&lt;/strong&gt;: Administrator. And &lt;strong&gt;which user is running App 2?&lt;/strong&gt;: IIS_IUSRS! that's it!&lt;/p&gt;

&lt;p&gt;8- &lt;strong&gt;App 1&lt;/strong&gt; is triggered from &lt;em&gt;Windows Scheduler&lt;/em&gt; every one minute to take a snapshot, and we just simply set user as &lt;em&gt;IIS_IUSRS&lt;/em&gt; in scheduler tasks from &lt;code&gt;security options&lt;/code&gt;&amp;gt;&lt;code&gt;Change User or Group&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion.
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Not always it's because of code. Don't blame developers!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maybe IIS has a list in cache which when a file creates in it's website directory, that list keeps permission details about that file, so when &lt;code&gt;ffmpeg&lt;/code&gt; creates the file and then updates the permissions after logic end, IIS does not update the file details instantly after modification. And this will cause exceptions in higher layers, especially when folder gets heavier in time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;powershell&lt;/code&gt; more. All those stuff could be simply handled using &lt;code&gt;.bat&lt;/code&gt; and basic Windows commands. Complexity makes troubleshooting difficult.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comment any code, any where, even if it is as simple as a &lt;code&gt;foreach thing in GetFiles()&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When it comes to a code which is going to run million times a day, check each obvious line of code again, and Copy-Paste potential errors from documentation to code comments with link and details.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope you will let me know if there is any comments. Thank you!&lt;/p&gt;

</description>
      <category>criticalsection</category>
      <category>authentication</category>
      <category>iis</category>
    </item>
    <item>
      <title>Messing with the Enemy: Surviving in a NoSQL world of MongoDB, dirty code, and resources limitation.</title>
      <dc:creator>Tayyebi</dc:creator>
      <pubDate>Fri, 01 Nov 2019 20:10:36 +0000</pubDate>
      <link>https://dev.to/tayyebi/messing-with-the-enemy-surviving-in-a-nosql-world-of-mongodb-dirty-code-and-resources-limitation-56am</link>
      <guid>https://dev.to/tayyebi/messing-with-the-enemy-surviving-in-a-nosql-world-of-mongodb-dirty-code-and-resources-limitation-56am</guid>
      <description>&lt;p&gt;CTO called me early in morning: “Server is down”. He was talking about an old GoLang code which was a acting as a store-and-forward server with a MongoDB behind. The database was used to save a copy of all passed traffic from clients.&lt;/p&gt;

&lt;p&gt;I wasn’t familiar with that code. It wasn’t a well formatted code, no comments and lots of files in bad named directories.&lt;/p&gt;

&lt;p&gt;“Do we have backup?”, I asked. And the answer was positive. The Network &amp;amp; Virtualization team is hero. They create a backup from whole machine periodically, and it’s perfect.&lt;/p&gt;

&lt;p&gt;So we asked for a mirror server to keep service online. They switched IP addresses of main server and the mirror server, and we were online! Bravo!&lt;/p&gt;

&lt;p&gt;Now we have to find the problem. We don't have time. Mirror server will die soon. So simply &lt;code&gt;ssh&lt;/code&gt;ed to the server (which is not currently under load) and asked for &lt;code&gt;top&lt;/code&gt; process list and &lt;code&gt;df&lt;/code&gt; disk status.&lt;/p&gt;

&lt;p&gt;Disk was full!!! There wasn’t any free space. Even for a byte of data! I just asked the hero team (Network &amp;amp; Virtualization) to add some space to &lt;code&gt;sda1&lt;/code&gt;. And they said that it’s not possible on their infrastructure. Maybe because that server’s startup time was for more than a year, software was old, no updates, nothing, totally an orphan server that no one cares about it’s existence.&lt;/p&gt;

&lt;p&gt;At first we thought that we must read the source code. How this code is working? Which data is it storing? What’s going on?&lt;br&gt;
But later we figured out that these are not good questions in this moment. We must ask, how can we kill this snake? The resource limitations? And which files we have to move?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo du -a / | sort -n -r | head -n 5&lt;/code&gt; → We called this command on the second server that had free space. It will not run on a machine which is out of space.&lt;/p&gt;

&lt;p&gt;So again we asked N&amp;amp;V team to add an external drive to the Ubuntu machine. A giant disk was added and it was time to move database files to new directory. We did so.&lt;/p&gt;

&lt;p&gt;Time for some edits in services. &lt;code&gt;sudo service mongod status&lt;/code&gt;. Failed to start with lots of errors in log file. But &lt;code&gt;EXEC&lt;/code&gt; command was a big help. It was a &lt;code&gt;--quite&lt;/code&gt; run of MongoDB. So I pasted it in terminal: &lt;code&gt;mogod –config /etc/mongod.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Edited the &lt;code&gt;dbpath&lt;/code&gt; to new directory. And it was another little problem. &lt;code&gt;mongodb&lt;/code&gt; user wasn’t permitted to &lt;code&gt;r/w&lt;/code&gt; on that directory. I don’t know why but &lt;code&gt;chown mongodb:mongodb -R /media/blob/bob&lt;/code&gt; did not work for us so we changed the &lt;code&gt;.service&lt;/code&gt; user to &lt;code&gt;whoami&lt;/code&gt; output with a nice &lt;code&gt;755&lt;/code&gt; permission to the mentioned username.&lt;/p&gt;

&lt;p&gt;It’s time to clear the database log &lt;code&gt;: &amp;gt; /var/log/mongodb/mongodb.log&lt;/code&gt; and remove the lock file which allows MongoDB to fire &lt;code&gt;sudo rm /tmp/mongodb-27017.sock&lt;/code&gt; and &lt;code&gt;sudo rm /var/lib/mongodb/mongodb.lock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We are now refactoring the code, moving data to a safe place, and writing a new SOS protocol.&lt;/p&gt;

&lt;p&gt;Lessons we learned:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Never accept a bad documented code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write a rescue plan that a five year old kid can read, understand, and perform it's actions step by step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's not important that how much big and complicated your business is, never forget old servers. Pay someone to take care of old infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Never keep your technical support team busy with non-critical stuff.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask system administrators to make limitations on software and users, so they will shutdown before reaching operating system's red lines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use SSH-based monitoring tools to monitor details which are not accessible from ESXi monitoring panel.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>mongodb</category>
    </item>
    <item>
      <title>7 face dice</title>
      <dc:creator>Tayyebi</dc:creator>
      <pubDate>Thu, 31 Oct 2019 17:27:23 +0000</pubDate>
      <link>https://dev.to/tayyebi/7-face-dice-2cgc</link>
      <guid>https://dev.to/tayyebi/7-face-dice-2cgc</guid>
      <description>&lt;p&gt;"God does not play dice", says Einstein. But we do! What if there were 7 players and you have to randomly choose one with a 6 face dice?&lt;/p&gt;

&lt;p&gt;Let me deface the question: What if there was a function &lt;em&gt;(Called rand6)&lt;/em&gt; that randomly generates a &lt;strong&gt;N&lt;/strong&gt;atural number between 1 to 6 and you have to write another function &lt;em&gt;(Called rand7)&lt;/em&gt; that generates a random &lt;strong&gt;N&lt;/strong&gt;atural number between 1 to 7 using first function &lt;em&gt;(rand6)&lt;/em&gt;? And &lt;em&gt;rand6&lt;/em&gt; is balanced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note that the probability of all events must be equal!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Wait a moment! Think! or just skip this step to my stupid solution.&lt;/p&gt;

&lt;h1&gt;
  
  
  This is the answer if you wish:
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/tayyebi/af474bc0c0820d7ed1bdbb6a64f0d23a"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OTDxnDEl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/D-IvjHbXYAAetdD%3Fformat%3Djpg%26name%3Dsmall" alt="python pyplot output" width="680" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  But how?
&lt;/h1&gt;

&lt;p&gt;The idea is to launch an election campaign! there will be a &lt;code&gt;local_max_count&lt;/code&gt; that will keep top candidates count which have equal votes. Candidates are one of {1,2,3,4,5,6,7} that will go for a second, third, or n*th* election. And there is also a &lt;code&gt;global_max&lt;/code&gt; variable that keeps the maximum count of votes of top candidate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int local_max_count = -1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In each election, we play dice for each candidate (not really what Facebook is made because of), and the number will be it's vote count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 7 ; i ++)
    if (votes[i] == global_max)
    {
        local_max_count ++;
        // call the rand6()
        votes[i] = rand6();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then &lt;code&gt;global max&lt;/code&gt; is defined as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Find the array maximum
for (int i = 0; i &amp;lt; 7 ; i ++)
    global_max = max (global_max, votes[i]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if there was a unique top candidate, function will return that as answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (local_max_count == 0)
    for (int i = 0; i &amp;lt; 7 ; i ++)
        if (votes[i] == global_max)
            return i + 1; // i + 1 because normal people start counting from 1.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if there were two or many other candidates?&lt;/p&gt;

&lt;p&gt;There is the point that way we have to recursively call our function and change a line in &lt;code&gt;// Election&lt;/code&gt; code to add value to previous value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;votes[i] += rand6();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Test
&lt;/h1&gt;

&lt;p&gt;You can run this function for 1000 times and visualize output with &lt;code&gt;pyplot&lt;/code&gt; or any thing you wish. But it has to be something like image below because all numbers must have same chance to keep fair.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZQyRE6qo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/D-I2aZcWkAIzY-U%3Fformat%3Dpng%26name%3Dlarge" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZQyRE6qo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/D-I2aZcWkAIzY-U%3Fformat%3Dpng%26name%3Dlarge" alt="7 face dice" width="640" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Question!
&lt;/h1&gt;

&lt;p&gt;What if &lt;code&gt;rand6&lt;/code&gt; function was unbalanced?&lt;/p&gt;

</description>
      <category>random</category>
      <category>algorithms</category>
      <category>python</category>
      <category>cpp</category>
    </item>
    <item>
      <title>PHP as a Pain Reliever</title>
      <dc:creator>Tayyebi</dc:creator>
      <pubDate>Fri, 18 Oct 2019 21:09:47 +0000</pubDate>
      <link>https://dev.to/tayyebi/php-as-a-pain-reliever-2ok1</link>
      <guid>https://dev.to/tayyebi/php-as-a-pain-reliever-2ok1</guid>
      <description>&lt;h1&gt;
  
  
  Intro 🎬
&lt;/h1&gt;

&lt;p&gt;If you are a dead eye and you don't wan't to fall on boss's sword, and go nuclear ☢️ (frameworks like Laravel I mean) to create a simple CRUD app, this post is written for you!&lt;br&gt;
I will talk about a solution that helps us to rapidly create a PHP-based mini-framework that handles authentication, authorization, tables CRUD, Server status monitor, and etc in some simple magic 🧙 steps like shooting fish in a barrel 🛢️.&lt;/p&gt;
&lt;h1&gt;
  
  
  Demo 🎥
&lt;/h1&gt;

&lt;p&gt;Some GIFs are provided in side each subtitle.&lt;/p&gt;
&lt;h1&gt;
  
  
  Overview 🔭
&lt;/h1&gt;

&lt;p&gt;MySQL functions are used to handle auth, we write HTML in SQL(!), and lots of other spaghetti 🍝 stuff to build the solution fast.&lt;/p&gt;
&lt;h1&gt;
  
  
  File Structure 🗂️
&lt;/h1&gt;

&lt;pre&gt;
- index.php
- lib.php
- master/
---- header.php
---- footer.php
- pages/
---- crud.php
---- superlitesql.php
---- users.php
- reports/
---- a_report.sql
---- filters/
-------- a_report.sql.csv
&lt;/pre&gt;
&lt;h1&gt;
  
  
  Step by step 🔬
&lt;/h1&gt;
&lt;h2&gt;
  
  
  master/header.php and master/footer.php
&lt;/h2&gt;

&lt;p&gt;You any theme on you own. Maybe bootstrap is a good choice. I just copied all the stuff in &lt;a href="https://getbootstrap.com/docs/4.0/examples/dashboard/"&gt;this example&lt;/a&gt; inside &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;footer&lt;/code&gt; files. Note that you have to keep a free space for variable contents. &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;footer&lt;/code&gt; files are here to give us a taste of &lt;strong&gt;master page&lt;/strong&gt; just like what we had in &lt;em&gt;ASP.NET web forms&lt;/em&gt; (RIP ⚰️).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;header.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;header&amp;gt;...&amp;lt;header&amp;gt;
&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;
    &amp;lt;main&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;footer.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;/main&amp;gt;
    &amp;lt;script&amp;gt;...&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  index.php
&lt;/h2&gt;

&lt;p&gt;This file handles authentication, calls &lt;code&gt;header.php&lt;/code&gt; and &lt;code&gt;footer.php&lt;/code&gt;, and totally he is a good boy, we can call him &lt;em&gt;loader&lt;/em&gt; or anything else.&lt;/p&gt;

&lt;p&gt;How to authenticate with MySQL users?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$conn = @new mysqli($servername
    , $_SERVER['PHP_AUTH_USER'] // Username
    , $_SERVER['PHP_AUTH_PW'] // Password
    , $dbname);

// Set database charset to support persian.
mysqli_set_charset($conn,"utf8");

// Check Auth
if (!isset($_SERVER['PHP_AUTH_USER'])
    || $conn-&amp;gt;connect_error
) {
    // Send login failed error to browser and expire temp login.
    header('WWW-Authenticate: Basic realm="Tayyebi Realm"');
    header('HTTP/1.0 401 Unauthorized');
    // die("Connection failed: " . $conn-&amp;gt;connect_error);
    echo 'Access Denied';
    exit;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will use browser basic authentication to ask for SQL connection info. If connection to database was successful, then code will pass to next lines. &lt;/p&gt;

&lt;p&gt;Code below, allows us to access to any page content we decide, with passing its &lt;code&gt;id&lt;/code&gt; to &lt;code&gt;index.php&lt;/code&gt; as a &lt;strong&gt;query string&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Header
include ('master/header.php');

// Container
$_GET['id'] = isset($_GET['id']) ? $_GET['id'] : 'welcome';
// includes the page content
include ('pages/' . $_GET['id'] . '.php');

// Footer
include ('master/footer.php');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  lib.php &lt;a href="https://github.com/tayyebi/tiny-php-pain-reliever/blob/master/lib.php"&gt;[src]&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;There are two important functions in this &lt;code&gt;static&lt;/code&gt; class. First to create a form from SQL table &lt;code&gt;describe&lt;/code&gt; and second to create a HTML table from SQL query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
abstract class SuperLiteSql {
    // Function to create tables from queries
    static function createTable_from_sql_select_query($sql_link, $query) {
        // ...
        echo $table;
    }

    // This function creates an HTML form from SQL table
    static function GenerateFormFromTable($table_name, $conn, $values) {

        // ...

        return $form;
    }
}
?&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SuperLiteSQL &lt;a href="https://github.com/tayyebi/tiny-php-pain-reliever/blob/master/pages/superlitesql.php"&gt;[src]&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4YXvfAI6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/superlitesql.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4YXvfAI6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/superlitesql.gif" alt="SQL Editor" width="720" height="781"&gt;&lt;/a&gt;&lt;br&gt;
Here we have a textbox and a button that allows you to submit the query and it will print out the results. Also we can pass &lt;code&gt;.sql&lt;/code&gt; file names to the page and it will automatically post it to those functions; so we will be able to simply create SQL reports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (isset($_GET['entry']))
    $_POST['the_query'] = file_get_contents("reports/" . $_GET['entry']);
// ...
if (isset($_POST['the_query']))
    SuperLiteSql::createTable_from_sql_select_query($conn, $_POST['the_query']);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  crud.php &lt;a href="https://github.com/tayyebi/tiny-php-pain-reliever/blob/master/pages/crud.php"&gt;[src]&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6MYGGVT0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/crud.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6MYGGVT0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/crud.gif" alt="Create, Read, Update, and Delete" width="720" height="781"&gt;&lt;/a&gt;&lt;br&gt;
CRUD is CRUD, everywhere. There is Create, Select, Update, and Delete on a table row which is known by a &lt;strong&gt;key&lt;/strong&gt;.&lt;br&gt;
So the &lt;code&gt;CRUD.php&lt;/code&gt; will use functions defined in &lt;code&gt;lib.php&lt;/code&gt; to create a table from items table and a form for each individual row. Finally it will listen for posted data to decide what to edit or delete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (isset($_POST['insert'])
{
        // ...
}
else if (isset($_POST['update'])
{
        // declare variables
        $update_query_key_values = '';

        // Get table structure
        // In this case: todo table
        $result = $conn-&amp;gt;query("DESCRIBE " . $table_name);

        // output data of each row
        while ($row = $result-&amp;gt;fetch_assoc()) {
            if ($row["Field"] != $table_id) { // because of auto increment
                // dont insert comma for the last record
                if ($update_query_key_values != '')
                    $update_query_key_values .= ', ';

                // apend keys to keys array
                $update_query_key_values .= '`' . $row["Field"] . '` = ';

                // Get field type
                // if it was a stirng, add quote in first and last of value
                $type = substr($row["Type"], 0, strpos($row["Type"], '('));
                $symbol = '';
                if ($type == "varchar"
                or $type == "char" ) {
                    $symbol = '\'';
                }


                // If value is posted and its not null
                if (! isset( $_POST[ $row["Field"] ] ) ) {
                    $update_query_key_values .= "NULL" ;
                }
                else if ($_POST[ $row["Field"] ] == ''
                    and ( $type == "int" or $type == "bit" or $type == "decimal" )
                ) {
                    $update_query_key_values .= "NULL" ;
                }
                else {
                    // append value to values array
                    $update_query_key_values .= $symbol . $_POST[ $row["Field"] ]  . $symbol;
                }
            }
        }

        // assemble final query
        $update_query  = 'UPDATE ' . $table_name . ' SET ' . $update_query_key_values . ' WHERE ' . $table_id . ' = '. $_POST[$table_id] ;

        // run the query !
        mysqli_query($conn, $update_query);
}
else if (isset($_POST['delete']))
{
        // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Users and Permissions
&lt;/h2&gt;

&lt;p&gt;We can easily manage users access level to any table using MySQL predefined functionality.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A3tZqbPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/permissions.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A3tZqbPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/permissions.gif" alt="Database Users Permissions" width="720" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bash script to log database transactions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while true
do
        mysql -u root -p&amp;lt;yourpasshere&amp;gt; -e "insert into test.mysql_general_log select * from mysql.general_log where argument like '%tss%' or argument like '%todo%' or argument like '%Transactions%'"
        mysql -u root -p&amp;lt;yourpasshere&amp;gt; -e "truncate mysql.general_log"
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code provided above, which you can call it &lt;code&gt;log.sh&lt;/code&gt; and run it in background, MySQL &lt;em&gt;cli&lt;/em&gt; will make a copy of all logs that have &lt;code&gt;todo&lt;/code&gt; or &lt;code&gt;Transaction&lt;/code&gt; tables name into the local &lt;code&gt;mysql_general_log&lt;/code&gt; which is made using the result of &lt;code&gt;SHOW CREATE TABLE mysql.general_log&lt;/code&gt; query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic reports
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UFBorHNI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/reports.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UFBorHNI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/tayyebi/tiny-php-pain-reliever/master/meta/reports.gif" alt="Reports filtering" width="720" height="781"&gt;&lt;/a&gt;&lt;br&gt;
We can create dynamic filters by merging our scripts and &lt;em&gt;comma separated value&lt;/em&gt; info about tables. We can define variables using a &lt;code&gt;@&lt;/code&gt; symbol and then generate forms that will accept user inputs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Downloads 📩
&lt;/h1&gt;

&lt;p&gt;Github Release page: &lt;a href="https://github.com/tayyebi/tiny-php-pain-reliever/releases"&gt;https://github.com/tayyebi/tiny-php-pain-reliever/releases&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Ref ⚓
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://7esl.com/weapons-idioms"&gt;https://7esl.com/weapons-idioms&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>mysql</category>
    </item>
    <item>
      <title>Linux as a web server</title>
      <dc:creator>Tayyebi</dc:creator>
      <pubDate>Wed, 25 Sep 2019 04:36:31 +0000</pubDate>
      <link>https://dev.to/tayyebi/linux-as-a-web-server-1l3i</link>
      <guid>https://dev.to/tayyebi/linux-as-a-web-server-1l3i</guid>
      <description>&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Who is this post for?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Those who need some &lt;a href="https://lmgtfy.com/?q=eli5&amp;amp;p=1"&gt;#eli5&lt;/a&gt; step by step notes, to simply configure a web server, to host multiple websites on a single server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is this everything about configuring of a web server?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No it's just a tranquilizer to newbie programmers mental challenges on hosting, and rapid Wordpressers who wanna mine money faster!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Spoil it!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Finally you will install Apache, MySQL, BIND, PHP, and etc... on a Linux server and configure it to host multiple domains like &lt;code&gt;a.b.com&lt;/code&gt; and &lt;code&gt;d.e.com&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Where to learn theory of everything?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just Google it with the following keyword: &lt;a href="https://www.lpi.org/"&gt;LPIC&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Connect to your server!
&lt;/h1&gt;

&lt;p&gt;use &lt;code&gt;ssh &amp;lt;IP&amp;gt;&lt;/code&gt; or &lt;code&gt;ssh &amp;lt;Domain&amp;gt;&lt;/code&gt; command to connect to your server.&lt;br&gt;
(e.g-&amp;gt; ssh example.com)&lt;/p&gt;
&lt;h1&gt;
  
  
  Install Apache
&lt;/h1&gt;

&lt;p&gt;What is Apache? Apache serves your content to the world. And also it can give you a hand to create dynamic website with PHP which Wordpress is also a PHP thing.&lt;/p&gt;

&lt;p&gt;To install Apache&lt;/p&gt;

&lt;p&gt;1- &lt;code&gt;sudo yum install httpd mod_ssl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2- &lt;code&gt;sudo /usr/sbin/apachectl start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If message appears: &lt;code&gt;Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName&lt;/code&gt;, edit the configuration file using &lt;code&gt;vim&lt;/code&gt; or any editor you wish (Step 3).&lt;/p&gt;

&lt;p&gt;3- &lt;code&gt;sudo vim /etc/httpd/conf/httpd.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and bring the following line out of comment:&lt;/p&gt;

&lt;p&gt;4- &lt;code&gt;#ServerName www.example.com:80&lt;/code&gt; =&amp;gt; &lt;code&gt;ServerName MyServerName&lt;/code&gt; (which &lt;em&gt;MyServerName&lt;/em&gt; is your own server name!)&lt;/p&gt;

&lt;p&gt;Allow Apache in firewall. As you know, Apache listens on port HTTP 80 by default.&lt;/p&gt;

&lt;p&gt;5.1- &lt;code&gt;sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;5.2- &lt;code&gt;sudo service iptables save&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restart Apache:&lt;/p&gt;

&lt;p&gt;6- &lt;code&gt;sudo /usr/sbin/apachectl restart&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Test your installation:&lt;/p&gt;

&lt;p&gt;7- &lt;code&gt;curl 127.0.0.1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As you know, it's very critical to allow Apache to access your codes!&lt;/p&gt;

&lt;p&gt;8- &lt;code&gt;sudo chcon -t httpd_sys_rw_content_t /var/www/html/mysite -R&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Learn more about FirewallD
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-firewalld-on-centos-7"&gt;https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-firewalld-on-centos-7&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Install PHP
&lt;/h1&gt;

&lt;p&gt;Install and enable EPEL repository:&lt;/p&gt;

&lt;p&gt;1- &lt;code&gt;sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install and enable Remi repository&lt;/p&gt;

&lt;p&gt;2- &lt;code&gt;sudo yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install &lt;em&gt;yum-config-manager&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3- &lt;code&gt;yum install yum-utils&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install PHP modules which programmers use to reduce their headache&lt;/p&gt;

&lt;p&gt;4- &lt;code&gt;yum install php php-mcrypt php-cli php-gd php-curl php-mysql php-ldap php-zip php-fileinfo&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Test the PHP's command line interface (CLI)&lt;/p&gt;

&lt;p&gt;5- &lt;code&gt;php -v&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Wanna create a secondary sysadmin user? (Sudoer guy)
&lt;/h1&gt;

&lt;p&gt;Create a user&lt;/p&gt;

&lt;p&gt;1- ‍‍‍&lt;code&gt;a‍dduser theusername&lt;/code&gt; (you say &lt;em&gt;theusername&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Choose a password&lt;/p&gt;

&lt;p&gt;2- &lt;code&gt;passwd theusername&lt;/code&gt; (you said &lt;em&gt;theusername&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Just like school, anyone is in a group. So you have to add new user to &lt;code&gt;wheel&lt;/code&gt;, which is a super user level group:&lt;/p&gt;

&lt;p&gt;3- &lt;code&gt;usermod -aG wheel theusername&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Switch user&lt;/p&gt;

&lt;p&gt;4- &lt;code&gt;su - username&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Disable a user login (EMail or FTP accounts maybe)
&lt;/h1&gt;

&lt;p&gt;1- Edit the &lt;code&gt;/etc/passwd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2- Change shell to &lt;code&gt;/bin/nologin&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Learn more about configuring FTP server:
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://linuxize.com/post/how-to-setup-ftp-server-with-vsftpd-on-centos-7/"&gt;https://linuxize.com/post/how-to-setup-ftp-server-with-vsftpd-on-centos-7/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Hey server! KEEP EVERYTHING IN MIND; even "Clean your mind"
&lt;/h1&gt;

&lt;p&gt;Edit &lt;code&gt;~/.bashrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;1- &lt;code&gt;vim ~/.bashrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2- Put following lines at the end of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export HISTCONTROL=ignoredups:erasedups  
shopt -s histappend
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
export HISTTIMEFORMAT='%F %T '
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- Test it: &lt;code&gt;history&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  How to install MySQL
&lt;/h1&gt;

&lt;p&gt;Install &lt;code&gt;wget&lt;/code&gt; which is more handy tool than &lt;code&gt;curl&lt;/code&gt; for heavy downloads.&lt;/p&gt;

&lt;p&gt;1- &lt;code&gt;yum install wget&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Download the package:&lt;/p&gt;

&lt;p&gt;2- &lt;code&gt;wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the package:&lt;/p&gt;

&lt;p&gt;3- &lt;code&gt;sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Update package manager:&lt;/p&gt;

&lt;p&gt;4- &lt;code&gt;yum update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install the package:&lt;/p&gt;

&lt;p&gt;5- &lt;code&gt;sudo yum install mysql-server&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Start daemon:&lt;/p&gt;

&lt;p&gt;6- &lt;code&gt;sudo systemctl start mysqld&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Configure installation:&lt;/p&gt;

&lt;p&gt;7- &lt;code&gt;sudo mysql_secure_installation&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Test installation:&lt;/p&gt;

&lt;p&gt;8- &lt;code&gt;mysql -u root -p&lt;/code&gt; (which &lt;em&gt;root&lt;/em&gt; is the root username)&lt;/p&gt;

&lt;p&gt;Create a MySQL user:&lt;/p&gt;

&lt;p&gt;9- mysql&amp;gt; &lt;code&gt;create user 'testuser'@'localhost' identified by 'mysecretpass';&lt;/code&gt; (username is &lt;em&gt;testuser&lt;/em&gt; and the password is &lt;em&gt;mysecretpass&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Grant permissions to user:&lt;/p&gt;

&lt;p&gt;10- mysql&amp;gt; &lt;code&gt;grant all on databasename.* to 'testuser' identified by 'mysecretpass';&lt;/code&gt; (replace &lt;em&gt;databasename&lt;/em&gt; with the database name)&lt;/p&gt;

&lt;h1&gt;
  
  
  WhatIsMyIP?
&lt;/h1&gt;

&lt;p&gt;If &lt;code&gt;ifconfig&lt;/code&gt; doesn't work:&lt;/p&gt;

&lt;p&gt;use: &lt;code&gt;ip addr show&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Change &lt;em&gt;hostname&lt;/em&gt;
&lt;/h1&gt;

&lt;p&gt;Configuration file is located in &lt;code&gt;/etc/sysconfig/network&lt;/code&gt;. So open it in editor and find the related line:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HOSTNAME=myserver.domain.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Also you can change the host that is associated with the main IP address for your server in &lt;code&gt;/etc/hosts&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Test command: &lt;code&gt;hostname&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Carefully restart networking (You may lose your connection to remote server!): &lt;code&gt;/etc/init.d/network restart&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  BIND DNS (Domain Name Server: The magic behind mycustomcomputername.com)
&lt;/h1&gt;

&lt;p&gt;You can check each domain's propagation using DNS checkers online. e.g-&amp;gt; &lt;a href="https://dnschecker.org/"&gt;https://dnschecker.org/&lt;/a&gt;&lt;br&gt;
Also there is a geeky way: &lt;code&gt;nslookup domain.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install BIND&lt;/p&gt;

&lt;p&gt;1- &lt;code&gt;sudo yum install bind bind-utils -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Configure BIND (Remember that you can define your zones here, but it's better to keep the standards.&lt;/p&gt;

&lt;p&gt;2- &lt;code&gt;sudo cat /etc/named.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Look for included files, and edit the file as described below:&lt;/p&gt;

&lt;p&gt;3- &lt;code&gt;sudo vi /etc/named.rfc1912.zones&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Define your zones in file same as following lines:&lt;/p&gt;

&lt;p&gt;4-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zone "mydomain.ir" IN {
    type master;
    file "mydomain.ir.zone";
    allow-transfer { none; };
};

zone "mycustomer1domain.com" IN {
    type master;
    file "customers.zone";
    allow-transfer { none; };
};

zone "mycustomer2domain.com" IN {
    type master;
    file "customers.zone";
    allow-transfer { none; };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So you have to create the &lt;code&gt;customers.zone&lt;/code&gt; and &lt;code&gt;mydomain.ir.zone&lt;/code&gt; files you just mentioned in directory &lt;code&gt;/var/named&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;5.1- &lt;code&gt;sudo touch /var/named/customers.zone&lt;/code&gt;&lt;br&gt;
5.2- &lt;code&gt;sudo touch /var/named/mydomain.ir.zone&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then edit them as you wish:&lt;/p&gt;

&lt;p&gt;6-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$TTL 86400
@   IN  SOA     ns1.mydomain.com. root.mydomain.com. (
        2013042201  ;Serial
        3600        ;Refresh
        1800        ;Retry
        604800      ;Expire
        86400       ;Minimum TTL
)
; Specify our two nameservers
        IN  NS      ns1.mydomain.ir.
        IN  NS      ns2.mydomain.ir.
; Resolve nameserver hostnames to IP, replace with your two droplet IP addresses.
ns1     IN  A       SERVER_IP_HERE
ns2     IN  A       SERVER_IP_HERE

; Define hostname -&amp;gt; IP pairs which you wish to resolve
@       IN  A       SERVER_IP_HERE
www     IN  A       SERVER_IP_HERE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then any domain that is decided to be hosted on this server, must set &lt;code&gt;ns1.mydomain.ir&lt;/code&gt; and &lt;code&gt;ns2.mydomain.ir&lt;/code&gt; as their name server in &lt;strong&gt;domain control panel&lt;/strong&gt;. If website was defined as a Virtual Host in Apache, it will be accessible.&lt;/p&gt;

&lt;h1&gt;
  
  
  Virtual Hosts
&lt;/h1&gt;

&lt;p&gt;Edit the config file: &lt;code&gt;sudo vi /etc/httpd/conf/httpd.conf&lt;/code&gt; &lt;em&gt;foreach&lt;/em&gt; website you want to host.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
   DocumentRoot "/var/www/html/domainname"
   ServerName domainname
   ServerAlias www.domainname
   RedirectPermanent / https://domainname2
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Refrence:
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twitter.com/MRezaTayyebi/status/1152794765164974080"&gt;https://twitter.com/MRezaTayyebi/status/1152794765164974080&lt;/a&gt;&lt;br&gt;
&lt;a href="https://support.rackspace.com/how-to/centos-6-apache-and-php-install/"&gt;https://support.rackspace.com/how-to/centos-6-apache-and-php-install/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tecmint.com/install-php-7-in-centos-7/"&gt;https://www.tecmint.com/install-php-7-in-centos-7/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-create-a-sudo-user-on-centos-quickstart"&gt;https://www.digitalocean.com/community/tutorials/how-to-create-a-sudo-user-on-centos-quickstart&lt;/a&gt;&lt;br&gt;
&lt;a href="https://gist.github.com/tayyebi/5e03f83dff1b897a51e530748d74e872"&gt;https://gist.github.com/tayyebi/5e03f83dff1b897a51e530748d74e872&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linode.com/docs/databases/mysql/how-to-install-mysql-on-centos-7/"&gt;https://www.linode.com/docs/databases/mysql/how-to-install-mysql-on-centos-7/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://support.rackspace.com/how-to/centos-hostname-change/"&gt;https://support.rackspace.com/how-to/centos-hostname-change/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-the-bind-dns-server-on-centos-6"&gt;https://www.digitalocean.com/community/tutorials/how-to-install-the-bind-dns-server-on-centos-6&lt;/a&gt;&lt;br&gt;
&lt;a href="https://httpd.apache.org/docs/2.4/vhosts/examples.html"&gt;https://httpd.apache.org/docs/2.4/vhosts/examples.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>centos</category>
      <category>devops</category>
      <category>webdev</category>
      <category>virtualhost</category>
    </item>
  </channel>
</rss>
