<?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: Alex Weininger</title>
    <description>The latest articles on DEV Community by Alex Weininger (@alexweininger).</description>
    <link>https://dev.to/alexweininger</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%2F554746%2F9a8744ec-6622-4003-9d8e-2a146f544863.jpeg</url>
      <title>DEV Community: Alex Weininger</title>
      <link>https://dev.to/alexweininger</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexweininger"/>
    <language>en</language>
    <item>
      <title>Setting up CI/CD with GitHub Actions and CapRover</title>
      <dc:creator>Alex Weininger</dc:creator>
      <pubDate>Mon, 06 Dec 2021 21:08:23 +0000</pubDate>
      <link>https://dev.to/alexweininger/setting-up-cicd-with-github-actions-and-caprover-ek8</link>
      <guid>https://dev.to/alexweininger/setting-up-cicd-with-github-actions-and-caprover-ek8</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/streamlux/pulsebanner" rel="noopener noreferrer"&gt;https://github.com/streamlux/pulsebanner&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I learned a lot about GitHub Actions creating this workflow, and specifically about how to use the &lt;a href="https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix" rel="noopener noreferrer"&gt;matrix strategy&lt;/a&gt;. I've included the section of the workflow that uses the matrix strategy below. This job deploys all 3 apps to the staging environment on CapRover.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;deploy_staging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Staging&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;build_next&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;build_nest&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;build_remotion&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Staging&lt;/span&gt;
        &lt;span class="na"&gt;concurrency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Staging&lt;/span&gt;

        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;CAPROVER_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.CAPROVER_URL }}&lt;/span&gt;
            &lt;span class="na"&gt;NEST_CAPROVER_APP_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NEST_CAPROVER_APP_TOKEN }}&lt;/span&gt;
            &lt;span class="na"&gt;NEXT_CAPROVER_APP_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NEXT_CAPROVER_APP_TOKEN }}&lt;/span&gt;
            &lt;span class="na"&gt;REMOTION_CAPROVER_APP_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.REMOTION_CAPROVER_APP_TOKEN }}&lt;/span&gt;

        &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nest&lt;/span&gt; &lt;span class="c1"&gt;# name of the app in Caprover&lt;/span&gt;
                      &lt;span class="na"&gt;token-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NEST_CAPROVER_APP_TOKEN&lt;/span&gt; &lt;span class="c1"&gt;# key used to get CAPROVER_APP_TOKEN from env&lt;/span&gt;
                      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ needs.build_nest.outputs.image-tag }}&lt;/span&gt; &lt;span class="c1"&gt;# image to deploy&lt;/span&gt;
                    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;next&lt;/span&gt;
                      &lt;span class="na"&gt;token-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NEXT_CAPROVER_APP_TOKEN&lt;/span&gt;
                      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ needs.build_next.outputs.image-tag }}&lt;/span&gt;
                    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;remotion&lt;/span&gt;
                      &lt;span class="na"&gt;token-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;REMOTION_CAPROVER_APP_TOKEN&lt;/span&gt;
                      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ needs.build_remotion.outputs.image-tag }}&lt;/span&gt;

        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Install Caprover CLI, which we use to deploy images to Caprover&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Install&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;caprover-cli'&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install -g caprover&lt;/span&gt;

            &lt;span class="c1"&gt;# Deploy each app by iterating over matrix values&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;matrix.app&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
              &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;APP_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.app }}&lt;/span&gt;
                  &lt;span class="na"&gt;APP_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.CAPROVER_URL }}&lt;/span&gt;
                  &lt;span class="na"&gt;CAPROVER_APP_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env[matrix.token-key] }}&lt;/span&gt;
                  &lt;span class="na"&gt;IMAGE_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.image }}&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;caprover&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--caproverUrl=$APP_URL&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--imageName=$IMAGE_NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--appName=$APP_NAME'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;DIY Deployments&lt;/p&gt;
