<?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: Candido Sales Gomes</title>
    <description>The latest articles on DEV Community by Candido Sales Gomes (@candidosales).</description>
    <link>https://dev.to/candidosales</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%2F6312%2F0563d738-5fd4-477a-ae9f-cff85c61b584.jpeg</url>
      <title>DEV Community: Candido Sales Gomes</title>
      <link>https://dev.to/candidosales</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/candidosales"/>
    <language>en</language>
    <item>
      <title>Deploying Payload CMS to Fly.io</title>
      <dc:creator>Candido Sales Gomes</dc:creator>
      <pubDate>Wed, 20 Nov 2024 04:27:40 +0000</pubDate>
      <link>https://dev.to/candidosales/deploying-payloadcms-to-flyio-23d3</link>
      <guid>https://dev.to/candidosales/deploying-payloadcms-to-flyio-23d3</guid>
      <description>&lt;h2&gt;
  
  
  Infra
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;th&gt;Disk&lt;/th&gt;
&lt;th&gt;CPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;256 MB RAM&lt;/td&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;1 (shared)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PayloadCMS (Node)&lt;/td&gt;
&lt;td&gt;1 GB RAM&lt;/td&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;1 (shared)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meilisearch&lt;/td&gt;
&lt;td&gt;1 GB RAM&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;1 (shared)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Install Fly CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;flyctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Login to your Fly account.&lt;/p&gt;

&lt;p&gt;Follow the instructions and return to the command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the &lt;code&gt;fly.toml&lt;/code&gt; and &lt;code&gt;Dockerfile&lt;/code&gt; in your current project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# fly.toml app configuration file generated for payload-app on 2024-11-19T22:14:01-05:00&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# See https://fly.io/docs/reference/configuration/ for information about how to use this file.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;

&lt;span class="py"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'payload-app'&lt;/span&gt;
&lt;span class="py"&gt;primary_region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'gru'&lt;/span&gt;
&lt;span class="py"&gt;kill_timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'5m0s'&lt;/span&gt;

&lt;span class="nn"&gt;[build]&lt;/span&gt;

&lt;span class="nn"&gt;[[mounts]]&lt;/span&gt;
  &lt;span class="py"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'media'&lt;/span&gt;
  &lt;span class="py"&gt;destination&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'/opt/app/media'&lt;/span&gt;
  &lt;span class="py"&gt;initial_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'1gb'&lt;/span&gt;

&lt;span class="nn"&gt;[http_service]&lt;/span&gt;
  &lt;span class="py"&gt;internal_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;
  &lt;span class="py"&gt;force_https&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="py"&gt;auto_stop_machines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'stop'&lt;/span&gt;
  &lt;span class="py"&gt;auto_start_machines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="py"&gt;min_machines_running&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="py"&gt;processes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'app'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[[services]]&lt;/span&gt;
  &lt;span class="py"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'tcp'&lt;/span&gt;
  &lt;span class="py"&gt;internal_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1337&lt;/span&gt;
  &lt;span class="py"&gt;processes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'app'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nn"&gt;[[services.ports]]&lt;/span&gt;
    &lt;span class="py"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
    &lt;span class="py"&gt;handlers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'http'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[[vm]]&lt;/span&gt;
  &lt;span class="py"&gt;cpu_kind&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'shared'&lt;/span&gt;
  &lt;span class="py"&gt;cpus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="py"&gt;memory_mb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the &lt;code&gt;Dockerfile&lt;/code&gt;. The example below is a multi-stage docker build of Payload for production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# syntax=docker.io/docker/dockerfile:1&lt;/span&gt;

&lt;span class="c"&gt;# From https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:22.12.0-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies only when needed&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;deps&lt;/span&gt;
&lt;span class="c"&gt;# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; libc6-compat
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies based on the preferred package manager&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; yarn.lock &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;yarn &lt;span class="nt"&gt;--frozen-lockfile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; package-lock.json &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;npm ci&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; pnpm-lock.yaml &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;corepack &lt;span class="nb"&gt;enable &lt;/span&gt;pnpm &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm i &lt;span class="nt"&gt;--frozen-lockfile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;else &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Lockfile not found."&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;fi&lt;/span&gt;


