<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: oandersonmagalhaes</title>
    <description>The latest articles on DEV Community by oandersonmagalhaes (@oandersonmagalhaes).</description>
    <link>https://dev.to/oandersonmagalhaes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1439081%2F44e15b1c-d7e3-4be0-a140-5dba924fe513.jpeg</url>
      <title>DEV Community: oandersonmagalhaes</title>
      <link>https://dev.to/oandersonmagalhaes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oandersonmagalhaes"/>
    <language>en</language>
    <item>
      <title>Deploying Your NextJS Project on Hostinger</title>
      <dc:creator>oandersonmagalhaes</dc:creator>
      <pubDate>Tue, 23 Apr 2024 02:05:53 +0000</pubDate>
      <link>https://dev.to/oandersonmagalhaes/deploying-your-nextjs-project-on-hostinger-4gpm</link>
      <guid>https://dev.to/oandersonmagalhaes/deploying-your-nextjs-project-on-hostinger-4gpm</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Steps to Follow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5ucuqo8cb3ytbnkhd7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5ucuqo8cb3ytbnkhd7z.png" alt="Steps to follow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hostinger hosting service&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Gitlab/Github or another tool capable of creating pipelines and adding secrets&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A simple application (optional)
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npx create-next-app@latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is our default application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxh69bqcimm1f8uqcoz3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxh69bqcimm1f8uqcoz3a.png" alt="NextJS default app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the "next.config.mjs"
&lt;/h2&gt;

&lt;p&gt;To output the static files into a folder, modify the “next.config.mjs” by adding &lt;code&gt;output&lt;/code&gt;, &lt;code&gt;basePath&lt;/code&gt;, and &lt;code&gt;assetPrefix&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/** @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;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After configuring, executing &lt;code&gt;npx next build&lt;/code&gt; will properly create the "out" directory with all links and CSS files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqgan6y2bewysr1e2b4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqgan6y2bewysr1e2b4k.png" alt="Out directory image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For images managed by &lt;code&gt;next/image&lt;/code&gt;, update the image paths as necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38cdksguu002kgjqqh1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38cdksguu002kgjqqh1d.png" alt="Git diff Image component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hostinger steps
&lt;/h2&gt;

&lt;p&gt;Create a subdomain or a specific folder in your Hostinger account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxwoqf55fqc2euarb1wp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxwoqf55fqc2euarb1wp.png" alt="Subdomain on Hostinger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider setting up a new FTP account limited to that directory to adhere to the Principle of Least Privilege (POLP).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwzvmpfz3f6gkbj76nn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwzvmpfz3f6gkbj76nn0.png" alt="FTP user config"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gitlab steps
&lt;/h2&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://gitlab.com/[GROUP_OR_NAMESPACE]/[PROJECT]/-/settings/ci_cd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkgrkqutzxrgdrhd9run.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkgrkqutzxrgdrhd9run.png" alt="Gitlab variables"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Define the environment as &lt;code&gt;prd&lt;/code&gt;, but you can create various environment variables as needed.&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;[project]&lt;/code&gt; for your project name:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

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


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://oandersonbm.medium.com/python-docker-image-security-and-trivy-scan-e8c90a2ffe28" rel="noopener noreferrer"&gt;More info about Alpine image&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If configured correctly, a new job will run for every update in the main branch, showing progress in each job log.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug1clkaflma4axmzefx3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug1clkaflma4axmzefx3.png" alt="Job list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fem3rztfx4zng8qof2s74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fem3rztfx4zng8qof2s74.png" alt="Job logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteesu4cmve4kgjfhxqwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteesu4cmve4kgjfhxqwj.png" alt="Published page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I trust this information proves valuable to you. Thank you for investing your time in reading this. :D&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jx21zi3uan2bxlza6nz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jx21zi3uan2bxlza6nz.png" alt="Thank you image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/andersonbmagalhaes/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/andersonbmagalhaes/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional possibilities
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Efficient delivery of changes to production.&lt;/li&gt;
&lt;li&gt;Ability to test code in pipelines before deployment.&lt;/li&gt;
&lt;li&gt;Low-cost solution suitable for public projects like marketing initiatives or POCs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advertising
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;This approach is not recommended for projects requiring strict compliance or control over the deployment tools (Hostinger, Gitlab/Github, secrets/environment variables).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://medium.com/@oandersonbm/deploying-your-nextjs-project-on-hostinger-dffdb6a05ffc" rel="noopener noreferrer"&gt;Original post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/app/api-reference/next-config-js/basePath?source=post_page" rel="noopener noreferrer"&gt;NextJS - BasePath&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/pages/building-your-application/deploying/static-exports?source=post_page-----dffdb6a05ffc--------------------------------" rel="noopener noreferrer"&gt;NextJS - Static Export&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cyberark.com/what-is/least-privilege/?source=post_page-----dffdb6a05ffc--------------------------------#:~:text=The%20principle%20of%20least%20privilege,perform%20his%2Fher%20job%20functions" rel="noopener noreferrer"&gt;CyberArk - POLP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.gitlab.com/ee/ci/variables/?source=post_page-----dffdb6a05ffc--------------------------------" rel="noopener noreferrer"&gt;Gitlab - Variables&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>gitlab</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
