<?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: Woovi</title>
    <description>The latest articles on DEV Community by Woovi (@woovi).</description>
    <link>https://dev.to/woovi</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%2Forganization%2Fprofile_image%2F6093%2Febdfab16-778c-4fd7-8302-36924ce6f889.png</url>
      <title>DEV Community: Woovi</title>
      <link>https://dev.to/woovi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/woovi"/>
    <language>en</language>
    <item>
      <title>Creating a Certificate X.509 expiration Dashboard using Grafana</title>
      <dc:creator>Sibelius Seraphini</dc:creator>
      <pubDate>Mon, 05 Jan 2026 12:49:08 +0000</pubDate>
      <link>https://dev.to/woovi/creating-a-certificate-x509-expiration-dashboard-using-grafana-211k</link>
      <guid>https://dev.to/woovi/creating-a-certificate-x509-expiration-dashboard-using-grafana-211k</guid>
      <description>&lt;p&gt;At Woovi, we need to manage many X.509 certificates that are not only related to site domains. We have certificates that enable mTLS connections, allow us to sign ISO 20022 XML messages, and provide some A1 and A3 certificates to emit electronic invoices (notas fiscais) and access certain Central Bank and government systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current state of certificate expiration tools
&lt;/h2&gt;

&lt;p&gt;Most certificate expiration tools are focused on renewing site domain certificates. My problem is just to check the expiration of X.509 without auto-renew, as the renewal process requires a real person verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  x509-certificate-exporter + Grafana Dashboard
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/enix/x509-certificate-exporter" rel="noopener noreferrer"&gt;x509-certificate-exporter&lt;/a&gt; is a Prometheus exporter that can read X.509 certificates from many sources, like files, Kubernetes configs, and secrets.&lt;/p&gt;

&lt;p&gt;Here is a basic deployment to watch files&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;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;x509-certificate-exporter&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;x509-certificate-exporter&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RollingUpdate&lt;/span&gt;
    &lt;span class="na"&gt;rollingUpdate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;maxSurge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&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;x509-certificate-exporter&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&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;x509-certificate-exporter&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;x509-certificate-exporter&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;enix/x509-certificate-exporter:latest&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9793&lt;/span&gt;
          &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;certs&lt;/span&gt;
              &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/certs&lt;/span&gt;
              &lt;span class="na"&gt;readOnly&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--debug&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--watch-dir=/etc/certs&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="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;certs&lt;/span&gt;
          &lt;span class="na"&gt;configMap&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;x509-certificates&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to use Kustomization to generate the configmaps from X.509 files.&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;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kustomize.config.k8s.io/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Kustomization&lt;/span&gt;

&lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;x509-certificate-exporter&lt;/span&gt;

&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deployment.yaml&lt;/span&gt;

&lt;span class="na"&gt;configMapGenerator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;x509-certificates&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./certs/cert-a.crt&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./certs/cert-b.crt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply this kustomization like this &lt;code&gt;kubectl apply -k /deployments/x509-certificate-exporter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add this Grafana dashboard &lt;a href="https://grafana.com/grafana/dashboards/13922-certificates-expiration-x509-certificate-exporter/" rel="noopener noreferrer"&gt;Certificates Expiration (X509 Certificate Exporter)&lt;/a&gt; and you are all set.&lt;/p&gt;

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

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

&lt;p&gt;Kubernetes, Prometheus, and Grafana are versatile tools that enable you to build a custom dashboard to solve common problems in many companies.&lt;br&gt;
Set this up in your company and avoid having certificate expiration issues forever.&lt;br&gt;
The next step would be to set up alerts to renew certificates before the expiration date.&lt;/p&gt;

&lt;p&gt;What monitoring solutions are you using in your company?&lt;/p&gt;




&lt;p&gt;Woovi&lt;br&gt;
&lt;a href="https://www.woovi.com" rel="noopener noreferrer"&gt;Woovi&lt;/a&gt; is a fintech platform revolutionizing how businesses and developers handle payments in Brazil. Built with a developer-first mindset, Woovi simplifies integration with instant payment methods like Pix, enabling companies to receive payments seamlessly and automate financial workflows.&lt;/p&gt;

&lt;p&gt;If you want to work with us, we are &lt;a href="https://woovi.com/jobs/" rel="noopener noreferrer"&gt;hiring&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>x509</category>
      <category>certificate</category>
      <category>grafana</category>
      <category>devops</category>
    </item>
    <item>
      <title>Saving Terraform State in S3</title>
      <dc:creator>Sibelius Seraphini</dc:creator>
      <pubDate>Thu, 04 Dec 2025 12:55:08 +0000</pubDate>
      <link>https://dev.to/woovi/saving-terraform-state-in-s3-4ja7</link>
      <guid>https://dev.to/woovi/saving-terraform-state-in-s3-4ja7</guid>
      <description>&lt;p&gt;Terraform is a solution to provision infrastructure using code (IaC).&lt;br&gt;
Terraform stores the infrastructure generated in a state.&lt;br&gt;
This state maps the real world and metadata to Terraform.&lt;br&gt;
This ensures that you won't duplicate or recreate existing resources.&lt;/p&gt;
&lt;h2&gt;
  
  
  Storing Terraform State in an S3 bucket
&lt;/h2&gt;

&lt;p&gt;You can use S3 as the backend of the state like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 4.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.0"&lt;/span&gt;

  &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="s2"&gt;"s3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform-state-dev"&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;                     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-key"&lt;/span&gt;
    &lt;span class="nx"&gt;region&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
    &lt;span class="nx"&gt;shared_credentials_file&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~/.aws/credentials"&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;You can have a single key to store all your Terraform state, or you can have one key for each Terraform state.&lt;/p&gt;

&lt;p&gt;You can start your Terraform using &lt;code&gt;terraform init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After any &lt;code&gt;terraform apply&lt;/code&gt; or &lt;code&gt;terraform apply&lt;/code&gt; the state in your S3 will be updated.&lt;/p&gt;

&lt;p&gt;At Woovi, we decided to have one key per Terraform provision.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to migrate existing local state?
&lt;/h2&gt;

&lt;p&gt;You can use this command to migrate existing local or another backend state to your S3 bucket&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init &lt;span class="nt"&gt;-migrate-state&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In Resume
&lt;/h2&gt;

&lt;p&gt;If you lose your Terraform state, this can cause significant trouble.&lt;br&gt;
Keeping them in an S3 bucket can make it shareable across your team.&lt;/p&gt;




&lt;p&gt;Woovi&lt;br&gt;
&lt;a href="https://www.woovi.com" rel="noopener noreferrer"&gt;Woovi&lt;/a&gt; is a fintech platform revolutionizing how businesses and developers handle payments in Brazil. Built with a developer-first mindset, Woovi simplifies integration with instant payment methods like Pix, enabling companies to receive payments seamlessly and automate financial workflows.&lt;/p&gt;

