en

Offshore VPS for Developers: Setup and Workflow Guide

An offshore VPS is an ideal development infrastructure component for developers who need privacy, freedom from geographic restrictions, and full control over their environment. Whether you are using it as a CI/CD runner, remote development server, Docker host, or staging environment, this guide covers the developer-specific setup and workflow optimizations.

Need this done for your project?

We implement, you ship. Async, documented, done in days.

Start a Brief

Docker Installation and Container Workflow

Docker is the foundation of modern development workflows on VPS. Install Docker from the official repository for the latest stable version - do not use the distribution's package as it is often outdated. Run the official install script: `curl -fsSL https://get.docker.com | sh`. Add your non-root user to the docker group: `usermod -aG docker youruser`. Log out and back in for the group change to take effect. Install Docker Compose V2 (the plugin version, not the standalone script): `apt install docker-compose-plugin`. Verify with `docker compose version`. Create a directory structure for your projects: `/opt/apps/projectname` with a `docker-compose.yml` and `.env` file per project. Never commit `.env` files to version control - use `.env.example` as a template. Enable BuildKit for faster image builds: set `DOCKER_BUILDKIT=1` in your shell profile, or add `{ "features": { "buildkit": true } }` to `/etc/docker/daemon.json`. Configure log rotation in daemon.json to prevent logs from filling your disk: `"log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }`. Set `"live-restore": true` so containers keep running during Docker daemon updates. Restart Docker to apply: `systemctl restart docker`.

SSH Tunnels and Remote Development Setup

SSH tunnels let you securely access services running on your VPS as if they were local. Forward a remote port to localhost: `ssh -L 8080:localhost:3000 user@vps-ip` makes your VPS's port 3000 available at `localhost:8080` on your machine. This is invaluable for accessing databases, admin panels, and development servers without opening ports in your firewall. For persistent tunnels, use `autossh`: `apt install autossh` locally, then `autossh -M 0 -f -N -L 5432:localhost:5432 user@vps-ip` to keep a PostgreSQL tunnel alive permanently. Create a systemd user service for tunnels you need at all times. Configure your local `~/.ssh/config` with server aliases, identity file paths, and `ControlMaster` settings to share connections: `ControlMaster auto`, `ControlPath ~/.ssh/cm-%r@%h:%p`, `ControlPersist 10m`. This reduces connection overhead dramatically when running multiple SSH commands in quick succession. VS Code Remote SSH extension lets you edit files on your VPS as if they were local, with full language server support, integrated terminal, and port forwarding. Install the Remote-SSH extension, add your VPS to `~/.ssh/config`, and connect via the Remote Explorer panel. The code runs on the VPS so you get the full power of the remote CPU/RAM for compilation and language servers while keeping your local UI responsive. This is particularly valuable for large codebases or resource-intensive builds.

CI/CD Pipelines with GitHub Actions Self-Hosted Runners

Running your own GitHub Actions runner on an offshore VPS gives you unlimited CI/CD minutes, custom build environments, access to private network resources, and no data leaving your infrastructure. Go to your GitHub repository Settings > Actions > Runners > New self-hosted runner. Select Linux, copy the provided download and configuration commands, and run them on your VPS. Install the runner as a service: after configuring, run `sudo ./svc.sh install && sudo ./svc.sh start`. The runner connects outbound to GitHub's API (no inbound firewall rules needed). Configure runner labels so workflows can target your specific runner: `runs-on: [self-hosted, linux, your-label]`. Create a dedicated user for the runner with limited privileges - it should not run as root. For Docker-based builds in your runner, add the runner user to the docker group. Use Docker layer caching between runs by mounting a cache volume. Set up multiple runners on the same VPS if you need parallel job execution. For security, use ephemeral runners (each job gets a fresh runner instance) if you are running untrusted code from pull requests. Store secrets in GitHub repository secrets or organization secrets, never in the runner's environment files. The offshore nature of your VPS means builds, tests, and deployments are not subject to geographic data routing restrictions.

Development Database Management and Staging Environments

Use Docker Compose to run isolated database environments for each project. A typical compose file includes a database service with a named volume for persistence, an `env_file` reference for credentials, and a `ports` mapping only to localhost (`127.0.0.1:5432:5432`) to prevent external access. Run `docker compose up -d db` to start just the database, leaving your application running natively for faster development cycles. Manage multiple project environments with `docker compose -p projectname` to namespace containers and networks. This prevents port conflicts when running several projects simultaneously. Use `docker compose -f docker-compose.yml -f docker-compose.override.yml` to layer development overrides (volume mounts, debug ports, dev-only services) on top of your base configuration without modifying production files. Set up a staging environment that mirrors production: same Docker images, same environment variables (with staging-specific values), same Compose file, but on a separate `/opt/apps/projectname-staging` directory. Use Nginx virtual hosts to route different subdomains to staging vs production. Practice deployments on staging first with `docker compose pull && docker compose up -d` before applying to production. Having a working staging environment eliminates a significant category of "works on my machine" production incidents. An offshore VPS with generous bandwidth and no traffic filtering is ideal for staging environments that need to replicate production load patterns.

Why Anubiz Host

100% async — no calls, no meetings
Delivered in days, not weeks
Full documentation included
Production-grade from day one
Security-first approach
Post-delivery support included

Ready to get started?

Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.

Anubiz Chat AI

Online