<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[andrizan]]></title><description><![CDATA[WARNING: This blog exists purely as notes for a forgetful coder.]]></description><link>https://blog.andrizan.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 28 Apr 2026 07:12:23 GMT</lastBuildDate><atom:link href="https://blog.andrizan.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Backup Proxmox VE to the CLOUD! Backup Hook Scripts and S3]]></title><description><![CDATA[Proxmox has a pretty good backup scheduler, but it relies on the backup destination being mounted as a storage location. This implies that the backup destination needs to be a protocol that Proxmox supports - SMB (CIFS), NFS, … or Proxmox Backup Serv...]]></description><link>https://blog.andrizan.com/backup-proxmox-ve-to-the-cloud-backup-hook-scripts-and-s3</link><guid isPermaLink="true">https://blog.andrizan.com/backup-proxmox-ve-to-the-cloud-backup-hook-scripts-and-s3</guid><category><![CDATA[Backup]]></category><category><![CDATA[virtualization]]></category><category><![CDATA[pve]]></category><category><![CDATA[proxmox]]></category><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Wed, 14 Aug 2024 03:47:59 GMT</pubDate><content:encoded><![CDATA[<p>Proxmox has a pretty good backup scheduler, but it relies on the backup destination being mounted as a storage location. This implies that the backup destination needs to be a protocol that Proxmox supports - SMB (CIFS), NFS, … or Proxmox Backup Server. If you want to push your backups to a cloud service, you probably need something a bit more complicated. Thankfully, Proxmox’s backup scheduler thought about this and has a hook feature we can use for this purpose, and we can use any protocol supported on the Debian base system, including things such as FUSE or s3cmd.</p>
<p>In this project, I integrate S3 object storage with the Proxmox backup scheduler, copying resulting backups to a cloud storage service directly from the Proxmox system. The S3 protocol is ubiquitous among cloud object storage providers, so we aren’t tied to AWS - we can use any service such as Backblaze. In my case, I’m demonstrating this with Linode.</p>
<h1 id="heading-proxmox-vzdump-hook-scripting">Proxmox VZDump hook scripting</h1>
<p>Proxmox’s documentation mentions briefly that the <code>--script</code> argument can be passed to <code>vzdump</code>, the Proxmox backup utility. We can also add the line <code>script &lt;path_to_script&gt;</code> in the <code>/etc/pve/jobs.conf</code> file, and it will retain this script argument even if you modify the backup job from the GUI. You can’t add a script command from the GUI, but you need to initially create the job there.</p>
<p>P<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">roxm</a>ox mentions a backup file (<a target="_blank" href="http://vzdump-hook-script.pl"><code>vzdump-hook-script.pl</code></a>), but I was unable to find a copy easily. For your convenience, I’ve uploaded it to my site <a target="_blank" href="https://www.apalrd.net/posts/2022/pve_backup/vzdump-hook-script.pl">here</a> for you to view. The tl;dr is that:</p>
<ul>
<li><p>The first argument to the script is the phase, which is one of:</p>
<ul>
<li><p>job-start</p>
</li>
<li><p>job-end</p>
</li>
<li><p>job-abort</p>
</li>
<li><p>backup-start</p>
</li>
<li><p>backup-end</p>
</li>
<li><p>backup-abort</p>
</li>
<li><p>log-end</p>
</li>
<li><p>pre-stop</p>
</li>
<li><p>pre-restart</p>
</li>
<li><p>post-restart</p>
</li>
</ul>
</li>
<li><p>The ‘job’ type phase<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">s ar</a>e called once for a job, while the rest are called for each backup in the job</p>
</li>
<li><p>The backup mode (stop/suspend/snapshot) and vmid are passed as arguments to the non-job types</p>
</li>
<li><p>Addition<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">al i</a>nformation is passed as environment variables for certain phase<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">s, i</a>ncluding <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/"><code>TARG</code></a><code>ET</code> (the <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">ful</a>l path on <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">the</a> local syste<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">m to</a> the backu<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">p fi</a>le), <code>LOGFILE</code> <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">(th</a>e full <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">path</a> to the <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">log</a> file), and <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">a fe</a>w other useful <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">att</a>ributes.</p>
</li>
</ul>
<p>In our case, we are going to hook to the <code>job-end</code>, <code>backup-end</code>, and <code>log-end</code> phases and do t<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">he f</a>ollowing:</p>
<ul>
<li><p>For <code>backup-end</code>, copy the file <code>TARGET</code> to the S3 bucket and delete the original</p>
</li>
<li><p><a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">For</a> <code>log-end</code>, copy the file <code>LOGFILE</code> to the S3 bucket and delete the original</p>
</li>
<li><p>For <code>job-end</code>, check if there are any backups which should be expired and remove them. This is done only once, even if there are multiple VMs to backup <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">in a</a> single job.</p>
</li>
</ul>
<h1 id="heading-s3-tools">S3 Tools</h1>
<p>There are a few different open source options for general purpose file manag<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">emen</a>t using the S3 protocol. The most common are <code>s3cmd</code> and <code>s3fs-fuse</code>. The first p<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">rovi</a>des a command line utility to perform actions on an S3 bucket (ls, put, get<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">, de</a>lete, …) and the second implements a filesystem backed by an S3 bucket. Since the S3 protocol can only replace files (not modify parts of a file), <code>s3fs-fuse</code> can be qu<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">ite</a> slow d<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">epen</a>ding on how files are written/read. Given the use of hook scripts here, I’ve decided to use <code>s3cmd</code>. It’s easily installed by running <code>apt install s3cmd</code> on Proxmox.</p>
<p>Once <code>s3cmd</code> is installed, we need to configure it by running <code>s3cmd --configure</code>. It will ask you a few questions, and the answers will depend on your cloud storage provider. They should have a guide on configuring S3 access with their service (i.e. Linode’s is <a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">here</a>). I’ve walked through my own setup in the video.</p>
<p>Once we run configure, it will generate a file called <code>~/.s3cfg</code> which includes the access key and endpo<a target="_blank" href="https://www.linode.com/docs/products/storage/object-storage/guides/s3cmd/">int</a> URL. Since we ran this as root, it will be <code>/root/.s3cfg</code> on our Proxmox host. That’s fine, since backup jobs run as root.</p>
<p>If you’re interested in the details, feel free to read the <a target="_blank" href="https://s3tools.org/usage">s3cmd docs here.</a></p>
<p>Once you’ve verified that you have <code>s3cmd</code> installed and can <code>s3cmd ls</code> and <code>s3cmd put</code> to the target bucket, we can add the s3 put’s to our backup script<a target="_blank" href="https://gist.github.com/JProffitt71/9044744">.</a></p>
<h1 id="heading-backup-expiration-script">Backup Expiration Script</h1>
<p>I <a target="_blank" href="https://gist.github.com/JProffitt71/9044744">found a script</a> to handle expiration of files in S3. I’ve copied it here for reference. I named it <code>s3cleanup.sh</code> on my system.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Usage: ./s3cleanup.sh "bucketname" "7 days"</span>

s3cmd ls s3://<span class="hljs-variable">$1</span> | grep <span class="hljs-string">" DIR "</span> -v | <span class="hljs-keyword">while</span> <span class="hljs-built_in">read</span> -r line;
  <span class="hljs-keyword">do</span>
    createDate=`<span class="hljs-built_in">echo</span> <span class="hljs-variable">$line</span>|awk {<span class="hljs-string">'print $1" "$2'</span>}`
    createDate=$(date -d <span class="hljs-string">"<span class="hljs-variable">$createDate</span>"</span> <span class="hljs-string">"+%s"</span>)
    olderThan=$(date -d <span class="hljs-string">"<span class="hljs-variable">$2</span> ago"</span> <span class="hljs-string">"+%s"</span>)
    <span class="hljs-keyword">if</span> [[ <span class="hljs-variable">$createDate</span> -le <span class="hljs-variable">$olderThan</span> ]];
      <span class="hljs-keyword">then</span>
        fileName=`<span class="hljs-built_in">echo</span> <span class="hljs-variable">$line</span>|awk {<span class="hljs-string">'print $4'</span>}`
        <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$fileName</span> != <span class="hljs-string">""</span> ]
          <span class="hljs-keyword">then</span>
            <span class="hljs-built_in">printf</span> <span class="hljs-string">'Deleting "%s"\n'</span> <span class="hljs-variable">$fileName</span>
            s3cmd del <span class="hljs-string">"<span class="hljs-variable">$fileName</span>"</span>
        <span class="hljs-keyword">fi</span>
    <span class="hljs-keyword">fi</span>
  <span class="hljs-keyword">done</span>;
</code></pre>
<p>Don’t forget to <code>chmod +x</code> it once you are done.</p>
<h1 id="heading-final-backup-script">Final Backup Script</h1>
<p>Here is the final backup script which you can copy to your system. Again, don’t forget to <code>chmod +x</code> it.</p>
<pre><code class="lang-perl"><span class="hljs-comment">#!/usr/bin/perl -w</span>
<span class="hljs-comment"># Hook script for vzdump to backup to an S3 bucket</span>
<span class="hljs-comment"># 2022 Andrew Palardy</span>
<span class="hljs-comment"># Based on example hook script from Proxmox</span>

<span class="hljs-keyword">use</span> strict;

<span class="hljs-comment"># Define the name of your bucket here</span>
<span class="hljs-keyword">my</span> $bucket = <span class="hljs-string">"apalrd-proxmox"</span>;
<span class="hljs-comment"># The S3 endpoint comes from the s3cmd --configure setup, it is not set here</span>

<span class="hljs-comment"># Define the number of days to retain backups in the bucket</span>
<span class="hljs-comment"># Only accepts days, doesn't check hours/minutes</span>
<span class="hljs-keyword">my</span> $retain = <span class="hljs-number">30</span>;


<span class="hljs-comment">#Uncomment this to see the hook script with arguments (not required)</span>
<span class="hljs-comment">#print "HOOK: " . join (' ', @ARGV) . "\n";</span>

<span class="hljs-comment">#Get the phase from the first argument</span>
<span class="hljs-keyword">my</span> $phase = <span class="hljs-keyword">shift</span>;

<span class="hljs-comment">#For job-based phases</span>
<span class="hljs-comment">#Note that job-init was added in PVE 7.2 or 7.3 AFAIK</span>
<span class="hljs-keyword">if</span> (    $phase eq <span class="hljs-string">'job-init'</span>  ||
        $phase eq <span class="hljs-string">'job-start'</span> || 
        $phase eq <span class="hljs-string">'job-end'</span>   || 
        $phase eq <span class="hljs-string">'job-abort'</span>) { 

        <span class="hljs-comment">#Env variables available for job based arguments</span>
        <span class="hljs-keyword">my</span> $dumpdir = $ENV<span class="hljs-string">{DUMPDIR}</span>;

        <span class="hljs-keyword">my</span> $storeid = $ENV<span class="hljs-string">{STOREID}</span>;

        <span class="hljs-comment">#Uncomment this to print the environment variables for debugging</span>
        <span class="hljs-comment">#print "HOOK-ENV: dumpdir=$dumpdir;storeid=$storeid\n";</span>

        <span class="hljs-comment">#Call s3cleanup at job end</span>
        <span class="hljs-keyword">if</span> ($phase eq <span class="hljs-string">'job-end'</span>) {
                <span class="hljs-keyword">system</span> (<span class="hljs-string">"/root/s3cleanup.sh $bucket \"$retain days\""</span>);
        }
<span class="hljs-comment">#For backup-based phases</span>
} <span class="hljs-keyword">elsif</span> ($phase eq <span class="hljs-string">'backup-start'</span> || 
         $phase eq <span class="hljs-string">'backup-end'</span> ||
         $phase eq <span class="hljs-string">'backup-abort'</span> || 
         $phase eq <span class="hljs-string">'log-end'</span> || 
         $phase eq <span class="hljs-string">'pre-stop'</span> ||
         $phase eq <span class="hljs-string">'pre-restart'</span> ||
         $phase eq <span class="hljs-string">'post-restart'</span>) {

        <span class="hljs-comment">#Data available to backup-based phases</span>
        <span class="hljs-keyword">my</span> $mode = <span class="hljs-keyword">shift</span>; <span class="hljs-comment"># stop/suspend/snapshot</span>

        <span class="hljs-keyword">my</span> $vmid = <span class="hljs-keyword">shift</span>;

        <span class="hljs-keyword">my</span> $vmtype = $ENV<span class="hljs-string">{VMTYPE}</span>; <span class="hljs-comment"># lxc/qemu</span>

        <span class="hljs-keyword">my</span> $dumpdir = $ENV<span class="hljs-string">{DUMPDIR}</span>;

        <span class="hljs-keyword">my</span> $storeid = $ENV<span class="hljs-string">{STOREID}</span>;

        <span class="hljs-keyword">my</span> $hostname = $ENV<span class="hljs-string">{HOSTNAME}</span>;

        <span class="hljs-keyword">my</span> $tarfile = $ENV<span class="hljs-string">{TARGET}</span>;

        <span class="hljs-keyword">my</span> $logfile = $ENV<span class="hljs-string">{LOGFILE}</span>; 

        <span class="hljs-comment">#Uncomment this to print environment variables</span>
        <span class="hljs-comment">#print "HOOK-ENV: vmtype=$vmtype;dumpdir=$dumpdir;storeid=$storeid;hostname=$hostname;tarfile=$tarfile;logfile=$logfile\n";</span>

        <span class="hljs-comment"># During backup-end, copy the target file to S3 and delete the original on the system</span>
        <span class="hljs-keyword">if</span> ($phase eq <span class="hljs-string">'backup-end'</span>) {
                <span class="hljs-comment">#S3 put</span>
                <span class="hljs-keyword">my</span> $result = <span class="hljs-keyword">system</span> (<span class="hljs-string">"s3cmd put $tarfile s3://$bucket/"</span>);
                <span class="hljs-comment">#rm original</span>
                <span class="hljs-keyword">system</span> (<span class="hljs-string">"rm $tarfile"</span>);
                <span class="hljs-comment">#Die of error returned</span>
                <span class="hljs-keyword">if</span>($result != <span class="hljs-number">0</span>) {
                        <span class="hljs-keyword">die</span> <span class="hljs-string">"upload backup failed"</span>;
                }
        }

        <span class="hljs-comment"># During log-end, copy the log file to S3 and delete the original on the system (same as target file)</span>
        <span class="hljs-keyword">if</span> ($phase eq <span class="hljs-string">'log-end'</span>) {
                <span class="hljs-keyword">my</span> $result = <span class="hljs-keyword">system</span> (<span class="hljs-string">"s3cmd put $logfile s3://$bucket/"</span>);
                <span class="hljs-keyword">system</span> (<span class="hljs-string">"rm $logfile"</span>);
                <span class="hljs-keyword">if</span>($result != <span class="hljs-number">0</span>) {
                        <span class="hljs-keyword">die</span> <span class="hljs-string">"upload logfile failed"</span>;
                }
        }
<span class="hljs-comment">#Otherwise, phase is unknown</span>
} <span class="hljs-keyword">else</span> {

        <span class="hljs-keyword">die</span> <span class="hljs-string">"got unknown phase '$phase'"</span>;

}

<span class="hljs-keyword">exit</span> (<span class="hljs-number">0</span>);
</code></pre>
<p>src :</p>
<ul>
<li><a target="_blank" href="https://www.apalrd.net/posts/2022/pve_backup/">https://www.apalrd.net/posts/2022/pve_backup/</a></li>
</ul>
<ul>
<li><a target="_blank" href="https://github.com/andrizan/proxmox-ve-backup-cloud">https://github.com/andrizan/proxmox-ve-backup-cloud</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Calibrate Sequences PostgreSQL]]></title><description><![CDATA[Sequences
Sequences in PostgreSQL are special kinds of database objects designed to generate unique numeric identifiers. These identifiers are often used as primary keys in tables. A sequence is essentially a counter that can be incremented or decrem...]]></description><link>https://blog.andrizan.com/calibrate-sequences-postgresql</link><guid isPermaLink="true">https://blog.andrizan.com/calibrate-sequences-postgresql</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[Query]]></category><category><![CDATA[SQL]]></category><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Wed, 24 Jul 2024 07:59:05 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-sequences">Sequences</h1>
<p>Sequences in PostgreSQL are special kinds of database objects designed to generate unique numeric identifiers. These identifiers are often used as primary keys in tables. A sequence is essentially a counter that can be incremented or decremented, and it ensures that each value it generates is unique and not reused.</p>
<p>When you create a sequence, you can specify various parameters such as the starting value, increment step, minimum and maximum values, and whether the sequence should cycle when it reaches its limit. You can also control the caching behavior to improve performance.</p>
<p>To use a sequence, you can call the <code>nextval</code> function, which increments the sequence and returns the next value. The <code>currval</code> function returns the current value of the sequence, and the <code>setval</code> function allows you to set the sequence to a specific value.</p>
<p>Sequences are particularly useful in multi-user environments where multiple transactions might need to generate unique identifiers concurrently. By using sequences, PostgreSQL ensures that each transaction gets a unique identifier without conflicts or the need for complex locking mechanisms.</p>
<p>In summary, sequences in PostgreSQL provide a robust and efficient way to generate unique numeric identifiers, making them an essential tool for database design and management.</p>
<h2 id="heading-query-for-calibrate-sequences">Query for calibrate Sequences</h2>
<pre><code class="lang-sql"><span class="hljs-keyword">DO</span> $$
<span class="hljs-keyword">DECLARE</span>
i <span class="hljs-built_in">TEXT</span>;
<span class="hljs-keyword">BEGIN</span>
  <span class="hljs-keyword">FOR</span> i <span class="hljs-keyword">IN</span> (
    <span class="hljs-keyword">SELECT</span> <span class="hljs-string">'SELECT SETVAL('</span>
        || quote_literal(quote_ident(PGT.schemaname) || <span class="hljs-string">'.'</span> || quote_ident(S.relname))
        || <span class="hljs-string">', COALESCE(MAX('</span> ||quote_ident(C.attname)|| <span class="hljs-string">'), 1) ) FROM '</span>
        || quote_ident(PGT.schemaname)|| <span class="hljs-string">'.'</span>||quote_ident(T.relname)|| <span class="hljs-string">';'</span>
      <span class="hljs-keyword">FROM</span> pg_class <span class="hljs-keyword">AS</span> S,
           pg_depend <span class="hljs-keyword">AS</span> D,
           pg_class <span class="hljs-keyword">AS</span> T,
           pg_attribute <span class="hljs-keyword">AS</span> C,
           pg_tables <span class="hljs-keyword">AS</span> PGT
     <span class="hljs-keyword">WHERE</span> S.relkind = <span class="hljs-string">'S'</span>
       <span class="hljs-keyword">AND</span> S.oid = D.objid
       <span class="hljs-keyword">AND</span> D.refobjid = T.oid
       <span class="hljs-keyword">AND</span> D.refobjid = C.attrelid
       <span class="hljs-keyword">AND</span> D.refobjsubid = C.attnum
       <span class="hljs-keyword">AND</span> T.relname = PGT.tablename
  ) <span class="hljs-keyword">LOOP</span>
      <span class="hljs-keyword">EXECUTE</span> i;
  <span class="hljs-keyword">END</span> <span class="hljs-keyword">LOOP</span>;