&lt;span class="c"&gt;# Rebuild the source code only when needed&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=deps /app/node_modules ./node_modules&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Next.js collects completely anonymous telemetry data about general usage.&lt;/span&gt;
&lt;span class="c"&gt;# Learn more here: https://nextjs.org/telemetry&lt;/span&gt;
&lt;span class="c"&gt;# Uncomment the following line in case you want to disable telemetry during the build.&lt;/span&gt;
&lt;span class="c"&gt;# ENV NEXT_TELEMETRY_DISABLED 1&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; yarn.lock &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;yarn run build&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; package-lock.json &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;npm run build&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; pnpm-lock.yaml &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;corepack &lt;span class="nb"&gt;enable &lt;/span&gt;pnpm &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm run build&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;else &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Lockfile not found."&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Production image, copy all the files and run next&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;runner&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV=production&lt;/span&gt;
&lt;span class="c"&gt;# Uncomment the following line in case you want to disable telemetry during runtime.&lt;/span&gt;
&lt;span class="c"&gt;# ENV NEXT_TELEMETRY_DISABLED 1&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;addgroup &lt;span class="nt"&gt;--system&lt;/span&gt; &lt;span class="nt"&gt;--gid&lt;/span&gt; 1001 nodejs
&lt;span class="k"&gt;RUN &lt;/span&gt;adduser &lt;span class="nt"&gt;--system&lt;/span&gt; &lt;span class="nt"&gt;--uid&lt;/span&gt; 1001 nextjs

&lt;span class="c"&gt;# COPY --from=builder /app/public ./public&lt;/span&gt;

&lt;span class="c"&gt;# Set the correct permission for prerender cache&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; .next
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chown &lt;/span&gt;nextjs:nodejs .next

&lt;span class="c"&gt;# Automatically leverage output traces to reduce image size&lt;/span&gt;
&lt;span class="c"&gt;# https://nextjs.org/docs/advanced-features/output-file-tracing&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder --chown=nextjs:nodejs /app/.next/standalone ./&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static&lt;/span&gt;

&lt;span class="c"&gt;# Media folder&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder --chown=nextjs:nodejs /app/media ./media&lt;/span&gt;


&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; nextjs&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PORT=3000&lt;/span&gt;

&lt;span class="c"&gt;# server.js is created by next build from the standalone output&lt;/span&gt;
&lt;span class="c"&gt;# https://nextjs.org/docs/pages/api-reference/next-config-js/output&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; HOSTNAME="0.0.0.0"&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You must add &lt;code&gt;standalone&lt;/code&gt; output for the NextJS to enable run in the Docker container.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;next.config.js&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;withPayload&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@payloadcms/next/withPayload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="cm"&gt;/** @type {import('next').NextConfig} */&lt;/span&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="c1"&gt;// Your Next.js config here&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;withPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create migrate folder
&lt;/h2&gt;

&lt;p&gt;Create a new migration file in the migrations directory.&lt;/p&gt;

&lt;p&gt;First, set up the &lt;code&gt;migrationDir&lt;/code&gt; in &lt;code&gt;payload.config.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;buildConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;buildConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// your config here&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;postgresAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URI&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;//  Add the path to migrations folder&lt;/span&gt;
    &lt;span class="na"&gt;migrationDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/migrations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, run the command below to generate the migrations in the folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run payload migrate:create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to run migrations at runtime, on initialization, you can pass your migrations to your database adapter under the prodMigrations key as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import your migrations from the `index.ts` file&lt;/span&gt;
&lt;span class="c1"&gt;// that Payload generates for you&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;migrations&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./migrations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;buildConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;buildConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// your config here&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;postgresAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//  your adapter config here&lt;/span&gt;
    &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URI&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;migrationDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/migrations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prodMigrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;migrations&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Passing your migrations, as shown above, will tell Payload, in production only, to execute any migrations that need to be run before completing the initialization of Payload. This is ideal for long-running services where Payload is only initialized at startup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;p&gt;Before deploying, you have to create the database. So run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly postgres create
&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%2Fp9bj1jsrepgz186ym3cm.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%2Fp9bj1jsrepgz186ym3cm.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating the database, copy the &lt;code&gt;Connection string&lt;/code&gt; in the safe place. You will use it as a secret &lt;code&gt;DATABASE_URI&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Generate your &lt;code&gt;PAYLOAD_SECRET&lt;/code&gt; at &lt;a href="https://randomkeygen.com/" rel="noopener noreferrer"&gt;https://randomkeygen.com/&lt;/a&gt; and store it in a safe place.&lt;/p&gt;

&lt;p&gt;Now, you will deploy the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly launch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And later ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step is to add the secrets in your app in Fly.io&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%2Fvqyed92pboyuaifjnpwa.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%2Fvqyed92pboyuaifjnpwa.png" alt=" " width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And deploy again to update the secrets; now, it will work on the migrations in runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The flow is simple, but I took too long to understand how to set up the migrations. I hope it will help you :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Source
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://payloadcms.com/docs/production/deployment#docker" rel="noopener noreferrer"&gt;https://payloadcms.com/docs/production/deployment#docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://payloadcms.com/docs/database/migrations#running-migrations-in-production" rel="noopener noreferrer"&gt;https://payloadcms.com/docs/database/migrations#running-migrations-in-production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/pages/api-reference/next-config-js/output" rel="noopener noreferrer"&gt;https://nextjs.org/docs/pages/api-reference/next-config-js/output&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flyio</category>
      <category>payloadcms</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Migrate Strapi from Render to Fly.io</title>
      <dc:creator>Candido Sales Gomes</dc:creator>
      <pubDate>Fri, 02 Aug 2024 01:23:31 +0000</pubDate>
      <link>https://dev.to/candidosales/migrate-strapi-from-render-to-flyio-lbi</link>
      <guid>https://dev.to/candidosales/migrate-strapi-from-render-to-flyio-lbi</guid>
      <description>&lt;p&gt;I was having cost issues with the Render server, and I can't reduce the server for small machines. Most of my users are from Brazil, so I moved my Strapi to Fly.io, which enables reduced costs. &lt;/p&gt;

