<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: JakovGlavac</title>
    <description>The latest articles on Forem by JakovGlavac (@jakovglavac).</description>
    <link>https://forem.com/jakovglavac</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%2F514556%2Fdff6b1ab-c83c-4926-ab1e-219560d35f15.jpg</url>
      <title>Forem: JakovGlavac</title>
      <link>https://forem.com/jakovglavac</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jakovglavac"/>
    <language>en</language>
    <item>
      <title>Creating Style Previews with Stable Diffusion</title>
      <dc:creator>JakovGlavac</dc:creator>
      <pubDate>Wed, 20 Sep 2023 02:29:35 +0000</pubDate>
      <link>https://forem.com/jakovglavac/revolutionizing-fashion-unleashing-style-previews-with-stable-diffusion-4o68</link>
      <guid>https://forem.com/jakovglavac/revolutionizing-fashion-unleashing-style-previews-with-stable-diffusion-4o68</guid>
      <description>&lt;h1&gt;
  
  
  Enhancing Your Shopping Experience with AI and LORA
&lt;/h1&gt;

&lt;p&gt;While wisiting a cloating e-commerce shop, I had a random thought: "Wouldn't it be cool to preview clothes on myself while shopping?" As a developer by trade, and having prior experience with stable diffusion using Dream Booth, I decided to build an MVP to do just that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring LORA
&lt;/h2&gt;

&lt;p&gt;First, I attempted to use Dream Booth to learn my face. However, I stumbled upon something even cooler: LORA (Low-Rank Adaptation). LORA proved to be faster and easier to train and had the potential for combining different aspects. For instance, you could combine a LORA model of a user's face with a LORA model of the clothes you want that user to wear.&lt;/p&gt;

&lt;p&gt;I started by creating a LORA model of my face and had some fun with it, generating cool images like this one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eZrIi9KB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13yngjmppey459o6itm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eZrIi9KB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13yngjmppey459o6itm3.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, I created a LORA model of jackets from images found on an e-commerce website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zR85ZqAx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akuf45bgkpf5sqegx5wb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zR85ZqAx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akuf45bgkpf5sqegx5wb.png" alt="Jacket images" width="685" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, I combined these LORA models in a prompt and achieved pretty decent results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vuPKNJQd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6wniv79om1d4szo067t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vuPKNJQd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6wniv79om1d4szo067t.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GB40X7JP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2m7vkx6i9yzb4n1bcvj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GB40X7JP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2m7vkx6i9yzb4n1bcvj9.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---4DqRv9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6pudlr3ol2ns9mzgjn2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---4DqRv9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6pudlr3ol2ns9mzgjn2q.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LTNdSrEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mot9f7d51hwbbxwm5uc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LTNdSrEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mot9f7d51hwbbxwm5uc2.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, I noticed that the images weren't perfect, especially when it came to small details of the jacket and my face. I ran more prompts and tried to improve the LORA model, but my face was consistently off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting the LORA Model
&lt;/h2&gt;

&lt;p&gt;I experimented with several solutions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I attempted to label a person in the jacket dataset as a model and included this as a negative prompt, but it didn't yield significant improvements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I refined the prompts and used WD4 to annotate images, but the results remained suboptimal.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After trying numerous approaches without groundbreaking success, I decided to explore using a control net to correct the person's pose and apply masks to allow LORA to work on each part of the image independently. Here's what it looked like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vXeqXuDG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5it8vq8aalre3uhvf8cb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vXeqXuDG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5it8vq8aalre3uhvf8cb.png" alt="Image description" width="800" height="1218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The results were better, though my face was still not quite right. At first glance, everything seemed to be working okay:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NAxzRIDZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44sieav92mf5jbaxnbp4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NAxzRIDZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44sieav92mf5jbaxnbp4.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nn0iqEbe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yu0l9rnl8nbt1fch4pum.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nn0iqEbe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yu0l9rnl8nbt1fch4pum.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u4wU-iWI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hlqquathm4xdxh53xobk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u4wU-iWI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hlqquathm4xdxh53xobk.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P5W_oJCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xnkeio5jov9t8jbomxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P5W_oJCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xnkeio5jov9t8jbomxk.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Encouraged by these results, I attempted to add another piece of clothing to see if it would work with three LORA models. Here are the original images from the shop:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tn1cQPcU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4lklbr7odgja9oewj15k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tn1cQPcU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4lklbr7odgja9oewj15k.png" alt="Image description" width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--52g0KXO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h80urqns9yrusw3ad3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--52g0KXO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h80urqns9yrusw3ad3b.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zz7RBtnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igwau62ss4jdqtrwk3pz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zz7RBtnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igwau62ss4jdqtrwk3pz.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V1jUYD0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mghijes0mhir69gktti6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V1jUYD0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mghijes0mhir69gktti6.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time, the jacket and jeans looked really good, but the face was worse than in the last batch. Unfortunately, I couldn't pinpoint the exact reason for this.&lt;/p&gt;

