<?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>Forem: Jude Wei</title>
    <description>The latest articles on Forem by Jude Wei (@weijunext).</description>
    <link>https://forem.com/weijunext</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%2F1317021%2Fc5c405c2-bf5c-4393-b5ec-db631dfc88b9.jpeg</url>
      <title>Forem: Jude Wei</title>
      <link>https://forem.com/weijunext</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/weijunext"/>
    <language>en</language>
    <item>
      <title>Deploying Next.js Projects with Dokploy</title>
      <dc:creator>Jude Wei</dc:creator>
      <pubDate>Wed, 29 Oct 2025 11:27:58 +0000</pubDate>
      <link>https://forem.com/weijunext/deploying-nextjs-projects-with-dokploy-52l6</link>
      <guid>https://forem.com/weijunext/deploying-nextjs-projects-with-dokploy-52l6</guid>
      <description>&lt;p&gt;This article provides a comprehensive guide on deploying Next.js projects using Dokploy, covering server purchase, Dokploy installation and configuration, direct deployment, and GitHub Actions automated deployment to help you quickly launch your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting deployment, it's recommended to add the following configuration to &lt;code&gt;next.config.mjs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;standalone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Add this line&lt;/span&gt;

  &lt;span class="c1"&gt;// other code...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since Dokploy runs on Docker, using &lt;code&gt;standalone&lt;/code&gt; mode can significantly reduce the build image size.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This article is based on the deployment steps for my Next.js SaaS boilerplate &lt;a href="https://nexty.dev/" rel="noopener noreferrer"&gt;Nexty.dev&lt;/a&gt;, and is the most comprehensive tutorial on the internet for deploying Next.js projects with Dokploy. I hope it helps everyone.&lt;/p&gt;

&lt;p&gt;Nexty.dev is one of the top 3 Next.js SaaS boilerplates, loved by many developers for its robust infrastructure and detailed documentation. If you're looking for an excellent Next.js SaaS boilerplate, you definitely shouldn't miss Nexty.dev.&lt;/p&gt;

&lt;p&gt;Original article: &lt;a href="https://nexty.dev/docs/start-project/dokploy" rel="noopener noreferrer"&gt;Deploying Next.js Projects with Dokploy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is Dokploy
&lt;/h2&gt;

&lt;p&gt;Dokploy is an open-source self-hosted PaaS (Platform as a Service) that serves as an alternative to services like Vercel, Netlify, Railway, and Zeabur.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5kwzsus87jdnj492xe43.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5kwzsus87jdnj492xe43.webp" alt=" " width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Server Setup and Dokploy Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Purchase a Server
&lt;/h3&gt;

&lt;p&gt;Using Dokploy requires purchasing your own server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Dokploy
&lt;/h3&gt;

&lt;p&gt;Open the VPS Terminal&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Faadl9et6n9e6imb4hrp1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Faadl9et6n9e6imb4hrp1.webp" alt=" " width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Log in to the VPS via SSH and execute the Dokploy installation command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://dokploy.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fhn2puuplrvorwaqwo2k8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhn2puuplrvorwaqwo2k8.webp" alt=" " width="582" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installation completes, visit the address shown in the command output to access the Dokploy dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Dokploy
&lt;/h3&gt;

&lt;p&gt;After registration and login, first set up a custom domain for the dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fl46hy66goil95x4n8r4l.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fl46hy66goil95x4n8r4l.webp" alt=" " width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then add a DNS record for this custom domain in your domain resolution platform (using CloudFlare as an example), select A type resolution, and enter the server IP address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftpwz1fbpjgxht74k7qjj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftpwz1fbpjgxht74k7qjj.webp" alt=" " width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the DNS propagates, you can access the Dokploy dashboard through the custom domain.&lt;/p&gt;

&lt;p&gt;Finally, connect your Git account as shown:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fy8lbflbk3wnl5z1cdyp9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fy8lbflbk3wnl5z1cdyp9.webp" alt=" " width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Option 1: Direct Deployment
&lt;/h2&gt;

&lt;p&gt;Dokploy provides a Vercel-like visual deployment interface. However, on resource-constrained servers, large builds can cause the server itself to crash or restart due to memory exhaustion. Therefore, direct deployment is only suitable for small projects.&lt;/p&gt;

&lt;p&gt;Create a Project, then create a Service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fg4pbvm6pljo6tipr7dbx.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fg4pbvm6pljo6tipr7dbx.webp" alt=" " width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnn6ti0assq9lysqtcfcw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnn6ti0assq9lysqtcfcw.webp" alt=" " width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the Service page, set the Provider by selecting Github Account, Repository, and Branch in sequence, then click Save:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5skxgg4xv8j5knj2xsja.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5skxgg4xv8j5knj2xsja.webp" alt=" " width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click the Deploy button at the top:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fpmhxs9v11jb3ye3k36dh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fpmhxs9v11jb3ye3k36dh.webp" alt=" " width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure environment variables. You need to redeploy the project after each modification:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fu9c2qnp9p35zd9j5xjs2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fu9c2qnp9p35zd9j5xjs2.webp" alt=" " width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;View build progress&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhq7n8ot4fhq19juryguf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhq7n8ot4fhq19juryguf.webp" alt=" " width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure custom domain&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fo7c1kitwwt5s1go12xyg.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fo7c1kitwwt5s1go12xyg.webp" alt=" " width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgdrzn06xyqhcnchiq9uv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgdrzn06xyqhcnchiq9uv.webp" alt=" " width="800" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the build completes, you need to set up DNS in Cloudflare:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fr06w7a4ifxy59znkjd6g.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fr06w7a4ifxy59znkjd6g.webp" alt=" " width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add two records:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;A record:
your-domain.com -&amp;gt; Your server IP
Enable Proxy