&lt;p&gt;Fly.io better manages your VM using &lt;a href="https://firecracker-microvm.github.io/" rel="noopener noreferrer"&gt;Firecracker&lt;/a&gt;, and I can choose servers located in &lt;a href="https://fly.io/docs/reference/regions/" rel="noopener noreferrer"&gt;Brazil&lt;/a&gt; (Guarulhos—Sao Paulo). It will provide a better experience for my users and better maintainability.&lt;/p&gt;

&lt;p&gt;In this article, you will see all my steps to accomplish this migration.&lt;/p&gt;

&lt;p&gt;My previous infrastructure was:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Render (Cost US$60.25/month)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;th&gt;Disk&lt;/th&gt;
&lt;th&gt;CPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;1 GB RAM&lt;/td&gt;
&lt;td&gt;16 GB (using only 96 MB)&lt;/td&gt;
&lt;td&gt;1 CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strapi (Node)&lt;/td&gt;
&lt;td&gt;2 GB RAM (using only 600MB)&lt;/td&gt;
&lt;td&gt;1 GB (using only 0.28GB)&lt;/td&gt;
&lt;td&gt;1 CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meilisearch&lt;/td&gt;
&lt;td&gt;1 GB RAM (using only 60MB)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;1 CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now ...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fly.io (Cost US$9.16/month)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;th&gt;Disk&lt;/th&gt;
&lt;th&gt;CPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;256 MB RAM&lt;/td&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;1 (shared)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strapi (Node)&lt;/td&gt;
&lt;td&gt;1 GB RAM&lt;/td&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;1 (shared)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meilisearch&lt;/td&gt;
&lt;td&gt;1 GB RAM&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;1 (shared)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Deploy Strapi in Fly.io
&lt;/h2&gt;

&lt;p&gt;Install Fly CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;flyctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Login to your Fly account. &lt;/p&gt;

&lt;p&gt;Follow the instructions and return to the command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the &lt;code&gt;fly.toml&lt;/code&gt;, &lt;code&gt;dockerfile&lt;/code&gt; and &lt;code&gt;.dockerignore&lt;/code&gt; in your current project&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fly.toml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# fly.toml app configuration file generated for app-name on 2024-07-29T15:46:53-04:00&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# See https://fly.io/docs/reference/configuration/ for information about how to use this file.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;

&lt;span class="py"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'app-name'&lt;/span&gt;
&lt;span class="py"&gt;primary_region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'gru'&lt;/span&gt;
&lt;span class="py"&gt;kill_timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'5m0s'&lt;/span&gt;

&lt;span class="nn"&gt;[build]&lt;/span&gt;

&lt;span class="nn"&gt;[[mounts]]&lt;/span&gt;
  &lt;span class="py"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'uploads'&lt;/span&gt;
  &lt;span class="py"&gt;destination&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'/public/uploads'&lt;/span&gt;
  &lt;span class="py"&gt;initial_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'1gb'&lt;/span&gt;

&lt;span class="nn"&gt;[http_service]&lt;/span&gt;
  &lt;span class="py"&gt;internal_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1337&lt;/span&gt;
  &lt;span class="py"&gt;force_https&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="py"&gt;auto_stop_machines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'stop'&lt;/span&gt;
  &lt;span class="py"&gt;auto_start_machines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="py"&gt;min_machines_running&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="py"&gt;processes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'app'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[[services]]&lt;/span&gt;
  &lt;span class="py"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'tcp'&lt;/span&gt;
  &lt;span class="py"&gt;internal_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1337&lt;/span&gt;
  &lt;span class="py"&gt;processes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'app'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nn"&gt;[[services.ports]]&lt;/span&gt;
    &lt;span class="py"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
    &lt;span class="py"&gt;handlers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'http'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[[vm]]&lt;/span&gt;
  &lt;span class="py"&gt;cpu_kind&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'shared'&lt;/span&gt;
  &lt;span class="py"&gt;cpus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="py"&gt;memory_mb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Multi-stage dockerfile using Alpine (it will reduce the image 4.3GB → 1.1GB)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:18-alpine3.18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build_image&lt;/span&gt;

