Back to Article List

Secure a Node.js production server on a VPS

Secure a Node.js production server on a VPS

Most deployment tutorials end with "your app is running." They don't say what happens if someone exploits a vulnerability in your code or a dependency. If your Node process runs as root, an attacker gets root access to the entire VPS. They can read all files, modify system configuration, install malware and pivot to other machines on your network.

A non-root process is confined. Damage is limited to your app's data and what that process can access. Security is the gap between running and running safely. This guide covers the practical steps: non-root users, file permissions, Node.js permission flags, environment variable management, HTTP security headers, rate limiting, dependency scanning and firewall rules.

Non-root user setup

Create a system user

Never run Node.js as root. Create a dedicated system user instead:

sudo adduser --system --group --shell /bin/bash nodeapp

This creates a system user called nodeapp with no password, a home directory at /home/nodeapp and a matching group. System users don't have login shells and can't SSH in. Perfect for services.

Verify the user was created:

id nodeapp
groups nodeapp

Directory ownership and permissions

Create your app directory and set ownership to the nodeapp user:

sudo mkdir -p /var/www/myapp
sudo chown -R nodeapp:nodeapp /var/www/myapp
sudo chmod 755 /var/www/myapp

chmod 755 gives nodeapp read-write-execute on the directory, and other users read-execute. Your app code is readable by others, but they can't modify it. If you have sensitive config in the directory, tighten it:

sudo chmod 750 /var/www/myapp

Now only nodeapp and members of the nodeapp group can enter the directory.

Running PM2 as non-root

Install PM2 globally (as root or with sudo), but run your app as nodeapp:

sudo npm install -g pm2
cd /var/www/myapp
sudo -u nodeapp pm2 start ecosystem.config.js
sudo pm2 startup systemd -u nodeapp --hp /home/nodeapp
sudo pm2 save

pm2 startup creates a systemd service that starts PM2 when the system boots, running under the nodeapp user. sudo pm2 save preserves your app list so PM2 restarts your apps on boot. Now your Node processes run as nodeapp, not root. If they're compromised, the attacker is confined to that user.

File permissions best practices

App files with 755 and 644

Your Node.js files should be readable but not writable by other users:

sudo find /var/www/myapp -type f -name "*.js" -exec chmod 644 {} \;
sudo find /var/www/myapp -type f -name "*.json" -exec chmod 644 {} \;
sudo find /var/www/myapp -type d -exec chmod 755 {} \;

