- kubectl - CLI tool for accessing Kubernetes cluster;
- kubectx - CLI tool for easier switching between Kubernetes contexts;
- helm - CLI tool for managing Kubernetes deployments;
- k8sec - CLI tool for managing Kubernetes Secrets easily;
How to install k8sec on Linux?
How to install k8sec on Linux?
Download k8sec tar.gz, then do:
Setup project
First, initialize your project. Typenpx create-ship-app@latest in the terminal then choose Digital Ocean Managed Kubernetes deployment type.

Container registry
You need to create Container Registry for storing Docker images. The deployment script will upload images to Container Registry during the build step, and Kubernetes will automatically pull these images from Container Registry to run a new version of service during the deployment step. Name container registry as the name of organization, which usually is equals to the name of the project:my-ship-app.


registry.digitalocean.com/my-ship-app is registry endpoint, where my-ship-app is registry name.
Docker images for each service are stored in separate repository.
In Digital Ocean repositories are created automatically when something is uploaded by specific paths.
During deployment process script will automatically create paths to repositories in next format:
- API - registry.digitalocean.com/my-ship-app/api;
- Scheduler - registry.digitalocean.com/my-ship-app/scheduler;
- Migrator - registry.digitalocean.com/my-ship-app/migrator;
- Web - registry.digitalocean.com/my-ship-app/web;
Kubernetes cluster
Now let’s create Managed Kubernetes cluster.Select a region
Navigate to the cluster creation page here


Set Node pool name
Set Node pool name (e.g. 
pool-app) and configure Nodes.
Digital Ocean recommends creating at least 2 nodes for the production environment. These settings will have an impact on the price of the cluster.
Set cluster name
Set cluster name (e.g. 
my-ship-app). A common practice is to use the project name for it.
Review and Create
Click on
Create Kubernetes Cluster button to create a cluster and wait for cluster to be ready.Personal access token
To upload docker images in Container Registry and pull them after from cluster we need Digital Ocean Personal Access Token. When you created cluster - one with Read Only scope was automatically created. But we need to generate a new one with:- Name (e.g.
my-ship-app-admin-deploy) - Full Access scope
- No expiration


Accessing cluster from a local machine
Download cluster's kubeconfig
Download cluster’s kubeconfig, this file includes information for accessing cluster through 
And replace initial Read only token with new Full access token from Personal access token section.
kubectl.
Expected structure of downloaded kubeconfig
Expected structure of downloaded kubeconfig
my-ship-app-kubeconfig.yaml
my-ship-app-kubeconfig.yaml
Add cluster, context and user to kubeconfig
You need to add information about the new cluster to your kubeconfig.
Find
.kube/config file on your machine, and add cluster, context and user values from my-ship-app-kubeconfig.yaml.~/.kube/config
Switch to cluster context
Execute kubectx in your terminal and select your cluster from the list.You will see the list of available clusters.Select your cluster from the list:
Ingress NGINX Controller
ingress-nginx is an Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer.Configure Helm Values (Optional)
This step is required only if you specified a custom node pool name in your Digital Ocean Kubernetes cluster.If you did, update the
doks.digitalocean.com/node-pool value in values.yaml.gotmpl:deploy/dependencies/ingress-nginx/values.yaml.gotmpl
DNS and SSL
Get Load Balancer Address
After deploying ingress-nginx, retrieve the Load Balancer’s external ip:Copy the value from the
EXTERNAL-IP column.Domain Naming Convention
You can follow this recommended naming pattern for different environments:
| Environment | API Domain | Web Domain |
|---|---|---|
| Production | api.ship.com | app.ship.com |
| Staging | api.staging.ship.com | app.staging.ship.com |
Configure DNS in Cloudflare
- First, ensure you have a domain in Cloudflare. You can either:
- In the Cloudflare DNS tab, create 2
Arecords:
- One for Web interface
- One for API endpoint
- Route traffic through Cloudflare
- Generate SSL certificates automatically


Cloudflare’s free Universal SSL certificates only cover the apex domain and one subdomain level. For multiple subdomain levels, you’ll need an Advanced Certificate.
MongoDB Atlas
MongoDB Atlas is a fully managed cloud database service that provides automated backups, scaling, and security features. It offers 99.995% availability with global deployment options and seamless integration with AWS infrastructure.Cluster Creation
Access MongoDB Atlas
Sign in to your MongoDB Atlas account and create a new project if needed.
Deploy New Cluster
Click Create to start cluster deployment.Cluster Tier Selection:
- Staging:
M0(Free tier) - Suitable for development and testing - Production:
M10or higher - Includes automated backups and advanced features

Security Configuration
Create Database User
Navigate to Database Access → Add New Database User
- Authentication Method: Password
- Username: Use environment-specific names (e.g.,
api-production,api-staging) - Password: Generate a strong password
- Database User Privileges: Read and write to any database

Get Connection String
Copy Connection String
- Select Drivers in the “Connect your application” section
- Choose Node.js driver and latest version
- Copy the connection string and replace
<db_password>with your actual password