&lt;p&gt;If you want to work with us, we are &lt;a href="https://woovi.com/jobs/" rel="noopener noreferrer"&gt;hiring&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>s3</category>
    </item>
    <item>
      <title>Creating a S3 bucket using Terraform</title>
      <dc:creator>Sibelius Seraphini</dc:creator>
      <pubDate>Wed, 03 Dec 2025 10:17:55 +0000</pubDate>
      <link>https://dev.to/woovi/creating-a-s3-bucket-using-terraform-4kgb</link>
      <guid>https://dev.to/woovi/creating-a-s3-bucket-using-terraform-4kgb</guid>
      <description>&lt;p&gt;S3 is the de facto and most well-known solution for object storage.&lt;br&gt;
Object storage allows you to store files in a specific bucket and key.&lt;/p&gt;

&lt;p&gt;When your application is small, you just need to manage a few S3 buckets, and you can manage them using the AWS UI.&lt;/p&gt;

&lt;p&gt;The problem is how to reproduce the same S3 bucket configuration over and over again, and from staging to production. &lt;br&gt;
Each S3 bucket has specific needs.&lt;/p&gt;

&lt;p&gt;It is also hard to see how all the S3 buckets are configured or how to change some configurations.&lt;/p&gt;
&lt;h2&gt;
  
  
  S3 using Terraform
&lt;/h2&gt;

&lt;p&gt;Terraform enables you to declare your infrastructure as code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 4.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Create S3 bucket for Terraform state&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"mybucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mybucket"&lt;/span&gt;

  &lt;span class="nx"&gt;force_destroy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mybucket"&lt;/span&gt;
    &lt;span class="nx"&gt;Environment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev"&lt;/span&gt;
    &lt;span class="nx"&gt;ManagedBy&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Enable versioning (so you can roll back state if needed)&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_versioning"&lt;/span&gt; &lt;span class="s2"&gt;"versioning"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mybucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;versioning_configuration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Enabled"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Enable server-side encryption by default&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_server_side_encryption_configuration"&lt;/span&gt; &lt;span class="s2"&gt;"sse"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mybucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;apply_server_side_encryption_by_default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sse_algorithm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AES256"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Block public access&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_public_access_block"&lt;/span&gt; &lt;span class="s2"&gt;"block"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mybucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;block_public_acls&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_policy&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;ignore_public_acls&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;restrict_public_buckets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You just need to type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform init
terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And your S3 bucket is created.&lt;/p&gt;

&lt;p&gt;If you modify your Terraform file and run &lt;code&gt;terraform apply&lt;/code&gt; , it will show what changed and only apply the modifications.&lt;/p&gt;

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

&lt;p&gt;Using Terraform to provision your infrastructure can help you go from simple S3 buckets to very complex applications.&lt;/p&gt;




&lt;p&gt;Woovi&lt;br&gt;
&lt;a href="https://www.woovi.com" rel="noopener noreferrer"&gt;Woovi&lt;/a&gt; is a fintech platform revolutionizing how businesses and developers handle payments in Brazil. Built with a developer-first mindset, Woovi simplifies integration with instant payment methods like Pix, enabling companies to receive payments seamlessly and automate financial workflows.&lt;/p&gt;

&lt;p&gt;If you want to work with us, we are &lt;a href="https://woovi.com/jobs/" rel="noopener noreferrer"&gt;hiring&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>s3</category>
      <category>objectstorage</category>
      <category>devops</category>
    </item>
    <item>
      <title>Copy and Paste on Proxmox VM</title>
      <dc:creator>Sibelius Seraphini</dc:creator>
      <pubDate>Tue, 02 Dec 2025 10:52:48 +0000</pubDate>
      <link>https://dev.to/woovi/copy-and-paste-on-proxmox-vm-15il</link>
      <guid>https://dev.to/woovi/copy-and-paste-on-proxmox-vm-15il</guid>
      <description>&lt;p&gt;Copy and paste does not work well on Proxmox KVM on the UI.&lt;br&gt;
You can try to connect using a serial port to enable copy and paste over the UI.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using a Script
&lt;/h2&gt;

&lt;p&gt;We created a script to simulate keyboard typing and paste data over KVM when using the UI.&lt;/p&gt;

&lt;p&gt;Open your Chrome Dev Tools, and paste this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eventType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;KeyboardEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;capsLockOn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SHIFT_NEEDED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Z!@#$%^&amp;amp;*()_+{}:"&amp;lt;&amp;gt;?~|&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keyup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;needsShift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SHIFT_NEEDED&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isUpperCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;needsShift&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shift&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;keyCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isUpperCase&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;capsLockOn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keyup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keyup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;needsShift&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;simulateKeyEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keyup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shift&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;keyCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CapsLock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;capsLockOn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;capsLockOn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Caps Lock state changed:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;capsLockOn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cp&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;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;typeChar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;sendKey&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;index&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
      &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;typeChar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Adjust delay as needed&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;typeChar&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;To paste something, you first need to focus on the UI, and then type &lt;code&gt;cp('mydata')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can use this when you don't have access to the VM over SSH.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;If you are creative enough, you can solve these limitations.&lt;/p&gt;




&lt;p&gt;Woovi&lt;br&gt;
&lt;a href="https://www.woovi.com" rel="noopener noreferrer"&gt;Woovi&lt;/a&gt; is a fintech platform revolutionizing how businesses and developers handle payments in Brazil. Built with a developer-first mindset, Woovi simplifies integration with instant payment methods like Pix, enabling companies to receive payments seamlessly and automate financial workflows.&lt;/p&gt;

&lt;p&gt;If you want to work with us, we are &lt;a href="https://woovi.com/jobs/" rel="noopener noreferrer"&gt;hiring&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>proxmox</category>
      <category>canvas</category>
      <category>script</category>
    </item>
    <item>
      <title>Using Terraform to create LXC in Proxmox</title>
      <dc:creator>Sibelius Seraphini</dc:creator>
      <pubDate>Mon, 01 Dec 2025 11:40:44 +0000</pubDate>
      <link>https://dev.to/woovi/using-terraform-to-create-lxc-in-proxmox-496h</link>
      <guid>https://dev.to/woovi/using-terraform-to-create-lxc-in-proxmox-496h</guid>
      <description>&lt;p&gt;Terraform is a well-known solution for defining, provisioning, and managing Infrastructure as Code (IaC).&lt;br&gt;
Most of the content out there focuses on major clouds as AWS, GCP, and Azure.&lt;br&gt;
I'd like to focus on Proxmox, an open source hypervisor used in a lot of home labs and also in production for companies that follow the baremetal approach, like Woovi.&lt;/p&gt;
&lt;h2&gt;
  
  
  Proxmox Infrastructure
&lt;/h2&gt;

&lt;p&gt;Proxmox is a virtualization platform. You can create VMs and LXC (Linux Containers) using the UI, but when your team grows, and you want to be able to reproduce the same staging environment at production, you need to use IaC.&lt;br&gt;
IaC is also great to make sure something is reproducible.&lt;/p&gt;
&lt;h2&gt;
  
  
  VMs vs LXC
&lt;/h2&gt;

&lt;p&gt;You can think of LXC as simpler and lighter VMs.&lt;br&gt;
LXC provides less isolation, and some software can't run on top of it easily, like microk8s nodes.&lt;br&gt;
We are going to focus on LXC to make this article simpler.&lt;/p&gt;
&lt;h2&gt;
  
  
  Provisioning using Terraform
