<p>
    Appwrite Functions are mini-applications in Appwrite with their own endpoints. 
    Each function can have many deployments, which can be thought of as versions of the mini-application.
</p>

<p>
    Functions can be created and deployed in different ways to meet your unique development habits.
    You can automatically deploy Appwrite Functions from source control, build your own deployment pipelines using the Appwrite CLI, or upload code files manually.
    Here's everything you need to know to deploy your first Appwrite Function.
</p>

<h2><a href="#git" id="git">Git</a></h2>
<p>
    The recommended way to manage your Appwrite Function deployments is to use a version control system, like Git.
    This offers simple versioning and collaboration that will easily fit into the rest of your development workflow.
</p>

<h3>Create Function</h3>
<p>Before deploying your function with Git, create a new function attached to your Git repo.</p>
<ol class="margin-top margin-bottom-large text-size-normal">
    <li>
        Navigate to <b>Functions</b> from the side bar of the Appwrite Console.
    </li>
    <li>
        Click <b>Create function</b>.
    </li>
    <li>
        When asked to <b>Choose your source</b>, under <b>Connect Git repository</b>, select your provider.
    </li>
    <li>
        Search for the Git repository that hold your function and click <b>connect</b>.
    </li>
    <li>
        Select a production branch. New commits pushed to the production branch will be <b>automatically activated</b>. Commits to any other branch will still be deployed, but not be activated.
    </li>
    <li>
        Input the root directory of the function inside the repository. If you have only one function in your repository, you can leave this empty. If you have multiple, root directory should point to the folder of your function. This should be the directory in which your custom build commands can run successfully. It also improves efficiency because only what's necessary is cloned.
    </li>
    <li>
        If you don't want deploy comments to be made on your pull requests or commits, select <b>Silent mode</b>.
    </li>
    <li>
        Name your function, select a runtime that matches your function, and enter entrypoint, relative to the root directory from the previous step. Entrypoint is path to the main file of your function, which exports the function to be run on every execution.
    </li>
    <li>
        If you have build steps, like installing dependencies, input the commands into the <b>Build settings</b> heading's <b>Command</b> field. 
        You can combine multiple commands using <code>&&</code>, such as <code>npm install && npm build</code>.
        For compiled languages you don't need to worry about installing dependencies, as that's done automatically during compilation step.
    </li>
    <li>
        Finally, configure the execute permissions of the function. For security, only provide execute permissions to the necessary roles.
    </li>
</ol>

<h3>Deploy</h3>
<ol class="margin-top margin-bottom-large text-size-normal">
    <li>
        Using Git, checkout the branch you configured as production branch when creating the Appwrite Function. 
    </li>
    <li>
        Create a new commit.
    </li>
    <li>
        Push your new commit.
    </li>
    <li>
        A new deployment will be automatically created, built and activated.
    </li>
</ol>

<h2><a href="#cli" id="cli">CLI</a></h2>
<div class="notice margin-bottom-small">
  <h2>CLI Setup</h2>
  <p>Before you can deploy with the Appwrite CLI, make sure you've <a href="/docs/command-line">installed and initialized</a> the CLI.</p>
</div>
<p>
    To deploy with the Appwrite CLI, your function must be added to <code>appwrite.json</code> that tells the CLI where each function is stored.
    To ensure the folder structure is setup correctly and <code>appwrite.json</code> is configured correctly, use the appwrite init function method to create a starter function, then paste in your function code.
</p>

<p>
    Run the following command in the folder holding the <code>appwrite.json</code> file. 
</p>
<div class="ide margin-bottom" data-lang="bash" data-lang-label="Bash">
    <pre class="line-numbers"><code class="prism language-bash" data-prism>appwrite init function</code></pre>
</div>

<p>
    Give your function a name and choose your runtime. 
    This will create a new starter function in the current directory and also add it to your <code>appwrite.json</code> file.
</p>

<p>
    Edit the automatically generated code and add dependencies to the dependency files of your language or framework.
    Then, deploy the function using the following command.
</p>

<div class="ide margin-bottom" data-lang="bash" data-lang-label="Bash">
    <pre class="line-numbers"><code class="prism language-bash" data-prism>appwrite deploy function</code></pre>
</div>

<div class="notice">
  <h2>Overwrite Warning</h2>
    <p>
        If you made changes in the Appwrite Console that is different from your <code>appwrite.json</code>, 
        using the CLI deploy command will overwrite your console changes, such as execution schedule or permissions.
        Update your <code>appwrite.json</code> manually before deploying to avoid overwriting changes.
    </p>
</div>

<h3>Manual Deployment</h3>
<p>You can upload your functions to be deployed using the Appwrite Console. The example below shows a simple Node.js function, but the same idea applies to any other language.</p>
<div class="ide margin-bottom">
    <pre class="line-numbers"><code class="prism" data-prism>.
├── package.json
└── index.js
</code></pre>
</div>

<p>First, navigate inside the folder that contains your dependency file. Package your code files into the <code>.tar.gz</code> format with this tar command:</p>