&lt;span class="c"&gt;# Installing libvips-dev for sharp Compatability&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk add &lt;span class="nt"&gt;--upgrade&lt;/span&gt; &lt;span class="nt"&gt;--no-cache&lt;/span&gt; vips-dev build-base fftw-dev gcc autoconf g++ make libc6-compat zlib-dev libpng-dev nasm bash &lt;span class="nt"&gt;--repository&lt;/span&gt; https://alpine.global.ssl.fastly.net/alpine/v3.18/community/

&lt;span class="c"&gt;# Set working directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /opt&lt;/span&gt;

&lt;span class="c"&gt;# Resolve node_modules for caching&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json yarn.lock ./&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Copy all for build and release cache if package.json update&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV=production&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn build

&lt;span class="c"&gt;# Remove unnecessary files from node_modules - https://github.com/tj/node-prune&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;wget https://gobinaries.com/tj/node-prune &lt;span class="nt"&gt;--output-document&lt;/span&gt; - | /bin/sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; node-prune

&lt;span class="c"&gt;#------------------------------------------------------------------------------------&lt;/span&gt;

&lt;span class="c"&gt;# Create a new namespace for the final Docker Image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:18-alpine3.18&lt;/span&gt;

&lt;span class="c"&gt;# Installing openssh &lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk &lt;span class="nt"&gt;--no-cache&lt;/span&gt; update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk add openssh

&lt;span class="c"&gt;# Installing vips-dev (https://www.libvips.org/) - https://github.com/strapi-community/strapi-plugin-local-image-sharp&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add vips-dev

&lt;span class="c"&gt;# Set working directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /opt/app&lt;/span&gt;

&lt;span class="c"&gt;# Only copy your source code without the system file&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build_image /opt ./&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 1337&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV=production&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; STRAPI_LOG_LEVEL=debug&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["yarn", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.dockerignore&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;.tmp/
.cache/
.git/
build/
node_modules/
data/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before launch, please copy and paste all environment variables in the &lt;code&gt;.env&lt;/code&gt; file to make it easier to deploy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly launch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait until the deployment finishes.&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%2Fzlikc61ektz9pv4gghfe.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%2Fzlikc61ektz9pv4gghfe.png" alt=" " width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Strapi data transfer
&lt;/h3&gt;

&lt;p&gt;Strapi provides an &lt;a href="https://docs.strapi.io/dev-docs/data-management/transfer" rel="noopener noreferrer"&gt;API to transfer data&lt;/a&gt; (schema, content, etc.) between servers. It’s pretty handy! Thanks, Strapi team!&lt;/p&gt;

&lt;p&gt;First, we have to access your Strapi Admin in the &lt;a href="http://Fly.io" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt; and generate a token that enables PUSH data&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%2Fjb6ybsf61g7wdxswlqwi.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%2Fjb6ybsf61g7wdxswlqwi.png" alt=" " width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the token with PUSH permission.&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%2Fzpyvqmr1aq9tlelkefxv.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%2Fzpyvqmr1aq9tlelkefxv.png" alt=" " width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save the token in a safe place.&lt;/p&gt;

&lt;p&gt;Access your Render server and run the following command in the root folder of the Strapi project (&lt;code&gt;~/project/src&lt;/code&gt;). This command will send all data related to the database (entities and links) to your &lt;a href="http://Fly.io" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt; server. It’s amazing! We will send the assets from the public folder later.&lt;br&gt;
    1. Unfortunately, I didn’t find a way to send the files (assets) because I received this &lt;code&gt;error: [FATAL] restore failed Error: The backup folder for the assets could not be created inside the public folder. Please ensure Strapi has write permissions on the public directory&lt;/code&gt;. This issue is caused by the folder linked to the volume not having permission to run some strapi scripts into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run strapi transfer &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--to&lt;/span&gt; https://app-name.fly.dev/admin &lt;span class="nt"&gt;--exclude&lt;/span&gt; files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now paste the transfer token when you are asked.&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%2F9pvqeep9jb1vdvbr923n.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%2F9pvqeep9jb1vdvbr923n.png" alt="Run the strapi transfer data command" width="800" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Waiting until finish the transfer.&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%2Fytnsnhmai3b3hz5uwinj.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%2Fytnsnhmai3b3hz5uwinj.png" alt="Final transfer Strapi data" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later you can check in the &lt;a href="http://Fly.io" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt; if the content is there.&lt;/p&gt;

&lt;p&gt;Next, transfer all environment variables of &lt;code&gt;.env&lt;/code&gt; file for Secrets in Fly.io&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%2Flyaeu518cu3izzlz868x.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%2Flyaeu518cu3izzlz868x.png" alt="Environment secrets" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we going to send the files (images)&lt;/p&gt;

&lt;h3&gt;
  
  
  Backup Render public folder
&lt;/h3&gt;

