Skip to content

Commit

Permalink
Merge pull request #60 from smyja/nextjs
Browse files Browse the repository at this point in the history
NextJs Deployment with Caprover and Github Actions
  • Loading branch information
KTom101 authored Nov 9, 2023
2 parents 23da7b4 + 5d102b5 commit 15e42a4
Show file tree
Hide file tree
Showing 21 changed files with 278 additions and 0 deletions.
Binary file removed content/smyja/api-browser.png
Binary file not shown.
Binary file added content/smyja/app-market.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/caprover-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/caprover-marketplace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/caprover-quick-access.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/container-port.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/cpu-choice.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/created-caprover-droplet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/docker-registeries.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/droplets.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/enable-https.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/enable-token.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/force-https.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/gh-actions-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
277 changes: 277 additions & 0 deletions content/smyja/nextjs-deployment-with-caprover-and-github-actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
---
Title: "NextJs Deployment with Caprover and Github Actions"
Description: "A guide on how to deploy Nextjs on Caprover using Github Actions"
DatePublished: "2023-06-13"
Categories:
- "javascript"
- "computer-science"
Tags:
- "GitHub"
- "JavaScript"
CatalogContent:
- "introduction-to-javascript"
- "paths/front-end-engineer-career-path"
---

_**Prerequisites:** Understanding of JavaScript._
_**Versions:** Node v18.12.1_

## Introduction

Next.js is an open-source React framework that enables you to create server-rendered, static generated, and hybrid web applications. It provides a number of features that make it easy to build high-performance web applications, including:

- Static site generation: Next.js can be used to generate static websites that are served directly from the browser. This can improve performance and SEO.
- Server-side rendering: Next.js can also be used to render pages on the server. This can improve performance for search engines and users who are not using JavaScript.
- Hybrid rendering: Next.js can also be used to combine server-side rendering and static site generation. This gives you the best of both worlds: performance and SEO.
- Automatic routing: Next.js provides automatic routing that makes it easy to create complex web applications with nested routes.
- Data fetching: Next.js provides a number of ways to fetch data from APIs, including asynchronous async/await and the fetch() API.
- Deployment: Next.js can be deployed to a variety of hosting services, including Vercel, Netlify, and AWS Amplify, DigitalOcean.

This tutorial will cover the creation of a NextJs app and Deploying it on Caprover(Opensource Platform as a service) using DigitalOcean and Github actions.

## What is Caprover?

CapRover is a free and open-source platform that simplifies the deployment and management of applications. It supports a wide range of programming languages, databases, and web servers, making it a versatile solution for developers of all levels. CapRover is also a cost-effective alternative to other popular platforms, such as Heroku and Microsoft Azure.

## What is Github actions

GitHub Actions is a tool that allows you to automate tasks and processes in your GitHub repository. You can define workflows as code, which means that you can use GitHub Actions to automate anything that you can do with code.

Workflows are triggered by events, such as code pushes, pull requests, or scheduled intervals. When a workflow is triggered, it will run a series of steps that you have defined. These steps can be used to perform any task that you need to automate, such as building your code, running tests, or deploying your application.

## Why use Next.js, Caprover, and Github Actions together?

Next.js, Caprover, and GitHub Actions are all powerful tools that can be used together to create and deploy web applications. Indiehackers often use these tools because they are:
- Efficient: These tools can help indiehackers save time and resources by automating tasks and making it easy to deploy applications.
- Scalable: These tools can be scaled to handle large traffic loads.
- Cost-effective: These tools are often free or low-cost, making them a good option for indiehackers with limited budgets.

### Setting up Caprover on Digital Ocean

