- Docker for delivering applications inside containers;
- Kubernetes for containers orchestration;
- Helm for managing Kubernetes applications;
- GitHub Actions for CI/CD deployment;
External services you need
- Kubernetes cluster, you can create DO Managed Kubernetes or AWS EKS;
- Container registry for your Docker images, mostly cloud providers has it own: DO Container Registry, AWS ECR;
- DNS provider account. We recommend CloudFlare, for AWS you can use Route 53;
- Managed MongoDB. We recommend MongoDB Atlas or DO Managed MongoDB;
Deployment schema

Deployment flow
The deployment flow is pretty simple. Once you make changes in any service, the script builds a new Docker image for it, adds image tag to it, and pushes it to the Container Registry. Script passes the image tag to deployment command, so Kubernetes knows which image needs to be downloaded from the registry. Image tag consists of repo branch and commits hash.We use Blue-Green deployment through Rolling Update.
deploy/script/src/index.js
We have separate GitHub Actions workflows for different environments.
Environment variables
When deploying “Ship” to Kubernetes, it’s essential to consider the configuration needs of different environments. By separating the environment-specific settings into dedicated files, you can easily manage and deploy the application across environments. TheAPP_ENV
environment variable is typically set based on the environment in which the application is running.
Its value corresponds to the specific environment, such as “development”, “staging” or “production”.
This variable helps the application identify its current environment and load the corresponding configuration.
For the web application, by setting the environment variable APP_ENV
,
the application can determine the environment in which it is running and download the appropriate configuration file:
APP_ENV | File |
---|---|
development | .env.development |
staging | .env.staging |
production | .env.production |
.env
file that houses its environment-specific configuration.
This file typically contains variables like API keys, secrets, or other sensitive information.
To ensure security, it’s crucial to add the .env
file to the .gitignore
file,
preventing it from being tracked and committed to the repository.
When deploying to Kubernetes,
you’ll need to include the appropriate environment-specific configuration files in your deployment manifests.
Kubernetes offers ConfigMaps and Secrets
for managing such configurations.
ConfigMaps are suitable for non-sensitive data,
while Secrets are recommended for sensitive information like API keys or database connection string.
Ensure that you create ConfigMaps or Secrets in your Kubernetes cluster
corresponding to the environment-specific files mentioned earlier.
Database setup
We recommend avoiding self-managed database solutions and use cloud service like MongoDB Atlas that provides managed database. It handles many quite complex things: database deployment, backups, scaling, and security.SSL
To make your application work in modern browsers and be secure, you need to configure SSL certificates. The easiest way is to use CloudFlare, it allows you to set up SSL in most simple way by proxying all traffic through CloudFlare. Use this guide. Cloudflare can be used as DNS nameservers for your DNS registrar, such as GoDaddy. Also, you can buy and register a domain in Cloudflare itself. If you are deploying in AWS you can use AWS Certificate Manager for SSL.Services
Services are parts of your application packaged as Helm Charts.Service | Description | Kubernetes Resource |
---|---|---|
Web | Next.js server that serves static files and API endpoints | Pod |
API | Backend server | Pod |
Scheduler | Service that runs cron jobs | Pod |
Migrator | Service that migrates database schema. It deploys before api through Helm pre-upgrade hook | Job |
deploy/script/src
Dependencies
Dependencies are third-party services packaged as Helm Charts and bash scripts that install configured resources in the cluster.Dependency | Description |
---|---|
ingress-nginx | Ingress controller for Kubernetes using Nginx as a reverse proxy and load balancer |
redis | Open source, advanced key-value store |
regcred | Bash script for creating Kubernetes Secret. Secret needs for authorizing in Container Registry when pulling images from cluster. Required only for Digital Ocean clusters |
deploy/bin
If you are adding new dependency, you need to create separate folder inside dependencies folder and configure new Chart.
Also, you need to add new dependency in deploy-dependencies.sh script.
You can do it following the example from neighboring dependencies.
Deploy scripts structure
Folder | Description |
---|---|
.github | GitHub Actions CI/CD pipelines for automated deployment on push in repo |
app | Helm charts for services |
bin | Utils scripts |
dependencies | Helm charts for dependencies |
script | Deployment script |