<span class="hljs-keyword">END</span> $$;
</code></pre>
<h2 id="heading-check">Check</h2>
<pre><code class="lang-sql"><span class="hljs-keyword">Select</span> <span class="hljs-keyword">nextval</span>(pg_get_serial_sequence(<span class="hljs-string">'my_table'</span>, <span class="hljs-string">'id'</span>)) <span class="hljs-keyword">as</span> new_id;
</code></pre>
<p>src :</p>
<ul>
<li><p><a target="_blank" href="https://stackoverflow.com/questions/35734701/postgresql-change-all-sequences-with-for-loop">https://stackoverflow.com/questions/35734701/postgresql-change-all-sequences-with-for-loop</a></p>
</li>
<li><p><a target="_blank" href="https://stackoverflow.com/questions/18232714/postgresql-next-serial-value-in-a-table">https://stackoverflow.com/questions/18232714/postgresql-next-serial-value-in-a-table</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[ColorSheme Flutter]]></title><description><![CDATA[these 10 colors are mandatory for creating a ColorSheme for Flutter ThemData.Values for each color are optional.
primary : This is the most used color in the application
onPrimary : This color is used to color the elements on top of the primary color...]]></description><link>https://blog.andrizan.com/colorsheme-flutter</link><guid isPermaLink="true">https://blog.andrizan.com/colorsheme-flutter</guid><category><![CDATA[Flutter]]></category><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Mon, 22 Apr 2024 07:56:31 GMT</pubDate><content:encoded><![CDATA[<p>these 10 colors are mandatory for creating a ColorSheme for Flutter ThemData.Values for each color are optional.</p>
<p><code>primary</code> : This is the most used color in the application</p>
<p><code>onPrimary</code> : This color is used to color the elements on top of the primary color such as text, icons, etc.</p>
<p><code>secondary</code> : This defines a secondary color, often used for less prominent elements like filter chips, toggle buttons, or background elements that need to stand out from the primary color but not overpower it.</p>
<p><code>onSecondary</code> : This color is used to color the elements on top of the secondary color.</p>
<p><code>error</code> : This is the color used for error messages or alerts, like a flashing red light to indicate a problem.</p>
<p><code>onError</code> : This is the text color that goes well on the <code>error</code> color, like white text on a red sign for easy reading.</p>
<p><code>background</code> : The primary background color for your entire application. Think of this as the canvas upon which all other UI elements are placed.</p>
<p><code>onBackground</code> : This color is used to color the elements on top of the background color.</p>
<p><code>surface</code> : Used as the base color for elevated UI elements like cards, sheets, dialogs, etc.</p>
<p><code>onSurface</code> : use to color the elements on top of the surface color.</p>
<p>src : <a target="_blank" href="https://medium.com/@nikhithsunil/theme-your-flutter-app-a-guide-to-themedata-and-colorscheme-d8bca920a6b5">https://medium.com/@nikhithsunil/theme-your-flutter-app-a-guide-to-themedata-and-colorscheme-d8bca920a6b5</a></p>
]]></content:encoded></item><item><title><![CDATA[Flutter NOTE]]></title><description><![CDATA[Provider
https://medium.com/@madampitige90/provider-state-management-in-flutter-3bc555a1eafb
https://www.dhiwise.com/post/achieving-optimal-performance-with-flutter-provider-state-management
https://nureddineraslan.medium.com/understanding-state-mana...]]></description><link>https://blog.andrizan.com/flutter-note</link><guid isPermaLink="true">https://blog.andrizan.com/flutter-note</guid><category><![CDATA[Flutter]]></category><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Tue, 27 Feb 2024 09:30:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-provider">Provider</h2>
<p><a target="_blank" href="https://medium.com/@madampitige90/provider-state-management-in-flutter-3bc555a1eafb">https://medium.com/@madampitige90/provider-state-management-in-flutter-3bc555a1eafb</a></p>
<p><a target="_blank" href="https://www.dhiwise.com/post/achieving-optimal-performance-with-flutter-provider-state-management">https://www.dhiwise.com/post/achieving-optimal-performance-with-flutter-provider-state-management</a></p>
<p><a target="_blank" href="https://nureddineraslan.medium.com/understanding-state-management-with-provider-in-flut-e74e0b9e49d9">https://nureddineraslan.medium.com/understanding-state-management-with-provider-in-flut-e74e0b9e49d9</a></p>
<p><a target="_blank" href="https://medium.com/bancolombia-tech/flutter-provider-what-is-it-what-is-it-for-and-how-to-use-it-47d6941860d7">https://medium.com/bancolombia-tech/flutter-provider-what-is-it-what-is-it-for-and-how-to-use-it-47d6941860d7</a></p>
<p><a target="_blank" href="https://medium.com/skyshidigital/state-management-dengan-provider-ddcaeef2ce5d">https://medium.com/skyshidigital/state-management-dengan-provider-ddcaeef2ce5d</a></p>
<h2 id="heading-button">Button</h2>
<p><a target="_blank" href="https://stackoverflow.com/questions/49991444/create-a-rounded-button-button-with-border-radius-in-flutter">https://stackoverflow.com/questions/49991444/create-a-rounded-button-button-with-border-radius-in-flutter</a></p>
<h2 id="heading-localization">localization</h2>
<p><a target="_blank" href="https://phrase.com/blog/posts/flutter-localization/">https://phrase.com/blog/posts/flutter-localization/</a></p>
<h2 id="heading-modal-bottom-sheet">Modal Bottom Sheet</h2>
<pre><code class="lang-dart">showModalBottomSheet(
  context: context,
  isScrollControlled: <span class="hljs-keyword">true</span>,
  builder: (BuildContext context) {
    <span class="hljs-keyword">return</span> Wrap(
      children: [
        Container(
          padding: EdgeInsets.only(
              bottom: MediaQuery.of(context).viewInsets.bottom),
          decoration: BoxDecoration(
            borderRadius: <span class="hljs-keyword">const</span> BorderRadius.only(
              topLeft: Radius.circular(<span class="hljs-number">10</span>),
              topRight: Radius.circular(<span class="hljs-number">10</span>),
            ),
            color: Theme.of(context).colorScheme.background,
          ),
          child: Container(
            margin: <span class="hljs-keyword">const</span> EdgeInsets.symmetric(
                horizontal: <span class="hljs-number">15</span>, vertical: <span class="hljs-number">10</span>),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: &lt;Widget&gt;[
                Center(
                  child: Container(
                    height: <span class="hljs-number">5</span>,
                    width: <span class="hljs-number">36</span>,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(<span class="hljs-number">8</span>),
                      color: Theme.of(context)
                          .colorScheme
                          .secondary
                          .withOpacity(<span class="hljs-number">0.4</span>),
                    ),
                  ),
                ),
                Column(
                  children: [
                    Container(
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(<span class="hljs-number">8.0</span>),
                        border: Border.all(
                          width: <span class="hljs-number">1</span>,
                          color: Theme.of(context)
                              .colorScheme
                              .secondaryContainer,
                        ),
                      ),
                      padding: <span class="hljs-keyword">const</span> EdgeInsets.all(<span class="hljs-number">15</span>),
                      margin: <span class="hljs-keyword">const</span> EdgeInsets.symmetric(
                        vertical: <span class="hljs-number">10</span>,
                      ),
                      child: Column(
                        children: [
                          Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              <span class="hljs-string">"TITLE"</span>,
                              style: TextStyle(
                                color: Theme.of(context)
                                    .colorScheme
                                    .onSecondary,
                                fontWeight: FontWeight.w700,
                                fontSize: <span class="hljs-number">14</span>,
                                fontFamily: FontFamily.mukta,
                              ),
                            ),
                          ),
                          Container(
                            margin: <span class="hljs-keyword">const</span> EdgeInsets.symmetric(
                                vertical: <span class="hljs-number">5</span>),
                            alignment: Alignment.centerLeft,
                            child: Text(
                              <span class="hljs-string">'DESC'</span>,
                              style: TextStyle(
                                color: Theme.of(context)
                                    .colorScheme
                                    .secondary,
                                fontWeight: FontWeight.w400,
                                fontSize: <span class="hljs-number">12</span>,
                                fontFamily: FontFamily.mukta,
                              ),
                            ),
                          ),
                          Container(
                            margin: <span class="hljs-keyword">const</span> EdgeInsets.symmetric(
                                vertical: <span class="hljs-number">5</span>),
                            alignment: Alignment.centerLeft,
                            child: Text(
                              <span class="hljs-string">'PRICE'</span>,
                              style: TextStyle(
                                color: Theme.of(context)
                                    .colorScheme
                                    .primary,
                                fontWeight: FontWeight.w700,
                                fontSize: <span class="hljs-number">14</span>,
                                fontFamily: FontFamily.mukta,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ],
    );
  },
);
</code></pre>
]]></content:encoded></item><item><title><![CDATA[netplan Error Ubuntu 22.04]]></title><description><![CDATA[(process:62555): WARNING : 14:00:14.501: Permissions for /etc/netplan/50-cloud-init.yaml are too open. Netplan configuration should NOT be accessible by others.
Fixes
sudo chmod 600 /etc/netplan/your_config_file.yaml
# run this then
$ sudo apt-get in...]]></description><link>https://blog.andrizan.com/netplan-error-ubuntu-2204</link><guid isPermaLink="true">https://blog.andrizan.com/netplan-error-ubuntu-2204</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Tue, 09 Jan 2024 07:03:18 GMT</pubDate><content:encoded><![CDATA[<p><code>(process:62555): WARNING : 14:00:14.501: Permissions for /etc/netplan/50-cloud-init.yaml are too open. Netplan configuration should NOT be accessible by others.</code></p>
<h1 id="heading-fixes">Fixes</h1>
<p><code>sudo chmod 600 /etc/netplan/your_config_file.yaml</code></p>
<pre><code class="lang-bash"><span class="hljs-comment"># run this then</span>
$ sudo apt-get install openvswitch-switch-dpdk
</code></pre>
<p>you may need to check installation by run these command again</p>
<p>after the installation complete, no annoying WARNING shows again:</p>
<pre><code class="lang-bash">$ sudo netplan try
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Store Credential Git]]></title><description><![CDATA[Attention: This method saves the credentials in plaintext on your PC's disk. Everyone on your computer can access it, e.g. malicious NPM modules.
Run
git config --global credential.helper store

then
git pull

provide a username and password and thos...]]></description><link>https://blog.andrizan.com/store-credential-git</link><guid isPermaLink="true">https://blog.andrizan.com/store-credential-git</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Tue, 12 Dec 2023 04:26:08 GMT</pubDate><content:encoded><![CDATA[<p><strong>Attention</strong>: This method saves the credentials in <strong>plaintext</strong> on your PC's disk. Everyone on your computer can access it, e.g. malicious NPM modules.</p>
<p>Run</p>
<pre><code class="lang-plaintext">git config --global credential.helper store
</code></pre>
<p>then</p>
<pre><code class="lang-plaintext">git pull
</code></pre>
<p>provide a username and password and those details will then be remembered later. The credentials are stored in a file on the disk, with the disk permissions of "just user readable/writable" but still in plaintext.</p>
<p>If you want to change the password later</p>
<pre><code class="lang-plaintext">git pull
</code></pre>
<p>Will fail, because the password is incorrect, git then removes the offending user+password from the <code>~/.git-credentials</code> file, so now re-run</p>
<pre><code class="lang-plaintext">git pull
</code></pre>
<p>to provide a new password so it works as earlier.</p>
<p>Origin = <a target="_blank" href="https://stackoverflow.com/a/35942890">https://stackoverflow.com/a/35942890</a></p>
]]></content:encoded></item><item><title><![CDATA[SCP Linux]]></title><description><![CDATA[Syntax:
scp <source> <destination>

To copy a file from B to A while logged into B:
scp /path/to/file username@a:/path/to/destination

To copy a file from B to A while logged into A:
scp username@b:/path/to/file /path/to/destination

To copy a file f...]]></description><link>https://blog.andrizan.com/scp-linux</link><guid isPermaLink="true">https://blog.andrizan.com/scp-linux</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Mon, 02 Oct 2023 08:05:25 GMT</pubDate><content:encoded><![CDATA[<p>Syntax:</p>
<pre><code class="lang-bash">scp &lt;<span class="hljs-built_in">source</span>&gt; &lt;destination&gt;
</code></pre>
<p>To copy a file from <code>B</code> to <code>A</code> while logged into <code>B</code>:</p>
<pre><code class="lang-bash">scp /path/to/file username@a:/path/to/destination
</code></pre>
<p>To copy a file from <code>B</code> to <code>A</code> while logged into <code>A</code>:</p>
<pre><code class="lang-bash">scp username@b:/path/to/file /path/to/destination
</code></pre>
<p>To copy a file from <code>B</code> to <code>A</code> while logged into <code>B</code>. NON STANDARD PORT:</p>
<pre><code class="lang-bash">scp -P 2200 /path/to/file username@a:/path/to/destination
</code></pre>
<p>download file:</p>
<pre><code class="lang-bash">scp riski@192.168.10.8:~/minio .
</code></pre>
<p><a target="_blank" href="https://unix.stackexchange.com/questions/106480/how-to-copy-files-from-one-machine-to-another-using-ssh">https://unix.stackexchange.com/questions/106480/how-to-copy-files-from-one-machine-to-another-using-ssh</a></p>
]]></content:encoded></item><item><title><![CDATA[Create tar.gz]]></title><description><![CDATA[How to create tar.gz file in Linux using command line
The procedure to create a tar.gz file on Linux is as follows:

Open the terminal application in Linux

Run tar command to create an archived named file.tar.gz for given directory name by running: ...]]></description><link>https://blog.andrizan.com/create-targz</link><guid isPermaLink="true">https://blog.andrizan.com/create-targz</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Mon, 02 Oct 2023 07:57:21 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-how-to-create-targz-file-in-linux-using-command-line">How to create tar.gz file in Linux using command line</h2>
<p>The procedure to create a tar.gz file on Linux is as follows:</p>
<ol>
<li><p>Open the terminal application in Linux</p>
</li>
<li><p>Run tar command to create an archived named file.tar.gz for given directory name by running: <kbd>tar -czvf file.tar.gz directory</kbd></p>
</li>
<li><p>Verify tar.gz file using the ls command and tar command</p>
</li>
</ol>
<p>Let us see all commands and options in details.</p>
<h2 id="heading-linux-create-targz-file-with-tar-command">Linux create tar.gz file with tar command</h2>
<p>Say you want to create tar.gz file named projects.tar.gz for directory called $HOME/projects/:</p>
<p><code>ls -l $HOME/projects/</code><br />Sample outputs from the ls command:</p>
<pre><code class="lang-bash">total 8
drwxr-xr-x 2 vivek vivek 4096 Oct 30 22:30 helloworld
drwxr-xr-x 4 vivek vivek 4096 Oct 30 13:16 myhellowebapp
</code></pre>
<p>The syntax for the tar command is as follows:  </p>
<p><code>tar -czvf filename.tar.gz /path/to/dir1   tar -czvf filename.tar.gz /path/to/dir1 dir2 file1 file2   # Create a tar.gz file from all pdf (".pdf") files   tar -czvf archive.tgz *.pdf</code></p>
<p><code>tar -czvf projects.tar.gz $HOME/projects/</code></p>
<p><img src="https://www.cyberciti.biz/media/new/faq/2013/06/How-to-create-tar.gz-file-in-Linux-using-command-line.png" alt=".cyberciti.biz/media/new/faq/2013/06/How-to-create-tar.gz-file-in-Linux-using-command-line.png" /></p>
<h3 id="heading-verification">Verification</h3>
<p>Next verify newly created tar.gz file in Linux using the ls command:  </p>
<p><code>ls -l projects.tar.gz</code><br />Example outputs:</p>
<pre><code class="lang-bash">-rw-r--r-- 1 vivek vivek 59262 Nov  3 11:08 projects.tar.gz
</code></pre>
<p>One can <a target="_blank" href="https://www.cyberciti.biz/faq/list-the-contents-of-a-tar-or-targz-file/">list the contents of a tar or tar.gz file</a> using the tar command:</p>
<p><code>tar -ztvf projects.tar.gz</code></p>
<p><img src="https://www.cyberciti.biz/media/new/faq/2013/06/Linuxlist-tar.gz-file-contents-300x145.png" alt="Linux list tar.gz file contents" /></p>
<h3 id="heading-how-to-extract-a-targz-compressed-archive-on-linux">How to extract a tar.gz compressed archive on Linux</h3>
<p>The syntax is follows to extract tar.gz file on Linux operating system:  </p>
<p><code>tar -xvf file.tar.gz   tar -xzvf file.tar.gz   tar -xzvf projects.tar.gz</code></p>
<p>The syntax is follows to extract tar.gz file on Linux operating system:</p>
<p><code>tar -xzvf projects.tar.gz -C /tmp/</code><br />Sample outputs:</p>
<pre><code class="lang-bash">home/vivek/projects/myhellowebapp/
home/vivek/projects/myhellowebapp/hellowebapp.working/
home/vivek/projects/myhellowebapp/hellowebapp.working/db.sqlite3
home/vivek/projects/myhellowebapp/hellowebapp.working/manage.py
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/models.py
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/admin.py
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/__init__.py
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/tests.py
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/static/
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/static/css/
home/vivek/projects/myhellowebapp/hellowebapp.working/collection/static/css/style.css
...
..
...
home/vivek/projects/myhellowebapp/hellowebapp/hellowebapp/__pycache__/urls.cpython-36.pyc
home/vivek/projects/myhellowebapp/hellowebapp/hellowebapp/wsgi.py
home/vivek/projects/myhellowebapp/hellowebapp/hellowebapp/settings.py
home/vivek/projects/helloworld/
</code></pre>
<h3 id="heading-understanding-tar-command-options">Understanding tar command options</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>tar command option</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td><kbd>-c</kbd></td><td>Create a new archive</td></tr>
<tr>
<td><kbd>-x</kbd></td><td>Extract files from an archive</td></tr>
<tr>
<td><kbd>-t</kbd></td><td>List the contents of an archive</td></tr>
<tr>
<td><kbd>-v</kbd></td><td>Verbose output</td></tr>
<tr>
<td><kbd>-f file.tar.gz</kbd></td><td>Use archive file</td></tr>
<tr>
<td><kbd>-C DIR</kbd></td><td>Change to DIR before performing any operations</td></tr>
<tr>
<td><kbd>-z</kbd></td><td>Filter the archive through gzip i.e. compress or decompress archive</td></tr>
</tbody>
</table>
</div><p><a target="_blank" href="https://www.cyberciti.biz/faq/how-to-create-tar-gz-file-in-linux-using-command-line/">https://www.cyberciti.biz/faq/how-to-create-tar-gz-file-in-linux-using-command-line/</a></p>
]]></content:encoded></item><item><title><![CDATA[Setting up Public Key Auth SSH & Allow root]]></title><description><![CDATA[configuration file
nano /etc/ssh/sshd_config

change
#AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2

#TO

AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2

allow root remote
#PermitRootLogin prohibit-password
# ...]]></description><link>https://blog.andrizan.com/setting-up-public-key-auth-ssh-allow-root</link><guid isPermaLink="true">https://blog.andrizan.com/setting-up-public-key-auth-ssh-allow-root</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Wed, 20 Sep 2023 07:49:22 GMT</pubDate><content:encoded><![CDATA[<p>configuration file</p>
<pre><code class="lang-bash">nano /etc/ssh/sshd_config
</code></pre>
<p>change</p>
<pre><code class="lang-bash"><span class="hljs-comment">#AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2</span>

<span class="hljs-comment">#TO</span>

AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2
</code></pre>
<p>allow root remote</p>
<pre><code class="lang-bash"><span class="hljs-comment">#PermitRootLogin prohibit-password</span>
<span class="hljs-comment"># TO</span>
PermitRootLogin yes
</code></pre>
<p>restart <code>ssh</code></p>
<pre><code class="lang-bash">systemctl restart ssh
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Install Bind9 Server Recursion  & RPZ Ubuntu 20.04]]></title><description><![CDATA[Install BIND9
The first thing you need to do is to update the package list and to install BIND9.
sudo apt update 
sudo apt install bind9

BIND9 configuration
cd /etc/bind/

The main configuration file is named.conf.options
sudo nano named.conf.option...]]></description><link>https://blog.andrizan.com/install-bind9-server-recursion-rpz-ubuntu-2004</link><guid isPermaLink="true">https://blog.andrizan.com/install-bind9-server-recursion-rpz-ubuntu-2004</guid><category><![CDATA[Bind]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[bind9]]></category><category><![CDATA[rpz]]></category><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Wed, 06 Sep 2023 09:47:35 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-install-bind9">Install BIND9</h2>
<p>The first thing you need to do is to update the package list and to install BIND9.</p>
<pre><code class="lang-bash">sudo apt update 
sudo apt install bind9
</code></pre>
<h2 id="heading-bind9-configuration">BIND9 configuration</h2>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /etc/<span class="hljs-built_in">bind</span>/
</code></pre>
<p>The main configuration file is <code>named.conf.options</code></p>
<pre><code class="lang-bash">sudo nano named.conf.options
</code></pre>
<pre><code class="lang-bash">acl LAN {
        192.168.1.0/24;
};