&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/hawkeyeventures" rel="noopener noreferrer"&gt;
        hawkeyeventures
      &lt;/a&gt; / &lt;a href="https://github.com/hawkeyeventures/pulsebanner" rel="noopener noreferrer"&gt;
        pulsebanner
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;PulseBanner&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting started&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Prerequisites&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;For Windows, install WSL and install these within WSL
&lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install" rel="nofollow noopener noreferrer"&gt;https://docs.microsoft.com/en-us/windows/wsl/install&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git &lt;a href="https://git-scm.com/downloads" rel="nofollow noopener noreferrer"&gt;https://git-scm.com/downloads&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Node.JS and npm &lt;a href="https://nodejs.org/en/download/" rel="nofollow noopener noreferrer"&gt;https://nodejs.org/en/download/&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;for WSL: &lt;a href="https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl" rel="nofollow noopener noreferrer"&gt;https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Docker engine &lt;a href="https://www.docker.com/get-started" rel="nofollow noopener noreferrer"&gt;https://www.docker.com/get-started&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Setup&lt;/h3&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Clone repo&lt;/li&gt;
&lt;li&gt;Create .env file in project root and copy paste the contents of &lt;code&gt;.env.template&lt;/code&gt; in and fill in the values.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;docker-compose up -d&lt;/code&gt; to start the development PostgreSQL database + Adminer.&lt;/li&gt;
&lt;li&gt;Open adminer to verify the database and adminer started properly. Enter password from .env file. &lt;a href="http://localhost:8080/?pgsql=db&amp;amp;username=postgres&amp;amp;psql" rel="nofollow noopener noreferrer"&gt;Adminer link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm install&lt;/code&gt; to install dependencies.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npx prisma db push&lt;/code&gt; to setup the database with our schema.&lt;/li&gt;
&lt;li&gt;Verify by viewing the newly created database 'mydb'. &lt;a href="http://localhost:8080/?pgsql=db&amp;amp;username=postgres&amp;amp;db=mydb&amp;amp;ns=public" rel="nofollow noopener noreferrer"&gt;Adminer link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npx prisma db seed&lt;/code&gt; to insert data into the database that is needed to run the application. (things from Stripe like products/prices)&lt;/li&gt;
&lt;li&gt;If you have changes in your prisma design, be sure to run &lt;code&gt;prisma migrate dev --name &amp;lt;short descriptive name&amp;gt;&lt;/code&gt; before merging *&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/hawkeyeventures/pulsebanner" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/streamlux/pulsebanner" rel="noopener noreferrer"&gt;https://github.com/streamlux/pulsebanner&lt;/a&gt;&lt;/p&gt;

</description>
      <category>actionshackathon21</category>
    </item>
    <item>
      <title>Debugging Azure Static Web Apps in VS Code</title>
      <dc:creator>Alex Weininger</dc:creator>
      <pubDate>Tue, 16 Nov 2021 17:41:35 +0000</pubDate>
      <link>https://dev.to/azure/debugging-azure-static-web-apps-in-vs-code-3gmm</link>
      <guid>https://dev.to/azure/debugging-azure-static-web-apps-in-vs-code-3gmm</guid>
      <description>&lt;p&gt;We've just released v0.9.0 of the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurestaticwebapps" rel="noopener noreferrer"&gt;Azure Static Web Apps extension for VS Code&lt;/a&gt;. This release includes features to help debug your static web app locally, including Azure Functions API routes, authentication, and routing.&lt;/p&gt;

&lt;p&gt;If you're new to Azure Static Web Apps, I highly recommend checking out the &lt;a href="https://docs.microsoft.com/en-us/azure/static-web-apps/overview" rel="noopener noreferrer"&gt;What is Azure Static Web Apps?&lt;/a&gt; documentation page.&lt;/p&gt;