&lt;p&gt;I'm still working on solving this issue, and when I do, I hope to share it with the community. If anyone has any insights or solutions, I would be incredibly grateful.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>How to use react three fiber in grafana</title>
      <dc:creator>JakovGlavac</dc:creator>
      <pubDate>Thu, 12 Jan 2023 17:35:28 +0000</pubDate>
      <link>https://forem.com/jakovglavac/how-to-use-react-three-fiber-in-grafana-4ol3</link>
      <guid>https://forem.com/jakovglavac/how-to-use-react-three-fiber-in-grafana-4ol3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Grafana and React Three Fiber
&lt;/h2&gt;

&lt;p&gt;Grafana is an open-source platform for data visualization and monitoring. It allows developers to create interactive and customizable dashboards, using a variety of data sources, including InfluxDB, Prometheus, and Elasticsearch. Grafana also provides a rich set of features, such as alerting, plugins, and an API, which makes it a powerful tool for monitoring and troubleshooting applications.&lt;/p&gt;

&lt;p&gt;React Three Fiber is a high-performance 3D library for React. It allows developers to create 3D graphics and animations using the familiar React syntax. React Three Fiber is built on top of Three.js, a powerful JavaScript library for creating 3D graphics, and it provides a set of hooks and components that make it easy to integrate 3D graphics into a React application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes That I've Encountered
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;React version specified in the package.json file may not match the version used by Grafana. To resolve this, it may be necessary to either upgrade Grafana or build a custom version with the desired React version. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OMcFbJp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73gluj424hybpp9yv5ov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OMcFbJp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73gluj424hybpp9yv5ov.png" alt="Image description" width="880" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When using React Three Fiber, it is important to remember to change the mode in webpack to production to avoid freezing the browser, which is a known &lt;a href="https://github.com/facebook/react/issues/14137"&gt;issue&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z1gs46vW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bq1gvb6nrtp87smy9pvj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z1gs46vW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bq1gvb6nrtp87smy9pvj.png" alt="Image description" width="387" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm writing this to save people a lot of time because this took me couple of days to figure out, maybe it looks simple but I've tried so many things that didn't work.&lt;/p&gt;

&lt;p&gt;I hope this will help someone.&lt;/p&gt;

</description>
      <category>react</category>
      <category>threefiber</category>
      <category>grafana</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Deploy Meilisearch on Fly.io</title>
      <dc:creator>JakovGlavac</dc:creator>
      <pubDate>Wed, 19 Oct 2022 23:08:19 +0000</pubDate>
      <link>https://forem.com/jakovglavac/deploy-meilisearch-on-flyio-p89</link>
      <guid>https://forem.com/jakovglavac/deploy-meilisearch-on-flyio-p89</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This guide explains how to deploy a ready-to-use Meilisearch instance on Fly.io.&lt;br&gt;
First time I tried this I've had some problems that wasted me a lot of time, so to save you the time I'll create step-by-step instructions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Just do it
&lt;/h2&gt;

&lt;p&gt;So if you want to deploy it to fly io as fast as possible, &lt;a href="https://i.imgflip.com/4pw07x.jpg"&gt;this is the way&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In any folder create &lt;code&gt;fly.toml&lt;/code&gt;, and copy the content&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="py"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"my-meilisearch"&lt;/span&gt;
&lt;span class="py"&gt;kill_signal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SIGINT"&lt;/span&gt;
&lt;span class="py"&gt;kill_timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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="nn"&gt;[build]&lt;/span&gt;
  &lt;span class="py"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"getmeili/meilisearch"&lt;/span&gt;

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

&lt;span class="nn"&gt;[experimental]&lt;/span&gt;
  &lt;span class="py"&gt;allowed_public_ports&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="py"&gt;auto_rollback&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;"disc1"&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;"/meili_data"&lt;/span&gt;