A record:
www.your-domain.com -&amp;gt; Your server IP
Enable Proxy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go to SSL/TLS settings and select Full or Flexible:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6sowrh2j4vcys5zeqpvh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6sowrh2j4vcys5zeqpvh.webp" alt=" " width="800" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set up redirects by going to Advanced - Redirects&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fv37o9u08g9qv7m7wkdyv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fv37o9u08g9qv7m7wkdyv.webp" alt=" " width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fo0zf9zqvt8symcrdir2j.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fo0zf9zqvt8symcrdir2j.webp" alt=" " width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I prefer redirecting the &lt;code&gt;www&lt;/code&gt; domain to the non-www domain, so I selected &lt;code&gt;Redirect to non-www&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fn0kjpgwguke7e4mtz27a.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fn0kjpgwguke7e4mtz27a.webp" alt=" " width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After completing these configurations, the project will be deployed and run successfully on Dokploy. Every code push will automatically trigger a new deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: This approach is not recommended. For actual deployment, use Option 2 described below.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Option 2: Deploy with GitHub Actions (Recommended)
&lt;/h2&gt;

&lt;p&gt;This approach uses GitHub Actions to build Docker images. After the build completes, Dokploy directly pulls the image and starts it, significantly reducing server load.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Configuration
&lt;/h3&gt;

&lt;p&gt;Initial configuration only needs to be set up once and can be used permanently.&lt;/p&gt;

&lt;p&gt;First, create a personal access token on GitHub, &lt;a href="https://github.com/settings/tokens/new" rel="noopener noreferrer"&gt;click here&lt;/a&gt;, and create a new Token&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmpyned36ickbmr9jf0po.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmpyned36ickbmr9jf0po.webp" alt=" " width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creation, you'll see the token. Save it as you'll need it later.&lt;/p&gt;

&lt;p&gt;If you forgot to save it, you can go back &lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;here&lt;/a&gt;, click the blue text to regenerate the token (Regenerate token)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9x98zrc8ylkzzn3pa1nk.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9x98zrc8ylkzzn3pa1nk.webp" alt=" " width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fewrpct6mmqq1nr0sgh57.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fewrpct6mmqq1nr0sgh57.webp" alt=" " width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return to the Dokploy dashboard, go to the Registry page, and add a Registry&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3tkugt4w6lzmddla34xb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3tkugt4w6lzmddla34xb.webp" alt=" " width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Registry Name: Custom name&lt;/li&gt;
&lt;li&gt;Username: Your GitHub ID&lt;/li&gt;
&lt;li&gt;Password: Token generated above&lt;/li&gt;
&lt;li&gt;Registry URL: &lt;a href="https://ghcr.io" rel="noopener noreferrer"&gt;https://ghcr.io&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkimj79jad825r0miigtq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkimj79jad825r0miigtq.webp" alt=" " width="800" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment Steps
&lt;/h3&gt;

