<?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[Global Classifieds Dev & Web Notes]]></title><description><![CDATA[Global Classifieds Dev & Web Notes]]></description><link>https://globalclassifieds-dev.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 29 Oct 2026 07:37:51 GMT</lastBuildDate><atom:link href="https://globalclassifieds-dev.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Hardening a Fresh Linux VPS in 30 Minutes: A Practical Checklist]]></title><description><![CDATA[A new VPS is reachable from the whole internet within seconds of booting, and automated scanners will find it fast. Here's a short, practical hardening…]]></description><link>https://globalclassifieds-dev.hashnode.dev/hardening-a-fresh-linux-vps-in-30-minutes-a-practical-checklist</link><guid isPermaLink="true">https://globalclassifieds-dev.hashnode.dev/hardening-a-fresh-linux-vps-in-30-minutes-a-practical-checklist</guid><category><![CDATA[Linux]]></category><category><![CDATA[Security]]></category><category><![CDATA[Devops]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Global Classifieds]]></dc:creator><pubDate>Tue, 27 Oct 2026 10:29:16 GMT</pubDate><content:encoded><![CDATA[<p>A new VPS is reachable from the whole internet within seconds of booting, and automated scanners will find it fast. Here's a short, practical hardening pass I run on every fresh server before deploying anything. Commands are for Debian/Ubuntu; equivalents for RHEL-based distros (AlmaLinux, Rocky) are noted.</p>
<h2>1. Update everything</h2>
<pre><code class="language-bash">sudo apt update &amp;&amp; sudo apt full-upgrade -y
# RHEL family: sudo dnf upgrade -y
</code></pre>
<p>Then enable automatic security updates:</p>
<pre><code class="language-bash">sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
# RHEL family: sudo dnf install dnf-automatic -y &amp;&amp; sudo systemctl enable --now dnf-automatic.timer
</code></pre>
<h2>2. Create a non-root user</h2>
<pre><code class="language-bash">sudo adduser deploy
sudo usermod -aG sudo deploy   # RHEL family: wheel
</code></pre>
<h2>3. Use SSH keys, then lock down SSH</h2>
<p>From your local machine:</p>
<pre><code class="language-bash">ssh-keygen -t ed25519 -C "deploy@myserver"
ssh-copy-id deploy@your.server.ip
</code></pre>
<p>Confirm you can log in with the key in a <strong>second</strong> terminal before changing anything. Then edit <code>/etc/ssh/sshd_config</code> (or a file in <code>/etc/ssh/sshd_config.d/</code>):</p>
<pre><code class="language-plaintext">PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
</code></pre>
<pre><code class="language-bash">sudo sshd -t &amp;&amp; sudo systemctl reload ssh   # sshd on RHEL family
</code></pre>
<p><code>sshd -t</code> validates the config so you don't lock yourself out.</p>
<h2>4. Turn on a firewall</h2>
<p>Allow only what you need:</p>
<pre><code class="language-bash">sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable
# RHEL family: firewalld
# sudo firewall-cmd --permanent --add-service={ssh,http,https} &amp;&amp; sudo firewall-cmd --reload
</code></pre>
<h2>5. Rate-limit brute-force attempts</h2>
<pre><code class="language-bash">sudo apt install fail2ban -y
sudo tee /etc/fail2ban/jail.local &gt;/dev/null &lt;&lt;'EOF'
[sshd]
enabled = true
maxretry = 5
findtime = 10m
bantime = 1h
EOF
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
</code></pre>
<h2>6. Check what's listening</h2>
<pre><code class="language-bash">sudo ss -tulpn
</code></pre>
<p>Anything you don't recognize should be stopped or bound to <code>127.0.0.1</code>. Databases in particular should not listen on public interfaces.</p>
<h2>7. Set the time and hostname</h2>
<pre><code class="language-bash">sudo timedatectl set-timezone UTC
sudo hostnamectl set-hostname web-01
</code></pre>
<p>Correct time matters for logs, TLS and scheduled jobs.</p>
<h2>8. Add swap on small instances</h2>
<pre><code class="language-bash">sudo fallocate -l 2G /swapfile &amp;&amp; sudo chmod 600 /swapfile
sudo mkswap /swapfile &amp;&amp; sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
</code></pre>
<p>This prevents the OOM killer from taking out your database during a traffic spike on a 1–2 GB box.</p>
<h2>9. Basic monitoring and logs</h2>
<ul>
<li>Keep <code>journalctl</code> logs persistent: set <code>Storage=persistent</code> in <code>/etc/systemd/journald.conf</code></li>
<li>Watch disk space: <code>df -h</code> and set an alert in your provider's dashboard</li>
<li>Install a lightweight monitor or uptime checker</li>
</ul>
<h2>10. Back up before you need it</h2>
<p>Snapshots from your provider plus off-server backups of databases and uploads. Test a restore at least once.</p>
<h2>Quick checklist</h2>
<ul>
<li><input disabled type="checkbox" /> Fully updated, automatic security updates on</li>
<li><input disabled type="checkbox" /> Non-root sudo user</li>
<li><input disabled type="checkbox" /> Key-only SSH, root login disabled, config validated</li>
<li><input disabled type="checkbox" /> Firewall allows only SSH/HTTP/HTTPS</li>
<li><input disabled type="checkbox" /> fail2ban on SSH</li>
<li><input disabled type="checkbox" /> No unexpected listening ports</li>
<li><input disabled type="checkbox" /> Swap on small instances</li>
<li><input disabled type="checkbox" /> Monitoring and tested backups</li>
</ul>
<p>If you're comparing hosting options or looking for server setups and guides, <a href="https://servers.cafe/">Servers.cafe</a> collects server and hosting resources.</p>
<p>What's the first thing <em>you</em> do on a new server?</p>
]]></content:encoded></item><item><title><![CDATA[Mobile-First Landing Pages: A Checklist That Actually Ships]]></title><description><![CDATA[Most landing-page traffic now arrives on a phone, yet many pages are still designed on a 27-inch monitor and "made responsive" at the end. Here's the…]]></description><link>https://globalclassifieds-dev.hashnode.dev/mobile-first-landing-pages-a-checklist-that-actually-ships</link><guid isPermaLink="true">https://globalclassifieds-dev.hashnode.dev/mobile-first-landing-pages-a-checklist-that-actually-ships</guid><category><![CDATA[Web Development]]></category><category><![CDATA[CSS]]></category><category><![CDATA[SEO]]></category><category><![CDATA[UX]]></category><dc:creator><![CDATA[Global Classifieds]]></dc:creator><pubDate>Tue, 27 Oct 2026 10:27:11 GMT</pubDate><content:encoded><![CDATA[<p>Most landing-page traffic now arrives on a phone, yet many pages are still designed on a 27-inch monitor and "made responsive" at the end. Here's the checklist I use to build mobile-first landing pages that load fast, read well and convert.</p>
<h2>Start at 360px wide</h2>
<p>Design and build the smallest layout first, then add breakpoints as space allows. It forces you to decide what actually matters above the fold.</p>
<pre><code class="language-css">.hero { padding: 1.25rem; }
.hero h1 { font-size: clamp(1.75rem, 6vw, 3rem); line-height: 1.15; }

@media (min-width: 768px) {
  .hero { display: grid; grid-template-columns: 1.1fr 1fr; gap: 2rem; padding: 3rem; }
}
</code></pre>
<p><code>clamp()</code> scales headings smoothly without a pile of media queries.</p>
<h2>One message, one action</h2>
<p>Above the fold on a phone you have room for:</p>
<ol>
<li>A headline that states the benefit</li>
<li>One supporting sentence</li>
<li>One primary button</li>
</ol>
<p>Everything else can scroll. If you need two buttons, make one clearly secondary.</p>
<h2>Tap targets and spacing</h2>
<p>Buttons and links should be comfortably tappable, at least around 44–48px tall, with space between them. Test with your thumb, not your mouse.</p>
<pre><code class="language-css">.btn { display: inline-flex; align-items: center; min-height: 48px; padding: 0 1.25rem; }
</code></pre>
<h2>Images that don't wreck performance</h2>
<ul>
<li>Serve <code>avif</code>/<code>webp</code> with a fallback</li>
<li>Always set <code>width</code> and <code>height</code> to prevent layout shift</li>
<li>Lazy-load anything below the fold</li>
</ul>
<pre><code class="language-html">&lt;img src="hero-800.webp"
     srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
     sizes="(min-width: 768px) 50vw, 100vw"
     width="800" height="600" alt="Dashboard showing weekly sales" fetchpriority="high"&gt;
</code></pre>
<p>Use <code>fetchpriority="high"</code> only for the hero image; lazy-load the rest with <code>loading="lazy"</code>.</p>
<h2>Fonts</h2>
<p>Limit yourself to one or two families and a few weights. Use <code>font-display: swap</code> so text appears immediately.</p>
<h2>Heading structure and SEO basics</h2>
<ul>
<li>Exactly one <code>&lt;h1&gt;</code>: the main headline</li>
<li>Section titles as <code>&lt;h2&gt;</code>, sub-points as <code>&lt;h3&gt;</code>, in order</li>
<li>Unique <code>&lt;title&gt;</code> (around 50–60 characters) and meta description</li>
<li>Descriptive link text, not "click here"</li>
<li>Structured data where it fits (Organization, Product, FAQPage)</li>
</ul>
<p>Clean structure helps search engines and AI assistants understand and quote your page.</p>
<h2>Forms that work on phones</h2>
<ul>
<li>Use the right input types: <code>type="email"</code>, <code>type="tel"</code>, <code>inputmode="numeric"</code></li>
<li>Add <code>autocomplete</code> attributes so browsers can fill fields</li>
<li>Keep it short: ask only what you need right now</li>
<li>Show errors next to the field, not in an alert</li>
</ul>
<pre><code class="language-html">&lt;input type="email" name="email" autocomplete="email" required&gt;
&lt;input type="tel" name="phone" autocomplete="tel" inputmode="tel"&gt;
</code></pre>
<h2>Test on a real device</h2>
<p>Emulators miss things: sticky headers covering content, the on-screen keyboard hiding the submit button, slow 4G. Open the page on an actual mid-range phone before calling it done.</p>
<h2>Measure</h2>
<p>Run Lighthouse or PageSpeed Insights, and watch Core Web Vitals (LCP, CLS, INP) in production. Fix the biggest offender first.</p>
<h2>Examples</h2>
<p>If you'd like to see mobile-first page layouts in practice, the <a href="https://www.pagedesign.info/port/">PageDesign.info portfolio</a> shows a range of landing pages and sites built this way, and <a href="https://www.pagedesign.info/">PageDesign.info</a> covers page design services.</p>
<h2>Checklist</h2>
<ul>
<li><input disabled type="checkbox" /> Built at 360px first</li>
<li><input disabled type="checkbox" /> One headline, one sentence, one primary action above the fold</li>
<li><input disabled type="checkbox" /> 48px tap targets</li>
<li><input disabled type="checkbox" /> Responsive, sized, lazy-loaded images</li>
<li><input disabled type="checkbox" /> One <code>h1</code>, ordered <code>h2</code>/<code>h3</code></li>
<li><input disabled type="checkbox" /> Mobile-friendly form inputs</li>
<li><input disabled type="checkbox" /> Tested on a real phone</li>
<li><input disabled type="checkbox" /> Core Web Vitals checked</li>
</ul>
<p>What's the most common mobile mistake you see on landing pages?</p>
]]></content:encoded></item></channel></rss>