Deploying Your NextJS Project on Hostinger
Tags: react, gitlab, nextjs
Published: 2024-04-23 02:05:53

Sometimes, you might need to deploy your front-end application or a proof of concept (POC), such as marketing pages, without spending too much. In such cases, using a personal host can be a practical solution. In this article, we will automate the deployment of our front-end into a Hostinger subdomain or subpage.

Steps to Follow:

![Steps to follow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5ucuqo8cb3ytbnkhd7z.png)



## Requirements
- Hostinger hosting service
- Git
- Gitlab/Github or another tool capable of creating pipelines and adding secrets



## A simple application (optional)

You can either create a new front-end application for testing or use an existing one. For this article, let’s build a NextJS application.

```
npx create-next-app@latest
```

This is our default application:

![NextJS default app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xh69bqcimm1f8uqcoz3a.png)



## Configuring the "next.config.mjs"

To output the static files into a folder, modify the “next.config.mjs” by adding `output`, `basePath`, and `assetPrefix`:

```
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "export",
  basePath: process.env.BASE_PATH ? process.env.BASE_PATH : "",
  assetPrefix: process.env.URL ? process.env.URL : undefined,
};

export default nextConfig;
```

After configuring, executing `npx next build` will properly create the "out" directory with all links and CSS files.


![Out directory image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqgan6y2bewysr1e2b4k.png)

For images managed by `next/image`, update the image paths as necessary.


![Git diff Image component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38cdksguu002kgjqqh1d.png)




## Hostinger steps

Create a subdomain or a specific folder in your Hostinger account.


![Subdomain on Hostinger](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axwoqf55fqc2euarb1wp.png)

Consider setting up a new FTP account limited to that directory to adhere to the Principle of Least Privilege (POLP).

![FTP user config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wwzvmpfz3f6gkbj76nn0.png)




## Gitlab steps

Although other deployment solutions are available, this tutorial focuses on using Gitlab. First, ensure your project is on Gitlab and add your Hostinger FTP client secrets in the CI/CD settings:

`https://gitlab.com/[GROUP_OR_NAMESPACE]/[PROJECT]/-/settings/ci_cd`

![Gitlab variables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkgrkqutzxrgdrhd9run.png)

- `[project]_base_path`: replace the links base_path, but we need to update manually in images
- `[project]_ftp_host`: e.g. ftp.1234.com
- `[project]_ftp_password`
- `[project]_ftp_user`
- `[project]_url`: it's your resource url (https://…), can be the your own site address or a cdn address.

Define the environment as `prd`, but you can create various environment variables as needed.

Replace `[project]` for your project name:

```
image: node:21.4.0-alpine

cache:
  paths:
    - node_modules/

before_script:
  - apk add lftp
  - npm install

upload:
  environment: prd
  stage: deploy
  script:
    - echo "Preparing FTP... $[project]_ftp_host $[project]_ftp_user $[project]_ftp_password"
    - URL=$[project]_url BASE_PATH=$[project]_base_path npx next build
    - lftp -c "set verify-certificate/$[project]_ftp_host no; set ftp:ssl-allow on; open -u $[project]_ftp_user,$[project]_ftp_password ftp://$[project]_ftp_host; mirror -Rev out/ ./ --ignore-time --parallel=10"

  only:
    - master
    - main
```

[More info about Alpine image](https://oandersonbm.medium.com/python-docker-image-security-and-trivy-scan-e8c90a2ffe28)





## Conclusion

If configured correctly, a new job will run for every update in the main branch, showing progress in each job log.


![Job list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ug1clkaflma4axmzefx3.png)


![Job logs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/em3rztfx4zng8qof2s74.png)


![Published page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/teesu4cmve4kgjfhxqwj.png)

I trust this information proves valuable to you. Thank you for investing your time in reading this. :D


![Thank you image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jx21zi3uan2bxlza6nz.png)

LinkedIn: https://www.linkedin.com/in/andersonbmagalhaes/

## Additional possibilities

- Separate your public files to a Content Delivery Network (CDN)
- Create multiple environments (e.g., Development, Testing, Production).
- Use GitHub Actions for alternative CI/CD approaches

## Benefits
- Efficient delivery of changes to production.
- Ability to test code in pipelines before deployment.
- Low-cost solution suitable for public projects like marketing initiatives or POCs.

## Advertising

> This approach is not recommended for projects requiring strict compliance or control over the deployment tools (Hostinger, Gitlab/Github, secrets/environment variables).

## References
[Original post](https://medium.com/@oandersonbm/deploying-your-nextjs-project-on-hostinger-dffdb6a05ffc)

[NextJS - BasePath](https://nextjs.org/docs/app/api-reference/next-config-js/basePath?source=post_page)

[NextJS - Static Export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports?source=post_page-----dffdb6a05ffc--------------------------------)

[CyberArk - POLP](https://www.cyberark.com/what-is/least-privilege/?source=post_page-----dffdb6a05ffc--------------------------------#:~:text=The%20principle%20of%20least%20privilege,perform%20his%2Fher%20job%20functions)

[Gitlab - Variables](https://docs.gitlab.com/ee/ci/variables/?source=post_page-----dffdb6a05ffc--------------------------------)