<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hisyam Johan</title>
    <description>The latest articles on DEV Community by Hisyam Johan (@nhisyamj).</description>
    <link>https://dev.to/nhisyamj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F779297%2F521f7b2b-5b63-4da0-aab9-d34da4cdd9f3.jpeg</url>
      <title>DEV Community: Hisyam Johan</title>
      <link>https://dev.to/nhisyamj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nhisyamj"/>
    <language>en</language>
    <item>
      <title>Fixing a GitLab CE Upgrade Error: FinalizeHkFixNonExistingTimelogUsers and undefined method 'id' for nil:NilClass</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Tue, 27 Jan 2026 04:48:23 +0000</pubDate>
      <link>https://dev.to/nhisyamj/fixing-a-gitlab-ce-upgrade-error-finalizehkfixnonexistingtimelogusers-and-undefined-method-id-476l</link>
      <guid>https://dev.to/nhisyamj/fixing-a-gitlab-ce-upgrade-error-finalizehkfixnonexistingtimelogusers-and-undefined-method-id-476l</guid>
      <description>&lt;p&gt;When upgrading my GitLab CE instance to 18.5.1, the upgrade repeatedly failed during database migrations with this Ruby error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;undefined method `id' for nil:NilClass
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/background_migration/fix_non_existing_timelog_users.rb:12:in `perform'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The failure happened inside a batched background migration finalize step called &lt;code&gt;FinalizeHkFixNonExistingTimelogUsers&lt;/code&gt;. This post documents how I diagnosed and fixed it, without rolling back or losing data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Environment and Symptoms
&lt;/h2&gt;

