Full-stack web product deployment with CapRover: a step-by-step guide

calendar icon
4 Jul
4 Jul
scroll

Finishing a web app always leads to the same question: how do you put it online? With so many hosting options, deployment often feels overwhelming. Every platform demands trade-offs in setup time, cost, security, and control. CapRover offers a simple way to self-host without the usual hassle, and in this article, we’ll show you how.

CapRover is an open-source platform that makes deploying and managing web apps easier. It runs on your own server, offering a simple web interface and automation tools to handle hosting without the usual complexity. Whether it’s apps or databases, CapRover helps you get projects online quickly while keeping full control. Let’s explore how it works and why it’s a solid choice for full-stack deployments. 

Reasons to choose CapRover?

The first thing that makes CapRover stand out is the level of control it gives you over server configuration, while still covering key aspects like performance and optimization. It supports deployments for a wide range of applications: from Node.js and Python to databases like MySQL, Postgres, and more. On top of that, the platform keeps things simple with a clean, intuitive interface. Routine tasks are automated in just a few clicks, making it approachable for developers of any experience level. And perhaps best of all, CapRover is a fraction of the cost compared to many mainstream hosting services.

Key features of the platform at a glance:

  • Web interface and CLI for automation and scripting
  • No vendor lock-in — remove CapRover anytime, and your apps will keep running
  • Docker Swarm supports containerization and clustering
  • Customizable Nginx templates for load balancing
  • Built-in Let’s Encrypt integration for free SSL (HTTPS)
CapRover’s clean interface and automation tools make even first-time deployment feel straightforward.

How to install and set up CapRover

One of the simplest ways to install CapRover is through the one-click app on the DigitalOcean marketplace. Just create a Droplet using the provided template. Choose the region, data center, CapRover image, CPU type, and authentication method (SSH key or password) that fits your setup. Then launch the Droplet to get started. It’s easier than it sounds — see the steps below.

Step 1: Select a region and datacenter location
Step 1: Select a region and datacenter location
Step 2: Pick the CapRover image from Marketplace
Step 2: Pick the CapRover image from Marketplace
Step 3: Select the server plan and storage options
Step 3: Select the server plan and storage options
Step 4: Finalize details and create your Droplet
Step 4: Finalize details and create your Droplet

Once your Droplet is created, it will appear in your DigitalOcean dashboard with an assigned IP address.

Dashboard showing your Droplet and IP information
Dashboard showing your Droplet and IP information

Now, open the link http://IP-ADDRESS:3000 in your browser to access the CapRover login page.

The CapRover login screen in your browser window
The CapRover login screen in your browser window

The default login password is captain42 (don’t forget to update it after logging in). After you log in, you’ll be prompted to connect a root domain. This allows you to use HTTPS and replace the plain IP address with a clean domain name. If you don’t have a custom domain, you can use a free option like server.your-ip.nip.io. This will point to your IP without extra setup, but note that HTTPS won’t be available with this method.

Root domain settings to replace your IP with a domain
Root domain settings to replace your IP with a domain

Tip: You’re not limited to DigitalOcean. CapRover works with any cloud provider. In that case, you’ll need to install Docker and set things up manually via terminal. A full setup guide with all the necessary commands is available on CapRover’s official website.

Overview of CapRover’s control panel

Once logged in, you’ll land in the CapRover control panel, which includes five tabs. Here’s what each tab does:

1. Dashboard — shows general system info and lets you set or update the root domain for your server.

CapRover dashboard showing domain configuration options
CapRover dashboard showing domain configuration options

2. Apps — where you create, configure, and deploy applications.

Apps tab for managing and deploying applications
Apps tab for managing and deploying applications

3. Monitoring — lets you track server performance, monitor metrics in real time with NetData, set up alerts through services like Email, Slack, or Telegram, and analyze logs using GoAccess.

Server stats and real-time performance metrics overview
Server stats and real-time performance metrics overview
Detailed system metrics displayed via NetData integration
Detailed system metrics displayed via NetData integration

4. Cluster — used for managing server clusters when running multiple nodes.

Cluster settings for configuring nodes and registries
Cluster settings for configuring nodes and registries

5. Settings — covers system-wide configurations like CapRover updates, backups, Nginx settings, disk cleanup, and more.

