{"id":212,"date":"2026-06-05T19:54:06","date_gmt":"2026-06-05T19:54:06","guid":{"rendered":"https:\/\/blog.offshorekaka.in\/?p=212"},"modified":"2026-08-27T05:43:34","modified_gmt":"2026-08-27T05:43:34","slug":"offshore-dedicated-server-setup-checklist","status":"publish","type":"post","link":"https:\/\/offshorekaka.in\/blog\/offshore-dedicated-server-setup-checklist\/","title":{"rendered":"Offshore Dedicated Server Setup Checklist"},"content":{"rendered":"<div class=\"ok-pro-panel\">\n<p><span class=\"ok-pro-kicker\">Server Guides<\/span><\/p>\n<h2>The day your dedicated server arrives<\/h2>\n<p>A dedicated server hands you the whole machine and nothing else. No panel, no stack, no firewall, no backups. Everything a shared host used to do quietly in the background is now yours to set up, and the order you do it in matters.<\/p>\n<p>This is the sequence we use on a new <a href=\"https:\/\/offshorekaka.in\/offshore-dedicated-server\/\">offshore dedicated server<\/a>, from first login to a site serving traffic with monitoring and backups behind it.<\/p>\n<div class=\"ok-pro-grid\">\n<div class=\"ok-pro-card\"><strong>Time<\/strong><span>Two to three hours end to end.<\/span><\/div>\n<div class=\"ok-pro-card\"><strong>Do first<\/strong><span>Check you got the hardware you paid for.<\/span><\/div>\n<div class=\"ok-pro-card\"><strong>Do last<\/strong><span>Point DNS at it.<\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"ok-toc\"><strong>On this page<\/strong><a href=\"#verify\">Check the hardware<\/a><a href=\"#base\">Base system<\/a><a href=\"#secure\">Lock it down<\/a><a href=\"#stack\">Stack or panel<\/a><a href=\"#deploy\">Deploy and go live<\/a><a href=\"#after\">Before you call it done<\/a><a href=\"#faq\">FAQ<\/a><\/div>\n<h2 id=\"verify\">Check the hardware first<\/h2>\n<p>Do this before you build anything on top. Providers make mistakes, and finding out three weeks later that you are on a spinning disk instead of NVMe is an annoying conversation to have.<\/p>\n<pre><code>lscpu | grep -Ei 'model name|^cpu(s)|thread|core'\nfree -h\nlsblk -d -o NAME,SIZE,ROTA,MODEL\ncat \/proc\/mdstat<\/code><\/pre>\n<figure class=\"wp-block-image size-large ok-inline-visual\"><img decoding=\"async\" src=\"https:\/\/offshorekaka.in\/blog\/wp-content\/uploads\/2026\/08\/ok-disk-type-check.webp\" alt=\"lsblk output distinguishing an NVMe drive from a rotational disk\" loading=\"lazy\" width=\"2296\" height=\"428\"><figcaption>ROTA 0 is solid state. If you paid for NVMe and see ROTA 1, raise it now.<\/figcaption><\/figure>\n<p>Check the CPU model against what was advertised, that the RAM total matches, and that the disks are the type and size you ordered. <code>cat \/proc\/mdstat<\/code> tells you whether software RAID is assembled. A dedicated server delivered with an unassembled second disk is common enough to be worth checking.<\/p>\n<h2 id=\"base\">Base system<\/h2>\n<pre><code>apt update &amp;&amp; apt upgrade -y\nhostnamectl set-hostname server.yourdomain.com\ntimedatectl set-timezone UTC<\/code><\/pre>\n<p>Set the timezone to UTC and leave it there. Every log on the machine gets timestamped with it, and when you are correlating a web server log against a database log against a provider status page at 2am, having everything in one timezone saves real time.<\/p>\n<p>Add the hostname to <code>\/etc\/hosts<\/code> as well, or a lot of software will complain about not being able to resolve it, including the mail daemon.<\/p>\n<h2 id=\"secure\">Lock it down before it is public<\/h2>\n<p>Do this before the site exists, not after. The IP is already being scanned.<\/p>\n<pre><code>adduser deployer\nusermod -aG sudo deployer\nufw default deny incoming\nufw default allow outgoing\nufw allow OpenSSH\nufw allow 80\/tcp\nufw allow 443\/tcp\nufw enable\napt install fail2ban -y\nsystemctl enable --now fail2ban<\/code><\/pre>\n<figure class=\"wp-block-image size-large ok-inline-visual\"><img decoding=\"async\" src=\"https:\/\/offshorekaka.in\/blog\/wp-content\/uploads\/2026\/08\/ok-firewall-ufw-status.webp\" alt=\"UFW status showing incoming denied with only SSH, HTTP and HTTPS open\" loading=\"lazy\" width=\"2296\" height=\"824\"><figcaption>The firewall as it should look before anything else goes on the machine.<\/figcaption><\/figure>\n<p>Then switch SSH to key only. The full sequence, including the config override that catches people out on modern Ubuntu, is in our <a href=\"https:\/\/offshorekaka.in\/blog\/ssh-hardening-for-offshore-vps\/\">SSH hardening guide<\/a>. The order is not negotiable: create the user, test sudo, add the key, test the key, then disable passwords.<\/p>\n<h2 id=\"stack\">Stack or panel<\/h2>\n<p>Decide this once, because switching later means rebuilding.<\/p>\n<p><strong>A control panel<\/strong> if you host client sites, need email accounts, or want someone else to be able to manage it. cPanel and WHM is the standard and it costs money. aaPanel and CyberPanel are free alternatives. Install a panel on a <em>clean<\/em> machine, before any web server exists, because they all want to own nginx, MySQL and PHP and they fight anything already installed.<\/p>\n<p><strong>A plain stack<\/strong> if this box runs your own applications and you are comfortable on the command line. Less overhead, fewer moving parts, no licence:<\/p>\n<pre><code>apt install nginx mariadb-server php-fpm php-mysql -y\nsystemctl enable --now nginx mariadb\nmysql_secure_installation<\/code><\/pre>\n<p>Do not skip <code>mysql_secure_installation<\/code>. It sets the root password, drops the anonymous users and removes the test database, all of which exist by default and none of which should.<\/p>\n<figure class=\"wp-block-image size-large ok-inline-visual\"><img decoding=\"async\" src=\"https:\/\/offshorekaka.in\/blog\/wp-content\/uploads\/2026\/08\/ok-stack-versions.webp\" alt=\"Terminal showing PHP, nginx, MySQL and WordPress version numbers\" loading=\"lazy\" width=\"2296\" height=\"630\"><figcaption>Record these. In six months you will want to know what this box was built with.<\/figcaption><\/figure>\n<p>Then confirm nothing is listening that should not be:<\/p>\n<figure class=\"wp-block-image size-large ok-inline-visual\"><img decoding=\"async\" src=\"https:\/\/offshorekaka.in\/blog\/wp-content\/uploads\/2026\/08\/ok-listening-ports.webp\" alt=\"ss output showing nginx on ports 80 and 443 and MySQL bound to localhost\" loading=\"lazy\" width=\"2296\" height=\"428\"><figcaption>MySQL on 127.0.0.1 rather than 0.0.0.0 is the line to check.<\/figcaption><\/figure>\n<h2 id=\"deploy\">Deploy and go live<\/h2>\n<ol>\n<li><strong>Create the vhost<\/strong> and put the site files in place.<\/li>\n<li><strong>Restore or import the database<\/strong>, then update the credentials in the site config.<\/li>\n<li><strong>Test by IP or a temporary hostname<\/strong> before touching DNS. Every page, not just the homepage.<\/li>\n<li><strong>Issue the certificate.<\/strong> <code>certbot --nginx -d yourdomain.com -d www.yourdomain.com<\/code>. This needs DNS pointing at the server, so on a migration you may need a DNS challenge instead.<\/li>\n<li><strong>Then change DNS<\/strong>, having lowered the TTL a day earlier. Our <a href=\"https:\/\/offshorekaka.in\/blog\/dns-propagation-after-hosting-migration\/\">DNS propagation guide<\/a> explains why that day matters.<\/li>\n<\/ol>\n<h2 id=\"after\">Before you call it done<\/h2>\n<p>This is the part that gets skipped, and it is the part that matters in six months.<\/p>\n<ul>\n<li><strong>Backups, running and tested.<\/strong> Not configured, tested. Restore one somewhere before you trust it. See the <a href=\"https:\/\/offshorekaka.in\/blog\/backup-strategy-for-offshore-servers\/\">backup guide<\/a>.<\/li>\n<li><strong>Monitoring, from outside the server.<\/strong> Uptime plus a disk space alert catches most of what goes wrong.<\/li>\n<li><strong>Automatic security updates<\/strong> with unattended-upgrades.<\/li>\n<li><strong>Log rotation<\/strong> confirmed, so logs cannot fill the disk.<\/li>\n<li><strong>Write down what you built.<\/strong> Versions, paths, vhost names, where backups go, where the certificate renewal lives. Future you will not remember.<\/li>\n<\/ul>\n<h2 id=\"test\">How to test the whole thing<\/h2>\n<ol>\n<li>Reboot the server. Everything should come back on its own. This finds services that were started but never enabled.<\/li>\n<li>Load the site over HTTPS with no warnings.<\/li>\n<li>Confirm the firewall is on and only the ports you expect are open.<\/li>\n<li>Confirm root SSH and password SSH are both refused.<\/li>\n<li>Run a backup by hand and restore it somewhere else.<\/li>\n<li>Stop nginx and confirm your monitoring alerts you.<\/li>\n<li>Check <code>certbot renew --dry-run<\/code> succeeds.<\/li>\n<\/ol>\n<p>The reboot test is the one people skip and the one that finds the most problems.<\/p>\n<h2 id=\"trouble\">When something breaks<\/h2>\n<table>\n<thead>\n<tr>\n<th>What you see<\/th>\n<th>Why<\/th>\n<th>Fix<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Services gone after a reboot<\/td>\n<td>Started but never enabled<\/td>\n<td><code>systemctl enable<\/code> each one, then reboot again<\/td>\n<\/tr>\n<tr>\n<td>Panel install fails<\/td>\n<td>A web server or MySQL was already installed<\/td>\n<td>Reinstall the OS clean, then install the panel first<\/td>\n<\/tr>\n<tr>\n<td>certbot cannot issue<\/td>\n<td>DNS is not pointing here yet, or port 80 is closed<\/td>\n<td>Use a DNS challenge, or open 80<\/td>\n<\/tr>\n<tr>\n<td>Half the disk is missing<\/td>\n<td>Second disk or RAID array never assembled<\/td>\n<td>Check <code>lsblk<\/code> and <code>\/proc\/mdstat<\/code>, raise it with the provider<\/td>\n<\/tr>\n<tr>\n<td>Mail from the server goes to spam<\/td>\n<td>New IP with no SPF, DKIM or reverse DNS<\/td>\n<td>Set reverse DNS in the provider panel, or send through a mail service<\/td>\n<\/tr>\n<tr>\n<td>Site loads by IP but not by domain<\/td>\n<td>vhost server_name does not match<\/td>\n<td>Fix the vhost and reload nginx<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"checklist\">Checklist<\/h2>\n<ul>\n<li>Hardware verified against what you ordered.<\/li>\n<li>System updated, hostname and timezone set.<\/li>\n<li>Non-root user, firewall, fail2ban, key-only SSH, all before going public.<\/li>\n<li>Panel or stack installed on a clean machine.<\/li>\n<li>MySQL secured and bound to localhost.<\/li>\n<li>Site tested by IP before DNS was changed.<\/li>\n<li>Certificate issued and renewal tested.<\/li>\n<li>Backups running and a restore actually tried.<\/li>\n<li>Monitoring alerting from outside.<\/li>\n<li>Reboot test passed.<\/li>\n<li>Build notes written down.<\/li>\n<\/ul>\n<div class=\"ok-cta-box\">\n<p><strong>Looking at a dedicated server?<\/strong><\/p>\n<p>OffshoreKaka runs AMD EPYC and Intel Xeon bare metal in Amsterdam and Frankfurt, with IPMI access so you are never locked out of your own machine.<\/p>\n<p><a class=\"btn ok-cta-link\" href=\"https:\/\/offshorekaka.in\/offshore-dedicated-server\/\">See the dedicated servers<\/a><\/p>\n<\/div>\n<h2 id=\"faq\">FAQ<\/h2>\n<h3>Can I do this without much Linux experience?<\/h3>\n<p>You can follow it, but an unmanaged dedicated server means every problem after today is also yours. If that is not something you want, a control panel takes most of the daily work away, and managed hosting takes all of it. Be honest with yourself before the machine is carrying real traffic.<\/p>\n<h3>Panel or plain stack?<\/h3>\n<p>Panel if other people need access, if you need email accounts, or if you host client sites. Plain stack if it is your own application and you live in a terminal anyway. The panel costs some RAM and some flexibility and saves a lot of time.<\/p>\n<h3>How is this different from setting up a VPS?<\/h3>\n<p>The software steps are nearly identical. What differs is that you should verify the hardware, check RAID, and set reverse DNS, none of which apply the same way on a VPS. There is more on choosing between them in <a href=\"https:\/\/offshorekaka.in\/blog\/bare-metal-vs-vps-dedicated-servers\/\">bare metal versus VPS<\/a>.<\/p>\n<h3>Does a good setup help my rankings?<\/h3>\n<p>Not directly. It keeps the site fast and available, and both of those matter to visitors. Search rankings still come from content and links.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From first login to live traffic, in the order that does not lock you out. Starting with checking you got the hardware you paid for.<\/p>\n","protected":false},"author":1,"featured_media":902,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-212","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server-guides"],"_links":{"self":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts\/212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/comments?post=212"}],"version-history":[{"count":5,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts\/212\/revisions"}],"predecessor-version":[{"id":1000,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts\/212\/revisions\/1000"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/media\/902"}],"wp:attachment":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/media?parent=212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/categories?post=212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/tags?post=212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}