&lt;/h2&gt;

&lt;p&gt;You can have the whole definition in the same file or split it into many files in the same folder.&lt;/p&gt;

&lt;p&gt;First, define the provider Proxmox from Telmate.&lt;/p&gt;

&lt;p&gt;Also, define the Proxmox provider variable like api_url, token ID, and token secret.&lt;br&gt;
You can follow this documentation &lt;a href="https://registry.terraform.io/providers/Terraform-for-Proxmox/proxmox/latest/docs" rel="noopener noreferrer"&gt;terraform for proxmox&lt;/a&gt; to generate the token ID and token secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;proxmox&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"telmate/proxmox"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3.0.2-rc04"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"proxmox"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;pm_api_url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://myproxmoxnode:8006/api2/json"&lt;/span&gt;
  &lt;span class="nx"&gt;pm_tls_insecure&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;pm_log_enable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;pm_debug&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;pm_api_token_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PM_API_TOKEN_ID&lt;/span&gt;
  &lt;span class="nx"&gt;pm_api_token_secret&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PM_API_TOKEN_SECRET&lt;/span&gt;
  &lt;span class="nx"&gt;pm_log_levels&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;_default&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"debug"&lt;/span&gt;
    &lt;span class="nx"&gt;_capturelog&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"PM_API_TOKEN_ID"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"PM_API_TOKEN_SECRET"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;define the LXC resource&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_lxc"&lt;/span&gt; &lt;span class="s2"&gt;"mongo-1"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;target_node&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev1"&lt;/span&gt;
  &lt;span class="nx"&gt;hostname&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mongo1"&lt;/span&gt;
  &lt;span class="nx"&gt;ostemplate&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst"&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LXC_PASSWORD&lt;/span&gt;

  &lt;span class="nx"&gt;unprivileged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;cores&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="nx"&gt;memory&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;
  &lt;span class="nx"&gt;swap&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;

  &lt;span class="nx"&gt;rootfs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local-lvm"&lt;/span&gt;
    &lt;span class="nx"&gt;size&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"50G"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;network&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eth0"&lt;/span&gt;
    &lt;span class="nx"&gt;bridge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vmbr0"&lt;/span&gt;
    &lt;span class="nx"&gt;ip&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.99.90.2/16"&lt;/span&gt;
    &lt;span class="nx"&gt;gw&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.99.0.3"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;ssh_public_keys&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"~/.ssh/id_ansible.pub"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;ini&lt;/code&gt; to initialize Terraform&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;apply&lt;/code&gt; to provision the lxc resource&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run destroy to destroy everything&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this setup, you need to save the local Terraform files to avoid recreating the resources. For production, the best approach is to keep  Terraform state in an S3 bucket&lt;/p&gt;

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

&lt;p&gt;You don't need to start your MVP Startup using Terraform to provision everything in your Proxmox. &lt;br&gt;
My recommendation is to keep improving automation as you and your team grow.&lt;br&gt;
After you get the first Terraform working, the rest gets easier.&lt;/p&gt;

&lt;p&gt;How are you using Terraform in your company?&lt;/p&gt;




&lt;p&gt;Woovi&lt;br&gt;
&lt;a href="https://www.woovi.com" rel="noopener noreferrer"&gt;Woovi&lt;/a&gt; is a fintech platform revolutionizing how businesses and developers handle payments in Brazil. Built with a developer-first mindset, Woovi simplifies integration with instant payment methods like Pix, enabling companies to receive payments seamlessly and automate financial workflows.&lt;/p&gt;

&lt;p&gt;If you want to work with us, we are &lt;a href="https://woovi.com/jobs/" rel="noopener noreferrer"&gt;hiring&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>proxmox</category>
      <category>baremetal</category>
      <category>iac</category>
    </item>
    <item>
      <title>Understanding IMAP and SMTP Mail Protocols</title>
      <dc:creator>Lucas Aguiar</dc:creator>
      <pubDate>Sat, 26 Jul 2025 01:48:38 +0000</pubDate>
      <link>https://dev.to/woovi/understanding-imap-and-smtp-mail-protocols-1bch</link>
      <guid>https://dev.to/woovi/understanding-imap-and-smtp-mail-protocols-1bch</guid>
      <description>&lt;p&gt;During a recent implementation of a customer service platform, I encountered several configuration challenges related to email communication protocols. This experience prompted me to conduct thorough research into SMTP and IMAP protocols, their interactions, and best implementation practices. The knowledge gained proved invaluable for resolving our technical issues, and I'm sharing these insights to benefit others facing similar challenges in their systems architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  📮 Introduction
&lt;/h2&gt;

&lt;p&gt;In the digital world, sending and receiving emails are fundamental communication processes. During my recent experience, I realized that understanding how these protocols work behind the scenes can make all the difference, especially when configuring or troubleshooting customer service systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Overview of Email Protocols
&lt;/h2&gt;

&lt;p&gt;Emails travel between computers using standardized protocols. The most common ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SMTP (Simple Mail Transfer Protocol)&lt;/strong&gt;: Used for sending messages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IMAP (Internet Message Access Protocol)&lt;/strong&gt;: Used for accessing and managing messages stored on the server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While POP3 also exists, this article focuses on SMTP and IMAP, which offer advantages for synchronization and email management across multiple devices.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  📤 SMTP - Simple Mail Transfer Protocol
&lt;/h2&gt;

&lt;p&gt;SMTP is the "engine" that sends emails. Here's a summary of what I learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primary Function&lt;/strong&gt;: SMTP is responsible for sending messages from the sender to the server, and between servers, ensuring the email reaches its recipient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How It Works&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The process begins with the email client sending the message to the SMTP server&lt;/li&gt;
&lt;li&gt;Commands like EHLO/HELO, MAIL FROM, RCPT TO, and DATA structure this communication&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Ports and Security&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Common ports include 25 (traditional) and 587 (for authenticated sending)&lt;/li&gt;
&lt;li&gt;Using TLS or SSL encryption is highly recommended to protect data during transmission&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  📥 IMAP - Internet Message Access Protocol
&lt;/h2&gt;

&lt;p&gt;While SMTP handles sending, IMAP is the "manager" of received emails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primary Function&lt;/strong&gt;: IMAP allows you to access and manage emails directly on the server. This means that regardless of which device you use—smartphone, tablet, or computer—your messages remain synchronized.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advantages over POP3&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Messages remain stored on the server, allowing viewing and organization from any device&lt;/li&gt;
&lt;li&gt;You can create, move, and delete folders directly on the server without downloading emails&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;How It Works&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;IMAP synchronizes message status (e.g., read/unread) and organizes emails into folders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Ports and Security&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Port 143 is used for unencrypted connections, while port 993 is for secure connections via SSL/TLS&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  ⚖️ Comparison Between SMTP and IMAP
&lt;/h2&gt;

&lt;p&gt;Although both protocols are part of email communication, they have distinct, complementary roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SMTP&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Responsible for sending emails&lt;/li&gt;
&lt;li&gt;Functions as the "digital mail carrier" distributing messages between servers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;IMAP&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Responsible for accessing and managing stored messages&lt;/li&gt;
&lt;li&gt;Allows you to track your emails in a synchronized manner across multiple devices&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  ⚙️ Technical Aspects and Implementation
&lt;/h2&gt;