Settings tab for updates, backups, and system configuration
Settings tab for updates, backups, and system configuration
Nginx configuration and disk cleanup overview panel
Nginx configuration and disk cleanup overview panel

Creating your first app in CapRover

Once your CapRover instance is up and running, it’s time to deploy your first app. This happens through the Apps tab in the control panel — the main place where you’ll manage and configure everything related to your applications. You can go the quick and easy route with One-Click Apps/Databases, where you just pick the technology you need from the list.

Library of preconfigured one-click apps and services
Library of preconfigured one-click apps and services

Or, if you’re working on a custom project, you can manually create an app (just click “Create New App”) and configure it exactly as you need.

Custom app created and ready for further setup
Custom app created and ready for further setup

Next, when you open a newly created project, CapRover gives you a straightforward settings panel with three key tabs to manage how your app runs and behaves:

1. HTTP Settings. Here you can view the public link to your app, enable HTTPS, connect a custom domain, configure Nginx settings, define the container port, and adjust other related options.

View showing how to configure HTTP and domain settings
View showing how to configure HTTP and domain settings

2. App Configs. This tab allows you to add environment variables (env), set the number of app instances, define a pre-deploy script, and adjust other configuration options.

App Configs tab with environment and scaling options
App Configs tab with environment and scaling options

3. Deployment. This tab covers the actual deployment process. You can view the current version of your app, roll back to previous builds, check logs, and deploy new updates via CLI, .tar files, or integrations with GitHub, Bitbucket, GitLab, and more.

Deployment tab with version history and app logs
Deployment tab with version history and app logs

Tip: To ensure your app is operating correctly, open the public link from the HTTP Settings tab and verify that it loads in your browser.

Default screen indicating no app has been deployed yet
Default screen indicating no app has been deployed yet

Deploying a project in CapRover using different methods

Let’s walk through a practical example of deploying a full-stack project in CapRover. We’ll be working with three separate components: frontend (Next.js), backend (Nest.js), and PostgreSQL database. Each will be set up as its own app in CapRover: test-frontend, test-backend, and test-pg-db. We’ll start by setting up PostgreSQL as our database:

1. In the Apps tab, select One-Click Apps/Databases to access CapRover’s list of ready-to-use stacks.

Panel for creating apps or accessing one-click deployment
Panel for creating apps or accessing one-click deployment

Find PostgreSQL in the list (or pick a different database if your project requires it).

One-Click Apps panel with ready-to-use deployment stacks
One-Click Apps panel with ready-to-use deployment stacks

Once selected, fill in the necessary details: name, version, username, password, and default database name. After completing these fields, start the deployment.

Form for setting up the database name, version, and access
Form for setting up the database name, version, and access

When it finishes, navigate back to Apps, open your newly created database, and check its settings or logs to ensure everything is working.

Note: If something goes wrong and the database doesn’t launch properly, simply delete the app and create it again. This quick reset often solves common setup hiccups.

HTTP configuration details for the database app
HTTP configuration details for the database app
Deployment logs confirming the PostgreSQL container is active
Deployment logs confirming the PostgreSQL container is active

2. Now, let’s deploy the backend part. We’ll use a Docker container to host the application. Start by creating a Dockerfile in the root of your project:

# Base image:
FROM node:20-alpine
# Create application directory inside the container:
RUN mkdir -p /usr/src/app
# Set working directory:
WORKDIR /usr/src/app
# Copy package.json and package-lock.json to the container:
COPY ./package*.json /usr/src/app/
# Install npm dependencies:
RUN npm install && npm cache clean –force
# Copy application code to the container:
COPY ./ /usr/src/app
 
# Build args
ARG NODE_ENV=${NODE_ENV}
ARG SERVER_PORT=${SERVER_PORT}
ARG POSTGRES_HOST=${POSTGRES_HOST}
ARG POSTGRES_USER=${POSTGRES_USER}
ARG POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
ARG POSTGRES_DB_NAME=${POSTGRES_DB_NAME}
ARG POSTGRES_PORT=${POSTGRES_PORT}
 