&lt;p&gt;Go to the Service page, open Advanced, and set Cluster Settings&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkm7rd89cp7hzn4y3x7qb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkm7rd89cp7hzn4y3x7qb.webp" alt=" " width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the registry you just created, then click Save:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fd4s1vd4573seqqt0xex7.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fd4s1vd4573seqqt0xex7.webp" alt=" " width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click General, select Docker for Provider, enter &lt;code&gt;ghcr.io/[GitHub ID]/[Repo Name]:[Branch]&lt;/code&gt; for Docker Image, then Save:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2cgiznyskgpszf8tn3gx.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2cgiznyskgpszf8tn3gx.webp" alt=" " width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open Deployments and copy the displayed Webhook URL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhunlg7smr86rw94ndb8k.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhunlg7smr86rw94ndb8k.webp" alt=" " width="800" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now return to your code and create the file &lt;code&gt;.github/workflows/docker-image.yml&lt;/code&gt; in the root directory. This is a GitHub Actions workflow configuration file for automating Docker image building and publishing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create and publish a Docker image&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;REGISTRY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io&lt;/span&gt;
  &lt;span class="na"&gt;IMAGE_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.repository }}&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-push-image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;timeout-minutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;attestations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Log in to the Container registry&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;registry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.REGISTRY }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.actor }}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Extract metadata (tags, labels) for Docker&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;meta&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Docker Buildx&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/setup-buildx-action@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push Docker image&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&lt;/span&gt;
        &lt;span class="na"&gt;timeout-minutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
          &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.meta.outputs.tags }}&lt;/span&gt;
          &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.meta.outputs.labels }}&lt;/span&gt;
          &lt;span class="na"&gt;cache-from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;type=gha&lt;/span&gt;
          &lt;span class="na"&gt;cache-to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;type=gha,mode=max&lt;/span&gt;
          &lt;span class="c1"&gt;# ⚠️&lt;/span&gt;
          &lt;span class="c1"&gt;# It's recommended to only include environment variables needed for the build&lt;/span&gt;
          &lt;span class="c1"&gt;# Environment variables starting with NEXT_PUBLIC_ use vars&lt;/span&gt;
          &lt;span class="c1"&gt;# Other environment variables use secrets&lt;/span&gt;
          &lt;span class="na"&gt;build-args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_SITE_URL=${{ vars.NEXT_PUBLIC_SITE_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_PRICING_PATH=${{ vars.NEXT_PUBLIC_PRICING_PATH }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_OPTIMIZED_IMAGES=${{ vars.NEXT_PUBLIC_OPTIMIZED_IMAGES }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_LOGIN_MODE=${{ vars.NEXT_PUBLIC_LOGIN_MODE }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_GITHUB_CLIENT_ID=${{ vars.NEXT_PUBLIC_GITHUB_CLIENT_ID }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_GOOGLE_CLIENT_ID=${{ vars.NEXT_PUBLIC_GOOGLE_CLIENT_ID }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_TURNSTILE_SITE_KEY=${{ vars.NEXT_PUBLIC_TURNSTILE_SITE_KEY }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_ENABLE_STRIPE=${{ vars.NEXT_PUBLIC_ENABLE_STRIPE }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_DEFAULT_CURRENCY=${{ vars.NEXT_PUBLIC_DEFAULT_CURRENCY }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_GOOGLE_ID=${{ vars.NEXT_PUBLIC_GOOGLE_ID }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_PLAUSIBLE_DOMAIN=${{ vars.NEXT_PUBLIC_PLAUSIBLE_DOMAIN }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_PLAUSIBLE_SRC=${{ vars.NEXT_PUBLIC_PLAUSIBLE_SRC }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_DISCORD_INVITE_URL=${{ vars.NEXT_PUBLIC_DISCORD_INVITE_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_AUTO_FILL_AI_PROVIDER=${{ vars.NEXT_PUBLIC_AUTO_FILL_AI_PROVIDER }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_AUTO_FILL_AI_MODEL_ID=${{ vars.NEXT_PUBLIC_AUTO_FILL_AI_MODEL_ID }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_DAILY_AI_AUTO_FILL_LIMIT=${{ vars.NEXT_PUBLIC_DAILY_AI_AUTO_FILL_LIMIT }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_DAILY_SUBMIT_LIMIT=${{ vars.NEXT_PUBLIC_DAILY_SUBMIT_LIMIT }}&lt;/span&gt;
            &lt;span class="s"&gt;NEXT_PUBLIC_DAILY_IMAGE_UPLOAD_LIMIT=${{ vars.NEXT_PUBLIC_DAILY_IMAGE_UPLOAD_LIMIT }}&lt;/span&gt;
            &lt;span class="s"&gt;R2_PUBLIC_URL=${{ secrets.R2_PUBLIC_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;R2_ACCOUNT_ID=${{ secrets.R2_ACCOUNT_ID }}&lt;/span&gt;
            &lt;span class="s"&gt;R2_ACCESS_KEY_ID=${{ secrets.R2_ACCESS_KEY_ID }}&lt;/span&gt;
            &lt;span class="s"&gt;R2_SECRET_ACCESS_KEY=${{ secrets.R2_SECRET_ACCESS_KEY }}&lt;/span&gt;
            &lt;span class="s"&gt;R2_BUCKET_NAME=${{ secrets.R2_BUCKET_NAME }}&lt;/span&gt;
            &lt;span class="s"&gt;DATABASE_URL=${{ secrets.DATABASE_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;BETTER_AUTH_SECRET=${{ secrets.BETTER_AUTH_SECRET }}&lt;/span&gt;
            &lt;span class="s"&gt;BETTER_AUTH_GITHUB_CLIENT_SECRET=${{ secrets.BETTER_AUTH_GITHUB_CLIENT_SECRET }}&lt;/span&gt;
            &lt;span class="s"&gt;GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}&lt;/span&gt;
            &lt;span class="s"&gt;STRIPE_SECRET_KEY=${{ secrets.STRIPE_SECRET_KEY }}&lt;/span&gt;
            &lt;span class="s"&gt;STRIPE_PUBLISHABLE_KEY=${{ secrets.STRIPE_PUBLISHABLE_KEY }}&lt;/span&gt;
            &lt;span class="s"&gt;STRIPE_WEBHOOK_SECRET=${{ secrets.STRIPE_WEBHOOK_SECRET }}&lt;/span&gt;
            &lt;span class="s"&gt;STRIPE_CUSTOMER_PORTAL_URL=${{ secrets.STRIPE_CUSTOMER_PORTAL_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;RESEND_API_KEY=${{ secrets.RESEND_API_KEY }}&lt;/span&gt;
            &lt;span class="s"&gt;RESEND_AUDIENCE_ID=${{ secrets.RESEND_AUDIENCE_ID }}&lt;/span&gt;
            &lt;span class="s"&gt;ADMIN_EMAIL=${{ secrets.ADMIN_EMAIL }}&lt;/span&gt;
            &lt;span class="s"&gt;ADMIN_NAME=${{ secrets.ADMIN_NAME }}&lt;/span&gt;
            &lt;span class="s"&gt;UPSTASH_REDIS_REST_URL=${{ secrets.UPSTASH_REDIS_REST_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;UPSTASH_REDIS_REST_TOKEN=${{ secrets.UPSTASH_REDIS_REST_TOKEN }}&lt;/span&gt;
            &lt;span class="s"&gt;OPENROUTER_API_KEY=${{ secrets.OPENROUTER_API_KEY }}&lt;/span&gt;
            &lt;span class="s"&gt;PLAUSIBLE_API_KEY=${{ secrets.PLAUSIBLE_API_KEY }}&lt;/span&gt;
            &lt;span class="s"&gt;PLAUSIBLE_URL=${{ secrets.PLAUSIBLE_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;DISCORD_SUBMIT_WEBHOOK_URL=${{ secrets.DISCORD_SUBMIT_WEBHOOK_URL }}&lt;/span&gt;
            &lt;span class="s"&gt;FIRECRAWL_API_KEY=${{ secrets.FIRECRAWL_API_KEY }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Trigger dokploy redeploy&lt;/span&gt;
        &lt;span class="c1"&gt;# ⚠️ Use the Webhook URL from Dokploy deployments&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -X GET https://xxxxx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Environment variables starting with &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; use &lt;code&gt;vars&lt;/code&gt; reference&lt;/li&gt;
&lt;li&gt;Other environment variables use &lt;code&gt;secrets&lt;/code&gt; reference&lt;/li&gt;
&lt;li&gt;Replace the https address at the end with the Webhook URL shown in Dokploy deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, create a &lt;code&gt;Dockerfile&lt;/code&gt; in the root directory that defines how to build the Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ============================================
# Dependencies Stage
# ============================================
FROM node:20-alpine AS deps
WORKDIR /app

# Enable corepack (for managing package manager versions)
RUN corepack enable

# Copy package management files
COPY package.json pnpm-lock.yaml* ./

# Prefetch dependencies using cache mount
RUN --mount=type=cache,target=/root/.local/share/pnpm/store/v3 \
  pnpm fetch
# Install dependencies using cache mount (frozen lockfile, offline mode)
RUN --mount=type=cache,target=/root/.local/share/pnpm/store/v3 \
  pnpm install --frozen-lockfile --offline

# ============================================
# Build Stage
# ============================================
FROM node:20-alpine AS builder
WORKDIR /app

# Enable corepack
RUN corepack enable

# Copy node_modules from dependencies stage
COPY --from=deps /app/node_modules ./node_modules
# Copy all source code
COPY . .

# ============================================
# Build Arguments
# Only declare variables needed at build time
# ============================================

# NEXT_PUBLIC_* variables (will be embedded in client-side JavaScript)
ARG NEXT_PUBLIC_SITE_URL
ARG NEXT_PUBLIC_PRICING_PATH
ARG NEXT_PUBLIC_OPTIMIZED_IMAGES
ARG NEXT_PUBLIC_LOGIN_MODE
ARG NEXT_PUBLIC_GITHUB_CLIENT_ID
ARG NEXT_PUBLIC_GOOGLE_CLIENT_ID
ARG NEXT_PUBLIC_TURNSTILE_SITE_KEY
ARG NEXT_PUBLIC_ENABLE_STRIPE
ARG NEXT_PUBLIC_DEFAULT_CURRENCY
ARG NEXT_PUBLIC_GOOGLE_ID
ARG NEXT_PUBLIC_PLAUSIBLE_DOMAIN
ARG NEXT_PUBLIC_PLAUSIBLE_SRC
ARG NEXT_PUBLIC_DISCORD_INVITE_URL
ARG NEXT_PUBLIC_AUTO_FILL_AI_PROVIDER
ARG NEXT_PUBLIC_AUTO_FILL_AI_MODEL_ID
ARG NEXT_PUBLIC_DAILY_AI_AUTO_FILL_LIMIT
ARG NEXT_PUBLIC_DAILY_SUBMIT_LIMIT
ARG NEXT_PUBLIC_DAILY_IMAGE_UPLOAD_LIMIT

# R2_PUBLIC_URL is needed by next.config.mjs for image remotePatterns
ARG R2_PUBLIC_URL
ARG R2_ACCOUNT_ID
ARG R2_ACCESS_KEY_ID
ARG R2_SECRET_ACCESS_KEY
ARG R2_BUCKET_NAME

# DATABASE_URL is needed for static site generation (SSG) at build time
ARG DATABASE_URL

# BETTER_AUTH
ARG BETTER_AUTH_SECRET
ARG BETTER_AUTH_GITHUB_CLIENT_SECRET
ARG GOOGLE_CLIENT_SECRET

# STRIPE
ARG STRIPE_SECRET_KEY
ARG STRIPE_PUBLISHABLE_KEY
ARG STRIPE_WEBHOOK_SECRET
ARG STRIPE_CUSTOMER_PORTAL_URL

# RESEND
ARG RESEND_API_KEY
ARG RESEND_AUDIENCE_ID
ARG ADMIN_EMAIL
ARG ADMIN_NAME

# UPSTASH
ARG UPSTASH_REDIS_REST_URL
ARG UPSTASH_REDIS_REST_TOKEN

# AI
ARG OPENROUTER_API_KEY
ARG FIRECRAWL_API_KEY

# PLAUSIBLE
ARG PLAUSIBLE_API_KEY
ARG PLAUSIBLE_URL

# DISCORD
ARG DISCORD_SUBMIT_WEBHOOK_URL

# ============================================
# Build Environment Variables
# ============================================

# Set NEXT_PUBLIC_* as environment variables so Next.js can embed them in the bundle
ENV NEXT_PUBLIC_SITE_URL=${NEXT_PUBLIC_SITE_URL}
ENV NEXT_PUBLIC_PRICING_PATH=${NEXT_PUBLIC_PRICING_PATH}
ENV NEXT_PUBLIC_OPTIMIZED_IMAGES=${NEXT_PUBLIC_OPTIMIZED_IMAGES}
ENV NEXT_PUBLIC_LOGIN_MODE=${NEXT_PUBLIC_LOGIN_MODE}
ENV NEXT_PUBLIC_GITHUB_CLIENT_ID=${NEXT_PUBLIC_GITHUB_CLIENT_ID}
ENV NEXT_PUBLIC_GOOGLE_CLIENT_ID=${NEXT_PUBLIC_GOOGLE_CLIENT_ID}
ENV NEXT_PUBLIC_TURNSTILE_SITE_KEY=${NEXT_PUBLIC_TURNSTILE_SITE_KEY}
ENV NEXT_PUBLIC_ENABLE_STRIPE=${NEXT_PUBLIC_ENABLE_STRIPE}
ENV NEXT_PUBLIC_DEFAULT_CURRENCY=${NEXT_PUBLIC_DEFAULT_CURRENCY}
ENV NEXT_PUBLIC_GOOGLE_ID=${NEXT_PUBLIC_GOOGLE_ID}
ENV NEXT_PUBLIC_PLAUSIBLE_DOMAIN=${NEXT_PUBLIC_PLAUSIBLE_DOMAIN}
ENV NEXT_PUBLIC_PLAUSIBLE_SRC=${NEXT_PUBLIC_PLAUSIBLE_SRC}
ENV NEXT_PUBLIC_DISCORD_INVITE_URL=${NEXT_PUBLIC_DISCORD_INVITE_URL}
ENV NEXT_PUBLIC_AUTO_FILL_AI_PROVIDER=${NEXT_PUBLIC_AUTO_FILL_AI_PROVIDER}
ENV NEXT_PUBLIC_AUTO_FILL_AI_MODEL_ID=${NEXT_PUBLIC_AUTO_FILL_AI_MODEL_ID}
ENV NEXT_PUBLIC_DAILY_AI_AUTO_FILL_LIMIT=${NEXT_PUBLIC_DAILY_AI_AUTO_FILL_LIMIT}
ENV NEXT_PUBLIC_DAILY_SUBMIT_LIMIT=${NEXT_PUBLIC_DAILY_SUBMIT_LIMIT}
ENV NEXT_PUBLIC_DAILY_IMAGE_UPLOAD_LIMIT=${NEXT_PUBLIC_DAILY_IMAGE_UPLOAD_LIMIT}

# R2
ENV R2_PUBLIC_URL=${R2_PUBLIC_URL}
ENV R2_ACCOUNT_ID=${R2_ACCOUNT_ID}
ENV R2_ACCESS_KEY_ID=${R2_ACCESS_KEY_ID}
ENV R2_SECRET_ACCESS_KEY=${R2_SECRET_ACCESS_KEY}
ENV R2_BUCKET_NAME=${R2_BUCKET_NAME}

# DATABASE_URL for static site generation
ENV DATABASE_URL=${DATABASE_URL}

# BETTER_AUTH
ENV BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
ENV BETTER_AUTH_GITHUB_CLIENT_SECRET=${BETTER_AUTH_GITHUB_CLIENT_SECRET}
ENV GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}

# Stripe
ENV STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
ENV STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY}
ENV STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
ENV STRIPE_CUSTOMER_PORTAL_URL=${STRIPE_CUSTOMER_PORTAL_URL}

# RESEND
ENV RESEND_API_KEY=${RESEND_API_KEY}
ENV RESEND_AUDIENCE_ID=${RESEND_AUDIENCE_ID}
ENV ADMIN_EMAIL=${ADMIN_EMAIL}
ENV ADMIN_NAME=${ADMIN_NAME}

# UPSTASH
ENV UPSTASH_REDIS_REST_URL=${UPSTASH_REDIS_REST_URL}
ENV UPSTASH_REDIS_REST_TOKEN=${UPSTASH_REDIS_REST_TOKEN}

# AI
ENV OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
ENV FIRECRAWL_API_KEY=${FIRECRAWL_API_KEY}

# PLAUSIBLE
ENV PLAUSIBLE_API_KEY=${PLAUSIBLE_API_KEY}
ENV PLAUSIBLE_URL=${PLAUSIBLE_URL}

# DISCORD
ENV DISCORD_SUBMIT_WEBHOOK_URL=${DISCORD_SUBMIT_WEBHOOK_URL}

# Disable Next.js telemetry
ENV NEXT_TELEMETRY_DISABLED=1

# Build the application
RUN --mount=type=cache,target=/root/.local/share/pnpm/store/v3 \
  pnpm build

# ============================================
# Runtime Stage
# ============================================
FROM node:20-alpine AS runner
WORKDIR /app

# ============================================
# No build arguments or environment variables needed here
# All runtime secrets will be injected by the container runtime (dokploy)
# Next.js standalone mode reads environment variables at runtime
# ============================================

# Set production environment
ENV NODE_ENV=production
# Disable Next.js telemetry
ENV NEXT_TELEMETRY_DISABLED=1

# Create system user group and user (for secure execution)
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Copy necessary files from build stage
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

# Switch to non-root user
USER nextjs

# Expose port
EXPOSE 3000

# Set port and hostname
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

# Start the application
CMD ["node", "server.js"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When configuring &lt;code&gt;docker-image.yml&lt;/code&gt;, &lt;code&gt;Dockerfile&lt;/code&gt; and GitHub Actions, you need to understand an important security principle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Private projects: Images are usually only accessible to you, so you can safely include all environment variables in the files and GitHub Actions without worrying about distinguishing between build-time and runtime variables&lt;/li&gt;
&lt;li&gt;Open-source projects or projects with public images: It's recommended to only include build-time environment variables in the files and GitHub Actions to ensure sensitive information isn't leaked&lt;/li&gt;
&lt;li&gt;You can check whether your image is public or private at &lt;code&gt;https://github.com/users/[your Github username]/packages/container/[project repository name]/settings&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fq659zbcmw3e5vxca8nfn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fq659zbcmw3e5vxca8nfn.webp" alt=" " width="800" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For best practices, you can also add a &lt;code&gt;.dockerignore&lt;/code&gt; file to the root directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.git
.github
node_modules
.next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After confirming the environment variables declared in &lt;code&gt;docker-image.yml&lt;/code&gt; and &lt;code&gt;Dockerfile&lt;/code&gt;, you need to define them in GitHub Actions' secrets and variables:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fobmoa4xvwom9jubylfte.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fobmoa4xvwom9jubylfte.webp" alt=" " width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define environment variables starting with &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; in Variables&lt;/li&gt;
&lt;li&gt;Define environment variables without the &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; prefix in Secrets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnpsdpjp2yj55mp6585qo.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnpsdpjp2yj55mp6585qo.webp" alt=" " width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fopybqzt758bcnmdatqmj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fopybqzt758bcnmdatqmj.webp" alt=" " width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Environment variables needed at runtime should be configured in Dokploy's Environment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Flda3tj7lcjacph8h4gac.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flda3tj7lcjacph8h4gac.webp" alt=" " width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For convenience, you can directly copy all environment variables here.&lt;/p&gt;

&lt;p&gt;Now push the code, which will trigger the GitHub Actions build process. After the build completes, Dokploy will automatically pull the latest image and complete the project update.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxmhpybkefxmvsdbub3vg.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxmhpybkefxmvsdbub3vg.webp" alt=" " width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need to rebuild without code updates, you can manually trigger the build process in GitHub Actions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjrao4uxyvrreatfnnwar.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjrao4uxyvrreatfnnwar.webp" alt=" " width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Choose Dokploy for Deployment
&lt;/h2&gt;

&lt;p&gt;Since using Dokploy requires maintaining your own server, although most situations won't have issues, if problems do occur, people without DevOps experience will find it difficult to resolve them. Therefore, I recommend considering Dokploy only when deploying on Vercel is not cost-effective, such as in the following scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Non-critical products where security risks are acceptable&lt;/li&gt;
&lt;li&gt;Products that don't generate revenue or have low profit margins&lt;/li&gt;
&lt;li&gt;Products with many pages, such as directory sites or documentation sites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my personal use, projects I currently deploy on Dokploy include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Third-party open-source tools, such as Plausible&lt;/li&gt;
&lt;li&gt;Blog and documentation sites, such as Nexty.dev documentation&lt;/li&gt;
&lt;li&gt;Directory sites, such as &lt;a href="https://dofollow.tools/" rel="noopener noreferrer"&gt;Dofollow.Tools&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lightweight small products&lt;/li&gt;
&lt;li&gt;Scheduled task crawlers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reference Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.dokploy.com/docs/core" rel="noopener noreferrer"&gt;Dokploy Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://weijunext.com/article/self-hosted-dokploy" rel="noopener noreferrer"&gt;Self-Host Dokploy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>saas</category>
      <category>solodev</category>
    </item>
    <item>
      <title>What Makes Nexty.dev Stand Out</title>
      <dc:creator>Jude Wei</dc:creator>
      <pubDate>Sun, 25 May 2025 03:43:50 +0000</pubDate>
      <link>https://forem.com/weijunext/what-makes-nextydev-stand-out-4f93</link>
      <guid>https://forem.com/weijunext/what-makes-nextydev-stand-out-4f93</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;First post on &lt;a href="https://nexty.dev/blogs/nexty-dev-stand-out" rel="noopener noreferrer"&gt;https://nexty.dev/blogs/nexty-dev-stand-out&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my Notion database, I've listed over 40 Next.js SaaS templates - all competitors of Nexty.dev. With such an overwhelming array of choices, it's difficult to quickly determine which one truly meets your needs.&lt;/p&gt;

&lt;p&gt;If you're searching for a solution that's not only secure and stable but also offers unique advanced features to help launch your SaaS product quickly, Nexty.dev deserves your attention.&lt;/p&gt;

&lt;p&gt;Nexty.dev is a flexible, multi-purpose full-stack SaaS template built on Next.js and Supabase. This article will explore Nexty.dev's unique advantages compared to its competitors to help you make the right choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nexty.dev's Core Features
&lt;/h2&gt;

&lt;p&gt;Before diving into Nexty.dev's unique advantages, let me introduce its robust features that match or exceed competitor offerings.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multi-language Support&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nexty.dev supports English, Chinese, and Japanese by default, and you can easily add more languages as needed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nexty.dev implements authentication through Supabase Auth, supporting multiple login methods including Google, GitHub, and email Magic Link. The &lt;a href="https://nexty.dev/docs/integration/supabase" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; provides detailed configuration steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgnjuqdaur7uk6nncium5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgnjuqdaur7uk6nncium5.png" alt="login" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Email Services&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nexty.dev implements domain email through Cloudflare, which can be configured by following the &lt;a href="https://nexty.dev/docs/integration/domain" rel="noopener noreferrer"&gt;documentation steps&lt;/a&gt;. A domain email address makes your brand appear more professional and helps build trust with users.&lt;/p&gt;

&lt;p&gt;Additionally, Nexty.dev implements subscriber management and email sending functionality through Resend, with detailed configuration steps in the &lt;a href="https://nexty.dev/docs/integration/resend" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The template's footer includes a built-in newsletter subscription module to help you better understand email service implementation and usage.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Analytics and Advertising&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nexty.dev includes built-in support for Google Analytics, Plausible, and Google Ads, allowing you to immediately start analyzing user behavior and running advertisements.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SEO-Friendly Structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nexty.dev provides an SEO-friendly page structure, eliminating the need to worry about technical SEO optimization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nexty.dev's Unique Advantages
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Payment Services and Pricing Card Management
&lt;/h3&gt;

&lt;p&gt;While similar templates often provide only a core payment flow, Nexty.dev's payment module comes with a complete built-in logic for one-time payments and recurring subscriptions. This includes adding credits upon payment, updating credits on subscription renewal, and clearing credits upon refund.&lt;/p&gt;

&lt;p&gt;But that's not all that makes Nexty.dev stand out. To make pricing card management more convenient, Nexty.dev has added pricing card management functionality to the admin dashboard, eliminating the need for complex multilingual JSON configuration.&lt;/p&gt;

&lt;p&gt;The pricing card management feature is exceptionally user-friendly. Let me explain through screenshots.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List View&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can view all pricing card core information in the list, including environment, card information, associated Stripe Price ID, payment method, and status. The action column supports editing, Duplicate, and deleting, with the "Duplicate" function allowing you to quickly create similar cards, reducing repetitive operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747680140699-ocjdw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747680140699-ocjdw9.png" title="nexty.dev prices list" alt="nexty.dev prices list" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create/Edit Pricing Cards&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The create/edit pricing card page supports selecting the environment, order, and visibility (Active); you can also see real-time previews to ensure proper display in the template and easily check for issues. These features are &lt;strong&gt;unmatched&lt;/strong&gt; among SaaS templates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676838140-gz99ji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676838140-gz99ji.png" title="nexty.dev prices form" alt="nexty.dev prices form" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Stripe integration, you just need to copy the Stripe Price ID to fetch accurate pricing information with one click, eliminating the need for manual data entry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676849949-7ymxq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676849949-7ymxq1.png" title="nexty.dev prices form" alt="nexty.dev prices form" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Card display information, including display price, plan benefits, highlighting, and button information, can all be configured through the form.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676862845-w8sb1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676862845-w8sb1c.png" title="nexty.dev prices form" alt="nexty.dev prices form" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676874546-uveclj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676874546-uveclj.png" title="nexty.dev prices form" alt="nexty.dev prices form" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To better accommodate multilingual scenarios, Nexty.dev's pricing cards also offer multilingual translation functionality - just configure the translation API Key in your environment variables.&lt;/p&gt;

&lt;p&gt;For technically-inclined template users who want to extend user benefits, Nexty.dev supports a "Benefits JSON" feature, allowing you to expand user benefits without modifying the data table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676886144-tzb0cd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676886144-tzb0cd.png" title="nexty.dev prices form" alt="nexty.dev prices form" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After updating the data, the pricing cards immediately update on the user end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676901713-4olih8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676901713-4olih8.png" title="nexty.dev pricing" alt="nexty.dev pricing" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is one of my favorite features because it allows template users to update pricing through the admin dashboard rather than modifying code, completing updates in just a minute.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Demo Provided
&lt;/h3&gt;

&lt;p&gt;While providing AI APIs has become standard for SaaS templates, Nexty.dev takes it further.&lt;/p&gt;

&lt;p&gt;Understanding that different products have different AI needs, Nexty.dev goes beyond just providing API calls. The template includes an AI Demo page with examples of various AI model implementations, including single-turn dialogue, multi-turn dialogue, text-to-image, image-to-image, and image-to-video.&lt;/p&gt;

&lt;p&gt;On the AI Demo page, you can quickly test different AI functionalities. If you're unfamiliar with AI features, you can use this page's code as a learning example to quickly understand AI development approaches - embodying the principle of "Give a man a fish, and you feed him for a day. Teach a man to fish, and you feed him for a lifetime".&lt;/p&gt;

&lt;p&gt;The AI Demo is also crucial for keeping up with rapidly evolving AI models, allowing you to quickly test new models and validate their feasibility ahead of the competition.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676922780-0s0spx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676922780-0s0spx.png" title="nexty.dev ai demo" alt="nexty.dev ai demo" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  File Management
&lt;/h3&gt;

&lt;p&gt;Nexty.dev implements file storage and management through Cloudflare R2, with built-in functionality for file upload, deletion, and list viewing.&lt;/p&gt;

&lt;p&gt;These features are integrated into the admin dashboard's R2 file management functionality, making file management convenient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747680166219-pw3wx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747680166219-pw3wx0.png" title="nexty.dev r2 file" alt="nexty.dev r2 file" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced CMS
&lt;/h3&gt;

&lt;p&gt;Nexty.dev's CMS module offers features that are &lt;strong&gt;unmatched&lt;/strong&gt; among SaaS templates, going beyond basic content management and publishing to support various application scenarios.&lt;/p&gt;

&lt;p&gt;Beyond basic blog information (title, slug, description, tags, cover image), Nexty.dev supports advanced settings like pinning, status (draft, published, archived), access permissions (public, logged-in users, subscribers); content editing supports both Markdown and rich text modes, plus AI translation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676961551-1oga7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676961551-1oga7o.png" title="nexty.dev cms form" alt="nexty.dev cms form" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676972035-by8rd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747676972035-by8rd9.png" title="nexty.dev cms form" alt="nexty.dev cms form" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, the list supports blog duplicate to create new posts, reducing repetitive operations and improving multilingual content production efficiency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747680181202-gathzj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.nexty.dev%2Fblog-images%2Fpost-image-1747680181202-gathzj.png" title="nexty.dev cms" alt="nexty.dev cms" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With these features, you can use the CMS module not only for blog sites but also for paid content sites - this truly makes Nexty.dev a multi-purpose template.&lt;/p&gt;

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

&lt;p&gt;As we've seen, Nexty.dev isn't just another feature-rich Next.js SaaS template - it's a thoughtfully designed solution addressing real development pain points. While it solidly covers essential SaaS modules like multilingual support, authentication, email services, analytics, and SEO, it goes &lt;strong&gt;far beyond&lt;/strong&gt; ordinary templates through unique advantages like &lt;strong&gt;visual pricing management&lt;/strong&gt;, &lt;strong&gt;inspiring AI demos&lt;/strong&gt;, &lt;strong&gt;convenient file management&lt;/strong&gt;, and &lt;strong&gt;powerful advanced CMS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Understanding the challenges developers face in building SaaS applications, every carefully designed feature in Nexty.dev - from visual pricing that eliminates tedious configuration to educational AI examples and advanced CMS capable of supporting paid content - aims to clear obstacles, significantly improve development efficiency, and inspire business innovation.&lt;/p&gt;

&lt;p&gt;If you're looking for a template that can truly accelerate your SaaS product launch while giving you powerful customization capabilities, Nexty.dev is undoubtedly your most trustworthy choice. Visit &lt;a href="https://nexty.dev/" rel="noopener noreferrer"&gt;nexty.dev&lt;/a&gt; now to turn your SaaS vision into reality quickly.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>startup</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
