DevOps and infrastructure
Servers that stay up on their own
Setup, deployment, backups, monitoring and migrations for web projects — arranged so that releasing is dull, restoring is rehearsed, and nothing important depends on one person remembering.
- Audit first
- findings in writing
- Access is yours
- no lock-in
- Kharkiv, UA
- working worldwide
Web server
The site, its admin panel, API and cron jobs. What most people mean by "a server".
Database server
MySQL, MariaDB, PostgreSQL or MS SQL — split off once traffic starts starving queries.
Backup server
Holds copies of the others and pulls them itself, so a breached host cannot erase history.
Video surveillance
An NVR sized for the retention you owe, recording without dropped frames, reached over VPN.
ERP and business applications
Accounting, warehouse or ERP with its database, and a terminal server for remote staff.
Access control and time tracking
Turnstiles, locks and readers, with their own database, a UPS and a tested restore.
File server
Shared documents with permissions, quotas and shadow copies, instead of twenty desktops.
Directory and authentication
One identity per person across the network, and one place to switch it off.
Mail
A mail server where volume demands one; more often a hosted box with the DNS set correctly.
Gateway and VPN
Firewall, routing between offices, per-person VPN keys. Everything else sits behind it.
Monitoring and logs
Watches the other machines and keeps their logs where a breached host cannot edit them.
Virtualisation host
Most of these end up as VMs on one or two hosts, separated so one reboot is not all of them.
Where it runs
Cloud, a plain server, or your own rack
Google Cloud
Compute Engine instances, Cloud SQL where a managed database earns its price, Cloud Storage for media and backups, a load balancer in front when there is more than one node. Snapshots scheduled, and instance sizes reviewed after real traffic rather than guessed at the start.
Amazon Web Services
EC2 with EBS volumes and snapshot policies, S3 for static assets and off-site copies, RDS when you would rather not run the database yourself, Route 53 and CloudFront for DNS and delivery. Security groups written as a deny-by-default list, not opened as you go.
A plain VPS
For most sites this is the honest answer. One properly configured machine at a European provider runs a busy WordPress or Shop-Script installation faster and far cheaper than a cloud architecture nobody on the team can debug.
Your own hardware
In your office or in a data centre. RAID with a tested rebuild, out-of-band access so a reboot does not need a car journey, UPS, a documented spare, and a second channel where the business cannot sit out an ISP outage.
Operating systems
Linux and Windows Server, run properly
Debian and Ubuntu Server
LTS releases, kept on the vendor package set rather than a pile of third-party repositories. Unattended security upgrades, SSH by key with root login off, fail2ban, nftables or ufw closed by default, journald and logrotate configured so a full disk is not how you learn about a runaway log.
Windows Server 2012 and newer
Through to the current releases: IIS with an application pool per site, MS SQL Server, Active Directory and group policy, Remote Desktop Services, file shares with quotas and shadow copies. Patching scheduled rather than postponed, and an upgrade path planned before a version leaves support.
Containers where they help
Docker and Compose to pin a stack that has to match between staging and production, or to run several PHP or Node versions side by side. Not used to make a single-site server more complicated than it needs to be.
Web environment
The stack under a site that has to stay fast
nginx, or nginx in front of Apache
nginx alone where the application allows it; as a reverse proxy in front of Apache where .htaccess rules have to keep working. HTTP/2, gzip and Brotli, sane client limits, and static files served without waking PHP at all.
PHP-FPM, pooled and isolated
A separate pool and a separate system user per site, so one compromised plugin cannot read the neighbour. OPcache sized to the codebase, realpath cache raised, limits set from measured usage, and the version chosen per site rather than for the whole machine.
MySQL, MariaDB or PostgreSQL
Buffer pool sized against actual data, slow query log on and read, indexes added where the log says so. Dumps taken consistently and, on larger sets, binary logs kept so recovery is to a point in time rather than to last night.
Redis or Memcached
Object cache and sessions off the database and out of the filesystem, with eviction policy and memory ceiling set deliberately. Bound to localhost or a private network — an open Redis is one of the most reliably exploited things on the internet.
Node.js when the front end needs it
Build steps run in the pipeline, not on the live server. Long-running processes under systemd with restart policy and log capture rather than a screen session someone opened once.
TLS that renews itself
Let's Encrypt via ACME with automatic renewal and a hook that reloads the web server, or a commercial certificate installed and diarised. Modern cipher suites, HSTS where it is safe to commit to it, and expiry monitored from outside the machine.
Business infrastructure
The other half: the office network
Domain and group policy
Active Directory with a second controller so a single failure does not stop the office logging in. Policies for drive mapping, printers, screen lock and software installation, applied centrally instead of machine by machine.
File server
Shares with permissions that follow the org chart, quotas so one department cannot fill the volume, and shadow copies so an overwritten document is a two-minute problem rather than a restore request.
Terminal server
Remote Desktop Services for accounting and line-of-business applications, licensed properly, sized for the number of people actually working at once, and reachable from home over VPN rather than exposed to the internet.
Remote access
WireGuard or OpenVPN into the office network, per-person keys that can be revoked when somebody leaves. RDP open to the world is how ransomware gets in, and it is still the most common thing found on an inherited network.
Mail that arrives
SPF, DKIM and DMARC set correctly for whichever provider you use, and reverse DNS where you send your own. Most "our invoices go to spam" tickets are one missing DNS record.
Security
Closed by default, and provably so
Closed by default
The firewall denies everything and is opened port by port for a stated reason. Databases, caches and admin interfaces bind to localhost or a private network — never to a public address because it was easier during setup.
Access that can be taken away
Named accounts rather than one shared login, SSH keys instead of passwords, sudo instead of root, two-factor wherever the panel supports it. When somebody leaves, one revocation ends their access everywhere — which is only true if it was built that way.
Sites isolated from each other
One system user and one PHP pool per site. On a shared server the usual way in is not the hardened site — it is the forgotten one next to it, and isolation is what stops that becoming everyone's problem.
Updates that happen
Unattended security upgrades on Linux, a scheduled patch window on Windows, and end-of-life dates tracked so a version does not quietly stop receiving fixes while still running your business.
Brute force and bad traffic
fail2ban on SSH and login endpoints, rate limits at the web server, and Cloudflare or an equivalent in front where the volume warrants it. Login pages are attacked constantly; the only question is whether anything is counting.
Secrets kept out of the code
Database passwords and API keys in environment configuration with restrictive permissions, not committed to the repository and not in a file the web server will happily serve. Rotated when anyone with access leaves.
A plan for the day it happens
If a site is compromised: isolate it, preserve the evidence, rebuild from a known-good source rather than deleting the files you can see, rotate every credential, then find the way in. Cleaning without finding the entry point means doing it again in a fortnight.
The most common finding on an inherited network is not exotic: it is RDP open to the internet, or a password reused across the server, the panel and the database. Both take an afternoon to fix and are the two ways ransomware usually arrives.
Backup and recovery
A backup is not a backup until it has been restored
Three copies, two media, one off-site
The old rule, and still the one that matters. A copy on the same server is not a backup — it burns with the machine, and it is deleted by whatever deleted the original.
Files, database and configuration
All three, or the restore is a puzzle. A database without the uploads is half a site; both without the web server and cron configuration is a day of rebuilding from memory.
Copies ransomware cannot reach
Off-site storage with append-only or versioned retention, and credentials that do not live on the server being backed up. Modern ransomware looks for the backups first, and finds them when the server can delete them.
Retention worth having
Daily kept for a fortnight, weekly for a couple of months, monthly for longer. Corruption and quiet data loss are often noticed weeks later, and a single overwritten copy is no help by then.
Recovery to a point in time
Where the data justifies it, binary logs or snapshots so you can return to an hour ago rather than to last night — the difference between losing an afternoon of orders and losing none.
Restores that have been performed
Each backup set is restored to a scratch environment and timed, so you know both that it works and how long it takes. That number is what you actually plan around, and almost nobody has it.
Truncated dumps, missing uploads, a job that stopped months ago and told nobody — these are the normal failures, and every one of them is invisible until the moment the backup is needed. Testing is the only thing that turns a backup from a hope into a fact.
Operations
What keeps running afterwards
Deployment
Code reaches the server the same way every time — from the repository, through a pipeline, with a build step and a way back. Nobody edits a live file over FTP, because that is how sites break at eleven at night.
Backups you have restored
Files and database, off the server, on a schedule, with retention. Then the part most setups skip: an actual restore, performed and timed, because a backup nobody has restored is a hope rather than a backup.
Monitoring and alerts
Uptime, certificate expiry, disk, memory, load, queue depth and error rate, watched from outside the server and delivered to somebody who can act. An alert that reaches no one is not monitoring.
Staging that matches production
A second environment on the same stack and the same versions, with data that is safe to work on. Most launch-day surprises are differences between the two that nobody knew about.
Migrations without downtime
Moving hosts, PHP or database versions with the switch planned rather than attempted: rehearsed on a copy, TTL lowered in advance, cut over at a quiet hour, old environment kept until the new one has proved itself.
Administration
Patching, user and access management, log review, capacity checks, and a defined response when something breaks. The unglamorous half, and the reason the other half keeps working.
How it runs
Look first, then fix, then automate
Audit
What is running, on what, patched to when, backed up how, and who can reach it. Delivered as a written list of findings ordered by what would hurt most, whether or not you go further.
Stabilise
The findings that are dangerous now: exposed services, missing or unverified backups, expiring certificates, unpatched versions. Fixed first, before anything is improved.
Automate
Deployment, backups, renewals and monitoring set up to run without anybody remembering to run them. This is what stops the same problems coming back.
Document
Where everything lives, how to deploy, how to restore, who to call. Written so your next administrator can read it, not so it proves the work happened.
Keep it running
Ongoing updates, monitoring and a defined response when something goes wrong — or a clean handover to your own team. Both are fine; drifting into neither is not.
Questions
Before you write in
Start
Send a request
What the project is, where it runs now and what worries you about it. If you do not know what it runs on, that is a normal answer and the audit exists for exactly that.