&lt;p&gt;In this post, we'll learn how to get started debugging a static web app locally. Then we'll add an Azure Functions API route, and debug our backend + frontend together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites 🛠️
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Google Chrome installed, (we make use of the debugger)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Azure Static Web Apps extension for VS Code&lt;/strong&gt; - &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurestaticwebapps" rel="noopener noreferrer"&gt;View on Marketplace&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Azure Static Web Apps CLI&lt;/strong&gt; 0.8.0 or greater - &lt;a href="https://github.com/Azure/static-web-apps-cli" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @azure/static-web-apps-cli@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting started 🟢
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone one of these repositories, and open it up in VS Code.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Repository&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Angular&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/staticwebdev/angular-basic" rel="noopener noreferrer"&gt;https://github.com/staticwebdev/angular-basic&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/staticwebdev/react-basic" rel="noopener noreferrer"&gt;https://github.com/staticwebdev/react-basic&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Svelte&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/staticwebdev/svelte-basic" rel="noopener noreferrer"&gt;https://github.com/staticwebdev/svelte-basic&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vue&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/staticwebdev/vue-basic" rel="noopener noreferrer"&gt;https://github.com/staticwebdev/vue-basic&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;npm install&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Theme: &lt;a href="https://marketplace.visualstudio.com/items?itemName=wesbos.theme-cobalt2" rel="noopener noreferrer"&gt;Cobalt2 Theme Official by Wes Bos&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Run and debug 🐞
&lt;/h2&gt;

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

&lt;ol&gt;
&lt;li&gt;Go to the "Run and Debug" view.&lt;/li&gt;
&lt;li&gt;Click "Show all automatic debug configurations."&lt;/li&gt;
&lt;li&gt;In the dropdown, select "Azure Static Web Apps...".&lt;/li&gt;
&lt;li&gt;Select the app you want to debug.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will start the Azure Static Web Apps CLI in the VS Code terminal, and launch the Chrome debugger on &lt;code&gt;http://localhost:4280&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now you can set and hit breakpoints in your frontend code. &lt;/p&gt;

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

&lt;h2&gt;
  
  
  Add an API route ⚡️
&lt;/h2&gt;

&lt;p&gt;Azure Static Web Apps has integrated API support provided by Azure Functions. In order to add and debug an API route, we must install some Azure Functions tools.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Azure Functions extension for VS Code&lt;/strong&gt; - &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions" rel="noopener noreferrer"&gt;Install from Marketplace&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Azure Functions Core Tools&lt;/strong&gt; - &lt;a href="https://github.com/Azure/azure-functions-core-tools" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g azure-functions-core-tools@3 --unsafe-perm true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can add an API route to your app by clicking the "Add HTTP Function..." button in the Azure Static Web Apps view.&lt;/p&gt;

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

&lt;p&gt;Select a language (I chose JavaScript), then name your Function (I put "hello"). And then an API route will be created for you that you can make requests to at &lt;code&gt;/api/hello&lt;/code&gt;.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Debug app with Functions API ✨
&lt;/h2&gt;

&lt;p&gt;We can debug our API routes and our frontend app simultaneously in VS Code.&lt;/p&gt;

&lt;p&gt;Select the "SWA: Run ..." debug configuration and click the green "Run and debug" button.&lt;/p&gt;

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

&lt;p&gt;VS Code will now run your Functions API routes and your frontend. When it's all started, a Chrome window will open at &lt;code&gt;http://localhost:4280&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Set a breakpoint in your Function endpoint.&lt;/p&gt;

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

&lt;p&gt;Go to &lt;code&gt;http://localhost:4280/api/hello&lt;/code&gt; in the Chrome window to hit the breakpoint.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Next steps 🏃‍♀️
&lt;/h2&gt;