&lt;p&gt;Access the server via SSH. How to set up your SSH connection.&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%2Fyh5s1otq00dxw48f9xwi.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%2Fyh5s1otq00dxw48f9xwi.png" alt=" " width="800" height="309"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;ssh&lt;/span&gt; &lt;span class="nx"&gt;YOUR_SERVICE&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ssh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;YOUR_REGION&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compress the &lt;code&gt;public&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zip &lt;span class="nt"&gt;-r&lt;/span&gt; public.zip public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Close the SSH connection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can transfer files using &lt;a href="https://man.openbsd.org/scp" rel="noopener noreferrer"&gt;SCP&lt;/a&gt;. Copying a file from your service to your local machine&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-s&lt;/span&gt; YOUR_SERVICE@ssh.YOUR_REGION.render.com:/path/to/remote/file /destination/path/for/local/file

scp &lt;span class="nt"&gt;-s&lt;/span&gt; srv-cbtddcr19n0c5dqs15i0@ssh.oregon.render.com:/opt/render/project/src/public.zip ./strapi/public.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we must create a folder called &lt;code&gt;public_&lt;/code&gt;in your &lt;strong&gt;strapi root folder&lt;/strong&gt; (locally). It will serve as a temporary folder to transfer the backup content. Now unzip the &lt;code&gt;public.zip&lt;/code&gt; into the folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;public_

&lt;span class="c"&gt;# Unzip, after creating a public folder into the public_ &lt;/span&gt;
&lt;span class="c"&gt;# We must move the content of the public_/public for public_&lt;/span&gt;
unzip public.zip &lt;span class="nt"&gt;-d&lt;/span&gt; public_

&lt;span class="c"&gt;# Enter into the folder, move the content and delete the unnecessary folder&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;public_ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mv &lt;/span&gt;public/&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; public

&lt;span class="c"&gt;# It should contain only robots.txt and uploads folder&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your project contains two public folders (one is &lt;code&gt;public_&lt;/code&gt; is a temp folder).&lt;/p&gt;

&lt;p&gt;Now run the deploy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the deployment, all folders from the project will be copied into the docker image so you can later access the VM and move the content.&lt;/p&gt;

&lt;p&gt;Wait until the deployment finishes.&lt;/p&gt;

&lt;p&gt;Now access via SSH the VM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly ssh console
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the VM, run the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /opt/app/public_/. /opt/app/public
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /opt/app/public_
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will copy the content from &lt;code&gt;public_&lt;/code&gt;to &lt;code&gt;public&lt;/code&gt;folder and later delete the &lt;code&gt;public_&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I know it’s pretty verbose and complex, but we have permission to perform this kind of operation only via SSH. &lt;/p&gt;

&lt;p&gt;💡 I hope the &lt;a href="http://Fly.io" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt; team will enable us to send files for our volumes without running a machine using &lt;code&gt;sftp&lt;/code&gt;. I tried other alternatives using &lt;code&gt;rsync&lt;/code&gt;  and &lt;code&gt;wireguard&lt;/code&gt;, which are the worst.&lt;/p&gt;

&lt;p&gt;Check if the volume of the machine was increased (the default is 70MB). This is an indication that persisted in volume.&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%2Fm47up87n78sqb5frcdyg.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%2Fm47up87n78sqb5frcdyg.png" alt=" " width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I hope this tutorial can help you migrate without pain.&lt;/p&gt;

&lt;p&gt;Fly.io is one of the best money-saving options for anyone starting a small project. I no longer had any problems connecting to the bank; even with the reduction of infrastructure, there was no loss in user experience.&lt;/p&gt;

&lt;p&gt;If you have any questions, please feel free to comment below.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://forum.strapi.io/t/fly-io-deployment/22438" rel="noopener noreferrer"&gt;https://forum.strapi.io/t/fly-io-deployment/22438&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.render.com/disks" rel="noopener noreferrer"&gt;https://docs.render.com/disks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=6zJKJb4dCsQ" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6zJKJb4dCsQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>strapi</category>
      <category>render</category>
      <category>flyio</category>
    </item>
    <item>
      <title>How to organize Figma files for developers</title>
      <dc:creator>Candido Sales Gomes</dc:creator>
      <pubDate>Tue, 22 Nov 2022 03:16:12 +0000</pubDate>
      <link>https://dev.to/candidosales/how-to-organize-figma-files-for-developers-2lcj</link>
      <guid>https://dev.to/candidosales/how-to-organize-figma-files-for-developers-2lcj</guid>
      <description>&lt;p&gt;I going to share a simple tip that I find recently that helps the productivity of our team.&lt;/p&gt;

