Launch pricing: every plan costs 30% less than the cheapest offshore competitor we track. See the benchmarkEvery plan 30% under the cheapest offshore host

Guides

Offshore WordPress hosting: set up WordPress on a VPS

We do not sell managed WordPress hosting. Here is how to run WordPress yourself on an offshore VPS: plan, location, domain, a tested Nginx, PHP and MariaDB setup, HTTPS, caching, security and mail.

12 min readBy the OffshoreServ team

Key takeaways

  • We do not sell shared or managed WordPress hosting: you run WordPress yourself on an offshore VPS, from $2.39 a month.
  • Offshore, US DMCA notices are not actioned, but local courts and, in EU locations, Digital Services Act notices can still require action.
  • A domain answers to its registrar's and registry's law: the .com and .net registries are run from the United States.
  • Nginx, PHP-FPM, MariaDB, WP-CLI and Certbot put a secure WordPress site online in 20 to 30 minutes.
  • Add caching, automatic updates, snapshots, off-server backups and an SMTP relay on port 587 for mail.
On this page
  1. What offshore WordPress hosting means
  2. Choose a plan and a location for offshore WordPress hosting
  3. Keep the domain as safe as the server
  4. Install Nginx, PHP and MariaDB
  5. Install WordPress with WP-CLI
  6. Configure Nginx and HTTPS
  7. Make WordPress fast
  8. Secure and back up WordPress
  9. Sending mail from WordPress
  10. A CDN in front of an offshore site: what it changes
  11. Frequently asked questions

Offshore WordPress hosting means running your WordPress site on a server in another country, under that country's law. We do not sell shared or managed WordPress hosting. You install WordPress yourself on an offshore VPS with full root access, from $2.39 a month, and with this guide it takes 20 to 30 minutes.

The steps cover Debian 12 and Ubuntu 24.04 LTS with Nginx, PHP-FPM, MariaDB, WP-CLI and a free Let's Encrypt certificate.

What offshore WordPress hosting means

Your site runs on a VPS in a country you choose for its law: with us, Iceland, Switzerland, Moldova, Romania, the Netherlands, Bulgaria or Malaysia. Three things change:

  • US DMCA notices are not actioned. The DMCA has no legal force in these countries: a notice is logged and answered, and nothing happens to the server. That is what "DMCA ignored WordPress hosting" accurately means.
  • Local law decides. A valid court order from the server's country can require action. We inform you first so you can respond, unless a court forbids it.
  • EU rules apply in EU locations. In Romania, the Netherlands and Bulgaria, a notice that meets the EU Digital Services Act's notice-and-action requirements can also require action.

What does not change: illegal content stays illegal, your own country's law still applies to you, and spam, phishing, malware, attacks, fraud and child sexual abuse material lead to immediate action. Our DMCA-ignored hosting page sets out the complaint process, and DMCA-ignored hosting explained covers what else can reach a site.

Choose a plan and a location for offshore WordPress hosting

Memory is the first limit a WordPress server reaches, and shops need the most: WooCommerce's cart, checkout and account pages hold each customer's own data, so a page cache must skip them and PHP builds them for every visitor.

SitePlanvCPU, RAM, NVMePer month
Test site or small personal blogDinghy1, 1 GB, 25 GB$2.39
Blog or business siteSloop1, 2 GB, 40 GB$3.49
Busy blog or several sitesCutter2, 4 GB, 70 GB$5.49
WooCommerce shopSchooner4, 8 GB, 160 GB$12.49
High traffic or several shopsBrigantine6, 16 GB, 240 GB$19.99

Pick the location closest to most of your readers with the latency estimates on our network page, then check its law on the locations page. A new VPS has a 72-hour money-back on its first period, refunded to your balance if no abuse complaint is pending. If the site outgrows its plan, request Upgrade to a larger plan under Server actions.

Keep the domain as safe as the server

Your host controls the server, not the name. The registrar is the company you register the name through; the registry operator keeps the master database of a top-level domain and runs its name servers. Both are bound by their own country's law and their contracts, wherever your server is.