644 means: owner read-write, group read, others read. No one but the owner can modify .js or .json files. Directories are 755: owner read-write-execute, others read-execute. This prevents accidental modifications and makes intrusions obvious (if a file suddenly has write permissions for others, something's wrong).

The .env file: 600 strictly

Your .env contains secrets. Lock it down:

sudo chmod 600 /var/www/myapp/.env
sudo chown nodeapp:nodeapp /var/www/myapp/.env

600 means: owner read-write only. Group and others have no access. If anyone else on the system could read /var/www/myapp/.env, they'd have your database passwords and API keys. Never make it 644 or 755.

SSH keys and certificates

If your app stores SSH keys or TLS certificates:

sudo chmod 600 /var/www/myapp/keys/*.pem
sudo chmod 600 /var/www/myapp/certs/*.key

Same logic: 600. Private keys readable by the owner only.

Verify ownership

After deploying code, check that files are owned correctly:

ls -la /var/www/myapp

You should see nodeapp:nodeapp for owner and group. If you see root:root, fix it:

sudo chown -R nodeapp:nodeapp /var/www/myapp

Node.js permission model with the permission flag

Understanding the permission flag

Node.js 22+ and 24+ have a stable permission model. It restricts what your process can access: file system, network or child processes. Enable it with the --permission flag in your ecosystem.config.js:

module.exports = {
  apps: [
    {
      name: 'my-api',
      script: './server.js',
      node_args: '--permission --allow-fs-read=/var/www/myapp --allow-fs-write=/var/www/myapp/logs --allow-net',
      instances: 'max',
      exec_mode: 'cluster'
    }
  ]
};

This means the Node process can read files in /var/www/myapp, write to /var/www/myapp/logs and make network requests (HTTP calls). It cannot read files outside that path or spawn child processes without explicit permission.

Allow-fs-read and allow-fs-write flags

Specify paths after each flag:

--allow-fs-read=/var/www/myapp --allow-fs-read=/etc/ssl/certs

This allows reading from the app directory and from the system certificate store. Use wildcards:

--allow-fs-read=/var/www/myapp/*

allows reading any file directly in that directory (but not subdirectories). Use --allow-fs-read=/var/www/myapp to allow the directory and everything inside recursively.

For write access, be specific:

--allow-fs-write=/var/www/myapp/logs

allows writing to /var/www/myapp/logs and files inside. Deny write access to other paths by default. If your app tries to write teh to a restricted path, it throws ERR_ACCESS_DENIED.

Network access with allow-net

--allow-net without arguments allows all network requests. To restrict to specific hosts:

--allow-net=api.example.com:443 --allow-net=db.internal:5432

The app can only make requests to those hosts and ports. If it tries to connect elsewhere, it's blocked. This limits damage if a dependency is compromised and tries to exfiltrate data.

Child process restrictions

Some apps spawn child processes (running shell commands). Don't allow this unless necessary:

--allow-child-process  # rarely needed

Most Node.js web apps don't spawn children. If you do, only use this if your code is trustworthy and you've audited the dependencies.

PM2 integration with permission flags

Pass all --permission flags via node_args in ecosystem.config.js:

module.exports = {
  apps: [
    {
      name: 'api',
      script: './server.js',
      node_args: '--permission --allow-fs-read=/var/www/api --allow-fs-write=/var/www/api/logs --allow-net --env-file=.env',
      instances: 'max',
      exec_mode: 'cluster'
    }
  ]
};

When PM2 starts the app, it passes these flags to node. If your app tries to access a restricted path, PM2 logs the error and the process crashes. This is intentional. You want to know immediately if your code is trying to do something you didn't allow.

Debugging permission errors

If your app gets ERR_ACCESS_DENIED when trying to read or write a file, the error message tells you which path is blocked. Add that path to the appropriate --allow-fs-read or --allow-fs-write flag. For example, if you see:

ERR_ACCESS_DENIED: access to /tmp/uploads is denied

Add --allow-fs-write=/tmp/uploads to your node_args. Test locally first:

node --permission --allow-fs-read=/var/www/myapp --allow-fs-write=/tmp/uploads server.js

If the app still errors, the path might be different or the app might be trying to access it in a way the permission model doesn't expect. Check your app logs and code.

Environment variable management

Native --env-file flag

Node.js 20.10+ and 22+ support --env-file natively. No need for dotenv:

node --env-file=.env server.js

Node loads variables from .env before running your app. In PM2:

module.exports = {
  apps: [
    {
      name: 'api',
      script: './server.js',
      node_args: '--env-file=.env --permission --allow-fs-read=/var/www/myapp',
      instances: 'max',
      exec_mode: 'cluster'
    }
  ]
};

Create /var/www/myapp/.env with production secrets:

DATABASE_URL=postgres://user:password@localhost/mydb
API_SECRET=your-secret-key-here
LOG_LEVEL=info
NODE_ENV=production

Access them in code with process.env.DATABASE_URL. Never hardcode secrets.

PM2 ecosystem environment config

You can also set environment variables directly in ecosystem.config.js:

module.exports = {
  apps: [
    {
      name: 'api',
      script: './server.js',
      env: {
        NODE_ENV: 'production',
        LOG_LEVEL: 'info'
      },
      env_staging: {
        NODE_ENV: 'staging',
        LOG_LEVEL: 'debug'
      }
    }
  ]
};

Run pm2 start ecosystem.config.js --env staging to use the env_staging block. This is handy for non-sensitive config. Keep secrets in .env (chmod 600) and non-secrets in ecosystem.config.js.

Secrets rotation practices

Rotate secrets regularly. If your .env is exposed, assume attackers have access to everything in it. Rotate immediately:

1. Generate new credentials (new database password, new API key, etc.)

2. Update .env with new values

3. Reload your app: pm2 reload api --update-env

4. Check logs to confirm the app loaded new values

5. If the old credentials were accessed by an attacker, they're now useless

Track which credentials you've rotated and when. For databases, change the password and revoke old users. For API keys, delete the compromised keys and create new ones. This limits the window of exposure.

HTTP security headers with Helmet

Content-Security-Policy explained

CSP tells browsers which sources of content your page is allowed to load. It prevents XSS (cross-site scripting) by blocking inline scripts:

import helmet from 'helmet';

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "https://cdn.example.com"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"]
    }
  }
}));

This CSP says: load scripts only from your domain and one CDN, load styles from your domain (and allow inline style tags), load images from your domain, data URLs and any https source. If a compromised dependency tries to load a script from evil.com, the browser blocks it.

X-Frame-Options prevents clickjacking

Helmet sets X-Frame-Options: DENY by default, which forbids iframes. An attacker can't frame your page in an invisible iframe and trick users into clicking something:

app.use(helmet({
  frameguard: {
    action: 'deny'  // forbid framing
  }
}));

If you need iframes for embedding (rare), use 'sameorigin' to allow only your domain.

Strict-Transport-Security forces HTTPS

HSTS tells browsers to always use HTTPS, even if the user types http://. Helmet sets this by default:

app.use(helmet({
  hsts: {
    maxAge: 31536000,  // 1 year
    includeSubDomains: true,
    preload: true
  }
}));

maxAge is in seconds. 31536000 is one year. After the browser sees this header once, it refuses to connect via HTTP for a year. includeSubDomains extends this to subdomains. preload submits your domain to the HSTS preload list, which is baked into browsers.

Custom Helmet configuration

Helmet sets 13 headers by default. Customize as needed:

import helmet from 'helmet';

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "https://trusted-cdn.example.com"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      upgradeInsecureRequests: []
    }
  },
  frameguard: { action: 'deny' },
  hsts: { maxAge: 31536000, includeSubDomains: true },
  xssFilter: true,
  noSniff: true,
  referrerPolicy: { policy: 'strict-no-referrer' }
}));

Test your headers with curl -i https://yourdomain.com and look for Security headers in the response. See Helmet docs for the complete list of options.

Rate limiting

Express-rate-limit setup

For Express:

npm install express-rate-limit

import rateLimit from 'express-rate-limit';

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,  // 15 minutes
  max: 100,  // limit each IP to 100 requests per windowMs
  standardHeaders: true,  // Return rate limit info in the RateLimit-* headers
  legacyHeaders: false
});

// Apply to all routes
app.use(limiter);

// Or apply to specific routes
app.post('/api/login', limiter, (req, res) => {
  // handle login
});

Fastify-rate-limit setup

For Fastify:

npm install @fastify/rate-limit

import rateLimit from '@fastify/rate-limit';

fastify.register(rateLimit, {
  max: 100,
  timeWindow: '15 minutes'
});

Per-route vs global limits

Apply global limits to all routes, then tighten specific routes:

// Global limit: 100 per 15 minutes
app.use(rateLimit({ max: 100, windowMs: 15 * 60 * 1000 }));

// Tighter limit on login endpoint: 5 per 15 minutes
app.post('/api/login', 
  rateLimit({ max: 5, windowMs: 15 * 60 * 1000 }),
  (req, res) => { /* ... */ }
);