options {
        dnssec-validation auto;

        listen-on-v6 { any; };

        directory <span class="hljs-string">"/var/cache/bind"</span>; // default directory
        max-cache-size 10m;
        allow-query { localhost; LAN;}; // allow queries from localhost and 192.168.1.0-192.168.1.255

        forwarders {
                1.1.1.1;
                1.0.0.1;
        }; // use CloudFlare 1.1.1.1 DNS as a forwarder

        recursion yes;  // allow recursive queries
        auth-nxdomain no;    <span class="hljs-comment"># conform to RFC1035</span>
        allow-recursion {
                LAN;
        };
};
</code></pre>
<h2 id="heading-create-rpz-response-policy-zoneshttpswwwiscorgrpz">Create RPZ (<a target="_blank" href="https://www.isc.org/rpz/">Response Policy Zones</a>)</h2>
<p>create rpz database.</p>
<pre><code class="lang-bash">cp db.local db.blocked
sudo nano db.blocked
</code></pre>
<pre><code class="lang-bash">;
; BIND data file <span class="hljs-keyword">for</span> <span class="hljs-built_in">local</span> loopback interface
;
<span class="hljs-variable">$TTL</span>    604800
@       IN      SOA     blocked.local. root.blocked.local. (
                         2309111627     ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      blocked.local.
@       IN      A       192.168.1.222
xxx.xxx IN    CNAME     @ <span class="hljs-comment"># blocked domain</span>
</code></pre>
<p>register database to zone</p>
<pre><code class="lang-bash">sudo nano named.conf.local
</code></pre>
<pre><code class="lang-bash">zone <span class="hljs-string">"blocked"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.blocked"</span>;
    allow-query {any;};
    allow-update {none;};
};

; === https://github.com/andrizan/partial-output ===
zone <span class="hljs-string">"trust-aa"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.trust-aa"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"trust-ab"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.trust-ab"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"adultaa"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.adultaa"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"adultab"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.adultab"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"adultac"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.adultac"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"adultad"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.adultad"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"adultae"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.adultae"</span>;
    allow-query {any;};
    allow-update {none;};
};
zone <span class="hljs-string">"adultaf"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.adultaf"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"adultag"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.adultag"</span>;
    allow-query {any;};
    allow-update {none;};
};

zone <span class="hljs-string">"malware"</span> {
    <span class="hljs-built_in">type</span> master;
    file <span class="hljs-string">"/etc/bind/db.malware"</span>;
    allow-query {any;};
    allow-update {none;};
};
</code></pre>
<p>Register the zone to the response policy.</p>
<pre><code class="lang-bash">sudo nano named.conf.options
</code></pre>
<pre><code class="lang-bash">acl LAN {
        192.168.1.0/24;
};

<span class="hljs-comment"># accept all connection</span>
<span class="hljs-comment"># acl all {</span>
<span class="hljs-comment">#        0.0.0.0/0;</span>
<span class="hljs-comment"># };</span>

options {
        dnssec-validation auto;

        listen-on-v6 { any; };

        directory <span class="hljs-string">"/var/cache/bind"</span>; // default directory
        max-cache-size 10m;
        cleaning-interval 480; // clean cache every 8 hours
        allow-query { localhost; LAN;}; // allow queries from localhost and 192.168.1.0-192.168.1.255
        response-policy {
                zone <span class="hljs-string">"blocked"</span>;
                zone <span class="hljs-string">"trust-aa"</span>;
                zone <span class="hljs-string">"trust-ab"</span>;
                zone <span class="hljs-string">"adultaa"</span>;
                zone <span class="hljs-string">"adultab"</span>;
                zone <span class="hljs-string">"adultac"</span>;
                zone <span class="hljs-string">"adultad"</span>;
                zone <span class="hljs-string">"adultae"</span>;
                zone <span class="hljs-string">"adultaf"</span>;
                zone <span class="hljs-string">"adultag"</span>;
<span class="hljs-comment">#               zone "malware";</span>
        } recursive-only no max-policy-ttl 60 break-dnssec no qname-wait-recurse no;

<span class="hljs-comment"># disable 'check-names'</span>
<span class="hljs-comment">#check-names master ignore;</span>
<span class="hljs-comment">#check-names slave ignore;</span>
<span class="hljs-comment">#check-names response ignore;</span>

        forwarders {
                1.1.1.1;
                1.0.0.1;
        }; // use CloudFlare 1.1.1.1 DNS as a forwarder

        recursion yes;  // allow recursive queries
        auth-nxdomain no;    <span class="hljs-comment"># conform to RFC1035</span>
        allow-recursion {
                LAN;
        };
};
</code></pre>
<h1 id="heading-docker">Docker</h1>
<p><a target="_blank" href="https://www.youtube.com/watch?v=syzwLwE3Xq4">https://www.youtube.com/watch?v=syzwLwE3Xq4</a></p>
<h1 id="heading-ref">Ref</h1>
<ul>
<li><p><a target="_blank" href="https://serverspace.io/support/help/configure-bind9-dns-server-on-ubuntu/">https://serverspace.io/support/help/configure-bind9-dns-server-on-ubuntu/</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/andrizan/partial-output">https://github.com/andrizan/partial-output</a></p>
</li>
<li><p><a target="_blank" href="https://www.isc.org/bind/">https://www.isc.org/bind/</a></p>
</li>
<li><p><a target="_blank" href="https://www.isc.org/rpz/">https://www.isc.org/rpz/</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[rsync Ubuntu]]></title><description><![CDATA[Using Rsync to Sync Local System
his puts folder A into folder B:
rsync -avu --delete "/home/user/A" "/home/user/B"

If you want the contents of folders A and B to be the same, put /home/user/A/ (with the slash) as the source. This takes not the fold...]]></description><link>https://blog.andrizan.com/rsync-ubuntu</link><guid isPermaLink="true">https://blog.andrizan.com/rsync-ubuntu</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Fri, 01 Sep 2023 06:16:36 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-using-rsync-to-sync-local-system">Using Rsync to Sync Local System</h2>
<p>his puts folder A into folder B:</p>
<pre><code class="lang-bash">rsync -avu --delete <span class="hljs-string">"/home/user/A"</span> <span class="hljs-string">"/home/user/B"</span>
</code></pre>
<p>If you want the <strong>contents of folders A and B</strong> to be the same, put <code>/home/user/A/</code> (with the slash) as the source. This takes not the folder A but all of its content and puts it into folder B. Like this:</p>
<pre><code class="lang-bash">rsync -avu --delete <span class="hljs-string">"/home/user/A/"</span> <span class="hljs-string">"/home/user/B"</span>
</code></pre>
<ul>
<li><p><code>-a</code> Do the sync preserving all filesystem attributes</p>
</li>
<li><p><code>-v</code> run verbosely</p>
</li>
<li><p><code>-u</code> only copy files with a newer modification time (or size difference if the times are equal)</p>
</li>
<li><p><code>--delete</code> delete the files in target folder that do not exist in the source</p>
</li>
</ul>
<p>Manpage: <a target="_blank" href="https://download.samba.org/pub/rsync/rsync.html">https://download.samba.org/pub/rsync/rsync.html</a></p>
<p>src = <a target="_blank" href="https://unix.stackexchange.com/questions/203846/how-to-sync-two-folders-with-command-line-tools">https://unix.stackexchange.com/questions/203846/how-to-sync-two-folders-with-command-line-tools</a></p>
<hr />
<h2 id="heading-using-rsync-to-sync-with-a-remote-system">Using Rsync to Sync with a Remote System</h2>
<p>To use <code>rsync</code> to sync with a remote system, you only need SSH access configured between your local and remote machines, as well as <code>rsync</code> installed on both systems. Once you have SSH access verified between the two machines, you can sync the <code>dir1</code> folder from the previous section to a remote machine by using the following syntax. Please note in this case, that you want to transfer the actual directory, so you’ll omit the trailing slash:</p>
<pre><code class="lang-bash">rsync -a ~/dir1 username@remote_host:destination_directory
<span class="hljs-comment">#OR</span>
rsync -a -e <span class="hljs-string">'ssh -p 2320'</span> ~/dir1 username@remote_host:destination_directory
</code></pre>
<p>This process is called a <em>push</em> operation because it “pushes” a directory from the local system to a remote system. The opposite operation is <em>pull</em>, and is used to sync a remote directory to the local system. If the <code>dir1</code> directory were on the remote system instead of your local system, the syntax would be the following:</p>
<pre><code class="lang-bash">rsync -a username@remote_host:/home/username/dir1 place_to_sync_on_local_machine
</code></pre>
<p>Like <code>cp</code> and similar tools, the source is always the first argument, and the destination is always the second.</p>
<p>src :</p>
<ul>
<li><p><a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories#using-rsync-to-sync-with-a-remote-system">https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories#using-rsync-to-sync-with-a-remote-system</a></p>
</li>
<li><p><a target="_blank" href="https://stackoverflow.com/questions/4549945/is-it-possible-to-specify-a-different-ssh-port-when-using-rsync">https://stackoverflow.com/questions/4549945/is-it-possible-to-specify-a-different-ssh-port-when-using-rsync</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Set Timezone Ubuntu]]></title><description><![CDATA[Changing the Timezone Using the timedatectl Command
Before changing the timezone, you’ll need to find out the long name for the timezone you want to use. The timezones are using “Region/City” format.
To list all available time zones, you can either l...]]></description><link>https://blog.andrizan.com/set-timezone-ubuntu</link><guid isPermaLink="true">https://blog.andrizan.com/set-timezone-ubuntu</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Fri, 01 Sep 2023 06:12:19 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-changing-the-timezone-using-the-timedatectl-command">Changing the Timezone Using the <code>timedatectl</code> Command</h2>
<p>Before changing the timezone, you’ll need to find out the long name for the timezone you want to use. The timezones are using “Region/City” format.</p>
<p>To list all available time zones, you can either list the files in the <code>/usr/share/zoneinfo</code> directory or invoke the <code>timedatectl</code> command with the <code>list-timezones</code> option:</p>
<pre><code class="lang-bash">timedatectl list-timezones
</code></pre>
<pre><code class="lang-bash">...
America/Montevideo
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
...
</code></pre>
<p>Once you identify which time zone is accurate to your location, run the following command as sudo user:</p>
<pre><code class="lang-bash">sudo timedatectl set-timezone your_time_zone
</code></pre>
<p>For instance, to change the system’s timezone to <code>Asia/Jakarta</code>:</p>
<pre><code class="lang-bash">sudo timedatectl set-timezone Asia/Jakarta
</code></pre>
<p>Invoke the <code>timedatectl</code> command to verify the changes:</p>
<pre><code class="lang-bash">timedatectl
</code></pre>
<pre><code class="lang-bash">               Local time: Wed 2020-05-06 15:41:42 EDT  
           Universal time: Wed 2020-05-06 19:41:42 UTC  
                 RTC time: Wed 2020-05-06 19:41:48      
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes                         
              NTP service: active                      
          RTC <span class="hljs-keyword">in</span> <span class="hljs-built_in">local</span> TZ: no