&lt;p&gt;My team is using &lt;a href="https://www.atlassian.com/software/jira" rel="noopener noreferrer"&gt;Jira&lt;/a&gt; to organize and track our tasks, and for each task that is related to design, the P.O. or S.M. adds the &lt;a href="https://www.figma.com/" rel="noopener noreferrer"&gt;Figma&lt;/a&gt; link associated with the task, but sometimes the link breaks, and we lose exactly which page we are going to work on.&lt;/p&gt;

&lt;p&gt;To solve this issue you can add a text at the top for each page and add the ID of the Jira task corresponding.&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%2F1gc0ef56bp4qdclaimf4.jpeg" 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%2F1gc0ef56bp4qdclaimf4.jpeg" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that, the page can be easily searchable by Jira ID on the search field in Figma.&lt;/p&gt;

&lt;p&gt;I hope this tip can be useful for your team.&lt;/p&gt;

&lt;p&gt;If you have any another tip, please comment here :) &lt;/p&gt;

</description>
      <category>figma</category>
      <category>developer</category>
      <category>productivity</category>
      <category>jira</category>
    </item>
    <item>
      <title>Deploying Strapi 4 to Digital Ocean App</title>
      <dc:creator>Candido Sales Gomes</dc:creator>
      <pubDate>Mon, 15 Aug 2022 22:18:12 +0000</pubDate>
      <link>https://dev.to/candidosales/deploying-strapi-4-to-digital-ocean-app-1d8d</link>
      <guid>https://dev.to/candidosales/deploying-strapi-4-to-digital-ocean-app-1d8d</guid>
      <description>&lt;h2&gt;
  
  
  What is Strapi?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://strapi.io/" rel="noopener noreferrer"&gt;Strapi&lt;/a&gt; is an open-source headless Content Management System that offers you the chance to develop API with distinctive features. It's built on Node.js and works with any GraphQL enabled Frontend Frameworks.&lt;/p&gt;

&lt;p&gt;You can create custom content types, relationships and media libraries for images and audio files with Strapi.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;a href="https://docs.digitalocean.com/products/app-platform/" rel="noopener noreferrer"&gt;Digital Ocean App&lt;/a&gt;?
&lt;/h2&gt;

&lt;p&gt;App Platform is a Platform-as-a-Service (PaaS) offering that allows developers to publish code directly to DigitalOcean servers without worrying about the underlying infrastructure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free SSL Certificate;&lt;/li&gt;
&lt;li&gt;Straightforward UI;&lt;/li&gt;
&lt;li&gt;You can choose the region;&lt;/li&gt;
&lt;li&gt;Enables horizontal or vertical &lt;a href="https://docs.digitalocean.com/glossary/scaling/" rel="noopener noreferrer"&gt;scaling&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;p&gt;Go to the repository and click &lt;code&gt;Deploy to Digital Ocean&lt;/code&gt;: &lt;a href="https://github.com/candidosales/digital-ocean-app_render_strapi" rel="noopener noreferrer"&gt;https://github.com/candidosales/digital-ocean-app_render_strapi&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%2F7pgtvobwpfop1m3pbw7j.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%2F7pgtvobwpfop1m3pbw7j.png" alt="Repository Github" width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be redirected to the page similar to the image below containing all information about the services that will be deployed. Click in &lt;code&gt;Next&lt;/code&gt;.&lt;br&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%2Fwjwdosny66zy2kmxey98.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%2Fwjwdosny66zy2kmxey98.png" alt="Digital Ocean page" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next section, &lt;code&gt;Environment Variables&lt;/code&gt;, fill up the env variables: &lt;code&gt;ADMIN_JWT_SECRET&lt;/code&gt;, &lt;code&gt;JWT_SECRET&lt;/code&gt;, &lt;code&gt;APP_KEYS&lt;/code&gt; and &lt;code&gt;API_TOKEN_SALT&lt;/code&gt;. You can use &lt;a href="https://randomkeygen.com/" rel="noopener noreferrer"&gt;https://randomkeygen.com/&lt;/a&gt;. &lt;br&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%2F1q7r5ic2sg49bfn2jmji.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%2F1q7r5ic2sg49bfn2jmji.png" alt="Filling up the environment variables" width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Info&lt;/code&gt; section, check if the project and region are correct.&lt;br&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%2F6oadygnwr04zmpvtc5lh.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%2F6oadygnwr04zmpvtc5lh.png" alt="Info section" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Review&lt;/code&gt; section, check the plan for each service, and click in &lt;code&gt;Create Resources&lt;/code&gt;.&lt;br&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%2F3aft79hlg051q23u2713.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%2F3aft79hlg051q23u2713.png" alt="Review section" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Waits until deployment is finished.&lt;br&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%2F4kv2nir4nm8lc48jproi.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%2F4kv2nir4nm8lc48jproi.png" alt="Deployment" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's done 🎉! &lt;/p&gt;