Environment variables
Kubernetes applications require proper environment variable configuration for both API and Web components. This section covers how to set up and manage environment variables securely using Kubernetes secrets and configuration files.API Environment Variables
For the API deployment, you need to set up environment variables using Kubernetes secrets to securely manage sensitive configuration data.Secrets in Kubernetes are used to store sensitive information, such as passwords, API tokens, and keys.
They are encoded in Base64 format to provide a level of security.
These can be mounted into containers as data volumes or used as environment variables.
| Name | Description | Example value |
|---|---|---|
APP_ENV | Application environment | production |
MONGO_URI | Database connection string | mongodb://<username>:<password>@ship.mongodb.net |
MONGO_DB_NAME | Database name | api-production |
API_URL | API domain URL | https://api.my-ship-app.paralect.com |
WEB_URL | Web app domain URL | https://my-ship-app.paralect.com |
Environment Variable Details
APP_ENV
APP_ENV
Specifies the application environment (development, staging, production). This controls logging levels, debugging features, error reporting, and other environment-specific behaviors. The API uses this to determine which configuration settings to load.
MONGO_URI
MONGO_URI
MongoDB connection string including authentication credentials and cluster information. This is the primary database connection for the API. Format:
mongodb+srv://username:password@cluster.mongodb.net. Each environment should use a separate database cluster or at minimum separate credentials.MONGO_DB_NAME
MONGO_DB_NAME
Name of the MongoDB database to use for this environment. Each environment (development, staging, production) should have its own database to prevent data conflicts and ensure proper isolation.
API_URL
API_URL
The fully qualified domain name where the API will be accessible. This must be a valid HTTPS URL and should match your Kubernetes ingress configuration. Used for CORS settings and internal service communication.
WEB_URL
WEB_URL
The fully qualified domain name where the web application will be accessible. Used for CORS configuration, redirect URLs, email templates, and social sharing metadata. Must be a valid HTTPS URL.
Setting up Kubernetes Secrets
Create namespaces and secret objects
Create Kubernetes namespaces and secret objects for staging and production environments:
Web Environment Variables
The web application uses Next.js environment variables that are embedded at build time and made available in the browser. Unlike API secrets, these variables are stored directly in the GitHub repository.Why Web Environment Variables Are Safe in Git: Web environment variables (prefixed with
NEXT_PUBLIC_) contain only public configuration like URLs and API endpoints. They don’t include sensitive data like passwords or API keys, making them safe to store in version control. These values are already exposed to users in the browser, so repository storage doesn’t create additional security risks.Configuration Files
Web environment variables are stored in separate files for each deployment environment:Environment Variables Reference
| Variable | Description | Example |
|---|---|---|
NEXT_PUBLIC_API_URL | Base URL for API requests | https://api.my-ship-app.paralect.com |
NEXT_PUBLIC_WS_URL | WebSocket server URL for real-time | https://api.my-ship-app.paralect.com |
NEXT_PUBLIC_WEB_URL | App’s own URL for redirects/metadata | https://my-ship-app.paralect.com |
Setting up GitHub Actions CI/CD
To automate deployment through Github Actions you need to configure Github Secrets inside workflow files.Configuring GitHub Actions secrets and variables
Before starting, make sure you have created a GitHub repository for your project.
| Name | Type | Description |
|---|---|---|
| DO_PERSONAL_ACCESS_TOKEN | secret | The secret access user created for CI/CD. This allows GitHub Actions to authenticate with DO services |
| CLUSTER_NAME_STAGING | variable | Name of the staging cluster. (our case: my-ship-app) |
| CLUSTER_NAME_PRODUCTION | variable | Name of the production cluster. (our case: my-ship-app, same as staging cluster since we have only one cluster) |
| CLUSTER_NODE_POOL | variable | Name of the node pool. (our case: pool-app) |
| REGISTRY_NAME | variable | Name of the Digital Ocean Container Registry. (our case: my-ship-app) |
Variables (unlike secrets) are visible in logs and can be used for non-sensitive configuration values that may need to be referenced or modified.
We set up DO_PERSONAL_ACCESS_TOKEN to be universal for both production and staging environments with Full access scope.
Your KUBE_CONFIG_PRODUCTION and KUBE_CONFIG_STAGING will be the same if you have only one cluster for both environments.





Setting up Upstash Redis database (recommended)
Upstash Redis Integration
Upstash Redis is a highly available, infinitely scalable Redis-compatible database that provides enterprise-grade features without the operational complexity.How Ship Uses Redis
Ship leverages Redis for several critical functionalities:| Use Case | Description | Implementation |
|---|---|---|
| Real-time Communication | Pub/Sub mechanism for WebSocket functionality | Socket.io Redis Adapter |
| Rate Limiting | API request throttling and abuse prevention | Redis counters with TTL |
| Caching | Application data caching for improved performance | Key-value storage with expiration |
Redis as a Message Broker: When scaling to multiple server instances, Redis acts as a message broker between Socket.io servers, ensuring real-time messages reach all connected clients regardless of which server they’re connected to.
Setting Up Upstash Redis
Create Your Database
Access Upstash Console
Log in to your Upstash account and navigate to the Redis section.
Create New Database
Click Create Database in the upper right corner to open the configuration dialog.

Configure Database Settings
Database Name: Choose a descriptive name for your database (e.g.,
my-ship-app-production)Primary Region: Select the region closest to your main application deployment for optimal write performance.Read Regions: Choose additional regions where you expect high read traffic for better global performance.Navigate to Connection Info
Go to your database dashboard and find the Connect to your database section.

Copy Connection String
- Select the Node tab for the appropriate connection string format
- Click Reveal to show the hidden password
- Copy the complete Redis URI (format:
rediss://username:password@host:port)
Verify Connection with Redis Insight
Redis Insight is a powerful GUI tool for managing and debugging Redis databases.Install Redis Insight
Download and install Redis Insight on your local machine.
Add Database Connection
- Open Redis Insight
- Click Add Database
- Paste your Upstash Redis connection string in the Connection URL field
- Click Add Database

Explore Your Database
Once connected, you can use Upstash Redis Console to:
- Browse keys and data structures
- Execute Redis commands directly
- Monitor real-time performance metrics
- Debug application data storage

Real-time Monitoring: Upstash Redis updates database metrics automatically every 10 seconds, giving you near real-time visibility into your Redis performance and usage.