&lt;p&gt;Now that you got your static web app running locally, you can &lt;a href="https://docs.microsoft.com/en-us/azure/static-web-apps/getting-started?tabs=react" rel="noopener noreferrer"&gt;deploy your static web app to Azure for free&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;If you're having issues, please check out the &lt;a href="https://github.com/microsoft/vscode-azurestaticwebapps/wiki/Guide:-Debugging-a-Static-Web-App-with-VS-Code#troubleshooting-" rel="noopener noreferrer"&gt;troubleshooting section in our wiki&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links + Resources 🔗
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/static-web-apps/" rel="noopener noreferrer"&gt;Azure Static Web Apps documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/AzureStaticApps" rel="noopener noreferrer"&gt;@AzureStaticWebApps on Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/staticwebdev/awesome-azure-static-web-apps" rel="noopener noreferrer"&gt;Awesome Azure Static Web Apps&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/aaronpowell/create-swa-app" rel="noopener noreferrer"&gt;create-swa-app&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Azure/static-web-apps-cli" rel="noopener noreferrer"&gt;Azure Static Web Apps CLI&lt;/a&gt;&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurestaticwebapps" rel="noopener noreferrer"&gt;Azure Static Web Apps extension for VS Code&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Hello 👋 I'm Alex 🤠 and I'm a developer working on the Azure Static Web Apps extension for VS Code. I hope you enjoyed the post! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/alexweininger" rel="noopener noreferrer"&gt;GitHub @alexweininger&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/alexweininger" rel="noopener noreferrer"&gt;Twitter @alexweininger&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>azure</category>
      <category>jamstack</category>
      <category>staticwebapps</category>
    </item>
    <item>
      <title>Adding custom Docker containers to Appwrite</title>
      <dc:creator>Alex Weininger</dc:creator>
      <pubDate>Tue, 01 Jun 2021 01:24:40 +0000</pubDate>
      <link>https://dev.to/streamlux/adding-custom-docker-containers-to-appwrite-2chp</link>
      <guid>https://dev.to/streamlux/adding-custom-docker-containers-to-appwrite-2chp</guid>
      <description>&lt;p&gt;In my second post to dev.to, I'll describe how you can add your very own Docker containers to Appwrite!&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;While exploring different backend infrastructure options at &lt;a href="https://streamlux.com"&gt;Streamlux&lt;/a&gt;, we decided it would be best to add our own containers to the Appwrite Traefik network. This way we could host completely custom web servers on the same machine as Appwrite. Allowing for extremely low latency between the server and Appwrite, and allowing us to have 100% flexibility in terms of API.&lt;/p&gt;

&lt;p&gt;If you haven't heard of Appwrite, taken from &lt;a href="https://appwrite.io"&gt;Appwrite.io&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Appwrite is a self-hosted solution that provides developers with a set of easy-to-use and integrate REST APIs to manage their core backend needs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From one developer to another, check it out, it's awesome!&lt;/p&gt;

&lt;p&gt;Now let's get back to the task at hand. Adding custom Docker containers to Appwrite is relatively straight forward. However, if you're new to Docker or Traefik it can be a bit daunting.&lt;/p&gt;

&lt;p&gt;The majority of the changes we have to make will be to the &lt;code&gt;docker-compose.yml&lt;/code&gt; file located in the folder where Appwrite has been installed. For me it was in a folder named &lt;code&gt;appwrite&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, I'll go into a little more detail on the changes we will be making to the &lt;code&gt;docker-compose.yml&lt;/code&gt; file, but feel free to skip the background section and get right into the changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;docker-compose.yml&lt;/code&gt; file handles the startup of all the Docker containers Appwrite consists of. Appwrite uses Traefik as a reverse proxy to route incoming network requests to the correct containers.&lt;/p&gt;

&lt;p&gt;When adding our own container, we usually want to be able to handle incoming network requests. To tell Traefik we want requests that are pointed to a specific endpoint like &lt;code&gt;www.mydomain.com/customApi&lt;/code&gt; to be routed to our container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changes
&lt;/h2&gt;