&lt;p&gt;You can access the Strapi admin via your &lt;a href="https://xxxx-xxxx.ondigitalocean.app/admin" rel="noopener noreferrer"&gt;https://xxxx-xxxx.ondigitalocean.app/admin&lt;/a&gt; and create a user account.&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%2Fv31vy6iiliqdmyzn1e22.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%2Fv31vy6iiliqdmyzn1e22.png" alt="Finished" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Extra
&lt;/h2&gt;

&lt;p&gt;In the same repository you can deploy on &lt;a href="https://render.com/" rel="noopener noreferrer"&gt;Render&lt;/a&gt; too 😁. The advantage of the Render is that it attaches a volume to store your images, which can be safe to store locally.&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%2F4t70prsoh9vdulzjtp23.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%2F4t70prsoh9vdulzjtp23.png" alt="Deploy to Render" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Added a &lt;code&gt;Service Group Name&lt;/code&gt; and click in &lt;code&gt;Apply&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%2F994k0bwg26apywq56aih.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%2F994k0bwg26apywq56aih.png" alt="Set up" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's just two clicks 🥲.&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%2Fhecprnu8xphynrr1s05k.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%2Fhecprnu8xphynrr1s05k.png" alt="Done" width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you find any issues, please, comment below.&lt;/p&gt;

&lt;p&gt;Feel free to improve the &lt;a href="https://github.com/candidosales/digital-ocean-app_render_strapi" rel="noopener noreferrer"&gt;repository&lt;/a&gt;. Your contribution is welcome! 😃 &lt;/p&gt;

</description>
      <category>strapi</category>
      <category>digitalocean</category>
      <category>render</category>
      <category>cms</category>
    </item>
    <item>
      <title>Deploying Strapi 4 to Railway</title>
      <dc:creator>Candido Sales Gomes</dc:creator>
      <pubDate>Wed, 03 Aug 2022 21:20:36 +0000</pubDate>
      <link>https://dev.to/candidosales/deploying-strapi-4-to-railway-589b</link>
      <guid>https://dev.to/candidosales/deploying-strapi-4-to-railway-589b</guid>
      <description>&lt;h2&gt;
  
  
  What is Strapi?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://strapi.io/" rel="noopener noreferrer"&gt;Strapi&lt;/a&gt; is an open-source headless Content Management System that offers you the chance to develop API with distinctive features. It's built on Node.js and works with any GraphQL enabled Frontend Frameworks.&lt;/p&gt;

&lt;p&gt;You can create custom content types, relationships and media libraries for images and audio files with Strapi.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;a href="https://railway.app/" rel="noopener noreferrer"&gt;Railway&lt;/a&gt;?
&lt;/h2&gt;