ICANN's guidance on domain name seizures describes court orders that make a registry or registrar lock a name, stop it resolving or transfer it. According to IANA's records, the .com and .net registries are run by VeriSign Global Registry Services in Reston, Virginia. So a US court order can take a .com or .net name offline wherever the website runs: the server keeps working, but visitors cannot reach it under that name. Choose the registrar and the domain with the same care as the host:

  • The registrar: its country, its terms on complaints and court orders, and the identity it asks for.
  • The top-level domain: the Root Zone Database shows who operates it, and where.
  • WHOIS privacy: a privacy service keeps your contact details out of WHOIS, and a proxy service becomes the holder of record instead of you. Either way, the provider still holds your details, under its own law.

Install Nginx, PHP and MariaDB

Setting up WordPress on a VPS starts with the web server, PHP and the database. Order the VPS with Debian 12 or Ubuntu 24.04 LTS, log in as in getting started and work through the hardening checklist. Then run everything as root (sudo -i), with your domain in place of example.com:

apt update
apt install -y nginx mariadb-server php-fpm php-mysql php-curl php-gd php-imagick php-intl php-mbstring php-xml php-zip curl gnupg sudo

WordPress's Site Health screen then reports all required and recommended PHP modules as installed. Debian 12 gets PHP 8.2 and Ubuntu 24.04 PHP 8.3, both with MariaDB 10.11. WordPress recommends PHP 8.3 or later, and Site Health flags 8.2 as an older version that should be updated, so choose Ubuntu 24.04 for a new site. By default, PHP accepts 2 MB uploads and 128 MB of memory per request; the WordPress hosting handbook recommends 256 MB:

PHPV=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
cat > /etc/php/$PHPV/fpm/conf.d/90-wordpress.ini <<'EOF'
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
EOF
systemctl restart php$PHPV-fpm

PHPV holds 8.2 or 8.3, and later steps reuse it. Now create the database and a user limited to it, with a random password:

DB_PASS=$(openssl rand -hex 24)
mariadb -e "CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
mariadb -e "CREATE USER wordpress@localhost IDENTIFIED BY '$DB_PASS'"
mariadb -e "GRANT ALL PRIVILEGES ON wordpress.* TO wordpress@localhost"

Stay in this shell: the next step writes $DB_PASS into wp-config.php. You do not need mariadb-secure-installation (or mysql_secure_installation): on both systems, MariaDB's root account logs in only through the local socket, there is no anonymous user or test database, and the server listens on 127.0.0.1 only.

Install WordPress with WP-CLI

WP-CLI manages WordPress from the shell. Download it and check its signature, as the WP-CLI handbook describes:

cd /tmp
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.asc
curl -L https://raw.githubusercontent.com/wp-cli/builds/gh-pages/wp-cli.pgp | gpg --import
gpg --fingerprint 63AF7AA15067C05616FDDD88A3A2E8F226F0BC06
gpg --verify wp-cli.phar.asc wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp

gpg --fingerprint must find the key, whose fingerprint WP-CLI publishes in its verification guide, and gpg --verify must report a good signature; its warning that the key is not certified is normal. Then create the site folder and a cache folder for WP-CLI, owned by www-data, the user PHP-FPM runs as, and install WordPress as that user:

install -d -o www-data -g www-data /var/www/example.com /var/www/.wp-cli
cd /var/www/example.com
sudo -u www-data wp core download
sudo -u www-data wp config create --dbname=wordpress --dbuser=wordpress --dbpass="$DB_PASS"
chmod 640 wp-config.php
sudo -u www-data wp core install --url=https://example.com --title="Example" --admin_user=YOUR_ADMIN_NAME --admin_email=ADMIN_EMAIL --skip-email

Because www-data owns the files, WordPress can install its own updates; the .wp-cli folder spares you a cache warning. wp-config.php, which holds the database password, is closed to other users. WP-CLI prints a generated admin password: keep it in your password manager.

Configure Nginx and HTTPS

Point A records for example.com and www.example.com at the server's IPv4 address, plus AAAA records for IPv6: Certbot needs both names to reach this server on port 80. Write the server block to /etc/nginx/sites-available/example.com, with php8.2-fpm.sock on Debian 12:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php;
    client_max_body_size 64m;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ^~ /.well-known/ {
        try_files $uri =404;
    }

    location ~ /\. {
        deny all;
    }

    location ~* /wp-content/uploads/.*\.php$ {
        deny all;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
}
try_files
Sends paths that are not files to index.php, for pretty permalinks.
Deny rules
Hidden files such as .git, and PHP files in uploads, get error 403; /.well-known/ stays open.
fastcgi-php.conf
Returns 404 for PHP files that do not exist.
client_max_body_size
Nginx's default of 1 MB would refuse larger uploads with error 413.