<ul class="phases clear" data-ui-phases>
    <li>
        <h3>Unix</h3>

        <div class="ide margin-bottom" data-lang="bash" data-lang-label="Bash">
            <pre class="line-numbers"><code class="prism language-bash" data-prism>tar --exclude code.tar.gz -czf code.tar.gz .</code></pre>
        </div>
    </li>
    <li>
        <h3>CMD</h3>

        <div class="ide margin-bottom" data-lang="bash" data-lang-label="CMD">
            <pre class="line-numbers"><code class="prism language-bash" data-prism>tar --exclude code.tar.gz -czf code.tar.gz .</code></pre>
        </div>
    </li>
    <li>
        <h3>PowerShell</h3>

        <div class="ide margin-bottom" data-lang="bash" data-lang-label="PowerShell">
            <pre class="line-numbers"><code class="prism language-bash" data-prism>tar --exclude code.tar.gz -czf code.tar.gz .</code></pre>
        </div>
    </li>
</ul>

<p>Next, navigate to your Appwrite Console and upload the function.</p>

<ol class="margin-top margin-bottom-large text-size-normal">
  <li class="margin-bottom-small">Navigate to the function you want to deploy.</li>
  <li class="margin-bottom-small">Click <i class="icon-plus"></i> <b>Create deployment</b>.</li>
  <li class="margin-bottom-small">Select the <b>Manual</b> tab.</li>
  <li class="margin-bottom-small">Input the entry point of your function under <b>Entrypoint</b>. For the example above, it would be <code>index.js</code>.</li>
  <li class="margin-bottom-small">Upload <code> code.tar.gz</code>.</li>
  <li class="margin-bottom-small">Select <b>Activate deployment after build</b> to use your new deployment.</li>
  <li class="margin-bottom-small">Click <b>Create</b> to deploy your function.</li>
</ol>

<h2><a href="#domains" id="domains">Domains</a></h2>
<p>
    Each deployed function can have its own domain. 
    By default, one is generated for each of your functions.
    You can find the generated domain for your function like this.
</p>

<ol class="margin-top margin-bottom-large text-size-normal">
    <li class="margin-bottom-small">Navigate to the Appwrite Console's <b>Functions</b> page.</li>
    <li class="margin-bottom-small">Navigate to the <b>Domains</b> tab.</li>
    <li class="margin-bottom-small">In the table, you'll find a link formatted similar to <code>https://64d4d22db370ae41a32e.appwrite.global</code>. This is your generated domain.</li>
</ol>

<p>
    You can also add a custom domain, which allows you to build custom REST APIs using nothing but Appwrite Functions.
    To do this, you need to first buy and register a domain.
    After obtaining a domain, follow these steps to add the domain to Appwrite.
</p>

<ol class="margin-top margin-bottom-large text-size-normal">
    <li class="margin-bottom-small">Navigate to the Appwrite Console's <b>Functions</b> page.</li>
    <li class="margin-bottom-small">Navigate to the <b>Domains</b> tab.</li>
    <li class="margin-bottom-small">Click on <b>Create domain</b>.</li>
    <li class="margin-bottom-small">Input your domain in the <b>Domain</b> input field and click <b>Next</b>.</li>
    <li class="margin-bottom-small">Copy the <b>CNAME</b> record provided to you, and add it to your domain registrar.</li>
    <li class="margin-bottom-small">Click <b>Go to console</b> and wait for the domain name to be verified and certificate to generate.</li>
</ol>

<p>
    DNS records can take up to 48 hours to propagate after they're added. 
    Please retry verification over the next 48 hours. 
    If the domain verification still fails and you have confirmed DNS records are added correctly, please contact support.
</p>

<h2><a href="#debugging" id="debugging">Debugging Build</a></h2>
<p>After deploying a function, you can find the status of the deployment and build logs in the Appwrite Console.</p>
<ol class="margin-top margin-bottom-large text-size-normal">
    <li>In Appwrite Console, navigate to <b>Functions</b>.</li>
    <li>Click to open a function you wish to inspect.</li>
    <li>Under the <b>Deployments</b> tab, you'll find the status of the current active deployment and previous inactive deployments.</li>
    <li>You can access build logs for the active deployment by clicking the <b>Build logs</b> button. You can click on an inactive function's three dots button to find their build logs.</li>
</ol>

<h2><a href="#redeploy" id="redeploy">Redeploy Builds</a></h2>
<p>
    After updating the configuration of your Appwrite Function, you need to redeploy your function for the changes to take effect.
    You can also redeploy builds to retry failed builds.
</p>
<ol class="margin-top margin-bottom-large text-size-normal">
    <li>In Appwrite Console, navigate to <b>Functions</b>.</li>
    <li>Click to open a function you wish to inspect.</li>
    <li>Under the <b>Deployments</b> tab, you'll find the status of the current active deployment.</li>
    <li>You can redeploy by clicking the triple-dots beside an execution, and hitting the <b>Redeploy</b> button.</li>
</ol>
<p>
    The redeployment behavior varies depending on how the initial deployment is created.
    For Git deployments, redeploy uses the same commit hash but updated function settings.
    For manual and CLI deployments, redeploy uses previously updated code but updated function settings.
</p>