&lt;p&gt;During my experience, I found that visualizing the email flow helps better understand how these protocols interact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sending and Receiving Flow&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The email leaves the client and goes to the SMTP server&lt;/li&gt;
&lt;li&gt;From there, it may be forwarded to other servers until it reaches the recipient's server&lt;/li&gt;
&lt;li&gt;Finally, the email client uses IMAP to access and manage this message on the server&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Configuration and Authentication&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Correctly configuring ports and authentication methods (such as TLS/SSL) is essential to ensure everything works smoothly&lt;/li&gt;
&lt;li&gt;In many situations, the challenge lies precisely in aligning these configurations for efficient and secure customer service operation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  🔒 Security and Best Practices
&lt;/h2&gt;

&lt;p&gt;To avoid headaches (like the one I faced), it's important to pay attention to these points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Common Threats&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Without proper security, data can be intercepted during transmission&lt;/li&gt;
&lt;li&gt;Configuration errors can create vulnerabilities for spam or even more serious attacks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Security Measures&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Always use encryption (SSL/TLS) in communications&lt;/li&gt;
&lt;li&gt;Regularly verify and update server authentication configurations&lt;/li&gt;
&lt;li&gt;Follow recommended best practices for both administrators and end users&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;Understanding SMTP and IMAP protocols was essential to solving the problem I encountered when configuring the customer service system. With SMTP handling sending and IMAP enabling access and message management, both complement each other to make email communication fluid and secure.&lt;/p&gt;

&lt;p&gt;I hope this article, written simply and based on my experience, helps you better understand how these protocols work. After all, sharing knowledge is a way to grow and make life easier for those who also need to deal with these configurations daily.&lt;/p&gt;




&lt;p&gt;If you have questions or want to explore any topic in greater depth, feel free to comment. We're all learning together!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My second week on Woovi: Getting into the swing of things (or almost there)</title>
      <dc:creator>Adam Neves</dc:creator>
      <pubDate>Tue, 15 Jul 2025 23:36:37 +0000</pubDate>
      <link>https://dev.to/woovi/my-second-week-on-woovi-getting-into-the-swing-of-things-or-almost-there-h1p</link>
      <guid>https://dev.to/woovi/my-second-week-on-woovi-getting-into-the-swing-of-things-or-almost-there-h1p</guid>
      <description>&lt;h3&gt;
  
  
  A False Sense of Comfort
&lt;/h3&gt;

&lt;p&gt;My second week at Woovi felt calmer. I started delivering more and understood the codebase better, although honestly, I probably understand only 1 percent of what I need.&lt;/p&gt;

&lt;p&gt;What’s interesting is that even as things started to fall into place, I realized how much context and depth are still missing. Each day exposes new gaps, unexpected architectural decisions, and subtle product nuances that force you to slow down and truly think.&lt;/p&gt;

&lt;h3&gt;
  
  
  Growth Beyond Code
&lt;/h3&gt;

&lt;p&gt;A clear pattern emerged: every day, someone taught me something, whether technical or related to soft skills.&lt;/p&gt;

&lt;p&gt;At Woovi, everyone seems to have a superpower. Some are masters of communication, others have exceptional technical depth, and some have sharp product instincts that guide big decisions. You start to see how each strength blends into the culture and how these traits build an environment where questioning and debating ideas is not just allowed but expected.&lt;/p&gt;

&lt;p&gt;One of the most interesting cultural lessons this week was about how learning is shared. For example, today I learned about &lt;strong&gt;eventual consistency&lt;/strong&gt;, a fundamental concept in distributed systems. It means that while data updates might not be immediately visible everywhere, the system will eventually reach a consistent state. In practice, this forces you to think differently about user experience, error handling, and how to communicate system states clearly to users.&lt;/p&gt;

&lt;p&gt;These small technical insights are passed around naturally, in PR comments, quick chats, or even casual messages. They aren't pushed in forced "knowledge sharing" sessions; they emerge as part of daily work.&lt;/p&gt;

&lt;p&gt;This also reinforces a crucial point: growth here depends on you actively engaging. If you stay passive, you risk missing valuable lessons hidden in daily interactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflow Maturity
&lt;/h3&gt;

&lt;p&gt;I noticed a significant evolution in our workflow. In the first few days, things felt a bit chaotic, with processes and responsibilities less defined. By the second week, communication aligned, priorities became clearer, and deliveries started to feel more predictable.&lt;/p&gt;

&lt;p&gt;This transition from initial chaos to controlled speed shows that Woovi is constantly iterating. There is no static mindset of “we’ve solved everything.” The culture is shaped around continuous improvement, even in internal processes. Everyone is expected to contribute to refining how we work, not just what we build.&lt;/p&gt;

&lt;h3&gt;
  
  
  Motivation and Expectation
&lt;/h3&gt;

&lt;p&gt;Watching the team operate at this level is energizing. It pushes you to deliver more, keep improving, and constantly challenge your own limits.&lt;/p&gt;

&lt;p&gt;Are we moving toward excellence? For me, the answer is yes. But it’s not the kind of excellence that comes from rigid structure or strict guidelines. It’s an evolving, living excellence that requires self-drive, curiosity, and a willingness to get uncomfortable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Progress can feel fast, but there is always deeper context to uncover.&lt;/li&gt;
&lt;li&gt;Learning here is organic and requires proactive behavior.&lt;/li&gt;
&lt;li&gt;Process improvements are constant and collective, not accidental.&lt;/li&gt;
&lt;li&gt;The culture values questioning and sees discomfort as a growth catalyst.&lt;/li&gt;
&lt;li&gt;Technical lessons like eventual consistency show how deep the rabbit hole goes, even in seemingly "simple" features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The second week was not about settling in. It was about realizing how much there still is to learn, both technically and personally.&lt;/p&gt;




&lt;p&gt;The main lesson? Onboarding never truly ends here, and that might be exactly the point.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My First 7 Days at Woovi: Learnings, Surprises, and Open Questions</title>
      <dc:creator>Adam Neves</dc:creator>
      <pubDate>Wed, 09 Jul 2025 01:54:54 +0000</pubDate>
      <link>https://dev.to/woovi/my-first-7-days-at-woovi-learnings-surprises-and-open-questions-3mb3</link>
      <guid>https://dev.to/woovi/my-first-7-days-at-woovi-learnings-surprises-and-open-questions-3mb3</guid>
      <description>&lt;p&gt;Starting at a new company is often romanticized: welcome coffees, a nicely packaged onboarding plan, and a slow ramp-up. My first week at Woovi turned out to be quite the opposite: a fast-paced, pragmatic environment where questioning is not only allowed but expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Impressions
&lt;/h2&gt;

&lt;p&gt;On day one, I realized the culture is heavily biased towards fast delivery and technical autonomy. Instead of following step-by-step tutorials, I was encouraged to explore real repositories, understand actual deployment flows, and challenge architectural decisions.&lt;/p&gt;