Rate limiting slows down attackers trying to brute-force passwords or exploit endpoints. Aggressive limits (5/15min) on sensitive routes like /login or /password-reset. Loose limits (100/15min) on public routes.

Redis-backed rate limiting for clusters

In-memory rate limits don't share across servers. Use Redis for multi-server setups:

npm install rate-limit-redis redis

import RedisStore from 'rate-limit-redis';
import { createClient } from 'redis';

const redisClient = createClient();
await redisClient.connect();

const limiter = rateLimit({
  store: new RedisStore({
    client: redisClient,
    prefix: 'rl:',  // rate limit key prefix
  }),
  max: 100,
  windowMs: 15 * 60 * 1000
});

Now all servers in your cluster share the same rate limit counters. If server A sees 50 requests from 192.168.1.1, and server B sees 60 from the same IP, the total is 110 and the client gets rate-limited.

Dependency security

npm audit and automated fixes

Regularly audit your dependencies for known vulnerabilities:

npm audit

This shows a list of vulnerabilities with severity (critical, high, moderate, low). High and critical issues should be fixed immediately:

npm audit fix

This updates vulnerable packages to patched versions automatically. If there's no patch available, the output tells you.

Socket.dev for supply chain analysis

npm audit only checks for known CVEs. Socket.dev detects suspicious behavior in packages: unusual system calls, shell execution, credential theft, etc. Visit socket.dev, connect your GitHub repo and Socket analyzes every dependency for red flags. It recieve the Shai-Hulud attack in 2025 (over 500 malicious packages exfiltrating credentials via TruffleHog).

Check Socket reports before accepting new dependencies. Look for signals like: new maintainer accounts, install scripts, obfuscated code and network activity you can't explain. When evaluating a package, Socket gives it a score out of 100 across Supply Chain Security, Vulnerability, Quality, Maintenance and License.

Lockfile integrity

Commit your package-lock.json (or yarn.lock) to git. This ensures everyone installs the exact same versions. When you deploy, use npm ci instead of npm install:

npm ci --production

npm ci reads package-lock.json and installs exact versions. It's faster and safer than npm install, which can update minor/patch versions. An attacker who modifies package.json but not package-lock.json gets blocked.

CI/CD integration

Automate dependency scanning in your CI pipeline:

# .github/workflows/security.yml
name: Security Audit