Sign up on [Digital Ocean](https://digitalocean.com) if you don't have an account yet.

> **Note:** In order to complete the signup process, Digital Ocean requires a payment method to be set up in order to verify the identity of new members.
Once you have signed up, create a droplet.

![created CapRover droplet](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/droplets.png)

Next, select CapRover from the marketplace.

![created CapRover droplet](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/caprover-marketplace.png)

Choose a region, specify the CPU as 1GB RAM, you can always upgrade it to a higher RAM.

![Specify CPU](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/cpu-choice.png)

Once the droplet has been created, you can access the caprover dashboard by visiting http://YOUR_IP_ADDRESS:3000 or click the `Get started` link ,then the Quick access to Caprover console.

![created caprover droplet](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/created-caprover-droplet.png)

The quick access button can be found here.
![caprover quick access](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/caprover-quick-access.png)

The default login for CapRover apps is `captain42`, ensure you change it from your dashboard settings.

After logging in, create an app. Give it any name.
![create caprover app](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/caprover-app.png)

Caprover has a marketplace of apps that can be created with one click including postgres, supabase and more.
![Caprover app marketplace](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/app-market.jpg)

Next, add a domain name to your app. You should log in to your domain registrar and point the domain name to the droplet/server's IP address. I am using a subdomain on Namecheap, here's what that looks like:
![point domain to ip](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/set-domain.png)

Now, add a wildcard to your domain. The wildcard domain is needed so we can change the CapRover server link from an IP address to a domain name.
![domain wildcard](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/root-domain.png)

Select force HTTPS and click the "save and update" button. This redirects HTTP traffic to HTTPS.
![force HTTPS](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/force-https.png)

Enable HTTPS for your domain. CapRover issues lets encrypt the certificate for domains.
![enable https certificate](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/enable-https.png)

Our website is live now, this is the default page for CapRover.

![created CapRover droplet](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/website.png)

### Setting up a NextJs app

Follow the guide on [Next.js Docs](https://nextjs.org/docs/getting-started/installation) to create a Next.js app.
Once that's setup, we will create a cluster for the app.
![remote registry](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/remote-registry.png)

To add a private Docker registry to CapRover, you must provide your username, personal access token (begins with ghp_), domain, and image prefix. We will be using the GitHub Container Registry (ghcr.io), your username will be your GitHub username, your password will be a personal token that you create with read package access, your domain will be ghcr.io, and your image prefix will be your GitHub username.

If your Docker images are stored in the format `your-username/your-image`, then you should use your GitHub username as your image prefix. Otherwise, if your images are stored in the format `my-org/my-image`, where `my-org` is your GitHub organization, then you should use `my-org` as your image prefix.

Once you have provided these credentials, CapRover will be able to pull images from your private Docker registry.

Your created registry would show:

![created CapRover droplet](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/docker-registeries.png)

Navigate to the deployments tab and enable app token, the token generated will be needed for this deployment.

![GitHub actions settings](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/enable-token.png)

CapRover uses Docker to create apps, to deploy our Next.js app we will create a Dockerfile

```docker
FROM node:16-alpine
# Set working directory
ENV NODE_ENV=production
# Copy package.json and package-lock.json (if available)
COPY package*.json ./
# Copy the built application files
COPY ./.next ./.next
COPY ./next.config.js ./next.config.js
COPY ./public ./public
COPY ./.next/static ./_next/static
COPY ./node_modules ./node_modules
# Expose the desired port (e.g., 3000)
EXPOSE 3000
# Start the Node.js server
CMD ["npm", "run", "start"]
```

The first stage of the build uses the `node:16-alpine` image as a base. This image is a lightweight version of Node.js that is optimized for production use. The `ENV NODE_ENV=production` line sets the environment variable `NODE_ENV` to production. This tells Next.js to use its production build configuration.

The second stage of the build copies the application files into the image. The `COPY package*.json ./` line copies the `package.json` and `package-lock.json` files into the image. These files are used to install the application's dependencies. The `COPY ./.next ./.next` line copies the built application files into the image. These files are the static files that are served by the Next.js server.

The `EXPOSE 3000` line exposes port 3000 on the image. This is the port that the Next.js server will listen on.

The `CMD ["npm", "run", "start"]` line tells Docker to run the `npm start` command when the container is started. This command will start the Next.js server.

Now, we need to specify the `PORT` on Caprover as 3000

![container port](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/container-port.png)

Caprover also uses a `captain-definition` file which specifies the path to the Dockerfile. For our Next.js app, the `captain-definition` file and the Dockerfile are to be placed at the root of our app along with the `package.json` file.

```json
{
"schemaVersion": 2,
"dockerfilePath": "Dockerfile"
}
```

To ensure every change we make to our Next.js app through commits automatically shows on the live website, we will need a workflow file with GitHub actions. Create a `.github` folder and a subfolder `workflows` with `release.yaml` file in this subfolder.
The yaml file should contain the below code.

```yaml
# GitHub Actions workflow for deploying a Docker image to CapRover
name: Deploy to caprover instance.

# Global environment variables used throughout the workflow
env:
CONTEXT_DIR: './' # Directory context for Docker
IMAGE_NAME: ${{ github.repository }} # Docker image name derived from the GitHub repository name
DOCKERFILE: ./Dockerfile # Path to Dockerfile
DOCKER_REGISTRY: ghcr.io # Docker registry to which the image will be pushed

# Trigger the workflow on push to the main branch
on:
push:
branches:
- main

# Define the jobs in the workflow
jobs:
# Job to handle building, testing, and publishing of the Docker image
build-and-publish:
runs-on: ubuntu-latest # Use the latest Ubuntu runner
permissions:
contents: read
packages: write
steps:
# Check out the repository code to the runner
- uses: actions/checkout@v1

# Cache dependencies for faster subsequent builds
- name: Cache
uses: actions/cache@v2
with:
path: |
~/.npm
${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.[jt]s', '**/*.[jt]sx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
# Set up the Node.js environment for the runner
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: "npm"

# Install project dependencies
- run: npm ci

# Build the project
- run: npm run build --if-present

# Run tests if they are available
- run: npm run test --if-present

# Log into the specified Docker registry
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata for the Docker image
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}

# Build the Docker image and push it to the specified registry
- name: Build and push Docker image
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

# Deploy the Docker image to the CapRover instance
- name: Deploy to CapRover
uses: caprover/deploy-from-github@d76580d79952f6841c453bb3ed37ef452b19752c
with:
server: ${{ secrets.CAPROVER_SERVER }} # CapRover server URL
app: ${{ secrets.APP_NAME }} # CapRover app name
token: '${{ secrets.APP_TOKEN }}' # CapRover app token
image: ${{ steps.meta.outputs.tags }} # Docker image to deploy

```

The code provided is a GitHub Actions workflow file for deploying a Docker image to a CapRover instance. CapRover is a multi-purpose deployment tool that simplifies the process of deploying applications to your own servers.

This workflow will trigger a build, test, and deployment whenever a push event occurs on the `main` branch. The Docker image will be built and pushed to the specified container registry, and then it will be deployed to the CapRover instance.
You will need to set up the necessary secrets in your GitHub repository to provide the CapRover server URL, application name, and application token. Make sure you have the CapRover server up and running and the required secrets configured correctly.

To configure your secrets, navigate to your Github repository's settings and click the Secrets and variables

![github actions settings](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/gh-actions-settings.png)

Your `CAPROVER_SERVER` should be similar to this` https://captain.example.scrapeweb.page`
`APP_NAME` is `server1`, the name you specified when creating the app.
`APP_TOKEN` is the Token generated when we enabled app token on the dashboard.

## Conclusion

We’ve now learned how to deploy a Next.js app with Caprover and connect a domain to it.

Source code: https://github.com/smyja/nextapp
Binary file added content/smyja/remote-registry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed content/smyja/restaurant-list.png
Binary file not shown.
Binary file added content/smyja/root-domain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/set-domain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/smyja/website.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions documentation/tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Integers
Interface
iOS
Iterators
JavaScript
Join
jQuery
JSON
Expand Down

0 comments on commit 15e42a4

Please sign in to comment.