</code></pre>
<p>srv : Changing the Timezone Using the <code>timedatectl</code> Command</p>
<p>Before changing the timezone, you’ll need to find out the long name for the timezone you want to use. The timezones are using “Region/City” format.</p>
<p>To list all available time zones, you can either list the files in the <code>/usr/share/zoneinfo</code> directory or invoke the <code>timedatectl</code> command with the <code>list-timezones</code> option:</p>
<pre><code class="lang-bash">timedatectl list-timezones
</code></pre>
<pre><code class="lang-bash">...
America/Montevideo
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
...
</code></pre>
<p>Once you identify which time zone is accurate to your location, run the following command as sudo user:</p>
<pre><code class="lang-bash">sudo timedatectl set-timezone your_time_zone
</code></pre>
<p>For instance, to change the system’s timezone to <code>America/New_York</code>:</p>
<pre><code class="lang-bash">sudo timedatectl set-timezone America/New_York
</code></pre>
<p>Invoke the <code>timedatectl</code> command to verify the changes:</p>
<pre><code class="lang-plaintext">timedatectl
</code></pre>
<pre><code class="lang-plaintext">               Local time: Wed 2020-05-06 15:41:42 EDT  
           Universal time: Wed 2020-05-06 19:41:42 UTC  
                 RTC time: Wed 2020-05-06 19:41:48      
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes                         
              NTP service: active                      
          RTC in local TZ: no