# Env vars
ENV NODE_ENV=${NODE_ENV}
ENV SERVER_PORT=${SERVER_PORT}
ENV POSTGRES_HOST=${POSTGRES_HOST}
ENV POSTGRES_USER=${POSTGRES_USER}
ENV POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
ENV POSTGRES_DB_NAME=${POSTGRES_DB_NAME}
ENV POSTGRES_PORT=${POSTGRES_PORT}
 
# Expose web server port:
EXPOSE 3000
 
# Build the application:
RUN npm run build
# Start the application:
CMD npm run start:prod

Note: You can adjust paths, environment variable names, port, and startup scripts based on your project’s requirements.

Next, create a captain-definition file in the root directory. This tells CapRover how to build and deploy your app:

{
   "schemaVersion": 2,
   "dockerfilePath": "./Dockerfile"
 }

Once the Docker file is set up, head back to the CapRover Apps tab and open your backend app.

HTTP settings panel for the backend application
HTTP settings panel for the backend application

In HTTP Settings, define the container port (e.g., 3000) and enable HTTPS.

Container port set to 3000 with HTTPS enabled for the app
Container port set to 3000 with HTTPS enabled for the app

In App Configs, add your environment variables. You can do this manually or use Bulk Edit for convenience.

Backend configuration showing each environment variable
Backend configuration showing each environment variable
Environment variables displayed in Bulk Edit format
Environment variables displayed in Bulk Edit format

When everything’s configured, proceed to the Deployment tab to launch your project.

Deployment panel with build logs and version details
Deployment panel with build logs and version details

Depending on your setup, you can launch the project using the CLI, a .tar file, or by connecting it directly to a GitHub, Bitbucket, or GitLab repository. For this example, we’ll use the CLI to push the backend from a local machine — a straightforward method and a good base for CI/CD automation later.

The CLI lets you deploy from your terminal in a few quick steps — simple and efficient.

a) First, install the CLI tool on your local machine by running the following command in your terminal:

npm install -g caprover

Then, log in to your CapRover instance by running:

caprover login

You’ll be prompted to enter the root domain, password, and the machine’s name.

CLI login prompt confirming successful authentication
CLI login prompt confirming successful authentication

Once you’re logged in, run the deploy command from the root directory of your project:

caprover deploy

Select the appropriate machine, pick your test-backend app in CapRover, and specify the Git branch you want to deploy.

CLI prompts for app, branch, and starts deployment steps

If everything goes well, your backend should now be live. Check the logs under the Deployment tab to verify that the server has started successfully. Then, open the public link from HTTP Settings to confirm that your app is accessible. If your project exposes API routes, you’ll see the Swagger documentation page displaying all available endpoints.

Backend deployment logs confirming successful startup
Backend deployment logs confirming successful startup

In this example backend, the /api-docs endpoint was implemented to display the Swagger documentation. In your project, the structure and addresses of endpoints may differ, so be sure to use the ones specific to your application to test your API.

Swagger UI displaying the API endpoints exposed by the backend
Swagger UI displaying the API endpoints exposed by the backend

b) For automated deployments, CapRover offers App Tokens. To use them, go to Apps, open your backend app, and go to Deployment.

Deployment tab with version history and App Token options
Deployment tab with version history and App Token options

Click “Enable App Token” and save the generated token.

Note: It is important to keep this token secure, as it grants access to your project.

Next, open your backend repository on GitHub, navigate to the Settings tab, and create the required variables under the Secrets section, adding:

  • Your server name (root domain)
  • App name
  • The App Token for CapRover
Repository secrets with server, app, and token details
Repository secrets with server, app, and token details

To automate project deployment, you need to set up a GitHub Action.

GitHub Actions page to configure deployment workflows
GitHub Actions page to configure deployment workflows

Then, create a script called main.yml that automatically triggers a deployment to CapRover whenever code is pushed to the main branch.

Deployment workflow defined in main.yml
Deployment workflow defined in main.yml
name: Build & Deploy
 
on:
  push:
	branches: [ "main" ]
 