&lt;p&gt;The environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 24.04
&lt;/li&gt;
&lt;li&gt;GitLab CE 18.5.1 (&lt;code&gt;/opt/gitlab/embedded/service/gitlab-rails&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;PostgreSQL 16.10 as the main DB (&lt;code&gt;gitlabhq_production&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gitlab-rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I saw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main: == 20250916232115 FinalizeHkFixNonExistingTimelogUsers: migrating
...
undefined method `id' for nil:NilClass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The stack trace pointed to &lt;code&gt;Gitlab::BackgroundMigration::FixNonExistingTimelogUsers&lt;/code&gt;, executed from the finalize migration &lt;code&gt;20250916232115_finalize_hk_fix_non_existing_timelog_users.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gitlab-ctl reconfigure&lt;/code&gt; also failed because it runs database migrations as part of the omnibus setup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Inspect background migrations
&lt;/h2&gt;

&lt;p&gt;GitLab provides a Rake task to list batched background migrations and their status. I started there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gitlab-rake gitlab:background_migrations:status &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;FixNonExistingTimelogUsers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This printed a long list of migrations with states like &lt;code&gt;finished&lt;/code&gt;, &lt;code&gt;finalized&lt;/code&gt;, and a few &lt;code&gt;active&lt;/code&gt;. The row for &lt;code&gt;FixNonExistingTimelogUsers&lt;/code&gt; showed &lt;code&gt;status = 5&lt;/code&gt; in the database, which corresponds to &lt;strong&gt;finalized&lt;/strong&gt; in GitLab’s internal enum.&lt;/p&gt;

&lt;p&gt;However, the finalize migration was still trying to &lt;strong&gt;run a job&lt;/strong&gt; for that background migration, and that job crashed when it encountered a &lt;code&gt;timelog&lt;/code&gt; whose associated record was &lt;code&gt;nil&lt;/code&gt; (hence &lt;code&gt;.id&lt;/code&gt; on &lt;code&gt;nil&lt;/code&gt;). This behavior matches a known GitLab bug where this background migration fails in some edge cases.&lt;/p&gt;

&lt;p&gt;At this point I knew:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The background migration itself was already marked as finalized.&lt;/li&gt;
&lt;li&gt;The failing piece was the &lt;strong&gt;post‑migration finalize step&lt;/strong&gt; (&lt;code&gt;FinalizeHkFixNonExistingTimelogUsers&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2: Try the official helper (and why it didn’t work)
&lt;/h2&gt;

&lt;p&gt;GitLab’s docs recommend using helper Rake tasks to manage batched migrations, such as marking jobs as succeeded or requeuing them.&lt;/p&gt;

&lt;p&gt;I tried:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gitlab-rake gitlab:background_migrations:mark_all_jobs_as_succeeded &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;FixNonExistingTimelogUsers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this failed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Don't know how to build task 'gitlab:background_migrations:mark_all_jobs_as_succeeded'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On this version/packaging of GitLab CE, that helper task simply doesn’t exist, so I couldn’t use the documented way to skip the broken migration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Inspect &lt;code&gt;batched_background_migrations&lt;/code&gt; directly
&lt;/h2&gt;

&lt;p&gt;Since the helper didn’t exist, the next step was to look directly at the &lt;code&gt;batched_background_migrations&lt;/code&gt; table in PostgreSQL.&lt;/p&gt;

&lt;p&gt;Connect to the DB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gitlab-psql &lt;span class="nt"&gt;-d&lt;/span&gt; gitlabhq_production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;job_class_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;batched_background_migrations&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;job_class_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'FixNonExistingTimelogUsers'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; id  |       job_class_name       | status
-----+----------------------------+--------
 548 | FixNonExistingTimelogUsers |      5
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to GitLab’s enum mapping, &lt;code&gt;status = 5&lt;/code&gt; means &lt;strong&gt;finalized&lt;/strong&gt;, which confirmed the background migration was already considered done.&lt;/p&gt;

&lt;p&gt;Initially I tried to set &lt;code&gt;status = 'finished'&lt;/code&gt;, but that failed because &lt;code&gt;status&lt;/code&gt; is a numeric (smallint) column, not a string. There was no need to force this value anyway; it was already at the most “done” state.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Identify the real culprit – the finalize migration
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;db:migrate&lt;/code&gt; kept trying to run this migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;== 20250916232115 FinalizeHkFixNonExistingTimelogUsers: migrating
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The traceback showed it calling &lt;code&gt;ensure_batched_background_migration_is_finished&lt;/code&gt;, which in turn tried to run another batch job for &lt;code&gt;FixNonExistingTimelogUsers&lt;/code&gt;, even though its status was already finalized. That job raised &lt;code&gt;undefined method 'id' for nil:NilClass&lt;/code&gt;, and the whole migration aborted.&lt;/p&gt;

&lt;p&gt;So the root cause was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A post‑migration (&lt;code&gt;FinalizeHkFixNonExistingTimelogUsers&lt;/code&gt;) that was &lt;strong&gt;incorrectly trying to execute a finalized background migration&lt;/strong&gt; and hitting a data edge case.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitLab has documented similar situations where a buggy batched migration requires a follow‑up fix or manual intervention.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Mark the finalize migration as applied in &lt;code&gt;schema_migrations&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;On my GitLab version, &lt;code&gt;schema_migrations&lt;/code&gt; only has a &lt;code&gt;version&lt;/code&gt; column (no &lt;code&gt;dirty&lt;/code&gt; flag), so the simplest fix was to tell Rails, “this finalize migration is already applied.”&lt;/p&gt;

&lt;p&gt;Again in &lt;code&gt;psql&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gitlab-psql &lt;span class="nt"&gt;-d&lt;/span&gt; gitlabhq_production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if the version exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;version&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;schema_migrations&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'20250916232115'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the query returns no rows, insert it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;schema_migrations&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'20250916232115'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;CONFLICT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DO&lt;/span&gt; &lt;span class="k"&gt;NOTHING&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then exit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This explicitly marks &lt;code&gt;20250916232115 FinalizeHkFixNonExistingTimelogUsers&lt;/code&gt; as already applied, so &lt;code&gt;db:migrate&lt;/code&gt; will skip it entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Rerun migrations and reconfigure
&lt;/h2&gt;

&lt;p&gt;After inserting that row, I reran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gitlab-rake db:migrate
&lt;span class="nb"&gt;sudo &lt;/span&gt;gitlab-ctl reconfigure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;db:migrate&lt;/code&gt; &lt;strong&gt;did not&lt;/strong&gt; print &lt;code&gt;== 20250916232115 FinalizeHkFixNonExistingTimelogUsers: migrating&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;undefined method 'id' for nil:NilClass&lt;/code&gt; error disappeared.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gitlab-ctl reconfigure&lt;/code&gt; completed successfully, and GitLab came up cleanly on 18.5.1.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;p&gt;A few takeaways from this troubleshooting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batched background migrations can block upgrades.&lt;/strong&gt; When a finalize post‑migration insists on finishing a batched job that has a bug, you can be stuck even if the underlying migration is already marked as finalized.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitLab’s helper Rake tasks differ by version.&lt;/strong&gt; On some installations, &lt;code&gt;gitlab:background_migrations:mark_all_jobs_as_succeeded&lt;/code&gt; and similar helpers may not exist, and you must operate directly at the DB layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;schema_migrations&lt;/code&gt; is the source of truth for Rails migrations.&lt;/strong&gt; If a finalize migration is purely orchestration around an already‑finalized batched job, marking that migration version as applied is a safe and effective way to unblock the upgrade, especially when there’s an upstream bug acknowledged in issues/MRs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you hit the same &lt;code&gt;FinalizeHkFixNonExistingTimelogUsers&lt;/code&gt; error on GitLab CE 18.x and see &lt;code&gt;FixNonExistingTimelogUsers&lt;/code&gt; already finalized in &lt;code&gt;batched_background_migrations&lt;/code&gt;, inserting the migration version into &lt;code&gt;schema_migrations&lt;/code&gt; as shown above should let you move forward while you watch for the official upstream fix.&lt;/p&gt;

</description>
      <category>database</category>
      <category>devops</category>
      <category>ruby</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Cloudflare Deep dive into 2025 Internet trends session highlights</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Thu, 22 Jan 2026 01:31:50 +0000</pubDate>
      <link>https://dev.to/nhisyamj/cloudflare-deep-dive-into-2025-internet-trends-session-highlights-nm1</link>
      <guid>https://dev.to/nhisyamj/cloudflare-deep-dive-into-2025-internet-trends-session-highlights-nm1</guid>
      <description>&lt;p&gt;Yesterday I was joining a session organised by Cloudflare. These are the input that may benefit all of us.&lt;/p&gt;

&lt;p&gt;This session highlights steady global traffic growth, rising attack intensity, and accelerating adoption of new encryption and AI-related behaviors across the Internet.&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;Overall Internet growth and popular services&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Global Internet traffic grew by just under 20% in 2025, following a familiar pattern of modest growth early in the year, then stronger increases from May and especially from late August onward.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The ranking of most-used Internet services remains very stable: Google leads, followed by Facebook, with Apple and Microsoft next, then major social platforms like Instagram, YouTube, TikTok, and services like AWS, Amazon, and WhatsApp in the top 10.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new generative AI category shows OpenAI/ChatGPT at the top, followed by Claude, Google Gemini, Grok, and others; these AI services are growing quickly but still sit below the very largest “traditional” platforms in overall usage.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Category trends: crypto, finance, and bots&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cryptocurrency remains heavily used but relatively less volatile at the top; exchanges such as Binance, OKX, and Coinbase continue to dominate, alongside information and tracking sites.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In financial services, Stripe ranks first, with strong representation from Asia-Pacific (for example Alipay) and Brazilian players like Nubank and Banco do Brasil, plus wallets such as Google Pay and some crypto payment platforms.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Around 40% of global bot traffic originates from the United States, with other major sources including Germany, Singapore, the Netherlands, Ireland, and China, closely matching where large cloud regions are located.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Major cloud providers’ networks (Amazon, Microsoft, Google and others) generate much of this traffic; Cloudflare stresses that a significant portion are “good” or verified bots such as search crawlers, performance monitors, and rendering systems, not just malicious automation.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security: DDoS, email attacks, and AI crawlers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DDoS attacks increased sharply in 2025, with peak attack size growing in “steps” over the year and culminating in a record of about 31 terabits per second after earlier peaks near 29.7 Tbps.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Speakers express concern that, as more insecure IoT and consumer devices (e.g., cameras, Android TV boxes, “smart” appliances) and even corporate devices are connected, attackers can build ever-larger botnets, potentially pushing future peaks even higher (they discuss the possibility of 60 Tbps raids).&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloudflare’s email security data shows over half (around 52%) of malicious emails containing deceptive links that visually imitate trusted destinations but redirect to phishing or malware sites.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other leading email threats are identity deception and brand impersonation, where attackers pretend to be a known individual or brand (for example, gift-card scams or fake vendor notices), exploiting user trust and psychological pressure rather than purely technical weaknesses.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI-related crawlers are now a visible share of web traffic; Googlebot (used both for search indexing and AI training) accounts for far more traffic than other AI crawlers, while OpenAI uses distinct bots (GPTBot for training, ChatGPT-User for live requests, OAI-Search for retrieval) that can be differentiated by purpose.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Encryption and post-quantum readiness&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cloudflare has been working on post-quantum (PQ) encryption since around 2017, motivated by the “harvest now, decrypt later” risk that future quantum computers could break today’s TLS and expose long-retained encrypted traffic.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post-quantum–protected traffic roughly doubled in 2025: it began near 27%, plateaued midyear, then jumped sharply when Apple enabled PQ support by default in its 2026 OS and Safari releases, pushing support from the high 30s to over 50% and then to above 60% of observed traffic.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adoption is driven mostly by modern browsers, OS updates, and infrastructure platforms; older Android devices, older browsers, and embedded/IoT devices (like appliances) often cannot be upgraded and thus lag behind, leaving a substantial fraction of traffic non–post-quantum-safe.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Speakers expect 2026 to bring more concrete PQ deployments rather than just discussion, with particular emphasis on sectors holding sensitive data such as finance, healthcare, and government, while noting that not every low-risk device or dataset needs equal protection.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Geography, sectors, and future outlook&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Country-level views show that even highly connected places can still experience very strong usage growth; for example, Singapore’s Internet traffic grew by roughly 50% year over year, with notable changes around June linked to local events such as elections and holiday behavior.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vertical/industry analysis of Layer 7 attack traffic shows that “People and Society” organizations (including many protected under Cloudflare’s Project Galileo) are heavily targeted globally, alongside sectors like gambling, gaming, computers and electronics, and education in specific countries.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Starlink-related traffic tracked by Cloudflare has roughly doubled over the last year and is appearing in more countries, reflecting the rise of satellite connectivity.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Looking ahead, the speakers anticipate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Continued growth in DDoS attack size and frequency, fueled by insecure devices and faster consumer connections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Much broader post-quantum readiness as more OS/browser vendors and infrastructure providers ship PQ by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rapid shifts in generative AI usage and AI-crawler behavior, with a mindset change from “all bots are bad” to assessing the purpose and impact of each bot in a machine-to-machine Internet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cloudflare</category>
    </item>
    <item>
      <title>🛠 Fixing “runsv not running” Error in GitLab CE</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Mon, 10 Nov 2025 01:30:32 +0000</pubDate>
      <link>https://dev.to/nhisyamj/fixing-runsv-not-running-error-in-gitlab-ce-1cn</link>
      <guid>https://dev.to/nhisyamj/fixing-runsv-not-running-error-in-gitlab-ce-1cn</guid>
      <description>&lt;p&gt;If you encounter this error while managing your GitLab instance:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gitlab-ce fail: postgresql: runsv not running&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;it means GitLab’s service supervision system (runit) isn’t running properly.&lt;br&gt;
When runsv or runsvdir stops, GitLab’s internal services — including PostgreSQL, Redis, Sidekiq, and Unicorn/Puma — all fail to start.&lt;/p&gt;

&lt;p&gt;🔍 Symptom&lt;/p&gt;

&lt;p&gt;You may see one or more of these errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;down: postgresql: runsv not running
down: redis: runsv not running
down: unicorn: runsv not running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;gitlab-ctl reconfigure&lt;/code&gt; might fail with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ActiveRecord::DatabaseConnectionError:
PG::ConnectionBad: connection to server failed: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 Root Cause&lt;/p&gt;

&lt;p&gt;GitLab uses runit (managed by &lt;code&gt;gitlab-runsvdir&lt;/code&gt;) to supervise all internal services.&lt;br&gt;
If the &lt;code&gt;gitlab-runsvdir&lt;/code&gt; process isn’t active, no service daemons (&lt;code&gt;runsv&lt;/code&gt;) are started — even if you manually run &lt;code&gt;gitlab-ctl start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This can happen after:&lt;/p&gt;

&lt;p&gt;A reboot where &lt;code&gt;gitlab-runsvdir&lt;/code&gt; wasn’t auto-enabled.&lt;/p&gt;

&lt;p&gt;Manual termination of the &lt;code&gt;runsvdir&lt;/code&gt; process.&lt;/p&gt;

&lt;p&gt;A system update or service interruption.&lt;/p&gt;

&lt;p&gt;✅ Quick Fix&lt;/p&gt;

&lt;p&gt;Start the GitLab runit service manually:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl start gitlab-runsvdir&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then verify:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gitlab-ctl status&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should now see all GitLab services in run: state, e.g.:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;run: postgresql: (pid 3214) 10s; run: log: (pid 1234) 100s&lt;/code&gt;&lt;/p&gt;

</description>
      <category>gitlab</category>
    </item>
    <item>
      <title>Installing Java and Maven with SDKMAN on Linux</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Tue, 09 Sep 2025 01:59:13 +0000</pubDate>
      <link>https://dev.to/nhisyamj/installing-java-and-maven-with-sdkman-on-linux-4mkm</link>
      <guid>https://dev.to/nhisyamj/installing-java-and-maven-with-sdkman-on-linux-4mkm</guid>
      <description>&lt;p&gt;When working with Java projects, you’ll often need to install and manage multiple versions of Java and build tools like Maven. Instead of manually downloading tarballs and updating environment variables, SDKMAN!&lt;br&gt;
 provides an easy way to install, manage, and switch between different versions of development kits on Linux and macOS.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through installing Java and Maven using SDKMAN on a Linux machine.&lt;/p&gt;



&lt;p&gt;What is SDKMAN?&lt;/p&gt;

&lt;p&gt;SDKMAN (Software Development Kit Manager) is a tool for managing parallel versions of multiple software development kits. It supports Java, Maven, Gradle, Kotlin, Scala, and more.&lt;/p&gt;

&lt;p&gt;Some of the benefits of using SDKMAN:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install and switch between multiple versions easily.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No need to manually configure environment variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consistent setup across development environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1: Install SDKMAN
&lt;/h2&gt;

&lt;p&gt;Open your terminal and run the following command to install SDKMAN:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -s "https://get.sdkman.io" | bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once the installation completes, initialize it by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;source "$HOME/.sdkman/bin/sdkman-init.sh"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To verify the installation, check the version:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sdk version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If it prints out a version number, SDKMAN is ready to use.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 2: Install Java
&lt;/h2&gt;

&lt;p&gt;SDKMAN supports different Java distributions (AdoptOpenJDK, Temurin, Amazon Corretto, Zulu, etc.).&lt;/p&gt;

&lt;p&gt;List available Java versions:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sdk list java&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pick the one you want to install. For example, to install Temurin JDK 21 (LTS):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sdk install java 21-tem&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To set a default version:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sdk default java 21-tem&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Verify the installation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;java -version&lt;/code&gt;&lt;/p&gt;



&lt;p&gt;Step 3: Install Maven&lt;/p&gt;

&lt;p&gt;Next, install Maven with SDKMAN:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sdk install maven&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To check available versions:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sdk list maven&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To set a specific version:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sdk install maven 3.9.9&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sdk default maven 3.9.9&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Verify Maven installation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mvn -version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Step 4: Managing Versions&lt;/p&gt;

&lt;p&gt;One of the best parts of SDKMAN is version switching.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sdk install java 17-tem
sdk use java 17-tem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can quickly switch between Java 17 and Java 21 without touching environment variables.&lt;/p&gt;

&lt;p&gt;Similarly, you can do the same for Maven or other tools.&lt;/p&gt;




&lt;p&gt;Conclusion&lt;/p&gt;

&lt;p&gt;Using SDKMAN makes it simple to manage Java, Maven, and many other SDKs on Linux. No more messing around with PATH variables or manual installations. With just a few commands, you can install, switch, and maintain multiple versions of your tools.&lt;/p&gt;

&lt;p&gt;If you’re working on multiple Java projects with different requirements, SDKMAN is a must-have for your development environment.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Extend Block Volume on OCI Instance</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Mon, 08 Sep 2025 02:58:44 +0000</pubDate>
      <link>https://dev.to/nhisyamj/extend-block-volume-on-oci-instance-ngb</link>
      <guid>https://dev.to/nhisyamj/extend-block-volume-on-oci-instance-ngb</guid>
      <description>&lt;h2&gt;
  
  
  How to Extend Boot Volume Storage in Oracle Cloud (OCI) Instance with LVM
&lt;/h2&gt;

&lt;p&gt;When you increase the &lt;strong&gt;boot volume size&lt;/strong&gt; of an OCI instance from the console, the new space is added to the disk, but your OS won’t automatically use it. You need to manually extend the partition, LVM physical volume, and filesystem.&lt;/p&gt;

&lt;p&gt;This guide walks you through the steps.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Extend the Boot Volume in OCI Console
&lt;/h2&gt;

&lt;p&gt;First, go to your &lt;strong&gt;OCI Instance → Boot Volume → Edit → Resize&lt;/strong&gt; and set the desirable new size (e.g., from &lt;strong&gt;50GB → 100GB&lt;/strong&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Discover the New Volume Size
&lt;/h2&gt;

&lt;p&gt;Run the &lt;code&gt;lsblk&lt;/code&gt; command to verify the new size:&lt;/p&gt;

&lt;p&gt;lsblk&lt;/p&gt;

&lt;p&gt;Example output after resize:&lt;/p&gt;

&lt;p&gt;NAME               MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT&lt;br&gt;
sda                  8:0    0  100G  0 disk &lt;br&gt;
├─sda1               8:1    0  100M  0 part /boot/efi&lt;br&gt;
├─sda2               8:2    0    1G  0 part /boot&lt;br&gt;
└─sda3               8:3    0 45.5G  0 part &lt;br&gt;
  ├─ocivolume-root 252:0    0 35.5G  0 lvm  /&lt;br&gt;
  └─ocivolume-oled 252:1    0   10G  0 lvm  /var/oled&lt;/p&gt;

&lt;p&gt;Here:&lt;/p&gt;

&lt;p&gt;Disk sda = 100G (boot volume)&lt;/p&gt;

&lt;p&gt;Partition sda3 = 45.5G&lt;/p&gt;

&lt;p&gt;Inside sda3 → LVM (ocivolume-root mounted at /, ocivolume-oled at /var/oled)&lt;/p&gt;

&lt;p&gt;At this point, the disk grew but the partition didn’t.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Grow Partition sda3
&lt;/h2&gt;

&lt;p&gt;Install growpart utility:&lt;/p&gt;

&lt;p&gt;sudo dnf install -y cloud-utils-growpart&lt;/p&gt;

&lt;p&gt;Grow the partition:&lt;/p&gt;

&lt;p&gt;sudo growpart /dev/sda 3&lt;/p&gt;

&lt;p&gt;Verify with:&lt;/p&gt;

&lt;p&gt;lsblk&lt;/p&gt;

&lt;p&gt;Now sda3 should show around 99G.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Grow the LVM Physical Volume
&lt;/h2&gt;

&lt;p&gt;sudo pvresize /dev/sda3&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;p&gt;sudo pvs&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Extend the Logical Volume
&lt;/h2&gt;

&lt;p&gt;Currently / = ocivolume-root = 35.5G.&lt;br&gt;
To extend it and use all available free space:&lt;/p&gt;

&lt;p&gt;sudo lvextend -l +100%FREE /dev/ocivolume/root&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Grow the Filesystem
&lt;/h2&gt;

&lt;p&gt;If using XFS (default for Oracle Linux 8):&lt;/p&gt;

&lt;p&gt;sudo xfs_growfs /&lt;/p&gt;

&lt;p&gt;If using ext4, run instead:&lt;/p&gt;

&lt;p&gt;sudo resize2fs /dev/ocivolume/root&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Verify the New Size
&lt;/h2&gt;

&lt;p&gt;df -h&lt;/p&gt;

&lt;p&gt;Your / should now be close to 90G, depending on how much space you allocated.&lt;/p&gt;

</description>
      <category>ol8</category>
    </item>
    <item>
      <title>Troubleshooting Umami Analytics: Resolving Unknown User Country Issue with Proxy Protocol on OCI</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Mon, 23 Sep 2024 06:50:54 +0000</pubDate>
      <link>https://dev.to/nhisyamj/troubleshooting-umami-analytics-resolving-unknown-user-country-issue-with-proxy-protocol-on-oci-3gke</link>
      <guid>https://dev.to/nhisyamj/troubleshooting-umami-analytics-resolving-unknown-user-country-issue-with-proxy-protocol-on-oci-3gke</guid>
      <description>&lt;p&gt;While using Umami for analytics, I recently encountered an issue where the user country information appeared as "Unknown." After some investigation, I discovered that the problem was related to the proxy protocol not being enabled on the Oracle Cloud Infrastructure (OCI) load balancer. Here's a detailed walkthrough of the solution.&lt;/p&gt;

&lt;p&gt;The Issue&lt;br&gt;
The primary cause of the "Unknown" country error stemmed from the fact that the user’s IP address wasn't correctly forwarded to the Umami server. When using a load balancer (such as OCI’s) in front of your application, it often proxies the request. Without the proxy protocol enabled, the originating IP address is lost, resulting in missing location data in Umami.&lt;/p&gt;

&lt;p&gt;The Solution&lt;br&gt;
To resolve this issue, follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Enable Proxy Protocol in OCI Load Balancer&lt;/strong&gt;&lt;br&gt;
In OCI, the proxy protocol is disabled by default. You need to enable it to ensure that the original client IP is passed to your backend (Nginx in this case). Here’s how you do it:&lt;/p&gt;

&lt;p&gt;Navigate to your OCI Load Balancer configuration.&lt;br&gt;
Under the load balancer listener settings, enable the Proxy Protocol.&lt;br&gt;
Once enabled, OCI will forward the original client IP along with the request to your Nginx ingress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Update Nginx Ingress Controller (For Kubernetes)&lt;/strong&gt;&lt;br&gt;
If you are using Nginx Ingress Controller in a Kubernetes cluster, you’ll need to update its configuration to handle the proxy protocol. This is done by modifying the Ingress Controller ConfigMap.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Locate the Nginx Ingress controller ConfigMap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following line to the data section:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data:
  use-proxy-protocol: "true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;After updating the ConfigMap, restart the Nginx Ingress controller deployment for the changes to take effect:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl rollout restart deployment &amp;lt;nginx-ingress-controller-deployment&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Update Nginx Configuration (For Standalone Nginx)&lt;/strong&gt;&lt;br&gt;
If you are using standalone Nginx (not in a Kubernetes cluster), you need to update the Nginx configuration directly to handle the proxy protocol.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open your Nginx configuration file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the &lt;code&gt;server&lt;/code&gt; block to include the &lt;code&gt;proxy_protocol&lt;/code&gt; directive, like so:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http {
    # Other settings...
    server {
        listen 80   proxy_protocol;
        listen 443  ssl proxy_protocol;
        # Other settings...
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;After updating the configuration, restart Nginx to apply the changes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think this implementation also applied to other analytic server.&lt;/p&gt;

</description>
      <category>oci</category>
      <category>loadbalancer</category>
    </item>
    <item>
      <title>Installing Apache, PHP, and MySQL on Oracle Linux 8</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Thu, 08 Aug 2024 13:31:56 +0000</pubDate>
      <link>https://dev.to/nhisyamj/installing-apache-php-and-mysql-on-oracle-linux-8-3j7m</link>
      <guid>https://dev.to/nhisyamj/installing-apache-php-and-mysql-on-oracle-linux-8-3j7m</guid>
      <description>&lt;p&gt;Bismillah...&lt;/p&gt;

&lt;h3&gt;
  
  
  Instructions to Install Apache, PHP, and MySQL on Oracle Linux 8
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Apache Web Server&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Installs the Apache HTTP server.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Enable and Start Apache&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;httpd
   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enables Apache to start on boot and restarts it to apply changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure Firewall&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--add-service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http &lt;span class="nt"&gt;--permanent&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Opens HTTP (port 80) on the firewall and reloads the firewall to apply the rule.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install PHP&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   dnf module list php
   &lt;span class="nb"&gt;sudo &lt;/span&gt;dnf module reset php
   &lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install&lt;/span&gt; @php:7.4
   &lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;php-mysqli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Lists available PHP modules, resets the PHP module, and installs PHP 7.4 with MySQL support.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Allow Apache to Connect to External Databases (optional)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   setsebool &lt;span class="nt"&gt;-P&lt;/span&gt; httpd_can_network_connect_db 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configures SELinux to allow Apache to connect to databases over the network.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set Permissions for Apache&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; apache:apache &lt;span class="k"&gt;*&lt;/span&gt;
   &lt;span class="c"&gt;# if you have folder to store uploaded file (optional)&lt;/span&gt;
   &lt;span class="nb"&gt;sudo chcon&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; httpd_sys_rw_content_t docsuploaded
   find /var/www/html &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;chmod &lt;/span&gt;755 &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
   find /var/www/html &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;chmod &lt;/span&gt;644 &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
   systemctl restart httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Changes ownership of files to Apache, sets security context for directories, adjusts file permissions, and restarts Apache.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install MySQL Server&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   yum &lt;span class="nb"&gt;install &lt;/span&gt;https://dev.mysql.com/get/mysql84-community-release-el8-1.noarch.rpm
   yum-config-manager &lt;span class="nt"&gt;--disable&lt;/span&gt; mysql-8.4-lts-community
   yum-config-manager &lt;span class="nt"&gt;--disable&lt;/span&gt; mysql-tools-8.4-lts-community
   yum-config-manager &lt;span class="nt"&gt;--enable&lt;/span&gt; mysql80-community
   yum-config-manager &lt;span class="nt"&gt;--enable&lt;/span&gt; mysql-tools-community
   yum repolist enabled | &lt;span class="nb"&gt;grep &lt;/span&gt;mysql
   &lt;span class="nb"&gt;sudo &lt;/span&gt;yum module disable mysql
   yum &lt;span class="nb"&gt;install &lt;/span&gt;mysql-community-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Installs MySQL Community Edition, disables unnecessary repositories, and installs the MySQL server.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start MySQL and Check Status&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   systemctl start mysqld
   systemctl status mysqld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Starts the MySQL server and checks its status.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Retrieve MySQL Temporary Root Password&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo grep&lt;/span&gt; &lt;span class="s1"&gt;'temporary password'&lt;/span&gt; /var/log/mysqld.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Fetches the temporary root password for MySQL from the log file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://buymeacoffee.com/nhisyamj" rel="noopener noreferrer"&gt;Buy Me A Coffee&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ol8</category>
      <category>apache</category>
      <category>php</category>
      <category>mysql</category>
    </item>
    <item>
      <title>Running Oracle 21c on Docker and Restoring a Backup</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Fri, 28 Jun 2024 02:57:05 +0000</pubDate>
      <link>https://dev.to/nhisyamj/run-oracle-21-on-docker-and-restore-backup-2bjl</link>
      <guid>https://dev.to/nhisyamj/run-oracle-21-on-docker-and-restore-backup-2bjl</guid>
      <description>&lt;p&gt;Bismillah...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this guide, we will cover how to run Oracle 21c on Docker and restore a backup from a dump file. This includes building a Docker image, running it as a container, and executing a backup restoration script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure you have Docker installed on your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Building the Docker Image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the following files:&lt;/p&gt;

&lt;p&gt;Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM gvenzl/oracle-xe:21
# If you have a backup file
COPY start.sh /opt/oracle/start.sh
COPY data.sql /container-entrypoint-initdb.d/data.sql
RUN mkdir -p /opt/oracle/dbbackupdmp
COPY mydb.dmp /opt/oracle/dbbackupdmp/mydb.dmp
USER root
RUN chown oracle:oinstall /opt/oracle/dbbackupdmp/mydb.dmp
USER oracle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;data.sql:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create user &amp;lt;user.name&amp;gt; IDENTIFIED BY &amp;lt;user.password&amp;gt;;
grant connect,resource,dba to &amp;lt;user.name&amp;gt;;
grant create session, grant any privilege to &amp;lt;user.name&amp;gt;;
grant unlimited tablespace to &amp;lt;user.name&amp;gt;;

create directory datapump as '/opt/oracle/dbbackupdmp';
grant read, write on directory datapump to &amp;lt;user.name&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;start.sh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impdp &amp;lt;user.name&amp;gt;/&amp;lt;user.password&amp;gt; directory=datapump dumpfile=mydb.dmp logfile=mydb.log schemas=&amp;lt;user.1&amp;gt;,&amp;lt;user.2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build the Docker image using:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t my/oracle:21 .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Running the Docker Container&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the image as a Docker container:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -d -p 1521:1521 -e ORACLE_PASSWORD=P@ssw0rd  --name=myoracle21 my/oracle:21&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Restoring the Backup (Optional)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Access the running container:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker exec -ti myoracle21 bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;&lt;code&gt;/opt/oracle&lt;/code&gt;&lt;/strong&gt; directory and execute the restoration script:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bash start.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Following these steps, you should have Oracle 21c running in a Docker container with your backup data restored. This setup is efficient for testing and development environments.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://buymeacoffee.com/nhisyamj"&gt;Buy Me A Coffee&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oracle12</category>
    </item>
    <item>
      <title>Monitor k8s with Loki, Prometheus and Grafana</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Mon, 06 Feb 2023 08:33:03 +0000</pubDate>
      <link>https://dev.to/nhisyamj/monitor-k8s-with-loki-prometheus-and-grafana-1klg</link>
      <guid>https://dev.to/nhisyamj/monitor-k8s-with-loki-prometheus-and-grafana-1klg</guid>
      <description>&lt;p&gt;Bismillah...&lt;/p&gt;

&lt;p&gt;We will learn how to monitor Kubernetes using Loki, Prometheus, and Grafana using existing helm packages.&lt;/p&gt;

&lt;p&gt;I found two helm packages which are very useful.&lt;/p&gt;

&lt;p&gt;First, let's install the helm package for Prometheus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm &lt;span class="nb"&gt;install &lt;/span&gt;monitoring-stack prometheus-community/kube-prometheus-stack &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's install the helm package for Loki:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; loki grafana/loki-stack &lt;span class="nt"&gt;--set&lt;/span&gt; fluent-bit.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,promtail.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To access Grafana locally, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl port-forward svc/monitoring-stack-grafana 8080:80 &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now access Grafana by opening &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;localhost:8080&lt;/a&gt; in your browser. Login with the following credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username: admin&lt;/li&gt;
&lt;li&gt;Password: prom-operator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, let's configure Loki as a datasource in Grafana. Follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the Grafana dashboard.&lt;/li&gt;
&lt;li&gt;Click on "Configuration" in the side menu.&lt;/li&gt;
&lt;li&gt;Click on "Data Sources".&lt;/li&gt;
&lt;li&gt;Click on "Add data source".&lt;/li&gt;
&lt;li&gt;Set the following configurations:

&lt;ul&gt;
&lt;li&gt;Name: Loki&lt;/li&gt;
&lt;li&gt;Type: Loki&lt;/li&gt;
&lt;li&gt;URL: &lt;a href="http://loki:3100" rel="noopener noreferrer"&gt;http://loki:3100&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Save &amp;amp; Test&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! You have successfully set up monitoring for Kubernetes using Loki, Prometheus, and Grafana.&lt;/p&gt;

&lt;p&gt;Enjoy monitoring your Kubernetes cluster!&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack#configuration" rel="noopener noreferrer"&gt;Prometheus Helm Package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://artifacthub.io/packages/helm/grafana/loki-stack" rel="noopener noreferrer"&gt;Loki Helm Package&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agritech</category>
      <category>iot</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>K8s Dashboard on OKE</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Sat, 04 Feb 2023 09:49:29 +0000</pubDate>
      <link>https://dev.to/nhisyamj/k8s-dashboard-on-oke-498i</link>
      <guid>https://dev.to/nhisyamj/k8s-dashboard-on-oke-498i</guid>
      <description>&lt;p&gt;Bismillah...&lt;/p&gt;

&lt;p&gt;We will learn on how to deploy and access Kubernetes (K8s) Dashboard in Oracle Kubernetes Engine (OKE). &lt;/p&gt;

&lt;p&gt;First, we will create filename oke-k8s-dashboard-auth.yaml with below details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: ServiceAccount
metadata:
  name: oke-admin
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: oke-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: oke-admin
  namespace: kube-system
---
apiVersion: v1
kind: Secret
metadata:
  name: oke-admin-sa-token
  namespace: kube-system
  annotations:
   kubernetes.io/service-account.name: oke-admin
type: kubernetes.io/service-account-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute this command&lt;br&gt;
&lt;code&gt;kubectl apply -f oke-k8s-dashboard-auth.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command will create ServiceAccount, ClusterRoleBinding and Secret.&lt;/p&gt;

&lt;p&gt;Execute this command to view token created for auth used later.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl describe secrets oke-admin-sa-token -n kube-system&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then execute this to deploy Kubernetes Dashboard.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To run it on your local, run &lt;code&gt;kubectl proxy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It now accessible at &lt;a href="http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/" rel="noopener noreferrer"&gt;http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;paste the token created. Have fun!&lt;br&gt;
&lt;a href="https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengstartingk8sdashboard.htm" rel="noopener noreferrer"&gt;source1&lt;/a&gt; &lt;a href="https://github.com/kubernetes/dashboard" rel="noopener noreferrer"&gt;source2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devto</category>
      <category>announcement</category>
      <category>webmonetization</category>
    </item>
    <item>
      <title>Install Kafka on CentOS 7</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Fri, 25 Nov 2022 03:19:08 +0000</pubDate>
      <link>https://dev.to/nhisyamj/install-kafka-on-centos-7-eig</link>
      <guid>https://dev.to/nhisyamj/install-kafka-on-centos-7-eig</guid>
      <description>&lt;p&gt;Bismillah&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Java 1.8&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installation:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download Kafka&lt;br&gt;
&lt;code&gt;wget https://mirrors.estointernet.in/apache/kafka/2.8.1/kafka_2.13-2.8.1.tgz&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extract downloaded zip&lt;br&gt;
&lt;code&gt;tar -xzf kafka_2.13-2.8.1.tgz&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create symlink&lt;br&gt;
&lt;code&gt;ln -s kafka_2.13-2.8.1 kafka&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Export&lt;br&gt;
&lt;code&gt;echo "export PATH=$PATH:/root/kafka__2.13-2.8.1/bin" &amp;gt;&amp;gt; ~/.bash_profile&lt;/code&gt;&lt;br&gt;
&lt;code&gt;source ~/.bash_profile&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run zookeeper&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd kafka/bin
./zookeeper-server-start.sh -daemon ~/kafka/config/zookeeper.properties
#check if zookeeper successfully running
telnet localhost 2181
# install telnet if not available (optional)
yum -y install telnet-server telnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run kafka
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./kafka-server-start.sh -daemon ~/kafka/config/server.properties
#check if kafka successfully running
telnet localhost 9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you are done install kafka on CentOS 7&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create kafka topic &lt;br&gt;
&lt;code&gt;./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic my-topic&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List created topic&lt;br&gt;
&lt;code&gt;./kafka-topics.sh --zookeeper localhost:2181 --list&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alhamdulillah&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>installation</category>
      <category>centos7</category>
    </item>
    <item>
      <title>Configure Ubuntu connection via WiFi</title>
      <dc:creator>Hisyam Johan</dc:creator>
      <pubDate>Sat, 03 Sep 2022 13:35:05 +0000</pubDate>
      <link>https://dev.to/nhisyamj/configure-ubuntu-connection-via-wifi-417o</link>
      <guid>https://dev.to/nhisyamj/configure-ubuntu-connection-via-wifi-417o</guid>
      <description>&lt;p&gt;Bismillah...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;edit yaml file &lt;code&gt;sudo /etc/netplan/00-installer-config-wifi.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# This is the network config written by 'subiquity'
network:
  version: 2
  wifis:
    wlp3s0:
      access-points:
        &amp;lt;wifi.name&amp;gt;:
          password: &amp;lt;wifi.password&amp;gt;
      dhcp4: true
      optional: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;execute &lt;code&gt;sudo netplan apply&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;execute &lt;code&gt;sudo reboot&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
