Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NextJs Deployment with Caprover and Github Actions #60

Merged
merged 44 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9b53def
Create introduction-to-multithreading-with-python.md
smyja Jan 18, 2023
2b1e9a3
switched to nextjs
smyja Jun 13, 2023
b9431b3
update
smyja Jun 13, 2023
9351041
update
smyja Jun 13, 2023
368291f
caprover
smyja Jul 4, 2023
d449919
deleted
smyja Jul 4, 2023
a5b7881
caprover images
smyja Jul 4, 2023
0f01a77
renamed images
smyja Jul 4, 2023
c4a259e
update
smyja Jul 4, 2023
714f739
initial draft for caprover setup
smyja Jul 4, 2023
ba4589d
updated
smyja Jul 5, 2023
ee4740e
update
smyja Jul 6, 2023
7d021e8
update
smyja Jul 6, 2023
7f28500
update
smyja Jul 9, 2023
c2e446d
resized images
smyja Jul 9, 2023
e3d2499
removed unused images
smyja Jul 9, 2023
34854aa
update
smyja Jul 9, 2023
147da48
Merge branch 'Codecademy:main' into nextjs
smyja Jul 9, 2023
8bb3102
Reformat
yangc95 Aug 30, 2023
84f293a
Edit frontmatter and add tag
yangc95 Aug 30, 2023
ea02519
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Sep 3, 2023
17cffc1
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Sep 3, 2023
55720c7
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
c05af29
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
e9a0862
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
9003a11
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
fc173e5
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
62a3fff
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
7012df2
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
1831c47
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
2554989
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
6e5dfe6
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 21, 2023
3510aae
Merge branch 'Codecademy:main' into nextjs
smyja Oct 21, 2023
1f8145e
e
smyja Oct 21, 2023
38d3ba2
update
smyja Oct 21, 2023
586a1e0
Revert "e"
smyja Oct 21, 2023
ec0802f
fixed
smyja Oct 21, 2023
20b3dd7
updated the workflow
smyja Oct 21, 2023
bf17b3b
reduced file size
smyja Oct 24, 2023
265d898
Apply suggestions from code review
smyja Oct 24, 2023
9cdf014
Update content/smyja/nextjs-deployment-with-caprover-and-github-actio…
smyja Oct 24, 2023
0c984ff
resolved comments
smyja Oct 24, 2023
454da3d
update
smyja Oct 24, 2023
5d102b5
Update nextjs-deployment-with-caprover-and-github-actions.md
KTom101 Nov 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
smyja marked this conversation as resolved.
Show resolved Hide resolved

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.
smyja marked this conversation as resolved.
Show resolved Hide resolved
![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.
smyja marked this conversation as resolved.
Show resolved Hide resolved
![remote registry](https://raw.githubusercontent.com/smyja/ugc/nextjs/content/smyja/remote-registry.png)
smyja marked this conversation as resolved.
Show resolved Hide resolved

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)
smyja marked this conversation as resolved.
Show resolved Hide resolved

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
Loading