jobs:
  build-and-deploy:
	runs-on: ubuntu-latest
 
	strategy:
  	matrix:
    	node-version: [18.x]
 
	steps:
  	- name: Check out repository
    	uses: actions/checkout@v4
  	- name: Use Node.js ${{ matrix.node-version }}
	uses: actions/setup-node@v3
    	with:
      	node-version: ${{ matrix.node-version }}
 
  	- uses: a7ul/tar-action@v1.1.0
    	with:
      	command: c
      	cwd: "./"
      	files: "./"
      	outPath: deploy.tar
 
  	- name: Deploy App to CapRover
    	uses: caprover/deploy-from-github@v1.0.1
    	with:
      	server: '${{ secrets.CAP_ROVER_SERVER }}'
      	app: '${{ secrets.CAP_ROVER_APP_NAME }}'
      	token: '${{ secrets.CAP_ROVER_TOKEN }}'

You can customize this script to suit your specific needs. For example, you could include steps to run tests, build the project, or configure different events that trigger the deployment.

c) Another way to deploy using CI/CD is through the command-line interface (CLI). This method involves running the following caprover deploy command in your CI workflow:

caprover deploy -h https://captain.root.domain.com -p password -b branchName -a app-name

Alternatively, instead of using a token, you can store your CapRover password in the Secrets section. In your CI workflow, install the CapRover CLI (as shown earlier in the local setup (a)) and then run the caprover deploy command, passing in the arguments from Secrets along with the branch name. That said, using a separate App Token for each project is a safer and more maintainable approach, as outlined in the previous step (b).

3. Now it’s time to deploy the frontend. Just like with the backend, we’ll package the app using Docker and connect it to CapRover. In this case, we’ll also show how to automate the process via GitHub — using either a personal access token or SSH key.

We’ll start with the first option: using a personal access token. To begin, create a Dockerfile in the root of your frontend project:

# Base image:
FROM node:20-alpine
# Create application directory inside the container:
RUN mkdir -p /usr/src/app
# Set working directory:
WORKDIR /usr/src/app
# Copy package.json and package-lock.json to the container:
COPY ./package*.json /usr/src/app/
# Install npm dependencies:
RUN npm install && npm cache clean –force
# Copy application code to the container:
COPY ./ /usr/src/app
 
# Expose web server port:
EXPOSE 5173
 
# Build the application:
RUN npm run build
# Start the application:
CMD npm run start

Note: Feel free to adjust the paths, environment variable names, port, and startup scripts to match your project’s specific requirements.

After that, create a captain-definition file (which CapRover needs) in the root of your project:

{
   "schemaVersion": 2,
   "dockerfilePath": "./Dockerfile"
 }

Once both files are ready, open the Apps tab in your CapRover dashboard and select your frontend app.

HTTP Settings panel for the frontend app
HTTP Settings panel for the frontend app

In HTTP Settings, define the container port (e.g., 8080), enable HTTPS, and set up automatic redirection from HTTP to HTTPS. If needed, you can also customize the Nginx configuration.

HTTPS and container port configured for the frontend app
HTTPS and container port configured for the frontend app

In the App Configs tab, add any required environment variables.

Specifying environment variables for frontend deployment
Specifying environment variables for frontend deployment

Now let’s walk through the deployment process, starting with GitHub integration.

One way to connect your GitHub repository is by entering your credentials directly into CapRover. To do this, you’ll need:

  • The GitHub repository URL
  • Your GitHub username
  • The name of the target branch
  • A personal access token (instead of a password)
Form for adding GitHub credentials and repository details
Form for adding GitHub credentials and repository details

To create the token:

  • Go to your GitHub Settings
  • Navigate to Developer Settings > Personal access tokens > Tokens (classic)
Navigation to Developer Settings and classic tokens in GitHub
Navigation to Developer Settings and classic tokens in GitHub
  • Click Generate new token, add a note, and grant access to your repositories
Creating a GitHub token and setting repo access permissions
Creating a GitHub token and setting repo access permissions

After creating the token, copy and paste it into the Password field in CapRover. A webhook URL will be generated automatically. Now, clicking “Force Build” will trigger the deployment from your connected GitHub repository into CapRover.

CapRover form with GitHub credentials and generated webhook URL
CapRover form with GitHub credentials and generated webhook URL

You can also copy the webhook URL and go to your GitHub repo’s Settings > Webhooks, then paste the URL there to create a new webhook.

GitHub Webhooks settings screen for adding a new webhook
GitHub Webhooks settings screen for adding a new webhook