&lt;span class="nn"&gt;[[services]]&lt;/span&gt;
  &lt;span class="py"&gt;http_checks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&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;7700&lt;/span&gt;
  &lt;span class="py"&gt;processes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["app"]&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;script_checks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nn"&gt;[services.concurrency]&lt;/span&gt;
    &lt;span class="py"&gt;hard_limit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
    &lt;span class="py"&gt;soft_limit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
    &lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"connections"&lt;/span&gt;

  &lt;span class="nn"&gt;[[services.ports]]&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;handlers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["http"]&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="nn"&gt;[[services.ports]]&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;"tls"&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="py"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;

  &lt;span class="nn"&gt;[[services.tcp_checks]]&lt;/span&gt;
    &lt;span class="py"&gt;grace_period&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1s"&lt;/span&gt;
    &lt;span class="py"&gt;interval&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"15s"&lt;/span&gt;
    &lt;span class="py"&gt;restart_limit&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;timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2s"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then login in fly io!&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;flyctl login&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;and then deploy it!&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;flyctl deploy&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Theory
&lt;/h2&gt;

&lt;h3&gt;
  
  
  persistent storage
&lt;/h3&gt;

&lt;p&gt;So, the "hard" part of deploying is to create persistent storage.&lt;br&gt;
Fly.io has a guide on that &lt;a href="https://fly.io/blog/persistent-storage-and-fast-remote-builds/"&gt;here&lt;/a&gt;, but in short you need to add this part to your toml.&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="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;"disc1"&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;"/meili_data"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates disc, that is mapped to this folder &lt;code&gt;meili_data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why use /meili_data, because there is where melisearch stores your data.&lt;/p&gt;

&lt;h3&gt;
  
  
  docker image
&lt;/h3&gt;

&lt;p&gt;If you want fly io to use docker image from docker hub you need to specify image in build step like this:&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="nn"&gt;[build]&lt;/span&gt;
  &lt;span class="py"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"getmeili/meilisearch"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  port
&lt;/h3&gt;

&lt;p&gt;Meilisearch is by default on port 7700, so you need to tell fly io to listen to internal 7700 port.&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="nn"&gt;[[services]]&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;7700&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else is pretty much default. &lt;/p&gt;

&lt;p&gt;And that's it 🎉!&lt;/p&gt;

</description>
      <category>flyio</category>
      <category>deploy</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to translate HTML for free using google translate.</title>
      <dc:creator>JakovGlavac</dc:creator>
      <pubDate>Sat, 20 Aug 2022 07:51:10 +0000</pubDate>
      <link>https://forem.com/jakovglavac/how-to-translate-html-for-free-using-google-translate-2nf</link>
      <guid>https://forem.com/jakovglavac/how-to-translate-html-for-free-using-google-translate-2nf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;While working on a new feature for my side project &lt;a href="https://instrukcije.eduo.help/" rel="noopener noreferrer"&gt;eduo instrukcije&lt;/a&gt;, I needed to translate HTML to other languages which was challenging to do for free. Google translate api has parameter "format" that when set to "html" ignores all tags and translates only real text, but it's not free. There are couple of reversed engineered google translate apis that are totally free, but none of them had the format option available. Then I found out that you can use Google Translate api inside google sheets, and you can create real apis with google sheets, and I think that's pretty cool.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to do it?
&lt;/h2&gt;

&lt;p&gt;First open google sheets and open a new app script&lt;br&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%2Fztsdt9z9p0nry6gfj8bl.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%2Fztsdt9z9p0nry6gfj8bl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then paste this doGet function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;translation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;LanguageApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;froml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ContentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTextOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;translation&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setMimeType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ContentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MimeType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TEXT&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;Then go and deploy your api&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%2F1s8lfx2a3krc4qizljau.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%2F1s8lfx2a3krc4qizljau.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure that type is Web app and that everyone has access to it&lt;br&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%2F3iix608m1tmiwfml21b8.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%2F3iix608m1tmiwfml21b8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then copy your url &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%2Fovlm2vef1c1iane7ert8.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%2Fovlm2vef1c1iane7ert8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Go to your url and add query parameters &lt;br&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%2Fp80amh23ixwipk2da41r.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%2Fp80amh23ixwipk2da41r.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it! &lt;/p&gt;
&lt;h2&gt;
  
  
  One more thing
&lt;/h2&gt;

&lt;p&gt;If you want to use this inside sheets, just modify the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;translation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;froml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;LanguageApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;froml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like this:&lt;br&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%2F4ayk2qqrm1xz1podte3r.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%2F4ayk2qqrm1xz1podte3r.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Press "run", and return on sheets.&lt;br&gt;
Then you can use it like this:&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%2F2ftr6xs5bg1qb5svrf7t.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%2F2ftr6xs5bg1qb5svrf7t.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>googlecloud</category>
      <category>verycool</category>
    </item>
  </channel>
</rss>