&lt;p&gt;This breaks the common assumption that onboarding must be 100% guided and “hand-holding.” Here, you’re treated as someone who should contribute from day one, not just passively consume information.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fear of Not Being Enough
&lt;/h2&gt;

&lt;p&gt;A hidden part of this experience was the fear of not being enough for the role. I came in wondering if I could really match the expectations, whether I would deliver fast enough, and whether I would truly add value.&lt;/p&gt;

&lt;p&gt;Very quickly, I realized there was no way to simply "meet expectations" here. Woovi feels more like a high-level engineering school than a typical company. You could be the most senior engineer out there, and you would still get overwhelmed by the codebase. It’s the result of years of creation, iteration, and continuous learning.&lt;/p&gt;

&lt;p&gt;This realization actually eased my anxiety. Instead of obsessing over "being enough," I shifted focus to learning fast and contributing incrementally. The expectation is not perfection on day one. The expectation is to keep moving, questioning, improving, and growing as part of the team.&lt;/p&gt;

&lt;p&gt;The codebase will push you out of your comfort zone. But in return, it turns you into a better engineer, faster than any comfortable environment ever could.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Challenges
&lt;/h2&gt;

&lt;p&gt;During the week, I dived into the main stack, Node.js, Koa, TypeScript, GraphQL, Relay and integrations with financial systems like Pix and payment gateways. One surprise was how modular yet unopinionated the architecture is: there’s more room for customization, and fewer rigid patterns.&lt;/p&gt;

&lt;p&gt;This requires critical thinking: you can’t just “do it like Google.” You have to weigh real trade-offs, performance vs readability, coupling vs delivery speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Team Integration
&lt;/h2&gt;

&lt;p&gt;Most interactions happened asynchronously. Far fewer meetings than I expected. This forces you to write better, whether it’s commits, pull requests, or internal docs, and not rely on endless live clarifications.&lt;/p&gt;

&lt;p&gt;Interestingly, this exposed a personal flaw: I underestimated how much poor written communication can slow down a project. If you don’t document well, everyone stops to answer your basic questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Still Question
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Does a loose, self-guided onboarding work for everyone?&lt;/li&gt;
&lt;li&gt;How much does full autonomy from day one increase the risk of mistakes or rework?&lt;/li&gt;
&lt;li&gt;Does async culture, while efficient, alienate those who prefer real-time discussions?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions stuck with me all week. I don’t have final answers yet, but I’m watching closely how this affects long-term alignment and productivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Writing good documentation is as critical as writing good code.&lt;/li&gt;
&lt;li&gt;Questioning architecture is not just tolerated, it’s actively encouraged.&lt;/li&gt;
&lt;li&gt;Onboarding doesn’t need to be paternalistic to be effective.&lt;/li&gt;
&lt;li&gt;Organizational performance is deeply tied to clear written communication.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My First 2 Days: Building a Centralized Onboarding Flow
&lt;/h2&gt;

&lt;p&gt;During my first two days, I noticed something that might sound paradoxical: &lt;em&gt;everything was documented, yet no one knew exactly how to navigate it&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;The documentation was thorough, covering internal APIs, deployment workflows, local setup, and architectural decisions. But each piece was isolated, like having a pile of puzzle pieces with no reference picture.  &lt;/p&gt;

&lt;p&gt;New engineers often found themselves constantly asking, &lt;em&gt;"In what order should I read these docs?"&lt;/em&gt; or &lt;em&gt;"What’s the first thing I should run locally before touching feature X?"&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Instead of just consuming the scattered docs and pinging people repeatedly, I decided to start drafting a &lt;strong&gt;centralized onboarding flow&lt;/strong&gt;. The goal was to connect all these pieces into a clear sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;What to clone first.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Which scripts to run and in which order.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What services need to be up before running the app.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Where to look for environment configuration and secrets.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key architectural diagrams to understand before jumping into PRs.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This initiative not only helped me get up to speed faster but also turned into a reusable asset for future newcomers.  &lt;/p&gt;

&lt;p&gt;It challenged the assumption that "more docs = better onboarding." In reality, &lt;em&gt;structured narrative beats raw volume every time&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;By proactively organizing this flow, I ended up learning the system more deeply and reduced the dependency on constant Slack or chat questions. And perhaps more importantly, I started contributing real value on day two instead of just passively absorbing information.&lt;/p&gt;




&lt;h2&gt;
  
  
  Special Thanks to the Woovi Engineering Team
&lt;/h2&gt;

&lt;p&gt;One thing that stood out immediately and deserves a special mention is the quality of the people here. It genuinely feels like every developer was handpicked, and after experiencing it firsthand, I now understand why the selection process is so demanding and sometimes lengthy.&lt;/p&gt;

&lt;p&gt;Everyone I've interacted with acted with an impressive sense of honor and strength, always pushing to help each other, no matter how busy they were. They deeply remember what it felt like to be new in the company, and they step up to assist with patience, without sarcasm or condescension.&lt;/p&gt;

&lt;p&gt;I won’t mention names, but to all of you who joined calls with me during this first week, consider this a public tribute. You turned what could have been a chaotic start into an empowering, fast-learning experience.&lt;/p&gt;

&lt;p&gt;This reinforced for me that a strong engineering culture isn't just about code quality or architecture; it's built on people who genuinely want each other to succeed.&lt;/p&gt;




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

&lt;p&gt;My first week at Woovi was less about a “cute onboarding” and more about a pragmatic deep dive. I realized that in a team focused on speed and autonomy, the worst mistake is waiting passively for instructions.&lt;/p&gt;

&lt;p&gt;If you’re about to join a fast-moving team, here’s a provocation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Are you ready to swim without a float? Or are you still sitting on the edge, waiting for the manual?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Your Turn
&lt;/h2&gt;

&lt;p&gt;Have you gone through an ultra-fast or hyper-structured onboarding before? What worked best for you? Share your thoughts in the comments.&lt;/p&gt;

</description>
      <category>career</category>
      <category>onboarding</category>
      <category>workplace</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>How MDX can accelerates document creation in websites</title>
      <dc:creator>Hállex da Silva Costa</dc:creator>
      <pubDate>Mon, 05 May 2025 14:39:54 +0000</pubDate>
      <link>https://dev.to/woovi/how-mdx-can-accelerates-document-creation-in-websites-2lm3</link>
      <guid>https://dev.to/woovi/how-mdx-can-accelerates-document-creation-in-websites-2lm3</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;See how MDX solves the problem of writing extremely long pages or articles.&lt;/p&gt;

&lt;p&gt;In this article, we will show you how MDX can be a powerful solution to speed up the documentation creation process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever seen a very common problem in many companies, such as outdated documents? Well, in a world where maintaining documents such as policies and privacy, terms and security is crucial.&lt;/p&gt;

&lt;p&gt;At the same time, having to deal with the fact that you will have to spend precious time writing &lt;strong&gt;N&lt;/strong&gt; pages that have already been written in a document like Word or PDF to an HTML, JSX or TSX page does not seem very pleasant or very smart.&lt;/p&gt;

&lt;p&gt;Finding efficient ways to create and maintain documents becomes essential.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Articles/Documentation
&lt;/h2&gt;