This way, once the webhook is added, every push to the main branch will automatically trigger a deployment to CapRover with the latest changes.

Another option is to connect your GitHub repository using an SSH key — no need to enter your credentials manually. To do that, start by generating a key pair with the following command:

ssh-keygen -m PEM -t rsa -b 4096 -C "caprover" -f ./project-name-key -q -N ""

Note: The -N option sets a passphrase. If the command in Windows asks for input or fails to generate the key, just remove -N. The tool will prompt you for a passphrase during generation. You can safely leave it blank — no need to add one just to make it work.

Now, copy the contents of project-name-key and paste it into the SSH field in CapRover.

CapRover SSH deployment setup with private key pasted in
CapRover SSH deployment setup with private key pasted in

Then go to the project’s repository on GitHub, select the Settings tab, and navigate to Deploy Keys.

GitHub repository Deploy Keys section ready for a new key
GitHub repository Deploy Keys section ready for a new key

Create a new key, specify a title for it, and paste the contents of the project-name-key.pub file.

Adding a new SSH deploy key to your GitHub repository
Adding a new SSH deploy key to your GitHub repository

That’s it! Now the frontend can be deployed in the same ways — using the “Force Build” button, GitHub webhooks, or CI/CD with SSH-based access — without entering a username or password.

To double-check that the site has deployed successfully and that the server is reachable from the internet, go to the Apps tab, select your frontend app, open the HTTP Settings tab, and click on the public link displayed there.

Default Next.js page shows the frontend is live and reachable
Default Next.js page shows the frontend is live and reachable

Cleaning up disk space in CapRover

In this section, we’ll look at how to clean up your server by removing unused Docker images and volumes, freeing up space, and getting rid of files that are no longer needed.

Every time you deploy a new version of your app, Docker creates a new image for it. By default, older images aren’t deleted automatically, so they accumulate over time. These images are compressed packages of your compiled code, and if you don’t need the old ones, you can safely remove them by running:

docker container prune--force 
docker image prune –all

Note: Only use this method if you’ve configured a Docker registry (local or remote).

In addition to images, unused volumes can also take up space. When you deploy an app that stores data, like a database, Docker assigns it a persistent volume. If the app is deleted or reconfigured, its old volumes often remain, even if they’re no longer in use. Docker treats a volume as “orphaned” when no container is attached to it, even if the app is only temporarily inactive.

To safely remove orphaned volumes, first check that all services are running correctly by running:

docker service ls

In the REPLICAS column, you should see healthy statuses like 1/1, 2/2, etc. If any service isn’t running, pause the cleanup process. If everything looks good, you can proceed with:

docker volume prune

For more control, you can view all volumes first:

docker volume ls

And then remove only the ones you’re sure you no longer need:

docker volume rm volume-name-goes-here

CapRover also offers a simple cleanup widget in the Settings tab. There, you can set how many recent builds to keep, click Get List to view all unused images, and delete them individually with just a few clicks.

List of unused images ready for removal in CapRover settings
List of unused images ready for removal in CapRover settings

Deploy smarter with CapRover

Now that you’ve seen what CapRover can do, it’s easy to understand why it’s gaining popularity among developers. It offers a streamlined way to host and manage applications on your own terms — with fewer limitations, less overhead, and just the right amount of automation. With a bit of setup, you can have full-stack projects up and running with confidence.

To keep your setup running efficiently, double-check your environment variables, monitor logs, and clean up unused images or volumes when needed. Once the essentials are in place, CapRover handles the rest, giving you a stable platform for building, deploying, and scaling your projects. Try it on your next build and see how much easier deployment can be. Good luck!

Writing team:
Olena
Copywriter
Have a project
in your mind?
Let’s communicate.
Get expert estimation
expert postexpert photo

Frequently Asked Questions

copy iconcopy icon
Ready to discuss
your project with us?
Let’s talk about how we can craft a user experience that not only looks great but drives real growth for your product.
Book a call
4.9 AVG. SCORE
Based on 80+ reviews
TOP RATED COMPANY
with 100% Job Success
FEATURED Web Design
AgencY IN UAE
TOP DESIGN AGENCY
WORLDWIDE