&lt;p&gt;The first change will be at the very top of your &lt;code&gt;docker-compose.yml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Change &lt;code&gt;providers.docker.exposedByDefault&lt;/code&gt; from &lt;code&gt;false&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;traefik&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;traefik:2.3&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appwrite-traefik&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--providers.file.directory=/storage/config&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--providers.file.watch=true&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--providers.docker=true&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--providers.docker.exposedByDefault=true&lt;/span&gt; &lt;span class="c1"&gt;# default is false, change it to true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, your appwrite service labels section needs to be updated to include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.enable=true"&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.constraint-label-stack=appwrite"&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.docker.network=appwrite"&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.appwrite-service.loadbalancer.server.port=80"&lt;/span&gt;
&lt;span class="c1"&gt;# http&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-http.entrypoints=web&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-http.rule=PathPrefix(`/`)&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-http.service=appwrite-service&lt;/span&gt;
&lt;span class="c1"&gt;# https&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.entrypoints=websecure&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.rule=PathPrefix(`/`)&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.service=appwrite-service&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.tls=true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the appwrite service will now look like this (leave everything after the labels section as it is).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;appwrite&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appwrite/appwrite:0.8.0&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appwrite&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;appwrite&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.enable=true"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.constraint-label-stack=appwrite"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.docker.network=appwrite"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.appwrite-service.loadbalancer.server.port=80"&lt;/span&gt;
        &lt;span class="c1"&gt;#http&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-http.entrypoints=web&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-http.rule=PathPrefix(`/`)&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-http.service=appwrite-service&lt;/span&gt;
        &lt;span class="c1"&gt;# https&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.entrypoints=websecure&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.rule=PathPrefix(`/`)&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.service=appwrite-service&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-https.tls=true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all the changes we have to make to the appwrite configuration. Now we can add our own service.&lt;/p&gt;

&lt;p&gt;Here is an example Node.js service definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;appwrite-customApi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node:12-alpine"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.middlewares.portainerpathstrip.stripprefix.prefixes=/customApi/"&lt;/span&gt; &lt;span class="c1"&gt;# requests to this endpoint will be routed to our container &lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.middlewares.portainerpathstrip.stripprefix.forceSlash=false"&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.enable=true"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.constraint-label-stack=appwrite"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.docker.network=appwrite"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.appwrite-customApi.loadbalancer.server.port=8081"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-http.middlewares=portainerpathstrip"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto = https&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-http.entrypoints=web&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-http.rule=PathPrefix(`/customApi`)&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-http.service=appwrite-customApi&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-https.middlewares=portainerpathstrip"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-https.entrypoints=websecure&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-https.rule=PathPrefix(`/customApi`)&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-https.service=appwrite-customApi&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.appwrite-customApi-https.tls=true&lt;/span&gt;

    &lt;span class="c1"&gt;# customize the following properties based on your docker container&lt;/span&gt;

    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node"&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/node/app&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NODE_ENV=production&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PORT=8081&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;../customApi/:/home/node/app&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;npm&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;prod"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;appwrite&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should be able to copy and paste this, and then change the properties to be able to start your container properly. One thing to note is the port. I have it running on port 8081, so when starting your web server in your container you should start it on port 8081. If you change the port, make sure you change it in all the places it's references in the &lt;code&gt;docker-compose.yml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;After you're done, you can run &lt;code&gt;docker-compose up -d&lt;/code&gt; to restart the docker containers that have had configuration changes. &lt;/p&gt;

&lt;p&gt;You can run &lt;code&gt;docker ps&lt;/code&gt; to view the containers and make sure your new container has started. &lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;docker logs [CONTAINER NAME]&lt;/code&gt; to view the logs from your container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finishing notes
&lt;/h2&gt;

&lt;p&gt;I would love to know if you have success adding your own container to the Appwrite Traefik proxy. It would be awesome to compile some example &lt;code&gt;docker-compose.yml&lt;/code&gt; files to make it easier for other users.&lt;/p&gt;

&lt;p&gt;Please reach out to me with any questions you have or things I missed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;First and foremost I have to give credit to Appwrite. And specifically the absolutely amazing Appwrite team. Go check them out and show your support for their awesome work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/appwrite"&gt;Appwrite on Dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io"&gt;Appwrite.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/discord"&gt;Join the Appwrite discord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite"&gt;Appwrite on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=Streamlux.vscode-appwrite"&gt;VS Code extension&lt;/a&gt; - maintained with ❤️ by the Streamlux team!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Streamlux
&lt;/h2&gt;

&lt;p&gt;And finally, if you found this post helpful, I am posting today on behalf of my company &lt;a href="https://streamlux.com"&gt;Streamlux&lt;/a&gt;. After months of hard work we've recently released a public beta of our desktop app. If you are a Twitch streamer or viewer come check out what we have in store.&lt;/p&gt;