&lt;p&gt;One of the biggest challenges in creating documentation is the time spent retyping content. Often, we need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewrite texts that already exist in other formats&lt;/li&gt;
&lt;li&gt;Maintain consistency between different versions of the same document&lt;/li&gt;
&lt;li&gt;Update multiple formats when changes occur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process not only consumes time but also increases the chance of errors and inconsistencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: MDX
&lt;/h2&gt;

&lt;p&gt;MDX (Markdown + JSX) emerges as an elegant solution to these problems. It combines the simplicity of Markdown with the power of JSX, allowing the creation of interactive and dynamic documents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Easy Conversion from DOCX to MD/MDX
&lt;/h3&gt;

&lt;p&gt;One of the biggest advantages of using MDX is the ease with which you can convert an existing document from docx to markdown and from markdown to MDX&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Follow This Approach?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Productivity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Less time spent on formatting&lt;/li&gt;
&lt;li&gt;Component reuse&lt;/li&gt;
&lt;li&gt;Faster updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Maintenance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Code and documentation together&lt;/li&gt;
&lt;li&gt;Simpler versioning&lt;/li&gt;
&lt;li&gt;Less content duplication&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Interactivity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Interactive components&lt;/li&gt;
&lt;li&gt;Executable code examples&lt;/li&gt;
&lt;li&gt;Better reader experience&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Flexibility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy integration with modern tools&lt;/li&gt;
&lt;li&gt;Support for different output formats&lt;/li&gt;
&lt;li&gt;Compatibility with popular documentation systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Here's an example of a &lt;code&gt;DocumentPage.tsx&lt;/code&gt; created using the tsx syntax for another page using the &lt;code&gt;DocumentPage.mdx&lt;/code&gt; syntax&lt;/p&gt;

&lt;h3&gt;
  
  
  DocumentPage.tsx
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DocumentPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"document-page max-w-4xl mx-auto py-8 px-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-3xl font-bold mb-8 text-center"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Terms of Service and Privacy Policy&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-semibold mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;1. Introduction&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Welcome to our Terms of Service and Privacy Policy. 
          This document establishes the rules and guidelines for using our services.
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          By accessing and using our platform, you agree to the terms set forth herein.
          We recommend reading this document carefully before proceeding.
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-semibold mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;2. Definitions&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;For the purposes of this document, the following terms shall have the meanings below:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list-decimal pl-6 space-y-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Platform:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; Refers to the set of services and features provided
            through our website and applications.
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;User:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; Any person who accesses or uses the Platform.
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Content:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; Information, data, text, images, and other materials provided
            through the Platform.
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-semibold mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;3. Platform Usage&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;By using our Platform, you agree to:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list-disc pl-6 space-y-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Provide accurate and up-to-date information&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Maintain the confidentiality of your account&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Not use the Platform for illegal purposes&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Respect intellectual property rights&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-semibold mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;4. Privacy and Data Protection&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Our privacy policy describes how we collect, use, and protect your personal information.
          For more details, please refer to our&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/privacy"&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-blue-600 hover:underline"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            complete Privacy Policy
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;.
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-50 p-4 rounded-lg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-semibold mb-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Collected Data&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list-disc pl-6 space-y-1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Registration information&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Platform usage data&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Device information&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Cookies and similar technologies&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-semibold mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;5. Responsibilities&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Our responsibilities include:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list-decimal pl-6 space-y-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Maintaining the Platform available and functioning properly
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Protecting user data in accordance with data protection laws
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Providing technical support when needed
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-semibold mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;6. Contact&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          For questions regarding these terms, please contact us via email at&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mailto:legal@company.com"&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-blue-600 hover:underline"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            legal@company.com
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;or by phone at (555) 123-4567.
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;footer&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-gray-600 mt-8 pt-4 border-t"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Last updated: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toLocaleDateString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;footer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;DocumentPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  DocumentPage.mdx
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Terms&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Service&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Privacy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Policy"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Terms&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;conditions&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;using&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;platform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;privacy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;policy"&lt;/span&gt;
&lt;span class="na"&gt;creationAt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2025-05-04"&lt;/span&gt;
&lt;span class="na"&gt;lastUpdated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2025-05-04"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

export const meta = {
  title: "Terms of Service and Privacy Policy",
  creationAt: "2025-05-04",
  lastUpdated: "2025-05-04"
};

&lt;span class="gh"&gt;# {meta.title}&lt;/span&gt;

{frontmatter.description}

&lt;span class="gu"&gt;## 1. Introduction&lt;/span&gt;

Welcome to our Terms of Service and Privacy Policy. 
This document establishes the rules and guidelines for using our services.

By accessing and using our platform, you agree to the terms set forth herein.
We recommend reading this document carefully before proceeding.

&lt;span class="gu"&gt;## 2. Definitions&lt;/span&gt;

For the purposes of this document, the following terms shall have the meanings below:
&lt;span class="p"&gt;
1.&lt;/span&gt; &lt;span class="gs"&gt;**Platform:**&lt;/span&gt; Refers to the set of services and features provided
   through our website and applications.
&lt;span class="p"&gt;
2.&lt;/span&gt; &lt;span class="gs"&gt;**User:**&lt;/span&gt; Any person who accesses or uses the Platform.
&lt;span class="p"&gt;
3.&lt;/span&gt; &lt;span class="gs"&gt;**Content:**&lt;/span&gt; Information, data, text, images, and other materials provided
   through the Platform.

&lt;span class="gu"&gt;## 3. Platform Usage&lt;/span&gt;

By using our Platform, you agree to:
&lt;span class="p"&gt;
*&lt;/span&gt; Provide accurate and up-to-date information
&lt;span class="p"&gt;*&lt;/span&gt; Maintain the confidentiality of your account
&lt;span class="p"&gt;*&lt;/span&gt; Not use the Platform for illegal purposes
&lt;span class="p"&gt;*&lt;/span&gt; Respect intellectual property rights

&lt;span class="gu"&gt;## 4. Privacy and Data Protection&lt;/span&gt;

Our privacy policy describes how we collect, use, and protect your personal information.
For more details, please refer to our &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;complete Privacy Policy&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/privacy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;.

&lt;span class="nt"&gt;&amp;lt;InfoBox&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  ### Collected Data
&lt;span class="p"&gt;
  *&lt;/span&gt; Registration information
&lt;span class="p"&gt;  *&lt;/span&gt; Platform usage data
&lt;span class="p"&gt;  *&lt;/span&gt; Device information
&lt;span class="p"&gt;  *&lt;/span&gt; Cookies and similar technologies
&lt;span class="nt"&gt;&amp;lt;/InfoBox&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## 5. Responsibilities&lt;/span&gt;

Our responsibilities include:
&lt;span class="p"&gt;
1.&lt;/span&gt; Maintaining the Platform available and functioning properly
&lt;span class="p"&gt;2.&lt;/span&gt; Protecting user data in accordance with data protection laws
&lt;span class="p"&gt;3.&lt;/span&gt; Providing technical support when needed

&lt;span class="gu"&gt;## 6. Contact&lt;/span&gt;

