Running your own GitLab, Jira and related DevOps tools on a VPS gives you more control over code, issues, CI/CD and data handling. But it also turns your team into a mini hosting provider: you now own capacity planning, storage growth, backups and security hardening. Undersized VPS plans, missing backups and weak security defaults can undermine an otherwise successful installation. This guide explains how to size and secure a VPS for a self-hosted DevOps stack. You’ll see illustrative resource budgets for different team sizes, example architectures (single VPS vs multiple servers), concrete security steps and how to avoid common bottlenecks around RAM, disk I/O and CI pipelines. The goal is simple: by the end, you should know what kind of VPS (or dedicated server) you actually need, how to structure your GitLab/Jira stack and which hardening steps to apply from day one.
Why Self-Host GitLab, Jira and DevOps Tools on a VPS?
Control and Compliance
Many teams move Git hosting, issue tracking and CI/CD in-house because they need strict control over data location, retention and access. When choosing a VPS or dedicated server, verify the available data center regions, administrative access and backup options. Define log retention, backup retention and access controls for the stack you operate. These controls can support contractual and KVKK/GDPR obligations, but self-hosting alone does not establish compliance.
Integration Freedom
This guide covers GitLab Self-Managed and Jira Software Data Center under an eligible existing subscription. Scope checked on 4 November 2026: Jira Server and Bitbucket Server support ended on 15 February 2024. New-customer sales of Jira Software Data Center ended on 30 March 2026; existing customers can buy new subscriptions and expansions until 30 March 2028. The ordinary end-of-life date is 28 March 2029, when expiring subscriptions make the products read-only. Any maintenance extension requires a specific Atlassian exception. Check Atlassian’s current transition policy and your contract. This is therefore a planning guide for eligible existing Jira customers, not a low-cost new Data Center purchase recommendation for small teams. Without that entitlement, evaluate GitLab issue tracking, Jira Cloud or another tool’s currently available self-hosted edition. Bitbucket and Bamboo Data Center are excluded from this EOL and continue through Hybrid licensing.
- Git repositories and merge requests in GitLab
- Issue tracking and project management in an eligible Jira Software Data Center installation
- GitLab CI runners or other CI agents building and testing code
- Container registry, artifact repositories and package registries
- Monitoring, logging, VPN and internal dashboards
On your own VPS you can tune every component: custom runners, caching layers, reverse proxies, WAF rules, private networks between services and custom backup flows. You’re not limited to a fixed SaaS feature set.
Comparing Long-Term Costs
When your team grows, per-user SaaS pricing for Git and issue tracking can climb quickly. A well-sized VPS or dedicated server can be more cost-effective for some workloads, but there is no universal break-even user count or CI-minute threshold. Compare hosting, required software licences, backups, administration and recovery costs against SaaS pricing. Right-sizing resources and tracking memory, disk and CPU utilisation are part of that comparison. Our guide to managing RAM, swap and the OOM killer on VPS servers explains how to track and tune memory usage so you don’t pay for idle capacity—or crash under load.
Capacity Planning: How Big Should Your VPS Be?
The technical examples use GitLab 19.x and Jira Software Data Center 11.3; check the security notices and platform matrix for the exact patch release you deploy. Developer counts are scenario labels, not capacity thresholds. The current GitLab requirements give a single-node baseline of 8 vCPU and 16 GB RAM. A specifically tuned memory-constrained installation can run with 8 GB, but that is not a combined production budget for GitLab and Jira. Add application/OS storage, repositories, databases, registries, logs, temporary files and backups separately. All other budgets below are hypothetical and need representative workload measurements.
Key Components and Their Resource Profiles
- GitLab core (web, API, background workers): Ruby and Go services; memory-hungry, benefits from multiple vCPUs and fast SSD/NVMe.
- GitLab database (PostgreSQL): latency-sensitive, prefers dedicated RAM and low disk latency.
- GitLab Redis/Valkey: used for caching and queues; relatively small but needs low latency.
- Jira application: Java-based; JVM heap + OS memory; can grow significantly with plugins and users.
- Jira database: the Jira 11.3 matrix lists PostgreSQL 16/17 and MySQL 8.4; MariaDB and Percona are not supported. Use the matrix for your Jira release, including its Java 21 requirement.
- CI runners (Docker-in-Docker, shell or Kubernetes runners): CPU- and RAM-intensive; each job eats resources for the build duration.
- Container registry / artifact storage: I/O- and disk-capacity heavy; needs good throughput and a clear retention policy.
- Reverse proxy (Nginx, Traefik, HAProxy): lightweight but critical for SSL/TLS and routing.
Scenario 1: Small Team (5–10 Developers)
For a small team, separate the GitLab and runner budgets first. Add Jira only under an eligible existing licence, with its own application host and database service. Jira Software Data Center starts at a 500-user licence tier; this example does not imply that a cheap 5–10-user self-hosted licence is available. Atlassian’s licensing tiers also affect Marketplace app costs.
- GitLab using its own PostgreSQL and Redis/Valkey components.
- Jira on a separate application VPS with a supported database instance dedicated to Jira. Do not add Jira to PostgreSQL managed by GitLab’s Linux package.
- CI runners on separate hosts and network boundaries; pipeline code is a workload with access to any credentials supplied to it.
Planning inputs to validate before choosing a VPS:
- GitLab: 8 vCPU/16 GB RAM single-node baseline. An illustrative 300–500 GB SSD/NVMe allowance must be checked against repository, retention and growth estimates.
- Jira: Budget JVM heap, off-heap memory, OS, plugins and database resources separately; GitLab’s RAM baseline does not include Jira.
- Runners: 4 vCPU/8 GB RAM is only a trial budget for lightweight jobs, with concurrency established by measurement.
- Transfer: Estimate repository pulls, image layers, artifacts, backups and their frequency; no universal monthly transfer minimum applies.
Check each service budget against its peak demands and leave capacity for maintenance and growth. Measure CPU and memory use per job, cap concurrency and leave headroom for core services before increasing the job count. Using containers for each service as described in our guide to running isolated Docker containers on a VPS helps organise services, but CPU and memory limits must be configured explicitly; containers have no resource constraints by default.
Scenario 2: Growing Team (20–50 Developers)
For a hypothetical team of 20–50 developers, sustained CI load may justify splitting the stack. Use measured contention and job concurrency, rather than a fixed developer-count threshold, to decide. One possible layout:
- GitLab host: Application/Gitaly resources with GitLab-specific PostgreSQL and Redis/Valkey services.
- Jira host: Separate application resources and a separate Jira database instance.
- Database lifecycle: GitLab 19.x supports PostgreSQL 17–18; Jira 11.3 lists PostgreSQL 16–17. The common version 17 does not by itself establish support for a shared instance. This design keeps instances, databases, users, extensions, upgrades and backups independent. Follow GitLab’s external database and schema rules; do not treat its bundled database as a general-purpose Jira service.
- Runner hosts: Separate from persistent registry/analysis services and production database access.
Illustrative budgets to validate against release requirements and peak load:
- GitLab: 8 vCPU/16 GB RAM and 300–500 GB storage form an illustrative single-node planning budget; distributed deployments need the per-component reference sizing.
- Jira and databases: Measure CPU, RAM, connections, I/O latency and backup space separately for each instance.
- Runner VPS: A hypothetical 4–8 vCPU/8–16 GB RAM budget may target lightweight jobs; even 4–6 concurrent jobs require measurement. One heavy build may exceed it.
- Registry/SonarQube: Add their own version requirements, retention capacity and analysis load.
Separating CI runners reduces direct CPU and memory contention on the core GitLab/Jira host. It also allows runner capacity to scale independently, but additional jobs still increase demand on GitLab, registries, storage and networking; monitor those services as runner capacity grows.
Scenario 3: Larger Setup (50+ Developers or Heavy CI)
For larger teams or heavy continuous integration, think in terms of roles rather than one big server:
- GitLab HA: The 3K reference architecture is scoped to Premium/Ultimate. It includes load balancing, Rails/Sidekiq, PostgreSQL/Patroni/PgBouncer, Redis/Sentinel, Gitaly/Praefect, a separate Praefect database and object storage. Full HA for Praefect’s database requires a third-party PostgreSQL solution. Replicating PostgreSQL and adding application nodes alone is not an HA design. The single-node 1K architecture is not HA.
- Jira clustering: Requires a Data Center licence, nodes on the same Jira version, separate local homes, a shared home, a common supported Jira database and a load balancer with session affinity and WebSocket support. The shared Jira database is not shared with GitLab. Follow the Jira cluster prerequisites.
- Runners: Scale separate hosts by job demand and trust level. Autoscaling requires an executor and infrastructure integration that support it.
- Persistent services: Size registry, object storage and monitoring separately, including their failure recovery paths.
This can be built with larger VPS plans or a mix of VPS and dedicated servers. Use fast NVMe disks for Git and database servers, and calculate container-image and artifact capacity from measured growth and retention, with lifecycle policies to prune old data.
Plan for Memory, Not Just CPU
GitLab, Jira and databases will use significant RAM. Starved memory leads to swapping, slow builds and even crashes. GitLab recommends disabling swap where possible, or providing enough RAM that GitLab never needs it. Use memory-pressure monitoring, as explained in our detailed guide on RAM, swap and the OOM killer for VPS servers. Aim for:
- Enough RAM for core services and their maintenance tasks without swapping in normal operation.
- Swap, if retained as an emergency buffer, does not replace sufficient RAM.
- Alerts for memory pressure, swap use, JVM/worker limits and out-of-memory events.
Architecture Choices: One VPS or Multiple Servers?
Single VPS: Scope and Trade-Offs
Co-hosting GitLab and Jira is something to assess in a non-production evaluation, not an assumed production baseline. This guide gives Jira a separate application host; its official cluster guidance recommends avoiding additional applications on Jira servers. If evaluating one host:
- Verify the existing Jira licence and both releases’ requirements.
- Add combined peak CPU, memory and I/O demands; developer count alone is insufficient.
- Keep CI on separate hosts and accept the shared maintenance and failure window.
- Keep application data, database instances, credentials and backups separate.
A single host reduces the number of machines to administer but concentrates failures and resource contention. It still needs separate application-aware backup and recovery procedures. Containers do not remove those shared-host constraints.
Separate CI Runners Early
Even small teams should consider a separate VPS for CI runners. CI jobs are bursty and resource-hungry; building a large Docker image or running end-to-end tests can temporarily consume a huge chunk of CPU and RAM. Separate runner hosts reduce direct CPU and RAM contention with core services, though pipeline traffic can still load GitLab, registries and shared storage.
Dev, Staging and Production Environments
Some teams run “internal staging” instances of GitLab or Jira for plugin testing, upgrades and major configuration changes. Others use a single production instance but separate environments for hosted applications. Our article on hosting architecture for development, staging and production environments explains the trade-offs between one big server and multiple VPS setups. The same principles apply to your DevOps tooling: staging instances reduce upgrade risk but add operational overhead.
When a Dedicated Server or Colocation Makes Sense
Heavy CI, large repositories or steady high utilisation may justify dedicated hardware or colocation. Compare measured demand, storage latency, resource allocation, hardware replacement, redundancy and total operating cost with the actual service specification. A dedicated machine is still a single failure domain unless the architecture addresses that risk.
Security Hardening for GitLab, Jira and DevOps Stacks
GitLab and Jira hold your source code, credentials, access tokens and infrastructure secrets. Treat this VPS like a crown jewel. Security is a layered exercise: operating system, network, application and identity.
1. OS and SSH Hardening
Before you even install GitLab or Jira, lock down the server:
- Keep the OS and applications patched with a maintenance and recovery plan.
- Verify a separate admin account, a fresh key-based SSH session, sudo and recovery-console access before disabling password and direct root login. Keep the current session open while checking the change.
- Use individual accounts and scoped privileges; hardware-backed keys can strengthen admin authentication.
- Changing the SSH port is only a minor nuisance barrier. Fail2ban or similar controls complement authentication and firewall policy.
Our VPS security hardening checklist walks through sshd_config, Fail2ban, automatic updates and disabling root SSH in detail. Adapt its checks to the host and verify access before changing SSH policy.
2. Firewall and Network Segmentation
At minimum, only expose the ports you actually need:
- HTTPS 443 for web and Git-over-HTTPS access; HTTP 80 only where redirects or the chosen certificate validation method need it.
- Admin SSH restricted to a VPN or approved administrator IPs. Developer Git-over-SSH is a distinct access path: do not break it by applying an admin-only IP list to the shared endpoint; plan endpoints/ports and GitLab application authorisation deliberately.
- Database access only from the relevant application nodes and controlled backup/admin processes. Do not grant runner jobs production database access.
Use the OS firewall (ufw, firewalld or raw iptables/nftables) as part of enforcing this policy. If you use Docker, published container ports can bypass the filtering you expect from ufw/firewalld; do not rely on host rules alone. Review port publishing and Docker networking rules together, avoid publicly publishing internal services such as databases, and test access from both permitted and untrusted networks. Our article on firewall configuration on VPS servers shows concrete ufw and firewalld examples that you can adapt for GitLab and Jira nodes.
For larger setups, consider placing GitLab/Jira behind a reverse proxy or WAF (Nginx, HAProxy, ModSecurity, Cloudflare, etc.) for the controls you need, such as rate limits, IP allowlists and TLS termination. Verify Git transfers, artifact uploads, webhooks and SSO against the proxy/WAF rules.
3. TLS/SSL and HTTP Security Headers
Configure HTTPS explicitly for web and Git-over-HTTPS access, including GitLab’s external URL, Jira’s base URL/connector and trusted reverse-proxy settings. Git-over-SSH uses SSH authentication separately. Use suitable TLS 1.2/1.3 settings and monitor certificate renewal. Enable HSTS only after permanent HTTPS is ready; includeSubDomains also affects child hosts. Test CSP and other headers against the application’s existing policy, SSO, plugins and embedded content before enforcing them.
dchost.com’s blog has multiple deep dives on HTTP security headers and keeping TLS configurations secure on real-world servers; consider following those patterns for your DevOps endpoints as well.
4. Application-Level Security
Inside GitLab and Jira themselves, review:
- Authentication: Use strong authentication and 2FA for admins. Verify which SSO/MFA features your edition, identity provider and plugins support, with recovery access documented.
- Access control: Use groups, project permissions and roles; avoid everyone having Owner/Admin access.
- Tokens and secrets: Scope tokens by job/environment, set expiries and revoke leaked credentials. Keep secrets out of repositories, image layers and logs. Masked/protected CI variables and environment variables do not prevent malicious job code from stealing values it receives; review pipeline and fork changes before exposing secrets.
- Webhooks and integrations: Restrict webhooks to trusted destinations; verify incoming callbacks using the integration’s documented authentication mechanism.
- Plugins (especially in Jira): Only install well-maintained, necessary add-ons and keep them updated.
5. Logs, Monitoring and Alerts
Self-hosting means you’re also responsible for noticing when something breaks or gets attacked. At a minimum:
- Collect system logs (auth, kernel, firewall) and application logs (GitLab, Jira, Nginx).
- Monitor CPU, RAM, disk usage, I/O wait and network throughput.
- Set alerts for unusual login patterns, repeated 500 errors or sudden spikes in 4xx/5xx responses.
If you centralise logs across multiple VPS servers, GitLab can emit structured logs to a logging stack (Loki, ELK, etc.). Our guide on centralising logs for multiple servers is a good starting point for a multi-node DevOps environment.
Storage, Backups and Disaster Recovery
Understand Your Storage Growth
GitLab and Jira storage usage tends to grow in bursts:
- New repositories and forks
- Binary artifacts, build logs and test reports
- Docker images in the container registry
- Attachments in Jira issues (screenshots, docs, logs, exports)
Plan not only for today’s disk usage but for 12–24 months ahead. Measure storage latency and IOPS as well as capacity under representative Git, database and CI traffic. For large artifact and image storage, use only the application’s supported object-storage integration and retention controls; moving active files manually can break references.
Backup Strategy: More Than Snapshots
Snapshots at the VPS level are useful, but they are not enough on their own. For GitLab and Jira you should have:
- GitLab: Follow its application-aware backup procedure. The normal archive does not include configuration/secrets, Redis or externally stored object data. Keep protected copies of configuration, secrets and TLS/SSH keys; back up object storage and registry data separately. Follow the documented background-job quiescing requirements for a consistent backup.
- Jira: Coordinate its supported database backup with the home/shared-home copy and the selected search engine/plugins. An arbitrary live rsync or VPS snapshot alone does not establish application consistency.
- Off-site copies: Keep encrypted copies with separate access in an independent environment; verify the storage service’s region, retention and recovery features.
- Restore validation: Rehearse in isolation, checking repositories, tickets/attachments, login and integrations. GitLab restoration requires the exact version and CE/EE type used to make the backup. Measure the elapsed time against the recovery objective.
If you already use S3-compatible object storage, tools like rclone or restic can transport and retain backup artifacts after the application-aware capture step. Our article on automating off-site backups to object storage with rclone, restic and cron explains the transport and scheduling layer; add each application’s consistency, secret and restoration requirements.
RPO/RTO for DevOps Tools
Define clear objectives:
- RPO: The maximum data loss your team can accept; use it to choose backup frequency and retention.
- RTO: The acceptable outage; include provisioning, data transfer, restoration and functional checks when measuring it.
These numbers dictate how often you run backups and how you design recovery. For example, if you need short RTO, evaluate a documented standby/recovery design and measure its promotion procedure; a standby’s age, consistency and dependencies determine the actual recovery time.
Running GitLab and Jira with Containers on a VPS
Many teams prefer to run GitLab, Jira and supporting services with Docker or container runtimes for repeatable packaging and manageable service boundaries, using the supported official images and version-specific upgrade procedure.
Benefits of Containerising Your DevOps Stack
- Resource control: Configure CPU/RAM limits explicitly; containers have no resource limits by default and still share the host kernel.
- Reproducibility: Pin image versions and test the same configuration in staging.
- Upgrade recovery: Keep persistent volumes and backups. Returning to an older image alone does not undo database migrations or ensure data compatibility.
- Host maintenance: A cleaner package layout still requires kernel, container-runtime, firewall and access maintenance.
However, containerisation doesn’t remove the need for VPS hardening. You still must secure SSH, firewalls, backups and the host kernel. Our tutorial on running isolated Docker containers on a VPS is a good reference if you plan to containerise GitLab, Jira, PostgreSQL and Redis on one or more servers.
Where CI Runners Should Live
Runner jobs execute repository-controlled code. The shell executor is suitable only for trusted builds. Privileged Docker-in-Docker or mounting the host Docker socket can expose the host; use isolated, ephemeral hosts and tight network boundaries where privileged builds are necessary. Persistent runners retain workspaces/caches and cannot be assumed stateless. Separate trust levels and secrets, clean up jobs and measure per-job CPU/RAM/I/O before raising concurrency. Autoscaling also depends on the supported executor and provider integration. See GitLab’s runner security guidance.
Choosing Infrastructure and an Operating Plan
Designing a stable home for GitLab, Jira and your DevOps tools on a VPS is mostly about being intentional: know your team size, CI workload, growth expectations and security requirements. Confirm the existing Jira entitlement and transition deadline, then size GitLab, Jira, databases and separate runners independently. Use storage measurements and recovery objectives to select the hosts. Lock down the host with solid SSH, firewall and update policies, following our first 24 hours on a new VPS checklist and the VPS security hardening guide. Then put serious thought into backups and recovery, using off-site object storage where appropriate.
When comparing DCHost VPS, dedicated-server and colocation options, verify the current resource allocation, storage, network, backup and support terms. Distinguish infrastructure support from responsibility for GitLab/Jira licensing, administration and recovery. A representative pilot provides a measurable basis for scaling; include Jira’s 2029 transition in the long-term plan.