on: [push, pull_request]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 22
      - run: npm ci
      - run: npm audit --audit-level=moderate
        # fail if moderate or higher vulnerabilities exist

This runs npm audit on every push and pull request. Block merges if high or critical vulnerabilities are found. This catches supply chain problems before they reach production.

Firewall with ufw

Default deny incoming

Start with a restrictive firewall that denies everything by default, then allow only what you need:

sudo ufw default deny incoming
sudo ufw default allow outgoing

All incoming connections are blocked. Outgoing is allowed (so your app can make API calls). Now whitelist specific ports.

Allow SSH, HTTP, HTTPS

Open the ports your users need:

sudo ufw allow 22/tcp     # SSH
sudo ufw allow 80/tcp     # HTTP
sudo ufw allow 443/tcp    # HTTPS
sudo ufw enable

Check the status:

sudo ufw status

You should see SSH, 80 and 443 allowed and the firewall active.

Internal-only ports

If you have internal services (Redis, database on the same machine), don't expose them to the network:

sudo ufw allow from 127.0.0.1 to 127.0.0.1 port 6379

This allows connections from localhost to port 6379 (Redis) only. External traffic to 6379 is blocked. Your Node app on localhost can reach Redis. An attacker from the internet cannot.

Fail2ban for brute force protection

Ufw is good for network-level rules. Fail2ban watches logs and bans IPs showing malicious behavior:

sudo apt update && sudo apt install -y fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

Create /etc/fail2ban/jail.local:

[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 300
bantime = 86400

This bans any IP that fails SSH authentication 3 times in 300 seconds for 86400 seconds (24 hours). Fail2ban reads /var/log/auth.log, detects the failed attempts and adds a firewall rule automatically. The attacker is locked out.

Check banned IPs:

sudo fail2ban-client status sshd

SSH hardening

Key-based authentication only

Disable password authentication. Use SSH keys instead. Edit /etc/ssh/sshd_config:

PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

Reload SSH:

sudo systemctl restart ssh

Now SSH access requires an authenticated key. Attackers can't brute-force passwords because password auth is disabled.

Disable root login

In /etc/ssh/sshd_config:

PermitRootLogin no

No one can SSH directly as root. You login as a regular user (deploy) and use sudo if you need root. This prevents attackers from targeting root directly.

Custom SSH port

Port 22 is the default SSH port. Botnets scan for it. Change it:

Port 2222

in /etc/ssh/sshd_config. This is not a security measure (security through obscurity is weak), but it stops automated port scans from bothering your SSH daemon. You'll need to update ufw and your client config:

sudo ufw allow 2222/tcp
ssh -p 2222 [email protected]

This is optional and adds minor friction. Most VPS hosts recommend leaving it at 22.

Keeping Node.js updated

Node.js releases security patches regularly. Check your LTS schedule. See the Node.js upgrade guide for step-by-step instructions.

Key dates: Node 20 LTS ends April 30, 2026. Node 22 LTS ends April 30, 2027. Node 24 LTS (released April 2025) ends April 30, 2028. Plan upgrades around these dates.

Security checklist

Before going live, verify every item:

Node.js runs as non-root user (nodeapp, not root)

.env is chmod 600, owned by nodeapp, never committed to git

--permission flags are set in PM2 config (--allow-fs-read, --allow-fs-write, --allow-net)

Helmet is installed and all security headers are set

Rate limiting is configured on public routes (especially login, password reset)

npm audit shows zero high or critical vulnerabilities

Firewall allows only 22 (SSH), 80 (HTTP) and 443 (HTTPS)

Fail2ban is installed and monitoring SSH attacks

SSH key-based auth is enabled, password auth disabled, root login disabled

Node.js is the latest LTS for your version (check nodejs.org/about/releases)

Nginx is the only process listening on 80 and 443 (Fastify/Express listens on 3000 internally)

All secrets in .env are strong and rotated at least quarterly

Package-lock.json is committed to git and npm ci is used in production

Your idea deserves better hosting

24/7 support 30-day money-back guarantee Cancel anytime
Platební období

1 GB RAM VPS

$3.99 Save  25 %
$2.99 Měsíčně
  • 1 vCPU AMD EPYC
  • 30 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Správa firewallu
  • Monitorování serveru zdarma

2 GB RAM VPS

$5.99 Save  17 %
$4.99 Měsíčně
  • 2 vCPU AMD EPYC
  • 30 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Správa firewallu
  • Monitorování serveru zdarma

6 GB RAM VPS

$14.99 Save  33 %
$9.99 Měsíčně
  • 6 vCPU AMD EPYC
  • 70 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Správa firewallu
  • Monitorování serveru zdarma

AMD EPYC VPS.P1

$7.99 Save  25 %
$5.99 Měsíčně
  • 2 vCPU AMD EPYC
  • 4 GB RAM paměť
  • 40 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

AMD EPYC VPS.P2

$14.99 Save  27 %
$10.99 Měsíčně
  • 2 vCPU AMD EPYC
  • 8 GB RAM paměť
  • 80 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

AMD EPYC VPS.P4

$29.99 Save  20 %
$23.99 Měsíčně
  • 4 vCPU AMD EPYC
  • 16 GB RAM paměť
  • 160 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

AMD EPYC VPS.P5

$36.49 Save  21 %
$28.99 Měsíčně
  • 8 vCPU AMD EPYC
  • 16 GB RAM paměť
  • 180 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

AMD EPYC VPS.P6

$56.99 Save  21 %
$44.99 Měsíčně
  • 8 vCPU AMD EPYC
  • 32 GB RAM paměť
  • 200 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

AMD EPYC VPS.P7

$69.99 Save  20 %
$55.99 Měsíčně
  • 16 vCPU AMD EPYC
  • 32 GB RAM paměť
  • 240 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

EPYC Genoa VPS.G1

$4.99 Save  20 %
$3.99 Měsíčně
  • 1 vCPU AMD EPYC Gen4 AMD EPYC Genoa 4. generace 9xx4 s 3,25 GHz nebo podobným výkonem, založený na architektuře Zen 4.
  • 1 GB DDR5 RAM paměť
  • 25 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

EPYC Genoa VPS.G2

$12.99 Save  23 %
$9.99 Měsíčně
  • 2 vCPU AMD EPYC Gen4 AMD EPYC Genoa 4. generace 9xx4 s 3,25 GHz nebo podobným výkonem, založený na architektuře Zen 4.
  • 4 GB DDR5 RAM paměť
  • 50 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

EPYC Genoa VPS.G4

$25.99 Save  27 %
$18.99 Měsíčně
  • 4 vCPU AMD EPYC Gen4 AMD EPYC Genoa 4. generace 9xx4 s 3,25 GHz nebo podobným výkonem, založený na architektuře Zen 4.
  • 8 GB DDR5 RAM paměť
  • 100 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

EPYC Genoa VPS.G6

$48.99 Save  31 %
$33.99 Měsíčně
  • 8 vCPU AMD EPYC Gen4 AMD EPYC Genoa 4. generace 9xx4 s 3,25 GHz nebo podobným výkonem, založený na architektuře Zen 4.
  • 16 GB DDR5 RAM paměť
  • 200 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

EPYC Genoa VPS.G7

$74.99 Save  27 %
$54.99 Měsíčně
  • 8 vCPU AMD EPYC Gen4 AMD EPYC Genoa 4. generace 9xx4 s 3,25 GHz nebo podobným výkonem, založený na architektuře Zen 4.
  • 32 GB DDR5 RAM paměť
  • 250 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

1 vCPU AMD Ryzen 9

$13.99 Save  29 %
$9.99 Měsíčně
  • Dedikované CPU 4.5GHz AMD Ryzen 9 7950X s nativní frekvencí CPU 4.5 GHz.
  • 4 GB DDR5 RAM paměť
  • 50 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

2 vCPU AMD Ryzen 9

$25.99 Save  19 %
$20.99 Měsíčně
  • Dedikované CPU 4.5GHz AMD Ryzen 9 7950X s nativní frekvencí CPU 4.5 GHz.
  • 8 GB DDR5 RAM paměť
  • 100 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

8 vCPU AMD Ryzen 9

$92.99 Save  30 %
$64.99 Měsíčně
  • Dedikované CPU 4.5GHz AMD Ryzen 9 7950X s nativní frekvencí CPU 4.5 GHz.
  • 32 GB DDR5 RAM paměť
  • 400 GB NVMe úložiště
  • Neomezený přenos dat
  • IPv4 a IPv6 v ceně Podpora IPv6 momentálně není dostupná ve Francii, Finsku a Nizozemsku.
  • 1 Gbps síť
  • Automatická záloha v ceně
  • Správa firewallu
  • Monitorování serveru zdarma

FAQ

What happens if Node runs as root and gets compromised?

An attacker can read all files on the VPS, modify system configuration, create new accounts, install malware and pivot to other systems. A non-root process is confined to that user's permissions. Damage is limited.

Skip the setup, start deploying

Your server comes ready with PM2, Nginx and Certbot. Pick a datacenter and push your first build in minutes.

GPU products are in high demand at the moment. Fill the form to get notified as soon as your preferred GPU server is back in stock.