For questions regarding these terms, please contact us via email at &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;legal@company.com&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;mailto:legal@company.com&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
or by phone at (555) 123-4567.

&lt;span class="nt"&gt;&amp;lt;LegalNotice&amp;gt;&lt;/span&gt;
  This document was last updated on {meta.lastUpdated}.
  We recommend checking periodically for updates.
&lt;span class="nt"&gt;&amp;lt;/LegalNotice&amp;gt;&lt;/span&gt;

{/&lt;span class="ge"&gt;* Custom components for legal elements *&lt;/span&gt;/}
&lt;span class="nt"&gt;&amp;lt;LegalSection&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Final Provisions&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    These terms are governed by the laws of the United States and any dispute shall be
    submitted to the jurisdiction of the courts of New York, NY.
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/LegalSection&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;TableOfContents&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Table of Contents&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ol&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#introduction"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Introduction&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#definitions"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Definitions&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#usage"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Platform Usage&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#privacy"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Privacy and Data Protection&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#responsibilities"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Responsibilities&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#contact"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/TableOfContents&amp;gt;&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Documente created at {meta.creationAt}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This MDX example demonstrates how we can create complex legal documents in a more structured and interactive way. Notice how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The frontmatter organizes the document metadata. Use it or export a new &lt;code&gt;meta&lt;/code&gt; variable to use in your markdown and communicate with external layer like the MDXProvider&lt;/li&gt;
&lt;li&gt;Markdown syntax keeps the content readable and well-formatted&lt;/li&gt;
&lt;li&gt;Custom components (&lt;code&gt;&amp;lt;InfoBox&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;LegalNotice&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;LegalSection&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;TableOfContents&amp;gt;&lt;/code&gt;) add specific functionality&lt;/li&gt;
&lt;li&gt;Custom styles for common elements as h1, h2, h3, h4, h5, p, a, li, ol, etc... Allows you to dynamically style markdown syntax elements such as &lt;code&gt;#&lt;/code&gt;, &lt;code&gt;##&lt;/code&gt;, &lt;code&gt;###&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;JavaScript code can be embedded for dynamic features (like the update date)&lt;/li&gt;
&lt;li&gt;The document structure is clear and well-organized&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach makes it much easier to maintain and update extensive legal documents, while also significantly improving the end-user experience.&lt;/p&gt;

&lt;p&gt;You can visit a repository with a simple example comparing TSX and MDX &lt;a href="https://github.com/HallexCosta/example-tsx-mdx" rel="noopener noreferrer"&gt;here&lt;/a&gt; and visit &lt;a href="https://mdxjs.com/playground/" rel="noopener noreferrer"&gt;here&lt;/a&gt; to play a little with mdx playground&lt;/p&gt;

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

&lt;p&gt;MDX is an excellent tool for saving time, maintaining code consistency, and improving efficiency. By combining the simplicity of Markdown with the power of JSX, it offers a robust solution to modern documentation challenges.&lt;/p&gt;

&lt;p&gt;The approach of converting existing documents to MDX not only speeds up the creation process but also improves the quality and maintainability of documentation. In a world where documentation is crucial, MDX presents itself as an essential tool for teams seeking efficiency, quality and save time.&lt;/p&gt;

</description>
      <category>mdx</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>Prometheus + Redis: Simple Guide to Monitor Redis Instances</title>
      <dc:creator>Lucas Aguiar</dc:creator>
      <pubDate>Mon, 21 Apr 2025 22:26:33 +0000</pubDate>
      <link>https://dev.to/woovi/prometheus-redis-simple-guide-to-monitor-redis-instances-n1f</link>
      <guid>https://dev.to/woovi/prometheus-redis-simple-guide-to-monitor-redis-instances-n1f</guid>
      <description>&lt;p&gt;Redis is often a critical part of modern infrastructure — whether used as a cache, message broker, or ephemeral store. Monitoring it properly helps you detect issues early and ensure system stability.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll learn how to build a Redis monitoring dashboard with Prometheus and Grafana to quickly identify issues and improve system reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Installing Prometheus (Quick Setup)
&lt;/h2&gt;

&lt;p&gt;We’ll start by deploying Prometheus using Helm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install kube-prometheus prometheus-community/kube-prometheus-stack \
  --namespace prometheus --create-namespace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This will install Prometheus, Grafana, and some built-in exporters.&lt;br&gt;
To access Grafana:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl port-forward svc/kube-prometheus-grafana -n prometheus 3000:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can access here -&amp;gt; &lt;a href="http://localhost:3000/login" rel="noopener noreferrer"&gt;http://localhost:3000/login&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Default login: admin / prom-operator&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧱 Installing Redis
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

helm install redis bitnami/redis \
  --namespace app-stg \
  --set architecture=standalone \
  --set auth.enabled=false \
  --create-namespace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This installs a standalone Redis with no password, perfect for testing.&lt;br&gt;
After this, you can point the Redis Exporter and your application to the correct Redis service. The hostname will be:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;redis-master.app-stg.svc.cluster.local:6379
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📦 Installing Redis Exporter
&lt;/h2&gt;

&lt;p&gt;Now let’s deploy the Redis Exporter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm install redis-exporter prometheus-community/prometheus-redis-exporter \
  --namespace prometheus \
  --set serviceMonitor.enabled=true \
  --set serviceMonitor.namespace=prometheus \
  --set serviceMonitor.interval=15s \
  --set serviceMonitor.labels.release=kube-prometheus \
  --set redisAddress=redis://redis-master.app-stg.svc.cluster.local:6379 \
  --create-namespace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Redis Exporter exposes metrics at a Prometheus-compatible /metrics endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl port-forward svc/redis-exporter-prometheus-redis-exporter -n prometheus 9121:9121
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open: &lt;a href="http://localhost:9121/metrics" rel="noopener noreferrer"&gt;http://localhost:9121/metrics&lt;/a&gt;&lt;br&gt;
You should see a long list of metrics like this:&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;✅ redis_up 1 means the exporter is connected to a Redis instance and it’s healthy.&lt;br&gt;
🚫 redis_up 0 means the exporter failed to connect — check the Redis address or service availability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If everything is working, you’ll also see metrics like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;redis_connected_clients&lt;/li&gt;
&lt;li&gt;redis_memory_used_bytes&lt;/li&gt;
&lt;li&gt;redis_total_commands_processed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🔍 Checking in Prometheus
&lt;/h2&gt;

&lt;p&gt;To validate that Prometheus is collecting Redis metrics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl port-forward svc/kube-prometheus-kube-prome-prometheus -n prometheus 9090
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;a href="http://localhost:9090" rel="noopener noreferrer"&gt;http://localhost:9090&lt;/a&gt;, go to &lt;a href="http://localhost:9090/targets" rel="noopener noreferrer"&gt;Status &amp;gt; Targets&lt;/a&gt;, and check that Redis Exporter is listed and UP.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7s4xgevvwa2crwfv43b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7s4xgevvwa2crwfv43b.png" alt="Prometheus target debuging" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything is working right!&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 Importing the Redis Dashboard on Grafana
&lt;/h2&gt;