</code></pre>
<p>src = <a target="_blank" href="https://linuxize.com/post/how-to-set-or-change-timezone-on-ubuntu-20-04/#changing-the-timezone-using-the-timedatectl-command">https://linuxize.com/post/how-to-set-or-change-timezone-on-ubuntu-20-04/#changing-the-timezone-using-the-timedatectl-command</a></p>
]]></content:encoded></item><item><title><![CDATA[How To Expand Ubuntu 20.04 LTS Filesystem Volume on Hyper-V]]></title><description><![CDATA[I tried existing solutions on 18.04 and found it doesn't work with a 'nothing to do' output. Some further searching had similar-but-slightly-different steps and needing to merge a few different bits-and-pieces from other solutions on the web to make ...]]></description><link>https://blog.andrizan.com/how-to-expand-ubuntu-2004-lts-filesystem-volume-on-hyper-v</link><guid isPermaLink="true">https://blog.andrizan.com/how-to-expand-ubuntu-2004-lts-filesystem-volume-on-hyper-v</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Mon, 28 Aug 2023 11:26:43 GMT</pubDate><content:encoded><![CDATA[<p>I tried existing solutions on 18.04 and found it doesn't work with a 'nothing to do' output. Some further searching had similar-but-slightly-different steps and needing to merge a few different bits-and-pieces from other solutions on the web to make work.</p>
<p>Setup: Hyper-V; VHDX file as hard disk; Ubuntu-18.04</p>
<p>Steps:</p>
<ol>
<li><p>Expand the VDHX file via Hyper-V as mentioned in existing solutions and then inside the VM:</p>
</li>
<li><p><code>fdisk -l</code></p>
<p> See which partition is the current Ubuntu setup - should be obvious based on size (in my case was sda3)</p>
</li>
<li><p><code>growpart /dev/sda 3</code></p>
<p> Note the space as mentioned.</p>
</li>
<li><p><code>pvresize /dev/sda3</code></p>
<p> This is the step which isn't mentioned in a lot of places; its the intemediate step that allows the logical volume extension step work.</p>
</li>
<li><p><code>lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv</code></p>
<p> The <code>/dev/</code> part can seen in the fdisk output from step 1.</p>
</li>
<li><p><code>resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv</code></p>
<p> After the prep above, this step now works. Takes a couple of moments and afterwards can verify with <code>df -h</code> that the partition is expanded.</p>
</li>
</ol>
<p>src = <a target="_blank" href="https://superuser.com/questions/1716141/how-to-expand-ubuntu-20-04-lts-filesystem-volume-on-hyper-v">https://superuser.com/questions/1716141/how-to-expand-ubuntu-20-04-lts-filesystem-volume-on-hyper-v</a></p>
]]></content:encoded></item><item><title><![CDATA[Install Redis 7 Ubuntu]]></title><description><![CDATA[Install on Ubuntu/Debian
You can install recent stable versions of Redis from the official packages.redis.io APT repository.
Prerequisites
If you're running a very minimal distribution (such as a Docker container) you may need to install lsb-release,...]]></description><link>https://blog.andrizan.com/install-redis-7-ubuntu</link><guid isPermaLink="true">https://blog.andrizan.com/install-redis-7-ubuntu</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Thu, 24 Aug 2023 05:12:46 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-install-on-ubuntudebian">Install on Ubuntu/Debian</h2>
<p>You can install recent stable versions of Redis from the official <a target="_blank" href="http://packages.redis.io"><code>packages.redis.io</code></a> APT repository.</p>
<p>Prerequisites</p>
<p>If you're running a very minimal distribution (such as a Docker container) you may need to install <code>lsb-release</code>, <code>curl</code> and <code>gpg</code> first:</p>
<pre><code class="lang-bash">sudo apt install lsb-release curl gpg
</code></pre>
<p>Add the repository to the <code>apt</code> index, update it, and then install:</p>
<pre><code class="lang-bash">curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg

<span class="hljs-built_in">echo</span> <span class="hljs-string">"deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb <span class="hljs-subst">$(lsb_release -cs)</span> main"</span> | sudo tee /etc/apt/sources.list.d/redis.list

sudo apt-get update
sudo apt-get install redis
</code></pre>
<h2 id="heading-testing-redis">Testing Redis</h2>
<p>As with any newly-installed software, it’s a good idea to ensure that Redis is functioning as expected before making any further changes to its configuration. We will go over a handful of ways to check that Redis is working correctly in this step.</p>
<p>Start by checking that the Redis service is running:</p>
<pre><code class="lang-bash">sudo systemctl status redis-server
</code></pre>
<h2 id="heading-binding-to-localhost">Binding to localhost</h2>
<p>By default, Redis is only accessible from <a target="_blank" href="http://localhost"><strong>localhost</strong></a>. However, if you installed and configured Redis by following a different tutorial than this one, you might have updated the configuration file to allow connections from anywhere. This is not as secure as binding to <a target="_blank" href="http://localhost"><strong>localhost</strong></a>.</p>
<p>To correct this, open the Redis configuration file for editing:</p>
<pre><code class="lang-bash">sudo nano /etc/redis/redis.conf
</code></pre>
<p>Locate this line and make sure it is uncommented (remove the <code>#</code> if it exists):</p>
<pre><code class="lang-bash"><span class="hljs-built_in">bind</span> 127.0.0.1 ::1
</code></pre>
<p>Save and close the file when finished (press <code>CTRL + X</code>, <code>Y</code>, then <code>ENTER</code>).</p>
<p>Then, restart the service to ensure that systemd reads your changes:</p>
<pre><code class="lang-bash">sudo systemctl restart redis-server
</code></pre>
<p>To check that this change has gone into effect, run the following <code>netstat</code> command:</p>
<pre><code class="lang-bash">sudo netstat -lnp | grep redis
</code></pre>
<pre><code class="lang-bash">Output
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      14222/redis-server  
tcp6       0      0 ::1:6379                :::*                    LISTEN      14222/redis-server
</code></pre>
<p><strong>Note</strong>: The <code>netstat</code> command may not be available on your system by default. If this is the case, you can install it (along with a number of other handy networking tools) with the following command:</p>
<pre><code class="lang-bash">sudo apt install net-tools
</code></pre>
<h2 id="heading-configuring-a-redis-password">Configuring a Redis Password</h2>
<p>Configuring a Redis password enables one of its two built-in security features — the <code>auth</code> command, which requires clients to authenticate to access the database. The password is configured directly in Redis’s configuration file, <code>/etc/redis/redis.conf</code>, so open that file again with your preferred editor:</p>
<pre><code class="lang-bash">sudo nano /etc/redis/redis.conf
</code></pre>
<p>Scroll to the <code>SECURITY</code> section and look for a commented directive that reads:</p>
<pre><code class="lang-bash">. . .
<span class="hljs-comment"># requirepass foobared</span>
. . .
</code></pre>
<p>Uncomment it by removing the <code>#</code>, and change <code>foobared</code> to a secure password.</p>
<p><strong>Note:</strong> Above the <code>requirepass</code> directive in the <code>redis.conf</code> file, there is a commented warning:</p>
<pre><code class="lang-bash">. . .
<span class="hljs-comment"># Warning: since Redis is pretty fast an outside user can try up to</span>
<span class="hljs-comment"># 150k passwords per second against a good box. This means that you should</span>
<span class="hljs-comment"># use a very strong password otherwise it will be very easy to break.</span>
<span class="hljs-comment">#</span>
. . .
</code></pre>
<p>Thus, it’s important that you specify a very strong and very long value as your password. Rather than make up a password yourself, you can use the <code>openssl</code> command to generate a random one, as in the following example. By piping the output of the first command to the second <code>openssl</code> command, as shown here, it will remove any line breaks produced by that the first command:</p>
<pre><code class="lang-bash">openssl rand 60 | openssl base64 -A
</code></pre>
<p>Your output should look something like:</p>
<pre><code class="lang-bash">Output
RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
</code></pre>
<p>After copying and pasting the output of that command as the new value for <code>requirepass</code>, it should read:</p>
<pre><code class="lang-bash">requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
</code></pre>
<p>After setting the password, save and close the file, then restart Redis:</p>
<pre><code class="lang-bash">sudo systemctl restart redis-server
</code></pre>
<p>To test that the password works, open up the Redis client:</p>
<pre><code class="lang-bash">redis-cli
</code></pre>
<p>The following shows a sequence of commands used to test whether the Redis password works. The first command tries to set a key to a value before authentication:</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; <span class="hljs-built_in">set</span> key1 10
</code></pre>
<p>That won’t work because you didn’t authenticate, so Redis returns an error:</p>
<pre><code class="lang-bash">Output
127.0.0.1:6379&gt; (error) NOAUTH Authentication required.
</code></pre>
<p>The next command authenticates with the password specified in the Redis configuration file:</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; auth your_redis_password
</code></pre>
<p>Redis acknowledges:</p>
<pre><code class="lang-bash">Output
OK
</code></pre>
<p>After that, running the previous command again will succeed:</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; <span class="hljs-built_in">set</span> key1 10
</code></pre>
<pre><code class="lang-bash">Output
OK
</code></pre>
<p><code>get key1</code> queries Redis for the value of the new key.</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; get key1
</code></pre>
<pre><code class="lang-bash">Output
<span class="hljs-string">"10"</span>
</code></pre>
<p>After confirming that you’re able to run commands in the Redis client after authenticating, you can exit <code>redis-cli</code>:</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; quit
</code></pre>
<p>src :</p>
<ul>
<li><p><a target="_blank" href="https://redis.io/docs/getting-started/installation/install-redis-on-linux/">https://redis.io/docs/getting-started/installation/install-redis-on-linux/</a></p>
</li>
<li><p><a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-20-04">https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-20-04</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Loging Query Lumen]]></title><description><![CDATA[app\Providers\AppServiceProvider.php
    function boot()
    {
        app('db')->listen(function ($query) {
            app('log')->info(
                $query->sql,
                $query->bindings,
                $query->time
            );
    ...]]></description><link>https://blog.andrizan.com/loging-query-lumen</link><guid isPermaLink="true">https://blog.andrizan.com/loging-query-lumen</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Wed, 23 Aug 2023 07:49:59 GMT</pubDate><content:encoded><![CDATA[<p><code>app\Providers\AppServiceProvider.php</code></p>
<pre><code class="lang-php">    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">boot</span>(<span class="hljs-params"></span>)
    </span>{
        app(<span class="hljs-string">'db'</span>)-&gt;listen(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$query</span>) </span>{
            app(<span class="hljs-string">'log'</span>)-&gt;info(
                $query-&gt;sql,
                $query-&gt;bindings,
                $query-&gt;time
            );
        });
</code></pre>
<p>log location</p>
<p><code>storage\logs\lumen-{date}.log</code></p>
]]></content:encoded></item><item><title><![CDATA[Proxmox]]></title><description><![CDATA[https://medium.com/it-homelabs/setting-up-an-it-homelab-with-proxmox-8473e7faa54d
https://medium.com/devops-dudes/proxmox-101-8204eb154cd5
https://medium.com/@saderi/create-vm-templates-on-proxmox-with-packer-84723b7e3919]]></description><link>https://blog.andrizan.com/proxmox</link><guid isPermaLink="true">https://blog.andrizan.com/proxmox</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Tue, 15 Aug 2023 08:44:11 GMT</pubDate><content:encoded><![CDATA[<p><a target="_blank" href="https://medium.com/it-homelabs/setting-up-an-it-homelab-with-proxmox-8473e7faa54d">https://medium.com/it-homelabs/setting-up-an-it-homelab-with-proxmox-8473e7faa54d</a></p>
<p><a target="_blank" href="https://medium.com/devops-dudes/proxmox-101-8204eb154cd5">https://medium.com/devops-dudes/proxmox-101-8204eb154cd5</a></p>
<p><a target="_blank" href="https://medium.com/@saderi/create-vm-templates-on-proxmox-with-packer-84723b7e3919">https://medium.com/@saderi/create-vm-templates-on-proxmox-with-packer-84723b7e3919</a></p>
]]></content:encoded></item><item><title><![CDATA[Windows Server Official ISO]]></title><description><![CDATA[https://web.archive.org/web/20220308212352/https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2016/
Windows 2012 R2 Essentials: http://download.microsoft.com/download/8/F/7/8F7024D2-AB2A-4BE2-8406-1E3AC49C5C1F/9600.16384.WINBLUE_RTM.1...]]></description><link>https://blog.andrizan.com/windows-server-official-iso</link><guid isPermaLink="true">https://blog.andrizan.com/windows-server-official-iso</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Tue, 15 Aug 2023 08:20:21 GMT</pubDate><content:encoded><![CDATA[<p><a target="_blank" href="https://web.archive.org/web/20220308212352/https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2016/">https://web.archive.org/web/20220308212352/https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2016/</a></p>
<p>Windows 2012 R2 Essentials: <a target="_blank" href="http://download.microsoft.com/download/8/F/7/8F7024D2-AB2A-4BE2-8406-1E3AC49C5C1F/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_SOLUTION_EN-US-IRM_SSSO_X64FRE_EN-US_DV5.ISO">http://download.microsoft.com/download/8/F/7/8F7024D2-AB2A-4BE2-8406-1E3AC49C5C1F/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_SOLUTION_EN-US-IRM_SSSO_X64FRE_EN-US_DV5.ISO</a></p>
<p>Windows 2012 R2: <a target="_blank" href="http://download.microsoft.com/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.17050.WINBLUE_REFRESH.140317-1640_X64FRE_SERVER_EVAL_EN-US-IR3_SSS_X64FREE_EN-US_DV9.ISO">http://download.microsoft.com/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.17050.WINBLUE_REFRESH.140317-1640_X64FRE_SERVER_EVAL_EN-US-IR3_SSS_X64FREE_EN-US_DV9.ISO</a></p>
<p>Windows 2016: <a target="_blank" href="https://software-download.microsoft.com/download/pr/Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO">https://software-download.microsoft.com/download/pr/Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO</a></p>
<p>Windows 2019 Essentials: <a target="_blank" href="https://software-download.microsoft.com/download/pr/17763.737.190906-2324.rs5_release_svc_refresh_SERVERESSENTIALS_OEM_x64FRE_en-us_1.iso">https://software-download.microsoft.com/download/pr/17763.737.190906-2324.rs5_release_svc_refresh_SERVERESSENTIALS_OEM_x64FRE_en-us_1.iso</a></p>
<p>Windows 2019: <a target="_blank" href="https://software-download.microsoft.com/download/pr/17763.737.190906-2324.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us_1.iso">https://software-download.microsoft.com/download/pr/17763.737.190906-2324.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us_1.iso</a></p>
<p>Windows 2022: <a target="_blank" href="https://software-static.download.prss.microsoft.com/sg/download/888969d5-f34g-4e03-ac9d-1f9786c66749/SERVER_EVAL_x64FRE_en-us.iso">https://software-static.download.prss.microsoft.com/sg/download/888969d5-f34g-4e03-ac9d-1f9786c66749/SERVER_EVAL_x64FRE_en-us.iso</a></p>
<p>src = <a target="_blank" href="https://gist.github.com/vinhjaxt/a774ac87b0313a34f4c445048d8e13cf">https://gist.github.com/vinhjaxt/a774ac87b0313a34f4c445048d8e13cf</a></p>
<hr />
<p>Windows Server 2022 = <a target="_blank" href="https://www.microsoft.com/en-us/evalcenter/download-windows-server-2022">https://www.microsoft.com/en-us/evalcenter/download-windows-server-2022</a></p>
<p>Windows Server 2019 = <a target="_blank" href="https://www.microsoft.com/en-us/evalcenter/download-windows-server-2019">https://www.microsoft.com/en-us/evalcenter/download-windows-server-2019</a></p>
]]></content:encoded></item><item><title><![CDATA[Deploy MinIO Ubuntu Server: Single-Node Single-Drive]]></title><description><![CDATA[Download the MinIO Server
The following tabs provide examples of installing MinIO onto 64-bit Linux operating systems using RPM, DEB, or binary. The RPM and DEB packages automatically install MinIO to the necessary system paths and create a minio ser...]]></description><link>https://blog.andrizan.com/deploy-minio-ubuntu-server-single-node-single-drive</link><guid isPermaLink="true">https://blog.andrizan.com/deploy-minio-ubuntu-server-single-node-single-drive</guid><category><![CDATA[#minio]]></category><category><![CDATA[Ubuntu]]></category><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Mon, 14 Aug 2023 10:36:52 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-download-the-minio-server">Download the MinIO Server</h1>
<p>The following tabs provide examples of installing MinIO onto 64-bit Linux operating systems using RPM, DEB, or binary. The RPM and DEB packages automatically install MinIO to the necessary system paths and create a <code>minio</code> service for <code>systemctl</code>. MinIO strongly recommends using the RPM or DEB installation routes. To update deployments managed using <code>systemctl</code>, see <a target="_blank" href="https://min.io/docs/minio/linux/operations/install-deploy-manage/upgrade-minio-deployment.html#minio-upgrade-systemctl">Update systemctl-Managed MinIO Deployments</a>.</p>
<h2 id="heading-amd64">AMD64</h2>
<p>Use the following commands to download the latest stable MinIO binary and install it to the system <code>$PATH</code>:</p>
<pre><code class="lang-bash">wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/<span class="hljs-built_in">local</span>/bin/
</code></pre>
<h1 id="heading-create-the-systemd-service-file">Create the <code>systemd</code> Service File</h1>
<p>The <code>.deb</code> or <code>.rpm</code> packages install the following <a target="_blank" href="https://www.freedesktop.org/wiki/Software/systemd/">systemd</a> service file to <code>/etc/systemd/system/minio.service</code>. For binary installations, create this file manually on all MinIO hosts:</p>
<pre><code class="lang-bash">[Unit]
Description=MinIO
Documentation=https://min.io/docs/minio/linux/index.html
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/<span class="hljs-built_in">local</span>/bin/minio

[Service]
WorkingDirectory=/usr/<span class="hljs-built_in">local</span>

User=minio-user
Group=minio-user
ProtectProc=invisible

EnvironmentFile=-/etc/default/minio
ExecStartPre=/bin/bash -c <span class="hljs-string">"if [ -z \"<span class="hljs-variable">${MINIO_VOLUMES}</span>\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"</span>
ExecStart=/usr/<span class="hljs-built_in">local</span>/bin/minio server <span class="hljs-variable">$MINIO_OPTS</span> <span class="hljs-variable">$MINIO_VOLUMES</span>

<span class="hljs-comment"># MinIO RELEASE.2023-05-04T21-44-30Z adds support for Type=notify (https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=)</span>
<span class="hljs-comment"># This may improve systemctl setups where other services use `After=minio.server`</span>
<span class="hljs-comment"># Uncomment the line to enable the functionality</span>
<span class="hljs-comment"># Type=notify</span>

<span class="hljs-comment"># Let systemd restart this service always</span>
Restart=always

<span class="hljs-comment"># Specifies the maximum file descriptor number that can be opened by this process</span>
LimitNOFILE=65536

<span class="hljs-comment"># Specifies the maximum number of threads this process can create</span>
TasksMax=infinity

<span class="hljs-comment"># Disable timeout logic and wait until process is stopped</span>
TimeoutStopSec=infinity
SendSIGKILL=no

[Install]
WantedBy=multi-user.target

<span class="hljs-comment"># Built for ${project.name}-${project.version} (${project.name})</span>
</code></pre>
<p>The <code>minio.service</code> file runs as the <code>minio-user</code> User and Group by default. You can create the user and group using the <code>groupadd</code> and <code>useradd</code> commands. The following example creates the user, group, and sets permissions to access the folder paths intended for use by MinIO. These commands typically require root (<code>sudo</code>) permissions.</p>
<pre><code class="lang-bash">groupadd -r minio-user
useradd -M -r -g minio-user minio-user
chown minio-user:minio-user /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4
</code></pre>
<p>The specified drive paths are provided as an example. Change them to match the path to those drives intended for use by MinIO.</p>
<p>Alternatively, change the <code>User</code> and <code>Group</code> values to another user and group on the system host with the necessary access and permissions.</p>
<p>MinIO publishes additional startup script examples on <a target="_blank" href="http://github.com/minio/minio-service">github.com/minio/minio-service</a>.</p>
<p>To update deployments managed using <code>systemctl</code>, see <a target="_blank" href="https://min.io/docs/minio/linux/operations/install-deploy-manage/upgrade-minio-deployment.html#minio-upgrade-systemctl">Update systemctl-Managed MinIO Deployments</a>.</p>
<h1 id="heading-create-the-environment-variable-file">Create the Environment Variable File</h1>
<p>Create an environment variable file at <code>/etc/default/minio</code>. For Windows hosts, specify a Windows-style path similar to <code>C:\minio\config</code>. The MinIO Server container can use this file as the source of all <a target="_blank" href="https://min.io/docs/minio/linux/reference/minio-server/minio-server.html#minio-server-environment-variables">environment variables</a>.</p>
<p>The following example provides a starting environment file:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># MINIO_ROOT_USER and MINIO_ROOT_PASSWORD sets the root account for the MinIO server.</span>
<span class="hljs-comment"># This user has unrestricted permissions to perform S3 and administrative API operations on any resource in the deployment.</span>
<span class="hljs-comment"># Omit to use the default values 'minioadmin:minioadmin'.</span>
<span class="hljs-comment"># MinIO recommends setting non-default values as a best practice, regardless of environment</span>

MINIO_ROOT_USER=myminioadmin
MINIO_ROOT_PASSWORD=minio-secret-key-change-me

<span class="hljs-comment"># MINIO_VOLUMES sets the storage volume or path to use for the MinIO server.</span>

MINIO_VOLUMES=<span class="hljs-string">"/mnt/data"</span>

<span class="hljs-comment"># MINIO_SERVER_URL sets the hostname of the local machine for use with the MinIO Server</span>
<span class="hljs-comment"># MinIO assumes your network control plane can correctly resolve this hostname to the local machine</span>

<span class="hljs-comment"># Uncomment the following line and replace the value with the correct hostname for the local machine and port for the MinIO server (9000 by default).</span>

<span class="hljs-comment">#MINIO_SERVER_URL="http://s3.domain.com"</span>
<span class="hljs-comment">#MINIO_CONSOLE_ADDRESS=":9001"</span>
<span class="hljs-comment">#MINIO_BROWSER_REDIRECT_URL="http://s3.domain.com/minio/ui"</span>

<span class="hljs-comment">#MINIO_PROMETHEUS_URL=http://192.168.100.16:9090</span>
<span class="hljs-comment">#MINIO_PROMETHEUS_JOB_ID="minio-job"</span>
</code></pre>
<p>Include any other environment variables as required for your local deployment.</p>
<h2 id="heading-nginx-reverse-proxy">Nginx (reverse proxy)</h2>
<p>install nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
   <span class="hljs-attribute">server_name</span> s3.domain.com;
   <span class="hljs-attribute">listen</span> <span class="hljs-number">80</span>;

   <span class="hljs-comment"># Allow special characters in headers</span>
   <span class="hljs-attribute">ignore_invalid_headers</span> <span class="hljs-literal">off</span>;
   <span class="hljs-comment"># Allow any size file to be uploaded.</span>
   <span class="hljs-comment"># Set to a value such as 1000m; to restrict file size to a specific value</span>
   <span class="hljs-attribute">client_max_body_size</span> <span class="hljs-number">0</span>;
   <span class="hljs-comment"># Disable buffering</span>
   <span class="hljs-attribute">proxy_buffering</span> <span class="hljs-literal">off</span>;
   <span class="hljs-attribute">proxy_request_buffering</span> <span class="hljs-literal">off</span>;

   <span class="hljs-attribute">location</span> / {
      <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$http_host</span>;
      <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
      <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
      <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-Proto <span class="hljs-variable">$scheme</span>;

      <span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">300</span>;
      <span class="hljs-comment"># Default is HTTP/1, keepalive is only enabled in HTTP/1.1</span>
      <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
      <span class="hljs-attribute">proxy_set_header</span> Connection <span class="hljs-string">""</span>;
      <span class="hljs-attribute">chunked_transfer_encoding</span> <span class="hljs-literal">off</span>;

      <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:9000; <span class="hljs-comment"># This uses the upstream directive definition to load balance</span>
   }

   <span class="hljs-attribute">location</span> /minio/ui/ {
      <span class="hljs-attribute">rewrite</span><span class="hljs-regexp"> ^/minio/ui/(.*)</span> /<span class="hljs-variable">$1</span> <span class="hljs-literal">break</span>;
      <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$http_host</span>;
      <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
      <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
      <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-Proto <span class="hljs-variable">$scheme</span>;
      <span class="hljs-attribute">proxy_set_header</span> X-NginX-Proxy <span class="hljs-literal">true</span>;

      <span class="hljs-comment"># This is necessary to pass the correct IP to be hashed</span>
      <span class="hljs-attribute">real_ip_header</span> X-Real-IP;

      <span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">300</span>;

      <span class="hljs-comment"># To support websockets in MinIO versions released after January 2023</span>
      <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
      <span class="hljs-attribute">proxy_set_header</span> Upgrade <span class="hljs-variable">$http_upgrade</span>;
      <span class="hljs-attribute">proxy_set_header</span> Connection <span class="hljs-string">"upgrade"</span>;
      <span class="hljs-comment"># Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)</span>
      <span class="hljs-comment"># Uncomment the following line to set the Origin request to an empty string</span>
      <span class="hljs-comment"># proxy_set_header Origin '';</span>

      <span class="hljs-attribute">chunked_transfer_encoding</span> <span class="hljs-literal">off</span>;

      <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:9001/;
   }

}
</code></pre>
<h1 id="heading-start-the-minio-service">Start the MinIO Service</h1>
<p>Issue the following command on the local host to start the MinIO <abbr>SNSD</abbr> deployment as a service:</p>
<pre><code class="lang-bash">sudo systemctl start minio.service
</code></pre>
<p>Use the following commands to confirm the service is online and functional:</p>
<pre><code class="lang-bash">sudo systemctl status minio.service
journalctl -f -u minio.service
</code></pre>
<p>MinIO may log an increased number of non-critical warnings while the server processes connect and synchronize. These warnings are typically transient and should resolve as the deployment comes online.</p>
<p>Changed in version RELEASE.2023-02-09T05-16-53Z: MinIO starts if it detects enough drives to meet the <a target="_blank" href="https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html#minio-ec-parity">write quorum</a> for the deployment.</p>
<p>If any drives remain offline after starting MinIO, check and cure any issues blocking their functionality before starting production workloads.</p>
<p>The <code>journalctl</code> output should resemble the following:</p>
<pre><code class="lang-bash">Status:         1 Online, 0 Offline.
API: http://192.168.2.100:9000  http://127.0.0.1:9000
RootUser: myminioadmin
RootPass: minio-secret-key-change-me
Console: http://192.168.2.100:9090 http://127.0.0.1:9090
RootUser: myminioadmin
RootPass: minio-secret-key-change-me

Command-line: https://min.io/docs/minio/linux/reference/minio-mc.html
   $ mc <span class="hljs-built_in">alias</span> <span class="hljs-built_in">set</span> myminio http://10.0.2.100:9000 myminioadmin minio-secret-key-change-me

Documentation: https://min.io/docs/minio/linux/index.html
</code></pre>
<p>The <code>API</code> block lists the network interfaces and port on which clients can access the MinIO S3 API. The <code>Console</code> block lists the network interfaces and port on which clients can access the MinIO Web Console.</p>
<h1 id="heading-connect-to-the-minio-service">Connect to the MinIO Service</h1>
<p>You can access the MinIO Console by entering any of the hostnames or IP addresses from the MinIO server <code>Console</code> block in your preferred browser, such as <a target="_blank" href="http://localhost:9090">http://localhost:9090</a>.</p>
<p>Log in with the <a target="_blank" href="https://min.io/docs/minio/linux/reference/minio-server/minio-server.html#envvar.MINIO_ROOT_USER"><code>MINIO_ROOT_USER</code></a> and <a target="_blank" href="https://min.io/docs/minio/linux/reference/minio-server/minio-server.html#envvar.MINIO_ROOT_PASSWORD"><code>MINIO_ROOT_PASSWORD</code></a> configured in the environment file specified to the container.</p>
<p><img src="https://min.io/docs/minio/linux/_images/console-bucket-none.png" alt="MinIO Console displaying Buckets view in a fresh installation" /></p>
<p>You can use the MinIO Console for general administration tasks like Identity and Access Management, Metrics and Log Monitoring, or Server Configuration. Each MinIO server includes its own embedded MinIO Console.</p>
<p>If your local host firewall permits external access to the Console port, other hosts on the same network can access the Console using the IP or hostname for your local host.</p>
<h1 id="heading-cloudflare-tunnel">Cloudflare Tunnel</h1>
<p>Disable <code>cache</code> to resolve error <code>403</code></p>
<p><code>dash.cloudflare.com &gt; caching &gt; cache-rules</code></p>
<p>rule :</p>
<ul>
<li><p>hostname = DOMAIN/sub Domain</p>
</li>
<li><p>Cache Status = Bypass Cache</p>
</li>
</ul>
<h1 id="heading-install-prometheus-on-ubuntu">Install Prometheus on Ubuntu</h1>
<h2 id="heading-update-system-packages">Update System Packages</h2>
<p>You should first update your system's package list to ensure that you are using the most recent packages. To accomplish this, issue the following command:</p>
<pre><code class="lang-bash">sudo apt update
</code></pre>
<h2 id="heading-create-a-system-user-for-prometheus">Create a System User for Prometheus</h2>
<p>Now create a group and a system user for Prometheus. To create a group and then add a user to the group, run the following command:</p>
<pre><code class="lang-bash">sudo groupadd --system prometheus
sudo useradd -s /sbin/nologin --system -g prometheus prometheus
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/01.png" alt="add group and user" /></p>
<p>This will create a system user and group named "prometheus" for Prometheus with limited privileges, reducing the risk of unauthorized access.</p>
<h2 id="heading-create-directories-for-prometheus">Create Directories for Prometheus</h2>
<p>To store configuration files and libraries for Prometheus, you need to create a few directories. The directories will be located in the <code>/etc</code> and the <code>/var/lib</code> directory respectively. Use the commands below to create the directories:</p>
<pre><code class="lang-bash">sudo mkdir /etc/prometheus
sudo mkdir /var/lib/prometheus
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/03.png" alt="create directories for Prometheus" /></p>
<h2 id="heading-download-prometheus-and-extract-files">Download Prometheus and Extract Files</h2>
<p>To download the latest update, go to the <a target="_blank" href="https://prometheus.io/download/#prometheus">Prometheus official downloads site</a> and copy the download link for Linux Operating System. Download using wget and the link you copied like so:</p>
<pre><code class="lang-bash">wget https://github.com/prometheus/prometheus/releases/download/v2.43.0/prometheus-2.43.0.linux-amd64.tar.gz
</code></pre>
<p>You should see it being downloaded.</p>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/04.png" alt="download Prometheus" /></p>
<p>After the download has been completed, run the following command to extract the contents of the downloaded file:</p>
<pre><code class="lang-bash">tar vxf prometheus*.tar.gz
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/05.png" alt="extract Prometheus file" /></p>
<h2 id="heading-navigate-to-the-prometheus-directory">Navigate to the Prometheus Directory</h2>
<p>After extracting the files, navigate to the newly extracted Prometheus directory using the following command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> prometheus*/
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/06.png" alt="change directory" /></p>
<p>Changing to the Prometheus directory allows for easier management and configuration of the installation. Subsequent steps will be performed within the context of the Prometheus directory.</p>
<h1 id="heading-configuring-prometheus-on-ubuntu-2204">Configuring Prometheus on Ubuntu 22.04</h1>
<h2 id="heading-move-the-binary-files-amp-set-owner">Move the Binary Files &amp; Set Owner</h2>
<p>First, you need to move some binary files (<strong>prometheus</strong> and <strong>promtool</strong>) and change the ownership of the files to the "<strong>prometheus"</strong> user and group. You can do this with the following commands:</p>
<pre><code class="lang-bash">sudo mv prometheus /usr/<span class="hljs-built_in">local</span>/bin
sudo mv promtool /usr/<span class="hljs-built_in">local</span>/bin
sudo chown prometheus:prometheus /usr/<span class="hljs-built_in">local</span>/bin/prometheus
sudo chown prometheus:prometheus /usr/<span class="hljs-built_in">local</span>/bin/promtool
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/07.png" alt="move binary files and set owner" /></p>
<h2 id="heading-move-the-configuration-files-amp-set-owner">Move the Configuration Files &amp; Set Owner</h2>
<h3 id="heading-create-minio-alertingyml">Create <code>minio-alerting.yml</code></h3>
<pre><code class="lang-yaml"><span class="hljs-comment"># minio-alerting.yml </span>
<span class="hljs-attr">groups:</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">minio-alerts</span>
  <span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">NodesOffline</span>
    <span class="hljs-attr">expr:</span> <span class="hljs-string">avg_over_time(minio_cluster_nodes_offline_total{job="minio-job"}[5m])</span> <span class="hljs-string">&gt;</span> <span class="hljs-number">0</span>
    <span class="hljs-attr">for:</span> <span class="hljs-string">10m</span>
    <span class="hljs-attr">labels:</span>
      <span class="hljs-attr">severity:</span> <span class="hljs-string">warn</span>
    <span class="hljs-attr">annotations:</span>
      <span class="hljs-attr">summary:</span> <span class="hljs-string">"Node down in MinIO deployment"</span>
      <span class="hljs-attr">description:</span> <span class="hljs-string">"Node(s) in cluster <span class="hljs-template-variable">{{ $labels.instance }}</span> offline for more than 5 minutes"</span>

  <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">DisksOffline</span>
    <span class="hljs-attr">expr:</span> <span class="hljs-string">avg_over_time(minio_cluster_disk_offline_total{job="minio-job"}[5m])</span> <span class="hljs-string">&gt;</span> <span class="hljs-number">0</span>
    <span class="hljs-attr">for:</span> <span class="hljs-string">10m</span>
    <span class="hljs-attr">labels:</span>
      <span class="hljs-attr">severity:</span> <span class="hljs-string">warn</span>
    <span class="hljs-attr">annotations:</span>
      <span class="hljs-attr">summary:</span> <span class="hljs-string">"Disks down in MinIO deployment"</span>
      <span class="hljs-attr">description:</span> <span class="hljs-string">"Disks(s) in cluster <span class="hljs-template-variable">{{ $labels.instance }}</span> offline for more than 5 minutes"</span>
</code></pre>
<h3 id="heading-create-alias-for-mc">Create ALIAS for <code>mc</code></h3>
<ol>
<li><p>install <code>mc</code></p>
<pre><code class="lang-bash"> curl --progress-bar -L https://dl.min.io/aistor/mc/release/linux-amd64/mc \
 --create-dirs \
 -o <span class="hljs-variable">$HOME</span>/aistor-binaries/mc

 chmod +x ~/aistor-binaries/mc
 <span class="hljs-built_in">echo</span> <span class="hljs-string">'export PATH="$HOME/aistor-binaries:$PATH"'</span> &gt;&gt; ~/.bashrc
 <span class="hljs-built_in">source</span> ~/.bashrc

 mc --<span class="hljs-built_in">help</span>
</code></pre>
<p> or add <code>export PATH=$PATH:$HOME/minio-binaries/</code> on <code>~/.profile</code></p>
<p> https://min.io/docs/minio/linux/reference/minio-mc.html</p>
</li>
<li><p>Create ALIAS</p>
<pre><code class="lang-bash"> mc <span class="hljs-built_in">alias</span> <span class="hljs-built_in">set</span> ALIAS HOSTNAME ACCESS_KEY SECRET_KEY
</code></pre>
<p> Example:</p>
<pre><code class="lang-bash"> mc <span class="hljs-built_in">alias</span> <span class="hljs-built_in">set</span> s3example https://s3.domain.com user <span class="hljs-string">'password'</span>
</code></pre>
</li>
<li><p>Generate minio job</p>
<pre><code class="lang-bash"> mc admin prometheus generate s3-example
</code></pre>
<p> https://min.io/docs/minio/linux/reference/minio-mc-admin/mc-admin-prometheus.html</p>
</li>
</ol>
<h3 id="heading-change-prometheusyml">Change <code>prometheus.yml</code></h3>
<pre><code class="lang-yaml"><span class="hljs-comment"># my global config</span>
<span class="hljs-attr">global:</span>
  <span class="hljs-attr">scrape_interval:</span> <span class="hljs-string">15s</span> <span class="hljs-comment"># Set the scrape interval to every 15 seconds. Default is every 1 minute.</span>
  <span class="hljs-attr">evaluation_interval:</span> <span class="hljs-string">15s</span> <span class="hljs-comment"># Evaluate rules every 15 seconds. The default is every 1 minute.</span>
  <span class="hljs-comment"># scrape_timeout is set to the global default (10s).</span>

<span class="hljs-comment"># Alertmanager configuration</span>
<span class="hljs-attr">alerting:</span>
  <span class="hljs-attr">alertmanagers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">static_configs:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span>
          <span class="hljs-comment"># - alertmanager:9093</span>

<span class="hljs-comment"># Load rules once and periodically evaluate them according to the global 'evaluation_interval'.</span>
<span class="hljs-attr">rule_files:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">minio-alerting.yml</span>
  <span class="hljs-comment"># - "first_rules.yml"</span>
  <span class="hljs-comment"># - "second_rules.yml"</span>

<span class="hljs-comment"># A scrape configuration containing exactly one endpoint to scrape:</span>
<span class="hljs-comment"># Here it's Prometheus itself.</span>
<span class="hljs-attr">scrape_configs:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">job_name:</span> <span class="hljs-string">minio-job</span>
    <span class="hljs-attr">bearer_token:</span> <span class="hljs-string">&lt;TOKEN&gt;</span>
    <span class="hljs-attr">metrics_path:</span> <span class="hljs-string">/minio/v2/metrics/cluster</span>
    <span class="hljs-attr">scheme:</span> <span class="hljs-string">http</span>
    <span class="hljs-attr">static_configs:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span> [<span class="hljs-string">'192.168.100.14:9000'</span>]

  <span class="hljs-comment"># The job name is added as a label `job=&lt;job_name&gt;` to any timeseries scraped from this config.</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">job_name:</span> <span class="hljs-string">"prometheus"</span>

    <span class="hljs-comment"># metrics_path defaults to '/metrics'</span>
    <span class="hljs-comment"># scheme defaults to 'http'.</span>

    <span class="hljs-attr">static_configs:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span> [<span class="hljs-string">"localhost:9090"</span>]
</code></pre>
<h3 id="heading-move-prometeus-files-amp-set-ownership">Move Prometeus Files &amp; Set Ownership</h3>
<p>Move the configuration files and set their ownership so that Prometheus can access them. To do this, run the following commands:</p>
<pre><code class="lang-bash">sudo mv consoles /etc/prometheus
sudo mv console_libraries /etc/prometheus
sudo mv prometheus.yml /etc/prometheus
sudo mv minio-alerting.yml /etc/prometheus
</code></pre>
<pre><code class="lang-bash">sudo chown prometheus:prometheus /etc/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus/consoles
sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries
sudo chown -R prometheus:prometheus /var/lib/prometheus
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/08.png" alt="move configuration files and set owner" /></p>
<p>The <code>prometheus.yml</code> file is the main Prometheus configuration file. It includes settings for targets to be monitored, data scraping frequency, data processing, and storage. You can set alerting rules and notification conditions in the file. You don't need to modify this file for this demonstration but feel free to open it in an editor to take a closer look at its contents.</p>
<pre><code class="lang-bash">sudo nano /etc/prometheus/prometheus.yml
</code></pre>
<p>Here's the default content of the Prometheus file:</p>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/09.png" alt="Prometheus file content" /></p>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/10.png" alt="Prometheus file content" /></p>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/11.png" alt="Prometheus file content" /></p>
<h2 id="heading-create-prometheus-systemd-service">Create Prometheus Systemd Service</h2>
<p>Now, you need to create a system service file for Prometheus. Create and open a <code>prometheus.service</code> file with the Nano text editor using:</p>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/prometheus.service
</code></pre>
<p>Include these settings to the file, save, and exit:</p>
<p>Configuration (Recomended)</p>
<pre><code class="lang-apache">[<span class="hljs-attribute">Unit</span>]
<span class="hljs-attribute">Description</span>=Prometheus
<span class="hljs-attribute">Wants</span>=network-online.target
<span class="hljs-attribute">After</span>=network-online.target

[<span class="hljs-attribute">Service</span>]
<span class="hljs-attribute">User</span>=prometheus
<span class="hljs-attribute">Group</span>=prometheus
<span class="hljs-attribute">Type</span>=simple
<span class="hljs-attribute">ExecStart</span>=/usr/local/bin/prometheus \
    --<span class="hljs-attribute">config</span>.file /etc/prometheus/prometheus.yml \
    --<span class="hljs-attribute">storage</span>.tsdb.path /var/lib/prometheus/ \
    --<span class="hljs-attribute">web</span>.console.templates=/etc/prometheus/consoles \
    --<span class="hljs-attribute">web</span>.console.libraries=/etc/prometheus/console_libraries

[<span class="hljs-attribute">Install</span>]
<span class="hljs-attribute">WantedBy</span>=multi-user.target
</code></pre>
<p><strong>Alternative Config</strong></p>
<pre><code class="lang-apache">[<span class="hljs-attribute">Unit</span>]
<span class="hljs-attribute">Description</span>=Prometheus #Description
<span class="hljs-attribute">Documentation</span>=https://prometheus.io/docs/introduction/overview/ #reference to documentation
<span class="hljs-attribute">Wants</span>=network-online.target
<span class="hljs-attribute">After</span>=network-online.target<span class="hljs-meta">
[Service]</span>
<span class="hljs-attribute">Type</span>=simple
<span class="hljs-attribute">User</span>=prometheus #user
<span class="hljs-attribute">Group</span>=prometheus #group
<span class="hljs-attribute">ExecReload</span>=/bin/kill -HUP \$MAINPID
<span class="hljs-attribute">ExecStart</span>=/usr/local/bin/prometheus \
--<span class="hljs-attribute">config</span>.file=/etc/prometheus/prometheus.yml \ #main config
--<span class="hljs-attribute">storage</span>.tsdb.path=/var/lib/prometheus \ #database
--<span class="hljs-attribute">web</span>.console.templates=/etc/prometheus/consoles \
--<span class="hljs-attribute">web</span>.console.libraries=/etc/prometheus/console_libraries \
--<span class="hljs-attribute">web</span>.listen-address=<span class="hljs-number">0.0.0.0:9090</span> \
--<span class="hljs-attribute">web</span>.external-url=
<span class="hljs-attribute">SyslogIdentifier</span>=prometheus #name of log file
<span class="hljs-attribute">Restart</span>=always #enable restart<span class="hljs-meta">
[Install]</span>
<span class="hljs-attribute">WantedBy</span>=multi-user.target
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/12.png" alt="Prometheus systemd service file" /></p>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/13.png" alt="Prometheus systemd service file" /></p>
<p>The "systems" service file for Prometheus defines how Prometheus should be managed as a system service on Ubuntu. It includes the service configuration, such as the user and group it should run as. It also includes the path to the Prometheus binary and the Prometheus configuration file location. Additionally, the file can be used to set storage locations for metrics data and pass additional command-line options to the Prometheus binary when it starts.</p>
<h2 id="heading-reload-systemd">Reload Systemd</h2>
<p>You need to reload the system configuration files after saving the <code>prometheus.service</code> file so that changes made are recognized by the system. Reload the system configuration files using the following:</p>
<pre><code class="lang-bash">sudo systemctl daemon-reload
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/14.png" alt="Reload systemd" /></p>
<h2 id="heading-start-prometheus-service">Start Prometheus Service</h2>
<p>Next, you want to enable and start your Prometheus service. Do this using the following commands:</p>
<pre><code class="lang-bash">sudo systemctl <span class="hljs-built_in">enable</span> prometheus
sudo systemctl start prometheus
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/15.png" alt="Start Prometheus service" /></p>
<h2 id="heading-check-prometheus-status">Check Prometheus Status</h2>
<p>After starting the Prometheus service, you may confirm that it is running or if you have encountered errors using:</p>
<pre><code class="lang-bash">sudo systemctl status prometheus
</code></pre>
<p>Sample output:</p>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/16.png" alt="Check Prometheus status" /></p>
<h1 id="heading-access-prometheus-web-interface">Access Prometheus Web Interface</h1>
<p>Prometheus runs on port 9090 by default so you need to allow port 9090 on your firewall, Do that using the command:</p>
<pre><code class="lang-bash">sudo ufw allow 9090/tcp
</code></pre>
<p><img src="https://www.cherryservers.com/v3/assets/blog/2023-05-16/17.png" alt="Allow port 9090" /></p>
<p>With Prometheus running successfully, you can access it via your web browser using <a target="_blank" href="http://localhost:9090">localhost:9090</a> or &lt;ip_address&gt;:9090</p>
<p>src</p>
<ul>
<li><p><a target="_blank" href="https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-single-node-single-drive.html#minio-snsd">https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-single-node-single-drive.html#minio-snsd</a></p>
</li>
<li><p><a target="_blank" href="https://www.cherryservers.com/blog/install-prometheus-ubuntu">https://www.cherryservers.com/blog/install-prometheus-ubuntu</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Setup PostgreSQL Cluster Ubuntu Server]]></title><description><![CDATA[Prerequisite
To follow this tutorial, we need three VM for PostgreSQL and one VM for HAproxy and etcd. Below is four VMs that we will deploy in Cloud Raya.




HostnameIP AddressApplications



haetcd199.180.130.99HAproxy

10.3.3.166etcd

pgsql110.3....]]></description><link>https://blog.andrizan.com/setup-postgresql-cluster-ubuntu-server</link><guid isPermaLink="true">https://blog.andrizan.com/setup-postgresql-cluster-ubuntu-server</guid><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Mon, 14 Aug 2023 10:12:01 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-prerequisite">Prerequisite</h2>
<p>To follow this tutorial, we need three VM for PostgreSQL and one VM for HAproxy and etcd. Below is four VMs that we will deploy in Cloud Raya.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Hostname</td><td>IP Address</td><td>Applications</td></tr>
</thead>
<tbody>
<tr>
<td>haetcd</td><td>199.180.130.99</td><td>HAproxy</td></tr>
<tr>
<td></td><td>10.3.3.166</td><td>etcd</td></tr>
<tr>
<td>pgsql1</td><td>10.3.3.12</td><td>patroni</td></tr>
<tr>
<td>pgsql2</td><td>10.3.3.71</td><td>patroni</td></tr>
<tr>
<td>pgsql3</td><td>10.3.3.70</td><td>patroni</td></tr>
</tbody>
</table>
</div><p>We will use haetcd as jumpbox server since the VM has Public IP Address that we can access from the outside network. In <code>/etc/host</code>, insert the hostname of the servers to make us easy to access the server without remembering the IP Address.</p>
<h3 id="heading-hosts">hosts</h3>
<p><a target="_blank" href="https://camo.githubusercontent.com/c90d5e27824ff1dd0ca20860ec66698008c7675ea5c0e249719bd60972e7ce7a/68747470733a2f2f636c6f7564726179612e636f6d2f77702d636f6e74656e742f75706c6f6164732f323032322f30352f696d6167652e706e67"><img src="https://camo.githubusercontent.com/c90d5e27824ff1dd0ca20860ec66698008c7675ea5c0e249719bd60972e7ce7a/68747470733a2f2f636c6f7564726179612e636f6d2f77702d636f6e74656e742f75706c6f6164732f323032322f30352f696d6167652e706e67" alt="host" /></a></p>
<h2 id="heading-install-postgresql-14">Install PostgreSQL 14</h2>
<p>In this step, we will use PostgreSQL14 for pgsql1, pgsql2, and pgsql3. Please the command below on each server.</p>
<pre><code class="lang-bash">sh -c <span class="hljs-string">'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" &gt; /etc/apt/sources.list.d/pgdg.list'</span>
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
sudo apt -y install postgresql-14 postgresql-server-dev-14
</code></pre>
<p>After the postgresql installation is completed, we need to stop and disable PostgreSQL service. Then we will continue to install patroni.</p>
<pre><code class="lang-bash">systemctl stop postgresql &amp;&amp; systemctl <span class="hljs-built_in">disable</span> postgresql
</code></pre>
<h2 id="heading-install-patroni">Install Patroni</h2>
<p>Patroni uses the utilities of PostgreSQL that we have installed previously which is located at <code>/usr/lib/postgresql/versin/bin</code> directory.</p>
<p>In this step, we create a symbolic link to PostgreSQL utilities on psql1, psql2, and psql3</p>
<pre><code class="lang-bash">ln -s /usr/lib/postgresql/14/bin/* /usr/sbin/
</code></pre>
<p>Next, we will install patroni on each server</p>
<pre><code class="lang-bash">apt -y install python3 python3-pip
pip install --upgrade setuptools
pip install psycopg2
pip install patroni
pip install python-etcd
</code></pre>
<h2 id="heading-configure-patroni-on-pgsql1-pgsql2-and-pgsql3">Configure Patroni on Pgsql1, Pgsql2, and Pgsql3</h2>
<p>Patroni uses <code>yaml</code> files to store the configuration. We will place the <code>yaml</code> file on <code>/etc</code> directory.</p>
<pre><code class="lang-bash">sudo nano /etc/patroni.yml
</code></pre>
<h3 id="heading-pgsql1">pgsql1</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">scope:</span> <span class="hljs-string">postgres</span>
<span class="hljs-attr">namespace:</span> <span class="hljs-string">/db/</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">pgsql1</span>

<span class="hljs-attr">restapi:</span>
    <span class="hljs-attr">listen:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.12</span><span class="hljs-string">:8008</span>
    <span class="hljs-attr">connect_address:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.12</span><span class="hljs-string">:8008</span>

<span class="hljs-attr">etcd:</span>
    <span class="hljs-attr">host:</span>  <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.166</span><span class="hljs-string">:2379</span>

<span class="hljs-attr">bootstrap:</span>
    <span class="hljs-attr">dcs:</span>
        <span class="hljs-attr">ttl:</span> <span class="hljs-number">30</span>
        <span class="hljs-attr">loop_wait:</span> <span class="hljs-number">10</span>
        <span class="hljs-attr">retry_timeout:</span> <span class="hljs-number">10</span>
        <span class="hljs-attr">maximum_lag_on_failover:</span> <span class="hljs-number">1048576</span>
        <span class="hljs-attr">postgresql:</span>
            <span class="hljs-attr">use_pg_rewind:</span> <span class="hljs-literal">true</span>

    <span class="hljs-attr">initdb:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">encoding:</span> <span class="hljs-string">UTF8</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">data-checksums</span>

    <span class="hljs-attr">pg_hba:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span><span class="hljs-string">/32</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.12</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.71</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.70</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">all</span> <span class="hljs-string">all</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>

    <span class="hljs-attr">users:</span>
        <span class="hljs-attr">admin:</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">admin</span>
            <span class="hljs-attr">options:</span>
                <span class="hljs-bullet">-</span> <span class="hljs-string">createrole</span>
                <span class="hljs-bullet">-</span> <span class="hljs-string">createdb</span>

<span class="hljs-attr">postgresql:</span>
    <span class="hljs-attr">listen:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.12</span><span class="hljs-string">:5432</span>
    <span class="hljs-attr">connect_address:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.12</span><span class="hljs-string">:5432</span>
    <span class="hljs-attr">data_dir:</span> <span class="hljs-string">/data/patroni</span>
    <span class="hljs-attr">pgpass:</span> <span class="hljs-string">/tmp/pgpass</span>
    <span class="hljs-attr">authentication:</span>
        <span class="hljs-attr">replication:</span>
            <span class="hljs-attr">username:</span> <span class="hljs-string">replicator</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">replogin321</span>
        <span class="hljs-attr">superuser:</span>
            <span class="hljs-attr">username:</span> <span class="hljs-string">postgres</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">secretlogin321</span>
    <span class="hljs-attr">parameters:</span>
        <span class="hljs-attr">unix_socket_directories:</span> <span class="hljs-string">'.'</span>

<span class="hljs-attr">tags:</span>
    <span class="hljs-attr">nofailover:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">noloadbalance:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">clonefrom:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">nosync:</span> <span class="hljs-literal">false</span>
</code></pre>
<h3 id="heading-pgsql2">pgsql2</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">scope:</span> <span class="hljs-string">postgres</span>
<span class="hljs-attr">namespace:</span> <span class="hljs-string">/db/</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">pgsql2</span>

<span class="hljs-attr">restapi:</span>
    <span class="hljs-attr">listen:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.71</span><span class="hljs-string">:8008</span>
    <span class="hljs-attr">connect_address:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.71</span><span class="hljs-string">:8008</span>

<span class="hljs-attr">etcd:</span>
    <span class="hljs-attr">host:</span>  <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.166</span><span class="hljs-string">:2379</span>

<span class="hljs-attr">bootstrap:</span>
    <span class="hljs-attr">dcs:</span>
        <span class="hljs-attr">ttl:</span> <span class="hljs-number">30</span>
        <span class="hljs-attr">loop_wait:</span> <span class="hljs-number">10</span>
        <span class="hljs-attr">retry_timeout:</span> <span class="hljs-number">10</span>
        <span class="hljs-attr">maximum_lag_on_failover:</span> <span class="hljs-number">1048576</span>
        <span class="hljs-attr">postgresql:</span>
            <span class="hljs-attr">use_pg_rewind:</span> <span class="hljs-literal">true</span>

    <span class="hljs-attr">initdb:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">encoding:</span> <span class="hljs-string">UTF8</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">data-checksums</span>

    <span class="hljs-attr">pg_hba:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span><span class="hljs-string">/32</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.12</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.71</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.70</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">all</span> <span class="hljs-string">all</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>

    <span class="hljs-attr">users:</span>
        <span class="hljs-attr">admin:</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">admin</span>
            <span class="hljs-attr">options:</span>
                <span class="hljs-bullet">-</span> <span class="hljs-string">createrole</span>
                <span class="hljs-bullet">-</span> <span class="hljs-string">createdb</span>

<span class="hljs-attr">postgresql:</span>
    <span class="hljs-attr">listen:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.71</span><span class="hljs-string">:5432</span>
    <span class="hljs-attr">connect_address:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.71</span><span class="hljs-string">:5432</span>
    <span class="hljs-attr">data_dir:</span> <span class="hljs-string">/data/patroni</span>
    <span class="hljs-attr">pgpass:</span> <span class="hljs-string">/tmp/pgpass</span>
    <span class="hljs-attr">authentication:</span>
        <span class="hljs-attr">replication:</span>
            <span class="hljs-attr">username:</span> <span class="hljs-string">replicator</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">replogin321</span>
        <span class="hljs-attr">superuser:</span>
            <span class="hljs-attr">username:</span> <span class="hljs-string">postgres</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">secretlogin321</span>
    <span class="hljs-attr">parameters:</span>
        <span class="hljs-attr">unix_socket_directories:</span> <span class="hljs-string">'.'</span>

<span class="hljs-attr">tags:</span>
    <span class="hljs-attr">nofailover:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">noloadbalance:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">clonefrom:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">nosync:</span> <span class="hljs-literal">false</span>
</code></pre>
<h3 id="heading-pgsql3">pgsql3</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">scope:</span> <span class="hljs-string">postgres</span>
<span class="hljs-attr">namespace:</span> <span class="hljs-string">/db/</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">pgsql3</span>

<span class="hljs-attr">restapi:</span>
    <span class="hljs-attr">listen:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.70</span><span class="hljs-string">:8008</span>
    <span class="hljs-attr">connect_address:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.70</span><span class="hljs-string">:8008</span>

<span class="hljs-attr">etcd:</span>
    <span class="hljs-attr">host:</span>  <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.166</span><span class="hljs-string">:2379</span>

<span class="hljs-attr">bootstrap:</span>
    <span class="hljs-attr">dcs:</span>
        <span class="hljs-attr">ttl:</span> <span class="hljs-number">30</span>
        <span class="hljs-attr">loop_wait:</span> <span class="hljs-number">10</span>
        <span class="hljs-attr">retry_timeout:</span> <span class="hljs-number">10</span>
        <span class="hljs-attr">maximum_lag_on_failover:</span> <span class="hljs-number">1048576</span>
        <span class="hljs-attr">postgresql:</span>
            <span class="hljs-attr">use_pg_rewind:</span> <span class="hljs-literal">true</span>

    <span class="hljs-attr">initdb:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">encoding:</span> <span class="hljs-string">UTF8</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">data-checksums</span>

    <span class="hljs-attr">pg_hba:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span><span class="hljs-string">/32</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.12</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.71</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">replication</span> <span class="hljs-string">replicator</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.70</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">host</span> <span class="hljs-string">all</span> <span class="hljs-string">all</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">/0</span> <span class="hljs-string">md5</span>

    <span class="hljs-attr">users:</span>
        <span class="hljs-attr">admin:</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">admin</span>
            <span class="hljs-attr">options:</span>
                <span class="hljs-bullet">-</span> <span class="hljs-string">createrole</span>
                <span class="hljs-bullet">-</span> <span class="hljs-string">createdb</span>

<span class="hljs-attr">postgresql:</span>
    <span class="hljs-attr">listen:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.70</span><span class="hljs-string">:5432</span>
    <span class="hljs-attr">connect_address:</span> <span class="hljs-number">10.3</span><span class="hljs-number">.3</span><span class="hljs-number">.70</span><span class="hljs-string">:5432</span>
    <span class="hljs-attr">data_dir:</span> <span class="hljs-string">/data/patroni</span>
    <span class="hljs-attr">pgpass:</span> <span class="hljs-string">/tmp/pgpass</span>
    <span class="hljs-attr">authentication:</span>
        <span class="hljs-attr">replication:</span>
            <span class="hljs-attr">username:</span> <span class="hljs-string">replicator</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">replogin321</span>
        <span class="hljs-attr">superuser:</span>
            <span class="hljs-attr">username:</span> <span class="hljs-string">postgres</span>
            <span class="hljs-attr">password:</span> <span class="hljs-string">secretlogin321</span>
    <span class="hljs-attr">parameters:</span>
        <span class="hljs-attr">unix_socket_directories:</span> <span class="hljs-string">'.'</span>

<span class="hljs-attr">tags:</span>
    <span class="hljs-attr">nofailover:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">noloadbalance:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">clonefrom:</span> <span class="hljs-literal">false</span>
    <span class="hljs-attr">nosync:</span> <span class="hljs-literal">false</span>
</code></pre>
<p>According to the yml file, the data of PostgreSQL will be stored at /data/patroni. Make sure the ownership of that directory is postgres.</p>
<pre><code class="lang-bash">mkdir -p /data/patroni
chown postgres:postgres /data/patroni
chmod 700 /data/patroni
</code></pre>
<h2 id="heading-create-a-service">Create a Service</h2>
<p>Next, we will create patroni service that allow us to start and stop the service on each server.</p>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/patroni.service
</code></pre>
<p>Add the following parameter in the <code>patroni.service</code></p>
<pre><code class="lang-bash">[Unit]
Description=High availability PostgreSQL Cluster
After=syslog.target network.target
[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/<span class="hljs-built_in">local</span>/bin/patroni /etc/patroni.yml
KillMode=process
TimeoutSec=30
Restart=no

[Install]
WantedBy=multi-user.target
</code></pre>
<h3 id="heading-create-and-enable-patroni-service">Create and Enable Patroni Service</h3>
<p>After the patroni service has been created then we enable it to make it autostart.</p>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl <span class="hljs-built_in">enable</span> patroni
</code></pre>
<h2 id="heading-install-etcd-and-haproxy-on-haetcd-vm">Install Etcd and Haproxy on Haetcd VM</h2>
<p>etcd is a fault-tolerant, a distributed key value store that can be used to store the state of PostgreSQL cluster. With etcd, it will keep the PostgreSQL cluster up and running.</p>
<p>Run the command below to install etcd</p>
<pre><code class="lang-bash">sudo apt -y install etcd
</code></pre>
<p>Next step, we will configure the <code>etcd</code> file. Add the below parameter in the <code>etcd</code> file:</p>
<pre><code class="lang-bash">sudo nano /etc/default/etcd
</code></pre>
<pre><code class="lang-bash">ETCD_LISTEN_PEER_URLS=<span class="hljs-string">"http://10.3.3.166:2380"</span>
ETCD_LISTEN_CLIENT_URLS=<span class="hljs-string">"http://localhost:2379,http://10.3.3.166:2379"</span>
ETCD_INITIAL_ADVERTISE_PEER_URLS=<span class="hljs-string">"http://10.3.3.166:2380"</span>
ETCD_INITIAL_CLUSTER=<span class="hljs-string">"default=http://10.3.3.166:2380"</span>
ETCD_ADVERTISE_CLIENT_URLS=<span class="hljs-string">"http://10.3.3.166:2379"</span>
ETCD_INITIAL_CLUSTER_TOKEN=<span class="hljs-string">"etcd-cluster"</span>
ETCD_INITIAL_CLUSTER_STATE=<span class="hljs-string">"new"</span>
</code></pre>
<p>Restart the <code>etcd</code> service to make a change effect</p>
<pre><code class="lang-bash">sudo systemctl restart etcd
</code></pre>
<h2 id="heading-start-patroni-on-each-pgsql-server">Start Patroni on Each Pgsql Server</h2>
<p>Before we start the patroni service, we need to activate the watchdog support to prevent split-brain on the PostgreSQL</p>
<p><a target="_blank" href="https://patroni.readthedocs.io/en/latest/watchdog.html">https://patroni.readthedocs.io/en/latest/watchdog.html</a></p>
<pre><code class="lang-bash">modprobe softdog
chown postgres /dev/watchdog
</code></pre>
<p>After the watchdog is activated, now we can start the patroni service again on each server.</p>
<pre><code class="lang-bash">systemctl start patroni
systemctl status patroni
</code></pre>
<p>pgsql1 as master. We can see, the pgsql1 will act as the PostgreSQL master</p>
<p>pgsql2 and pgsql3 as slave</p>
<h2 id="heading-install-haproxy">Install Haproxy</h2>
<p>Our last step install HAproxy service to give us an endpoint to which the application can connect to the database.</p>
<pre><code class="lang-bash">sudo add-apt-repository ppa:vbernat/haproxy-2.8
sudo apt -y install haproxy
</code></pre>
<p>Edit the haproxy file configuration as follow</p>
<pre><code class="lang-bash">nano /etc/haproxy/haproxy.cfg
</code></pre>
<pre><code class="lang-bash">global
    maxconn 100

defaults
    <span class="hljs-built_in">log</span> global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    <span class="hljs-built_in">bind</span> *:7000
    stats <span class="hljs-built_in">enable</span>
    stats uri /

listen postgres
    <span class="hljs-built_in">bind</span> *:5000
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server pgsql1 10.3.3.12:5432 maxconn 100 check port 8008
    server pgsql2 10.3.3.71:5432 maxconn 100 check port 8008
    server pgsql3 10.3.3.70:5432 maxconn 100 check port 8008
</code></pre>
<p>Check our haproxy configuration using the following command:</p>
<pre><code class="lang-bash">sudo /usr/sbin/haproxy -c -V -f /etc/haproxy/haproxy.cfg
</code></pre>
<p>If the configuration is valid, we can restart our haproxy service</p>
<pre><code class="lang-bash">sudo systemctl restart haproxy
</code></pre>
<p>In the final step, we can monitor the PostgreSQL cluster using the browser as shown in the screenshot below:</p>
<pre><code class="lang-bash">http://199.180.130.99:7000/
</code></pre>
<p>As we can see, psql1 is the leader of the PostgreSQL cluster with the green line row. Now we will kill patroni service on psql1, to see which VM will be acting as the leader.</p>
<pre><code class="lang-bash">systemctl stop patroni
</code></pre>
<p>After we stop service patroni service in psql1, the psql2 will be elected as the leader node.</p>
<h2 id="heading-test-postgressql-cluster">Test PostgresSQL Cluster</h2>
<p>If we want to make a connection to PostgreSQL, we use the IP Address of HAProxy and port 5000.</p>
<pre><code class="lang-bash">su - postgres
psql -U postgres -h 199.180.130.99 -p 5000
</code></pre>
<p>You now have a high availability PostgreSQL Cluster in Cloud Raya that is ready to use.</p>
<h2 id="heading-src">src</h2>
<p>repo: <a target="_blank" href="https://github.com/andrizan/postgre-cluster">https://github.com/andrizan/postgre-cluster</a></p>
<p><a target="_blank" href="https://cloudraya.com/knowledge-base/set-up-high-availability-postgresql-cluster-using-patroni-on-cloud-raya/">https://cloudraya.com/knowledge-base/set-up-high-availability-postgresql-cluster-using-patroni-on-cloud-raya/</a></p>
]]></content:encoded></item><item><title><![CDATA[Install Nginx, PHP, PostgreSQL for  Laravel/Lumen Ubuntu Server]]></title><description><![CDATA[Install the PostgreSQL Database Server Package

Add the PostgreSQL repository to your server's APT sources.
  $ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'


Import ...]]></description><link>https://blog.andrizan.com/install-nginx-php-postgresql-for-laravellumen-ubuntu-server</link><guid isPermaLink="true">https://blog.andrizan.com/install-nginx-php-postgresql-for-laravellumen-ubuntu-server</guid><category><![CDATA[Laravel]]></category><category><![CDATA[laravel-lumen]]></category><category><![CDATA[ubuntu-server]]></category><category><![CDATA[nginx]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[PHP]]></category><dc:creator><![CDATA[andrizan]]></dc:creator><pubDate>Mon, 14 Aug 2023 09:04:19 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-install-the-postgresql-database-server-package">Install the PostgreSQL Database Server Package</h2>
<ol>
<li><p>Add the PostgreSQL repository to your server's APT sources.</p>
<pre><code class="lang-bash">  $ sudo sh -c <span class="hljs-string">'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" &gt; /etc/apt/sources.list.d/pgdg.list'</span>
</code></pre>
</li>
<li><p>Import the PostgreSQL repository key to your server using the <code>wget</code> utility.</p>
<pre><code class="lang-bash"> $ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/trusted.gpg.d/postgresql.asc &gt; /dev/null
</code></pre>
</li>
<li><p>Update the server packages to synchronize the new PostgreSQL repository.</p>
<pre><code class="lang-bash"> $ sudo apt update
</code></pre>
</li>
<li><p>Install PostgreSQL on your server.</p>
<pre><code class="lang-bash"> $ sudo apt install postgresql-15
</code></pre>
</li>
<li><p>Start the PostgreSQL database server.</p>
<pre><code class="lang-bash"> $ sudo systemctl restart postgresql
</code></pre>
</li>
<li><p>View the PostgreSQL service status and verify that it's active.</p>
<pre><code class="lang-bash"> $ sudo systemctl status postgresql
</code></pre>
<p> Output:</p>
<pre><code class="lang-bash">  ● postgresql.service - PostgreSQL RDBMS
       Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
       Active: active (exited) since Sun 2024-04-21 16:08:10 UTC; 13s ago
      Process: 6756 ExecStart=/bin/<span class="hljs-literal">true</span> (code=exited, status=0/SUCCESS)
     Main PID: 6756 (code=exited, status=0/SUCCESS)
          CPU: 1ms
</code></pre>
</li>
</ol>
<hr />
<h2 id="heading-install-php-fpm">Install PHP-FPM</h2>
<h3 id="heading-all-in-one-code"><strong>ALL IN ONE CODE</strong></h3>
<pre><code class="lang-bash">sudo apt update &amp;&amp; sudo apt upgrade -y
sudo add-apt-repository ppa:ondrej/php <span class="hljs-comment">#private repo</span>
sudo apt update
sudo apt-get install -y php8.2-fpm php8.2-cli php8.2-common php8.2-zip php8.2-gd php8.2-mbstring php8.2-curl php8.2-xml php8.2-bcmath php8.2-pgsql
</code></pre>
<h3 id="heading-1-run-system-updates">1. Run system updates</h3>
<p>The first thing to do in a new system is to update our repositories in order to make them up to date. Run upgrade command also.</p>
<pre><code class="lang-bash">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
<h3 id="heading-2-add-ondrej-sury-ppa-repository">2. Add Ondrej sury PPA repository</h3>
<p>To run PHP 8.2 on Ubuntu 22.04, we need to add Ondrej sury PPA into our system. This is the maintainer of the PHP repository at the moment. This PPA is not currently checked so installing from it will not be guaranteed 100% results.</p>
<p>To add this PPA use the following command on our terminal.</p>
<pre><code class="lang-bash">sudo add-apt-repository ppa:ondrej/php
</code></pre>
<p>After installation is complete we need to update the repositories again for the changes to take effect.</p>
<pre><code class="lang-bash">sudo apt update
</code></pre>
<h3 id="heading-3-install-php-82-on-ubuntu-server">3. Install PHP 8.2 on Ubuntu Server</h3>
<p>We should now be able to install PHP 8.2 on Ubuntu 22.04 Linux machine. The commands to run are as shared below:</p>
<pre><code class="lang-bash">sudo apt install php8.2-fpm -y
</code></pre>
<p>Check for the currently active version of PHP with the following command:</p>
<pre><code class="lang-bash">php --version
</code></pre>
<h3 id="heading-4-install-php-82-extensions">4. Install PHP 8.2 Extensions</h3>
<p>Besides PHP itself, you will likely want to install some additional PHP modules. You can use this command to install additional modules, replacing <code>PACKAGE_NAME</code> with the package you wish to install:</p>
<pre><code class="lang-bash">sudo apt-get install php8.2-PACKAGE_NAME
</code></pre>
<p>You can also install more than one package at a time. Here are a few suggestions of the most common modules you will most likely want to install:</p>
<pre><code class="lang-bash">sudo apt-get install -y php8.2-cli php8.2-common php8.2-zip php8.2-gd php8.2-mbstring php8.2-curl php8.2-xml php8.2-bcmath php8.2-pgsql
</code></pre>
<p>This command will install the following modules:</p>
<ul>
<li><p><code>php8.2-cli</code> – command interpreter, useful for testing PHP scripts from a shell or performing general shell scripting tasks</p>
</li>
<li><p><code>php8.2-common</code> – documentation, examples, and common modules for PHP</p>
</li>
<li><p><code>php8.2-zip</code> – for working with compressed files</p>
</li>
<li><p><code>php8.2-gd</code> – for working with images</p>
</li>
<li><p><code>php8.2-mbstring</code> – used to manage non-ASCII strings</p>
</li>
<li><p><code>php8.2-curl</code> – lets you make HTTP requests in PHP</p>
</li>
<li><p><code>php8.2-xml</code> – for working with XML data</p>
</li>
<li><p><code>php8.2-bcmath</code> – used when working with precision floats</p>
</li>
<li><p><code>php8.2-pgsql</code> – for working with PostgreSQL databases</p>
</li>
</ul>
<hr />
<h2 id="heading-install-composer-ubuntu-server">Install Composer Ubuntu Server</h2>
<pre><code class="lang-bash">sudo apt-get install curl php8.2-cli php8.2-mbstring git unzip
curl –sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/<span class="hljs-built_in">local</span>/bin/composer
composer -V
</code></pre>
<hr />
<h2 id="heading-install-latest-nginx-ubuntu-server">Install Latest Nginx Ubuntu Server</h2>
<h3 id="heading-ubuntu-2204">Ubuntu 22.04</h3>
<p>Install the prerequisites:</p>
<pre><code class="lang-bash">sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
</code></pre>
<p>Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key:</p>
<pre><code class="lang-bash">curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg &gt;/dev/null
</code></pre>
<p>Verify that the downloaded file contains the proper key:</p>
<pre><code class="lang-bash">gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
</code></pre>
<p>The output should contain the full fingerprint <code>573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62</code> as follows:</p>
<pre><code class="lang-bash">pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
      573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid                      nginx signing key &lt;signing-key@nginx.com&gt;
</code></pre>
<p>If the fingerprint is different, remove the file.</p>
<p>To set up the apt repository for stable nginx packages, run the following command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx"</span> \
    | sudo tee /etc/apt/sources.list.d/nginx.list
</code></pre>
<p>If you would like to use mainline nginx packages, run the following command instead:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx"</span> \
    | sudo tee /etc/apt/sources.list.d/nginx.list
</code></pre>
<p>Set up repository pinning to prefer our packages over distribution-provided ones:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> -e <span class="hljs-string">"Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n"</span> \
    | sudo tee /etc/apt/preferences.d/99nginx
</code></pre>
<p>To install nginx, run the following commands:</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install nginx
</code></pre>
<h3 id="heading-debianubuntu-2004-packages">Debian/Ubuntu 20.04 packages</h3>
<p>The available NGINX Ubuntu release support is listed at <a target="_blank" href="https://nginx.org/packages/ubuntu/dists/">this distribution page</a>. For a mapping of Ubuntu versions to release names, please visit the <a target="_blank" href="https://wiki.ubuntu.com/Releases">Official Ubuntu Releases page</a>.</p>
<p>Append the appropriate stanza to <code>/etc/apt/sources.list</code>. If there is concern about persistence of repository additions (i.e. DigitalOcean Droplets), the appropriate stanza may instead be added to a different list file under <code>/etc/apt/sources.list.d/</code>, such as <code>/etc/apt/sources.list.d/nginx.list</code>.</p>
<pre><code class="lang-bash"><span class="hljs-comment">## Replace $release with your corresponding Ubuntu release.</span>
deb https://nginx.org/packages/ubuntu/ <span class="hljs-variable">$release</span> nginx
deb-src https://nginx.org/packages/ubuntu/ <span class="hljs-variable">$release</span> nginx
</code></pre>
<p>e.g. Ubuntu 20.04 (Focal Fossa):</p>
<pre><code class="lang-bash">deb https://nginx.org/packages/ubuntu/ focal nginx
deb-src https://nginx.org/packages/ubuntu/ focal nginx
</code></pre>
<p>To install the packages, execute in your shell:</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install nginx
</code></pre>
<p>If a <code>W: GPG error:</code><a target="_blank" href="https://nginx.org/packages/ubuntu"><code>https://nginx.org/packages/ubuntu</code></a><code>focal InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY $key</code> is encountered during the NGINX repository update, execute the following:</p>
<pre><code class="lang-bash"><span class="hljs-comment">## Replace $key with the corresponding $key from your GPG error.</span>
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys <span class="hljs-variable">$key</span>
sudo apt update
sudo apt install nginx
</code></pre>
<p>You have now nginx installed on your server but not ready to serve web pages. you have to start the nginx. You can do this by using this command:</p>
<pre><code class="lang-bash">sudo systemctl start nginx
</code></pre>
<hr />
<h2 id="heading-server-config-laravel-amp-lumen">Server Config Laravel &amp; Lumen</h2>
<h3 id="heading-path">Path</h3>
<pre><code class="lang-bash">/etc/nginx/conf.d/{name-app}.conf
</code></pre>
<h3 id="heading-laravel">Laravel</h3>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">80</span>;
    <span class="hljs-attribute">listen</span> [::]:<span class="hljs-number">80</span>;
    <span class="hljs-attribute">server_name</span> example.com;
    <span class="hljs-attribute">root</span> /var/www/example.com/public;

    <span class="hljs-attribute">add_header</span> X-Frame-Options <span class="hljs-string">"SAMEORIGIN"</span>;
    <span class="hljs-attribute">add_header</span> X-Content-Type-Options <span class="hljs-string">"nosniff"</span>;

    <span class="hljs-attribute">index</span> index.php;

    <span class="hljs-attribute">charset</span> utf-<span class="hljs-number">8</span>;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> <span class="hljs-variable">$uri</span>/ /index.php?<span class="hljs-variable">$query_string</span>;
    }

    <span class="hljs-attribute">location</span> = /favicon.ico { <span class="hljs-attribute">access_log</span> <span class="hljs-literal">off</span>; <span class="hljs-attribute">log_not_found</span> <span class="hljs-literal">off</span>; }
    <span class="hljs-attribute">location</span> = /robots.txt  { <span class="hljs-attribute">access_log</span> <span class="hljs-literal">off</span>; <span class="hljs-attribute">log_not_found</span> <span class="hljs-literal">off</span>; }

    <span class="hljs-attribute">error_page</span> <span class="hljs-number">404</span> /index.php;

    <span class="hljs-attribute">location</span> <span class="hljs-regexp">~ \.php$</span> {
        <span class="hljs-attribute">fastcgi_pass</span> unix:/var/run/php/php8.2-fpm.sock;
        <span class="hljs-attribute">fastcgi_param</span> SCRIPT_FILENAME <span class="hljs-variable">$realpath_root</span><span class="hljs-variable">$fastcgi_script_name</span>;
        <span class="hljs-attribute">include</span> fastcgi_params;
    }

    <span class="hljs-attribute">location</span> <span class="hljs-regexp">~ /\.(?!well-known).*</span> {
        <span class="hljs-attribute">deny</span> all;
    }

    <span class="hljs-attribute">server_tokens</span> <span class="hljs-literal">off</span>; <span class="hljs-comment"># for production</span>

    <span class="hljs-attribute">access_log</span>  /var/log/nginx/app_access.log;
    <span class="hljs-attribute">error_log</span>  /var/log/nginx/app_error.log <span class="hljs-literal">crit</span>;
}
</code></pre>
<h3 id="heading-lumen">Lumen</h3>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">80</span> default_server;
    <span class="hljs-attribute">listen</span> [::]:<span class="hljs-number">80</span> default_server ipv6only=<span class="hljs-literal">on</span>;

    <span class="hljs-attribute">root</span> /var/www/lumen/public;
    <span class="hljs-attribute">index</span> index.php index.html index.htm;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> <span class="hljs-variable">$uri</span>/ /index.php?<span class="hljs-variable">$query_string</span>;
    }

    <span class="hljs-attribute">location</span> <span class="hljs-regexp">~ \.php$</span> {
        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> /index.php =<span class="hljs-number">404</span>;
        <span class="hljs-attribute">fastcgi_split_path_info</span><span class="hljs-regexp"> ^(.+\.php)(/.+)$</span>;
        <span class="hljs-attribute">fastcgi_pass</span> unix:/var/run/php/php8.2-fpm.sock;
        <span class="hljs-attribute">fastcgi_index</span> index.php;
        <span class="hljs-attribute">fastcgi_param</span> SCRIPT_FILENAME <span class="hljs-variable">$document_root</span><span class="hljs-variable">$fastcgi_script_name</span>;
        <span class="hljs-attribute">include</span> fastcgi_params;
    }

    <span class="hljs-attribute">server_tokens</span> <span class="hljs-literal">off</span>; <span class="hljs-comment"># for production</span>

    <span class="hljs-attribute">access_log</span>  /var/log/nginx/app_access.log;
    <span class="hljs-attribute">error_log</span>  /var/log/nginx/app_error.log <span class="hljs-literal">crit</span>;
}
</code></pre>
<hr />
<h3 id="heading-set-permission">Set Permission</h3>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /var/www/
sudo chown -R www-data:www-data &lt;DIR&gt;
sudo chmod -R g+w &lt;DIR&gt;
</code></pre>
<p>set user nginx</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/nginx.conf
</code></pre>
<p>Before</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">user</span>  nginx;
<span class="hljs-attribute">worker_processes</span>  auto;

<span class="hljs-attribute">error_log</span>  /var/log/nginx/error.log <span class="hljs-literal">notice</span>;
<span class="hljs-attribute">pid</span>        /var/run/nginx.pid;
...
</code></pre>
<p>After</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">user</span>  www-data;
<span class="hljs-attribute">worker_processes</span>  auto;

<span class="hljs-attribute">error_log</span>  /var/log/nginx/error.log <span class="hljs-literal">notice</span>;
<span class="hljs-attribute">pid</span>        /var/run/nginx.pid;
...
</code></pre>
<p>restart <code>nginx</code> and <code>php-fpm</code></p>
<pre><code class="lang-bash">sudo systemctl restart nginx
sudo systemctl restart php8.2-fpm
</code></pre>
<h2 id="heading-install-certbot-lets-encrypt-client">Install Certbot (Let’s Encrypt Client)</h2>
<ol>
<li>Install Certbot using the following command.</li>
</ol>
<pre><code class="lang-bash">sudo apt install certbot python3-certbot-nginx
</code></pre>
<ol start="2">
<li>Run Certbot to obtain and install the SSL certificate for your domain. Replace <code>your_domain</code> with your actual domain name.</li>
</ol>
<pre><code class="lang-bash">sudo certbot --nginx -d your_domain
</code></pre>
<ol start="3">
<li>Verify Certificate Renewal (Optional)</li>
</ol>
<pre><code class="lang-bash">sudo certbot renew --dry-run
</code></pre>
<p>src:</p>
<ul>
<li><p><a target="_blank" href="https://www.nginx.com/resources/wiki/start/topics/tutorials/install/">https://www.nginx.com/resources/wiki/start/topics/tutorials/install/</a></p>
</li>
<li><p><a target="_blank" href="https://josuamarcelc.com/install-php-8-2-on-ubuntu-with-nginx/">https://josuamarcelc.com/install-php-8-2-on-ubuntu-with-nginx/</a></p>
</li>
<li><p><a target="_blank" href="https://docs.vultr.com/how-to-install-postgresql-database-server-on-ubuntu-22-04">https://docs.vultr.com/how-to-install-postgresql-database-server-on-ubuntu-22-04</a></p>
</li>
<li><p><a target="_blank" href="https://www.kamatera.com/knowledgebase/how-to-secure-nginx-with-lets-encrypt/">https://www.kamatera.com/knowledgebase/how-to-secure-nginx-with-lets-encrypt/</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>