</description>
      <category>appwrite</category>
      <category>docker</category>
      <category>backend</category>
    </item>
    <item>
      <title>Appwrite VS Code extension</title>
      <dc:creator>Alex Weininger</dc:creator>
      <pubDate>Sat, 22 May 2021 06:28:08 +0000</pubDate>
      <link>https://dev.to/streamlux/appwrite-vs-code-extension-1356</link>
      <guid>https://dev.to/streamlux/appwrite-vs-code-extension-1356</guid>
      <description>&lt;p&gt;In my very first post to dev.to I'll be talking about the Appwrite for VS Code extension, what you can use it for, and some features I hope to include in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;The team at Streamlux chose to utilize &lt;a href="https://appwrite.io/" rel="noopener noreferrer"&gt;Appwrite&lt;/a&gt; for many good reasons. One of my favorite reasons was that with Appwrite being relatively new, we'd have a great opportunity to contribute to the open source Appwrite community.&lt;/p&gt;

&lt;p&gt;To quickly summarize what Appwrite is, from their website:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Appwrite is an open-source, self-hosted Backend-as-a-Service that aims to make app development &lt;strong&gt;easier&lt;/strong&gt; with SDKs available in a variety of programming languages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, after a few weeks after using Appwrite, our first contribution to the Appwrite community is the Appwrite extension for Visual Studio Code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/streamlux/vscode-appwrite" rel="noopener noreferrer"&gt;View Appwrite for VS Code on GitHub&lt;/a&gt;&lt;br&gt;
 &lt;a href="https://marketplace.visualstudio.com/items?itemName=Streamlux.vscode-appwrite" rel="noopener noreferrer"&gt;View on the Visual Studio Marketplace&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Current features
&lt;/h1&gt;

&lt;p&gt;Here are the features we've built so far! &lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-project support
&lt;/h3&gt;

&lt;p&gt;If you happen to be working with more than one Appwrite project, then the extension has you covered! Easily switch between as many projects as you'd like.&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;VS Code theme: &lt;a href="https://marketplace.visualstudio.com/items?itemName=wesbos.theme-cobalt2" rel="noopener noreferrer"&gt;Cobalt2&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Database
&lt;/h3&gt;

&lt;p&gt;The comprehensive and robust database features that Appwrite &lt;br&gt;
 provides were one of the things that ultimately led to the team and I choosing it to power Streamlux.&lt;/p&gt;

&lt;p&gt;With the extension, you can manage databases, collections, and documents.&lt;/p&gt;

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

&lt;p&gt;You can also add, edit, and remove rules and permissions right from VS Code.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Users
&lt;/h3&gt;

&lt;p&gt;Another feature that makes using Appwrite so simple are the features surrounding users. From authentication, to managing user sessions and preferences, Appwrite makes it a breeze.&lt;/p&gt;

&lt;p&gt;And we strive to match this experience in the extension. Easily view project users, as well as create new ones.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Health
&lt;/h3&gt;

&lt;p&gt;And last but not least, you can monitor the health and status of all the services that make up your Appwrite project to make sure everything is running properly.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Future features
&lt;/h2&gt;

&lt;p&gt;One of the recently added features to Appwrite that also might be the best feature is &lt;a href="https://appwrite.io/docs/functions" rel="noopener noreferrer"&gt;Appwrite Functions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We think we can provide a great experience for creating and debugging Appwrite Functions in VS Code. And so the next large feature we want to add is functions support.&lt;/p&gt;

&lt;p&gt;If you've made it this far through my first dev.to post, thank you for reading!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/streamlux/vscode-appwrite" rel="noopener noreferrer"&gt;View Appwrite for VS Code on GitHub&lt;/a&gt;&lt;br&gt;
 &lt;a href="https://marketplace.visualstudio.com/items?itemName=Streamlux.vscode-appwrite" rel="noopener noreferrer"&gt;View on the Visual Studio Marketplace&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, I must mention it because the Appwrite team members provide absolute top tier support in their amazing &lt;a href="https://appwrite.io/discord" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;. If you're interested in Appwrite or already use Appwrite I highly recommend joining :)&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>30daysofappwrite</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