&lt;p&gt;To visualize your Redis metrics in a clean and ready-to-use panel, you can import a community-maintained dashboard from Grafana Labs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://grafana.com/grafana/dashboards/14091-redis-dashboard-for-prometheus-redis-exporter-1-x/" rel="noopener noreferrer"&gt;https://grafana.com/grafana/dashboards/14091-redis-dashboard-for-prometheus-redis-exporter-1-x/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧭 How to Import
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Access Grafana by establishing port forwarding and navigating to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; in your browser&lt;/li&gt;
&lt;li&gt;Navigate to the "+" icon in the left sidebar and select "Import"&lt;/li&gt;
&lt;li&gt;Enter the dashboard ID or URL in the provided field and click "Load"&lt;/li&gt;
&lt;li&gt;Click "Import" to finalize the installation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Allow a few moments for the system to process your request as the metrics populate on your dashboard&lt;/p&gt;

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

&lt;p&gt;Thats it!&lt;br&gt;
⎈Happy Helming!⎈&lt;/p&gt;

</description>
      <category>redis</category>
      <category>prometheus</category>
      <category>grafana</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Resilient Node.js servers without using docker</title>
      <dc:creator>Hállex da Silva Costa</dc:creator>
      <pubDate>Tue, 04 Mar 2025 01:55:09 +0000</pubDate>
      <link>https://dev.to/woovi/resilient-nodejs-servers-without-using-docker-43kb</link>
      <guid>https://dev.to/woovi/resilient-nodejs-servers-without-using-docker-43kb</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Now you will learn how we create resilient services without interrupting the main SSH connection or without the need to create N SSH connections with N open terminals while developing our services in our remote development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Requirements&lt;/li&gt;
&lt;li&gt;What is PM2?&lt;/li&gt;
&lt;li&gt;Installing PM2&lt;/li&gt;
&lt;li&gt;Persisting Processes&lt;/li&gt;
&lt;li&gt;Check Processes&lt;/li&gt;
&lt;li&gt;In Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;NPM&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is PM2?
&lt;/h2&gt;

&lt;p&gt;PM2 is a daemon process manager that will help you manage and keep your application online 24/7&lt;/p&gt;

&lt;p&gt;The services running through it become resilient. A similar analogy is comparing PM2 with NGINX&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing PM2
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; pm2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Persisting Processes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Explanation: pm2 start &amp;lt;package-manager&amp;gt; --name &amp;lt;app-name&amp;gt; -- &amp;lt;script-name&amp;gt;&lt;/span&gt;
pm2 start pnpm &lt;span class="nt"&gt;--name&lt;/span&gt; woovi-front &lt;span class="nt"&gt;--&lt;/span&gt; woovi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your server is launched in daemon mode, meaning it runs as a detached background process. &lt;/p&gt;

&lt;p&gt;Under the hood, PM2 spawns a new process for your service that is independent of the initial terminal session. &lt;/p&gt;

&lt;p&gt;This decoupling ensures that the server continues to run even if you close the terminal, while PM2 monitors, logs, and automatically restarts the process if it encounters any issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check Processes
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;You can view the daemon processes that PM2 spawns for your services, and check the following information&lt;/p&gt;

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

&lt;p&gt;If the status is "online", your service already be up, then you can test using the command curl&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I already know that my service may be running on port 3000, you must change the port to your application's port&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# use this for test in your VPS&lt;/span&gt;
curl http://localhost:3000

&lt;span class="c"&gt;# or this, if want to test in the machine host&lt;/span&gt;
curl http://yourmachineip:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PM2 is powerful when it comes to process management it has many other commands like &lt;code&gt;pm2 delete&lt;/code&gt; to delete an unused daemon process, &lt;code&gt;pm2 restart&lt;/code&gt; to restart a process, and &lt;code&gt;pm2 stop&lt;/code&gt; to end a process execution&lt;/p&gt;

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

&lt;p&gt;Integrating PM2 into remote development environments is an effective strategy to ensure that your services or applications remain running continuously and stably so that you can move freely without worrying about tying up the main process of your SSH connection and ending up interrupting the service at some point.&lt;/p&gt;

</description>
      <category>node</category>
      <category>docker</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Woovi monorepos best practices</title>
      <dc:creator>Hállex da Silva Costa</dc:creator>
      <pubDate>Mon, 24 Feb 2025 15:04:11 +0000</pubDate>
      <link>https://dev.to/woovi/woovi-monorepos-best-practices-415l</link>
      <guid>https://dev.to/woovi/woovi-monorepos-best-practices-415l</guid>
      <description>&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Look the conflict between dependencies version&lt;/li&gt;
&lt;li&gt;Always update the packages remember of updates your codependencies&lt;/li&gt;
&lt;li&gt;Clear the cache&lt;/li&gt;
&lt;li&gt;
Change error also is progress
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Look at the conflict between the dependencies version
&lt;/h2&gt;

&lt;p&gt;This detail implies if any dependencies can be resolved correctly and if not have a version conflict.&lt;br&gt;
As the example we have the &lt;a href="https://styled-components.com" rel="noopener noreferrer"&gt;styled-components&lt;/a&gt; lib, it can have a problem with type Symbol reference where the library doesn´t find your properties of themes because, in your internal code, it uses the symbolObject which is a unique object that refers your set configs. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This rule is valid for any type of dependency like &lt;code&gt;react-relay, relay-compiler, style-components, react&lt;/code&gt; and so on.&lt;br&gt;
If you use &lt;code&gt;pnpm&lt;/code&gt; you can run the command &lt;code&gt;pnpm list &amp;lt;package-name&amp;gt; --recursive&lt;/code&gt; to help you find duplicate packages with different versions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Always update a package remember to update your codependencies
&lt;/h2&gt;

&lt;p&gt;Here I will use &lt;code&gt;relay-compiler&lt;/code&gt; as an example, if you update the project's relay version, ensure that the &lt;code&gt;react-relay&lt;/code&gt;, &lt;code&gt;babel&lt;/code&gt;, &lt;code&gt;swc&lt;/code&gt;, or in the general context, all relay plugins and your codependency this updates can prevent conflict of compatibility and unexpected bugs. &lt;br&gt;
Also remember to delete any artifact that may have been generated by an old version of some library you are using, such as the &lt;code&gt;__generated__&lt;/code&gt; folder of &lt;code&gt;relay-compiler&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clear the cache
&lt;/h2&gt;

&lt;p&gt;If some error is thrown on the screens and the value is undefined it should have some value and probably have a persistence of cache from older executions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Change the error also is a progress
&lt;/h2&gt;

&lt;p&gt;Sometimes you may get stuck on an error or bug, just following these other steps above may not solve the problem 100%, but it will probably change the error and this can be considered progress.&lt;/p&gt;

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

&lt;p&gt;Synchronizing codependencies and using tools like &lt;code&gt;pnpm list &amp;lt;package-name&amp;gt; --recursive&lt;/code&gt; helps identify incompatible versions while updating related packages ensures compatibility. Clearing caches, and removing old artifacts of relay-compiler can help get closer to the goal, and errors should be treated as progress steps toward resolution.&lt;/p&gt;

</description>
      <category>woovi</category>
      <category>programming</category>
      <category>development</category>
    </item>
  </channel>
</rss>