&lt;p&gt;It's a PaaS (similar to Heroku) that allows you to connect your Git repository and with each commit or new PR you trigger an event to deploy your application. Railway has several very nice features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;a href="https://github.com/railwayapp/nixpacks" rel="noopener noreferrer"&gt;NixPacks&lt;/a&gt; to build the images;&lt;/li&gt;
&lt;li&gt;Free SSL Certificate;&lt;/li&gt;
&lt;li&gt;Straightforward UI;&lt;/li&gt;
&lt;li&gt;Create multiple environments;&lt;/li&gt;
&lt;li&gt;"Pay as you grow";&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, there are some features I wish it had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More regions available - 🇧🇷 please (&lt;a href="https://feedback.railway.app/feature-requests/p/configurable-deployment-region" rel="noopener noreferrer"&gt;See the thread&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;Access the application console via UI (Similar to Digital Ocean and Render);&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;p&gt;Create your account and create a new project&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%2Furq6ame4u4ftdoygo4y8.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%2Furq6ame4u4ftdoygo4y8.png" alt="Creating a new project" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search by &lt;code&gt;Strapi&lt;/code&gt; and select the first option.&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%2Fmshbvm5z2fqsrhr6x6l6.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%2Fmshbvm5z2fqsrhr6x6l6.png" alt="Selecting the Strapi option" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a valid name for your repository. &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%2Fdyfrxjtwge7f2tklmneh.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%2Fdyfrxjtwge7f2tklmneh.png" alt="Adding environment variables" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The railway will copy a &lt;a href="https://github.com/candidosales/strapi-railway-deploy" rel="noopener noreferrer"&gt;project&lt;/a&gt; into your account during the deployment process. As shown in the image below, you will have to add the environment 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%2Fa1typb8q63hwolb4tswz.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%2Fa1typb8q63hwolb4tswz.png" alt="The project" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use the &lt;a href="https://randomkeygen.com/" rel="noopener noreferrer"&gt;https://randomkeygen.com/&lt;/a&gt; to fill up the &lt;code&gt;ADMIN_JWT_SECRET&lt;/code&gt;,&lt;code&gt;JWT_SECRET&lt;/code&gt;, &lt;code&gt;APP_KEYS&lt;/code&gt; and &lt;code&gt;API_TOKEN_SALT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In that &lt;a href="https://github.com/candidosales/strapi-railway-deploy" rel="noopener noreferrer"&gt;project&lt;/a&gt; is set up the Strapi with Postgres and &lt;a href="https://cloudinary.com/" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt;. Cloudinary is responsible for managing your media library, so you must have a &lt;a href="https://cloudinary.com/" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt; account.&lt;/p&gt;

&lt;p&gt;In the Cloudinary, you copy your credentials.&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%2Fbe6y46tgvc1i12mzhtzw.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%2Fbe6y46tgvc1i12mzhtzw.png" alt="Cloudinary Credentials" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then paste it into the Railway Environment variables and click on &lt;code&gt;Deploy&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%2Ffutxbb1p075rse1ytsr3.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%2Ffutxbb1p075rse1ytsr3.png" alt="Railway Environment variables" width="800" height="1069"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Waiting the building and deploy!&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%2Fs9jd63xw7i3vd7008f7m.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%2Fs9jd63xw7i3vd7008f7m.png" alt="Building" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's done! &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%2F1ey8h5cab4eopsd2ev88.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%2F1ey8h5cab4eopsd2ev88.png" alt="Deployed" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can access the Strapi admin via your &lt;code&gt;https://strapi-production-XXXX.up.railway.app/admin&lt;/code&gt; and create a user account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;One annoying thing about Strapi is that it doesn't have &lt;strong&gt;development mode&lt;/strong&gt; enabled by default, so I can't create new collections.&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%2Fnt2pxg51gfxr16hypm9z.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%2Fnt2pxg51gfxr16hypm9z.png" alt="Can't create new collections" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wasted a lot of time thinking that changing the &lt;code&gt;NODE_ENV&lt;/code&gt; environment variable could solve it, but it didn't.&lt;/p&gt;

&lt;p&gt;So I found another way to solve this.&lt;/p&gt;

&lt;p&gt;An important thing to note: the current version deployed is &lt;code&gt;v4.1.9&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%2F8ozcw4spk12lrxa63y5i.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%2F8ozcw4spk12lrxa63y5i.png" alt="v4.1.9" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To enable &lt;strong&gt;development mode&lt;/strong&gt; and update the project we need to make a change to the project created by Railway in your Github account.&lt;/p&gt;

&lt;p&gt;Change the file &lt;code&gt;package.json&lt;/code&gt; to be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strapi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A Strapi application"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"develop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strapi develop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strapi develop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&amp;lt;-----&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Here&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strapi build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strapi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strapi"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@strapi/plugin-i18n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.1.9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Upgrade&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.3&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@strapi/plugin-users-permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.1.9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Upgrade&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.3&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@strapi/provider-upload-cloudinary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.1.9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Upgrade&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.3&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@strapi/strapi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.1.9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Upgrade&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.3&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8.7.3"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A Strapi developer"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"strapi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"35d7a084-3088-4d0b-869e-f503693ee8e5"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"engines"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;=12.x.x &amp;lt;=16.x.x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"npm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;=6.0.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start Strapi in &lt;strong&gt;development mode&lt;/strong&gt;, I changed the value for &lt;code&gt;strapi develop&lt;/code&gt; in the command start.&lt;/p&gt;

&lt;p&gt;⚠️ Don't forget to run &lt;code&gt;yarn install&lt;/code&gt; to update the &lt;code&gt;yarn.lock&lt;/code&gt; before pushing your commit.&lt;/p&gt;

&lt;p&gt;You can see my commit here: &lt;a href="https://github.com/candidosales/strapi-railway-deploy/commit/529cb16521f33a5d824a34a1de3f30868b122ff7" rel="noopener noreferrer"&gt;https://github.com/candidosales/strapi-railway-deploy/commit/529cb16521f33a5d824a34a1de3f30868b122ff7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After pushing the commit, the build will start again and when finished ... &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%2Fy6bzrc1n712g6iepjdu5.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%2Fy6bzrc1n712g6iepjdu5.png" alt="Deployed!" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can verify that it will be in the new version, and you can create new collections.&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%2Fse9ms0qjvnsad9502hau.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%2Fse9ms0qjvnsad9502hau.png" alt="v4.3.2" width="800" height="372"&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%2Fkhk23qcjro3mdxnsavxr.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%2Fkhk23qcjro3mdxnsavxr.png" alt="Enable to create collections" width="800" height="719"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you want to have more control over the media gallery and don't want to deploy using Cloudinary, in the following article, I'll teach you how to deploy Strapi 4 to &lt;a href="https://render.com/" rel="noopener noreferrer"&gt;Render&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Any feedback is welcome! 😄  &lt;/p&gt;

</description>
      <category>strapi</category>
      <category>railway</category>
      <category>cloudinary</category>
      <category>cms</category>
    </item>
  </channel>
</rss>