Enable the site in place of the default one, then switch to pretty permalinks:

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
rm /etc/nginx/sites-enabled/default
nginx -t
systemctl reload nginx
sudo -u www-data wp --path=/var/www/example.com rewrite structure '/%postname%/'

If ufw is on from the hardening guide, also run ufw allow 80/tcp. Install Certbot as a snap, following the EFF's instructions. Ubuntu 24.04 has snapd; on Debian 12, install snapd first with apt install -y snapd and snap install snapd. Then:

snap install --classic certbot
ln -s /snap/bin/certbot /usr/local/bin/certbot
certbot --nginx -d example.com -d www.example.com
certbot renew --dry-run

Certbot proves control of the domain, adds the certificate to the server block and redirects HTTP to HTTPS by default. The snap renews certificates automatically, and the dry run tests renewal. Certbot also asks for an email address, which you can skip with --register-unsafely-without-email at the cost of notices such as revocations. Let's Encrypt stopped sending expiry reminders on June 4, 2025. Your dashboard is now at https://example.com/wp-admin/.

Make WordPress fast

Run wp from /var/www/example.com, with PHPV set as above. PHP OPcache keeps compiled code in memory and is already on, with 128 MB; this must print opcache.enable => On => On:

php-fpm$PHPV -i | grep '^opcache.enable '

A page cache saves each page as static HTML and serves it to the next visitors. WP Super Cache, from Automattic, serves those files through PHP in its recommended Simple mode, so it needs no Nginx rules, and WooCommerce tells it to skip the cart, checkout and account pages:

sudo -u www-data wp plugin install wp-super-cache --activate

Turn caching on under Settings > WP Super Cache. When you are logged out, the end of a page's source then shows the comment Cached page generated by WP-Super-Cache. An object cache keeps data that WordPress would fetch from the database in memory, which helps the pages a page cache cannot serve. Redis and the Redis Object Cache plugin provide one:

apt install -y redis-server php-redis
systemctl restart php$PHPV-fpm
sudo -u www-data wp plugin install redis-cache --activate
sudo -u www-data wp redis enable
sudo -u www-data wp redis status

The status must read Connected; Redis listens on 127.0.0.1 and ::1 only. PHP-FPM runs at most five workers by default (pm.max_children in /etc/php/$PHPV/fpm/pool.d/www.conf): raise it on larger plans while all workers still fit in memory.

Secure and back up WordPress

Open only SSH, HTTP and HTTPS

apt install -y ufw
ufw limit 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
ufw status verbose

Answer y to the SSH warning, and use your own SSH port if you changed it. Port 80 serves the redirect to HTTPS and Certbot's renewals.

Update automatically

Since WordPress 5.6, new installations update themselves to minor and major releases, and our test install had major updates on. Plugins and themes need switching on:

cd /var/www/example.com
sudo -u www-data wp plugin auto-updates enable --all
sudo -u www-data wp theme auto-updates enable --all

Update checks are WP-Cron events, and WP-Cron runs only when pages load, so hand it to the system scheduler:

sudo -u www-data wp config set DISABLE_WP_CRON true --raw
echo '*/5 * * * * www-data cd /var/www/example.com && /usr/local/bin/wp cron event run --due-now --quiet' > /etc/cron.d/wordpress

Tighten file permissions

find /var/www/example.com -type d -exec chmod 755 {} +
find /var/www/example.com -type f -exec chmod 644 {} +
chmod 640 /var/www/example.com/wp-config.php

On Ubuntu, sudo gives www-data a umask of 002, so the files WP-CLI created are group-writable; these commands restore 755 and 644 and keep wp-config.php private. To stop PHP from changing code at all, give the files to another user and let www-data write only to wp-content/uploads: automatic updates then stop, and you update with WP-CLI as that user.

Limit logins and XML-RPC

Slow down password guessing: create /etc/nginx/conf.d/wp-login-limit.conf with this line,

limit_req_zone $binary_remote_addr zone=wplogin:10m rate=10r/m;

then add these blocks to the server block (php8.2-fpm.sock on Debian 12), run nginx -t and reload:

location = /wp-login.php {
    limit_req zone=wplogin burst=5 nodelay;
    limit_req_status 429;
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

location = /xmlrpc.php {
    deny all;
}

Each address gets six quick login requests, then one every six seconds: in our test, the seventh rapid request got error 429. The second block turns off the XML-RPC API, through which other applications create and edit posts, media and comments. Leave that block out if you need XML-RPC, as Jetpack does.

Snapshots and off-server backups

Before large updates, request Take a snapshot under Server actions on your server's page; VPS plans include 2 to 5 snapshots. Snapshots live with the VPS, so also dump the database and send /var/www and the dumps elsewhere with restic or Borg, as in VPS snapshots and off-site backups:

mkdir -p /root/db-dumps
chmod 700 /root/db-dumps
mariadb-dump --single-transaction wordpress > /root/db-dumps/wordpress.sql

Sending mail from WordPress

Through PHP's mail function, WordPress hands password resets, comment notices and shop orders to /usr/sbin/sendmail. On the Debian and Ubuntu systems we tested, that program did not exist and wp_mail() returned false, and outbound port 25 is closed by default on our network anyway. You have two ways to send:

  1. An SMTP relay on port 587, the simpler way. Take a mail service with authenticated SMTP submission, add its SPF and DKIM records to your DNS, and connect WordPress with a plugin such as FluentSMTP, which is free and works with any SMTP server. The port 25 block does not apply to port 587.
  2. Direct delivery on port 25. Request Open port 25 (outgoing mail) under Server actions on the server's page, saying what you will send and from which domain. Then request Set the reverse DNS (PTR) for your mail hostname, and publish SPF and DKIM records.

Either way, spam and phishing are zero-tolerance offenses and end the service at once.

A CDN in front of an offshore site: what it changes

You do not need a CDN for protection: DDoS mitigation is included on our network, with always-on filtering at the edge. A CDN can speed up a site for distant readers, but it adds a company, with its own jurisdiction and complaint rules, between your visitors and your server.

Take Cloudflare, Inc., of San Francisco. Traffic to a proxied site routes through Cloudflare, and such a reverse proxy can decrypt it. Cloudflare forwards copyright complaints to website operators and hosting providers, gives rights holders the hosting provider's information and lets organizations in its trusted reporter program obtain origin IP addresses. With abuse complaints, it passes the origin IP address to the hosting provider.

So a CDN hides your server's address from the public, not from complainants. If you use one, configure Nginx's real IP module with the CDN's address ranges, or the login limit above will count the CDN's servers instead of your visitors.

Frequently asked questions

What is offshore WordPress hosting?

It is WordPress running on a server in another country, chosen for its law. To host a website offshore this way, you rent a VPS there and install WordPress on it. The host then follows local law: US DMCA notices are not actioned, while local courts and, in EU countries, Digital Services Act notices can still require action.

Yes. Renting a server abroad is legal almost everywhere; what can make it illegal is the use. Illegal content stays illegal offshore, the server's country decides what its host must do, and your own country's law still applies to you. Our article is offshore hosting legal covers data protection, sanctions and tax.

Can I host a WordPress site anonymously?

Partly. Our account is an email address and a password, paid in crypto, with no identity check, as on our no-KYC VPS. But anonymous website hosting also depends on the domain registrar, which may ask for more and keeps what you give it. WordPress also publishes your admin name, and what you write can identify you.

Do you offer managed WordPress hosting?

No. We do not sell shared or managed WordPress hosting. You get a VPS with full root access and install WordPress on it yourself, which takes about 20 to 30 minutes with this guide. Updates, backups and security are then in your hands, and the steps above automate the updates.

How much RAM does WordPress need?

For one small site, 1 GB works with a swap file, and 2 GB is comfortable. Right after installation on our Debian 12 test system, MariaDB used about 110 MB and five PHP-FPM workers about 105 MB together; plugins make each worker larger. Plan on 4 GB for a busy blog or several sites and 8 GB for a WooCommerce shop.

Host it where the law is on your side.

Offshore VPS, dedicated, RDP and GPU servers in seven jurisdictions. No KYC, paid in crypto.

Welcome back

Sign in to manage your servers and your balance.

No KYCHuman check by Cloudflare TurnstileNo tracking