<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arnaud Lefebvre, Author at Clever Cloud</title>
	<atom:link href="https://www.clever.cloud/blog/author/arnaud-lefebvreclever-cloud-com/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>From Code to Product</description>
	<lastBuildDate>Thu, 27 Nov 2025 14:50:09 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://cdn.clever-cloud.com/uploads/2023/03/cropped-cropped-favicon-32x32.png</url>
	<title>Arnaud Lefebvre, Author at Clever Cloud</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Migration Required for Buckets on Cellar C1 Cluster</title>
		<link>https://www.clever.cloud/blog/engineering/2022/01/19/migration-required-for-buckets-on-cellar-c1-cluster/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Wed, 19 Jan 2022 09:41:48 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[addons]]></category>
		<category><![CDATA[cellar]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[Support]]></category>
		<guid isPermaLink="false">https://www.clever-cloud.com/?p=5142</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="cellarupdate" decoding="async" fetchpriority="high" srcset="https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate.png 1400w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-1368x528.png 1368w" sizes="(max-width: 1400px) 100vw, 1400px" /></p><!-- wp:paragraph -->
<p><strong>tl;dr: </strong>On March 21th 2022 the Cellar C1 cluster will reach its end of life. So we ask you to perform a migration to a newer cluster Cellar, which will also improve performance. The C1 cluster did not accept new add-ons since the 20th January 2019.<br></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In fact, data need to be migrated from this old add-on to a new Cellar add-on. Newly created Cellar C2 add-ons come with various improvements&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>A better S3 protocol support (including the AWS V4&nbsp;signature)</li><li>Improved upload and download performances (x3 for upload, x2 for download)</li><li>Improved resilience and availability of your data (Data is now replicated across two datacenters more than 20km apart)</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3><strong>How to migrate my data?</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We can help you to migrate your data by syncing it directly on our side. To do that, reach the support and include in your message source and destination add-ons, including the buckets to migrate. The support team is here to help.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you wish to migrate on your side, or at least keep your buckets synchronized, we built a simple tool to help you:&nbsp;<a href="https://github.com/CleverCloud/cellar-c1-migration-tool" target="_blank" rel="noreferrer noopener">Cellar&nbsp;migration tool</a>.<br>You can run this tool as many times as you need. It will only synchronize objects that are different between the source and the destination buckets.<br>If you do not feel comfortable using it, you can also use the&nbsp;<code>s3cmd sync</code>&nbsp;command from the&nbsp;<a href="https://s3tools.org/s3cmd" target="_blank" rel="noreferrer noopener">s3cmd tool</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If your application handle it, we encourage you to upload new objects as soon as possible to the new bucket. Then when you need to query that object, your application can query both buckets (old and new) to get it. You can also store the complete URL to make this easier. This should help you transition from one bucket to another without downtime.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Please note that we can't make sure that the buckets names you use will be available on the destination cluster. If you have a name conflict, please contact us and we will work something out.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A few days before the deadline, we will have short service brown-outs to remind customers that the service is going to be shut down. Those brown-outs will be announced on our&nbsp;<a href="https://www.clevercloudstatus.com" target="_blank" rel="noreferrer noopener">status page</a>&nbsp;a few days before. Make sure to&nbsp;<a href="https://www.clevercloudstatus.com/subscribe" target="_blank" rel="noreferrer noopener">subscribe to Status Updates</a>&nbsp;to receive a notification.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3><strong>What will happen if I can't do the migration?</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If you can't do the migration or have any questions about it, we strongly recommend that you contact our support team via the console.<br>Before shutting down the cluster, we will backup your data and keep it for 6 months. Our support team will be able to provide you a download link or re-inject the data in a new bucket if you wish to recover it.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="cellarupdate" decoding="async" srcset="https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate.png 1400w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2022/01/cellarupdate-1368x528.png 1368w" sizes="(max-width: 1400px) 100vw, 1400px" /></p><!-- wp:paragraph -->
<p><strong>tl;dr: </strong>On March 21th 2022 the Cellar C1 cluster will reach its end of life. So we ask you to perform a migration to a newer cluster Cellar, which will also improve performance. The C1 cluster did not accept new add-ons since the 20th January 2019.<br></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In fact, data need to be migrated from this old add-on to a new Cellar add-on. Newly created Cellar C2 add-ons come with various improvements&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>A better S3 protocol support (including the AWS V4&nbsp;signature)</li><li>Improved upload and download performances (x3 for upload, x2 for download)</li><li>Improved resilience and availability of your data (Data is now replicated across two datacenters more than 20km apart)</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3><strong>How to migrate my data?</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We can help you to migrate your data by syncing it directly on our side. To do that, reach the support and include in your message source and destination add-ons, including the buckets to migrate. The support team is here to help.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you wish to migrate on your side, or at least keep your buckets synchronized, we built a simple tool to help you:&nbsp;<a href="https://github.com/CleverCloud/cellar-c1-migration-tool" target="_blank" rel="noreferrer noopener">Cellar&nbsp;migration tool</a>.<br>You can run this tool as many times as you need. It will only synchronize objects that are different between the source and the destination buckets.<br>If you do not feel comfortable using it, you can also use the&nbsp;<code>s3cmd sync</code>&nbsp;command from the&nbsp;<a href="https://s3tools.org/s3cmd" target="_blank" rel="noreferrer noopener">s3cmd tool</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If your application handle it, we encourage you to upload new objects as soon as possible to the new bucket. Then when you need to query that object, your application can query both buckets (old and new) to get it. You can also store the complete URL to make this easier. This should help you transition from one bucket to another without downtime.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Please note that we can't make sure that the buckets names you use will be available on the destination cluster. If you have a name conflict, please contact us and we will work something out.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A few days before the deadline, we will have short service brown-outs to remind customers that the service is going to be shut down. Those brown-outs will be announced on our&nbsp;<a href="https://www.clevercloudstatus.com" target="_blank" rel="noreferrer noopener">status page</a>&nbsp;a few days before. Make sure to&nbsp;<a href="https://www.clevercloudstatus.com/subscribe" target="_blank" rel="noreferrer noopener">subscribe to Status Updates</a>&nbsp;to receive a notification.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3><strong>What will happen if I can't do the migration?</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If you can't do the migration or have any questions about it, we strongly recommend that you contact our support team via the console.<br>Before shutting down the cluster, we will backup your data and keep it for 6 months. Our support team will be able to provide you a download link or re-inject the data in a new bucket if you wish to recover it.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing Jenkins integration for Clever Cloud</title>
		<link>https://www.clever.cloud/blog/features/2021/10/14/introducing-jenkins-integration-for-clever-cloud/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Thu, 14 Oct 2021 12:31:35 +0000</pubDate>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[CD]]></category>
		<category><![CDATA[CI]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[runners]]></category>
		<guid isPermaLink="false">https://www.clever-cloud.com/?p=3519</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/10/jenkins.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="jenkins" decoding="async" srcset="https://cdn.clever-cloud.com/uploads/2021/10/jenkins.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-1368x528.jpg 1368w" sizes="(max-width: 1400px) 100vw, 1400px" /></p>Today, we are proud to announce the release of our Jenkins add-on with a custom Clever Cloud integration!

Jenkins is an open source automation server which enables developers to build, test, and deploy their software.<span id="more-3519"></span> It facilitates continuous integration (CI) and continuous delivery (CD), is highly configurable and benefits from a huge community as well as many online resources.
<figure id="attachment_3691"><img title="Jenkins Dashboard on Clever Cloud" src="https://cdn.clever-cloud.com/uploads/2021/10/Screenshot-2021-09-30-at-19-37-38-Console-Clever-Cloud-1.png" alt="Jenkins Dashboard on Clever Cloud" />
<figcaption id="caption-attachment-3691" class="wp-caption-text">Jenkins Dashboard on Clever Cloud</figcaption></figure>
<h3>Clever Cloud applications to run your jobs</h3>
Customise your Jenkins with to the huge variety of available Jenkins plugins: you can install and update any plugin you need to customise your jobs in the best possible ways. We also provide our own custom plugin to manage the runners that will execute your jobs. It means that tasks won't be executed on the Jenkins controller instance but in dedicated virtual machines deployed on Clever Cloud infrastructure. This allows you to configure the Docker image to use with all the tools you need, and the size of the virtual machine that would suit your jobs. The minimum size is <strong>XS (1 vCPU, 2 GiB RAM)</strong> and the maximum is a <strong>3XL (16 vCPU, 32 GiB RAM).</strong> If you need bigger runner sizes for your jobs, let us know!

There are no limits in the number of jobs you can run, either in parallel or in total, you can start as many jobs as you need. Each job will only be billed for the time it really took, down to the second.
<h3>Enhance your Clever Cloud deployments workflow</h3>
Clever Cloud Jenkins add-ons can enhance your deployment workflow on Clever Cloud. For example, if you wish to automatically deploy your project once all tests are successful, you can configure your job to install our <a href="https://www.clever.cloud/developers/reference/clever-tools/getting_started/">CLI clever-tools</a> and then push your code to your Clever Cloud application.

Here is a Jenkinsfile example on how you could achieve this. It uses multiple stages to install clever-tools and start the deployment of your default application. Clever-tools will automatically pick up the secrets in the environment variables defined in <code>CLEVER_TOKEN</code> and <code>CLEVER_SECRET</code> to be authenticated. You will need to create two Jenkins credentials with actual tokens. Tokens can be easily retrieved on your local machine by looking in <code>~/.config/clever-cloud</code> on Linux and Mac OSX and <code>%APPDATA%/clever-cloud</code> on Windows.
<pre><code class="language-java">pipeline {
  environment {
    CLEVER_TOKEN = credentials('CLEVER_TOKEN')
    CLEVER_SECRET = credentials('CLEVER_SECRET')
  }

  stage('clever-tools') {
      steps {
        script {
          sh 'npm install -g clever-tools'
       }
     }
  }

  stage('tests') {
    // Your tests steps
  }

  stage('deployment') {
    steps {
      script {
        // Deploy the application
        // A .clever.json file must exists in the repository
        sh 'clever deploy'
      }
    }
  }
}</code></pre>
You can also use Jenkins's own environment variables to customise your build. You can get a list of those variables by appending <code>/env-vars.html</code> at the end of your add-on's URL. Using those, you could decide whether to deploy on your staging or production application based on the branch name.
<h3>Built with the classic features you love</h3>
As with any other products we release, Jenkins add-ons have <strong>automatic backups</strong>, <strong>metrics</strong>, <strong>logs</strong> and <strong>encryption at rest</strong>. You will also be able to use Clever Cloud <strong>Single Sign-On</strong> to connect to your Jenkins add-on, meaning that every organization member can access the Jenkins instance under its own account.

You can find more information about how to configure Jenkins <a href="https://www.clever.cloud/developers/doc/addons/jenkins/">in our documentation</a>.
<h3>Pricing</h3>
<script type="module" src="https://components.clever-cloud.com/load.js?version=7&amp;lang=en&amp;components=cc-pricing-product.smart-addon,cc-pricing-product.smart-runtime"></script>

You will find below the pricing of both <strong>Jenkins</strong> and <strong>Jenkins Runners</strong>. The <a href="https://www.clever.cloud/pricing#https://www.clever.cloud/pricing#jenkins">pricing page</a> is here to help you estimate various configurations.
<div>Jenkins is the managed service on which you will configure your jobs.
<div></div>
</div>
<div>The instances running your tasks, known as Jenkins Runners, billed on a per-second basis:
<div></div>
</div>
<h3 id="whats-next">What's next?</h3>
We plan to provide an even better integration with Jenkins. Our next goals are to add multiple runner retention policies (having successive jobs on the same runner) in addition to improve boot time of runners. We will also open source our Jenkins plugin and upstream it to the Jenkins plugins repository. That way, we will bring the ability to start your own Clever Cloud Jenkins runners from your self-hosted Jenkins instance.]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/10/jenkins.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="jenkins" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/10/jenkins.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/10/jenkins-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p>Today, we are proud to announce the release of our Jenkins add-on with a custom Clever Cloud integration!

Jenkins is an open source automation server which enables developers to build, test, and deploy their software.<span id="more-3519"></span> It facilitates continuous integration (CI) and continuous delivery (CD), is highly configurable and benefits from a huge community as well as many online resources.
<figure id="attachment_3691"><img title="Jenkins Dashboard on Clever Cloud" src="https://cdn.clever-cloud.com/uploads/2021/10/Screenshot-2021-09-30-at-19-37-38-Console-Clever-Cloud-1.png" alt="Jenkins Dashboard on Clever Cloud" />
<figcaption id="caption-attachment-3691" class="wp-caption-text">Jenkins Dashboard on Clever Cloud</figcaption></figure>
<h3>Clever Cloud applications to run your jobs</h3>
Customise your Jenkins with to the huge variety of available Jenkins plugins: you can install and update any plugin you need to customise your jobs in the best possible ways. We also provide our own custom plugin to manage the runners that will execute your jobs. It means that tasks won't be executed on the Jenkins controller instance but in dedicated virtual machines deployed on Clever Cloud infrastructure. This allows you to configure the Docker image to use with all the tools you need, and the size of the virtual machine that would suit your jobs. The minimum size is <strong>XS (1 vCPU, 2 GiB RAM)</strong> and the maximum is a <strong>3XL (16 vCPU, 32 GiB RAM).</strong> If you need bigger runner sizes for your jobs, let us know!

There are no limits in the number of jobs you can run, either in parallel or in total, you can start as many jobs as you need. Each job will only be billed for the time it really took, down to the second.
<h3>Enhance your Clever Cloud deployments workflow</h3>
Clever Cloud Jenkins add-ons can enhance your deployment workflow on Clever Cloud. For example, if you wish to automatically deploy your project once all tests are successful, you can configure your job to install our <a href="https://www.clever.cloud/developers/reference/clever-tools/getting_started/">CLI clever-tools</a> and then push your code to your Clever Cloud application.

Here is a Jenkinsfile example on how you could achieve this. It uses multiple stages to install clever-tools and start the deployment of your default application. Clever-tools will automatically pick up the secrets in the environment variables defined in <code>CLEVER_TOKEN</code> and <code>CLEVER_SECRET</code> to be authenticated. You will need to create two Jenkins credentials with actual tokens. Tokens can be easily retrieved on your local machine by looking in <code>~/.config/clever-cloud</code> on Linux and Mac OSX and <code>%APPDATA%/clever-cloud</code> on Windows.
<pre><code class="language-java">pipeline {
  environment {
    CLEVER_TOKEN = credentials('CLEVER_TOKEN')
    CLEVER_SECRET = credentials('CLEVER_SECRET')
  }

  stage('clever-tools') {
      steps {
        script {
          sh 'npm install -g clever-tools'
       }
     }
  }

  stage('tests') {
    // Your tests steps
  }

  stage('deployment') {
    steps {
      script {
        // Deploy the application
        // A .clever.json file must exists in the repository
        sh 'clever deploy'
      }
    }
  }
}</code></pre>
You can also use Jenkins's own environment variables to customise your build. You can get a list of those variables by appending <code>/env-vars.html</code> at the end of your add-on's URL. Using those, you could decide whether to deploy on your staging or production application based on the branch name.
<h3>Built with the classic features you love</h3>
As with any other products we release, Jenkins add-ons have <strong>automatic backups</strong>, <strong>metrics</strong>, <strong>logs</strong> and <strong>encryption at rest</strong>. You will also be able to use Clever Cloud <strong>Single Sign-On</strong> to connect to your Jenkins add-on, meaning that every organization member can access the Jenkins instance under its own account.

You can find more information about how to configure Jenkins <a href="https://www.clever.cloud/developers/doc/addons/jenkins/">in our documentation</a>.
<h3>Pricing</h3>
<script type="module" src="https://components.clever-cloud.com/load.js?version=7&amp;lang=en&amp;components=cc-pricing-product.smart-addon,cc-pricing-product.smart-runtime"></script>

You will find below the pricing of both <strong>Jenkins</strong> and <strong>Jenkins Runners</strong>. The <a href="https://www.clever.cloud/pricing#https://www.clever.cloud/pricing#jenkins">pricing page</a> is here to help you estimate various configurations.
<div>Jenkins is the managed service on which you will configure your jobs.
<div></div>
</div>
<div>The instances running your tasks, known as Jenkins Runners, billed on a per-second basis:
<div></div>
</div>
<h3 id="whats-next">What's next?</h3>
We plan to provide an even better integration with Jenkins. Our next goals are to add multiple runner retention policies (having successive jobs on the same runner) in addition to improve boot time of runners. We will also open source our Jenkins plugin and upstream it to the Jenkins plugins repository. That way, we will bring the ability to start your own Clever Cloud Jenkins runners from your self-hosted Jenkins instance.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Auto managed connection pooling for MySQL add-ons</title>
		<link>https://www.clever.cloud/blog/features/2021/05/05/proxysql-release/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Wed, 05 May 2021 13:44:00 +0000</pubDate>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[connection]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pool]]></category>
		<category><![CDATA[proxysql]]></category>
		<category><![CDATA[release]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2021/05/05/proxysql-release/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="mysql connection pooling 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p>Starting today, we provide <a href="https://www.proxysql.com/">ProxySQL</a>, a MySQL proxy, on all of our managed instances for out of the box connection pooling to your MySQL add-ons.

<span id="more-2987"></span>

ProxySQL acts as a local proxy between your application and your MySQL add-on. Your application will be able to connect to ProxySQL which will then forward your requests to the linked MySQL add-on.
<blockquote>A connection pool will cache your database connections and keep them open for future requests</blockquote>
Thanks to the connection pool, your database connections will be cached and your application won't have to wait for the connection to be established to your add-on. This can lead to faster response time when a lot of requests are executed. It also solves the problem of too many opened connections to the database. You will be able to do as many queries as you need without getting a "user max connection exceeded" error. ProxySQL will queue all the requests until a connection slot is available.

<em>Sidenote: ProxySQL is not available on Docker instances as we do not manage your Dockerfile.</em>
<h2 id="configure-proxysql">Configure ProxySQL</h2>
To enable ProxySQL for your application, you first need to have a MySQL add-on linked to your application. You then have to set the <code>CC_ENABLE_MYSQL_PROXYSQL=true</code> environment variable.

Once enabled, the <code>CC_MYSQL_PROXYSQL_SOCKET_PATH</code> environment variable will be injected during the deployment phase. It provides a <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix Domain Socket</a> path to use to connect to ProxySQL.

There are also two other environment variables you can set to configure ProxySQL to match your needs:
<ul>
 	<li><code>CC_MYSQL_PROXYSQL_USE_TLS</code>: A boolean (<code>true</code> or <code>false</code>) to enable <code>TLS</code> between ProxySQL and your MySQL add-on. Defaults to <code>true</code>.</li>
 	<li><code>CC_MYSQL_PROXYSQL_MAX_CONNECTIONS</code>: An integer which defines how many maximum connections ProxySQL will open to your MySQL add-on. Defaults to <code>10</code>. You can refer to <a href="https://www.clever.cloud/developers/deploy/addon/mysql/proxysql#scalability">our ProxySQL documentation</a> to learn more about how you should compute the maximum connection value when auto scalability is involved.</li>
</ul>
<h3 id="examples">Examples</h3>
Here are some examples on how to connect to ProxySQL using various languages:
<h4 id="php-using-pdo">PHP using PDO</h4>
Using <a href="https://www.php.net/manual/en/ref.pdo-mysql.connection.php">PDO</a>, you have to use the <code>unix_socket</code> option in your DSN:
<pre><code class="language-php">&lt;?php
// This variable is injected during the deployment
$socket = getenv("CC_MYSQL_PROXYSQL_SOCKET_PATH");
// Get the database name from the environment
$db = getenv("MYSQL_ADDON_DB");
// Get the database user from the environment
$user = getenv("MYSQL_ADDON_USER");
// Get the database password from the environment
$pass = getenv("MYSQL_ADDON_PASSWORD");
$dsn = "mysql:unix_socket=$socket;dbname=$db";
try {
  $pdo = new PDO($dsn, $user, $pass);
} catch (PDOException $e) {
  throw new PDOException($e-&gt;getMessage(), (int)$e-&gt;getCode());
}
</code></pre>
<h4 id="wordpress">Wordpress</h4>
For Wordpress, you can change the <code>DB_HOST</code> variable in your <code>wp-config.php</code>:
<pre><code class="language-php">// To connect using a unix socket, the syntax is: `localhost:/path/to/socket`
define('DB_HOST', "localhost:" . getenv("CC_MYSQL_PROXYSQL_SOCKET_PATH") );
// Get the database user from the environment
define('DB_USER', getenv("MYSQL_ADDON_USER"));
// Get the database password from the environment
define('DB_PASSWORD', getenv("MYSQL_ADDON_PASSWORD"));
// Get the database name from the environment
define('DB_NAME', getenv("MYSQL_ADDON_DB"));
</code></pre>
<h4 id="nodejs">Node.js</h4>
On Node.js, using the <code>mysql</code> npm package, you have to set the <code>socketPath</code> property :
<pre><code class="language-javascript">const mysql      = require('mysql');
const connection = mysql.createConnection({
  // Get ProxySQL unix domain socket path from the environment
  socketPath : process.env["CC_MYSQL_PROXYSQL_SOCKET_PATH"],
  // Get the database user from the environment
  user       : process.env["MYSQL_ADDON_USER"],
  // Get the database password from the environment
  password   : process.env["MYSQL_ADDON_PASSWORD"],
  // Get the database name from the environment
  database   : process.env["MYSQL_ADDON_DB"]
});
connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }

  console.log('connected as id ' + connection.threadId);
});
</code></pre>
<h3 id="metrics">Metrics</h3>
ProxySQL exposes some metrics using the Prometheus format. Those metrics are automatically collected into our Metrics system and can be accessed in the <a href="https://www.clever.cloud/developers/administrate/metrics/overview/#display-metrics">Advanced Metrics</a> view of your application. This allows you to track how effective your connection pool is and how many request your instances are making. You can get the list of metrics we expose in <a href="https://www.clever.cloud/developers/deploy/addon/mysql/proxysql#metrics">our ProxySQL documentation</a>
<h3 id="documentation">Documentation</h3>
You can find more information about this feature in <a href="https://www.clever.cloud/developers/deploy/addon/mysql/proxysql">our ProxySQL documentation</a>.
<h3 id="conclusion">Conclusion</h3>
Using ProxySQL may help decrease the response time of your application if it does a lot of SQL requests. We'd love to hear from you on how ProxySQL's connection pool affected your applications performances.]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="mysql connection pooling 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/mysql-connection-pooling-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p>Starting today, we provide <a href="https://www.proxysql.com/">ProxySQL</a>, a MySQL proxy, on all of our managed instances for out of the box connection pooling to your MySQL add-ons.

<span id="more-2987"></span>

ProxySQL acts as a local proxy between your application and your MySQL add-on. Your application will be able to connect to ProxySQL which will then forward your requests to the linked MySQL add-on.
<blockquote>A connection pool will cache your database connections and keep them open for future requests</blockquote>
Thanks to the connection pool, your database connections will be cached and your application won't have to wait for the connection to be established to your add-on. This can lead to faster response time when a lot of requests are executed. It also solves the problem of too many opened connections to the database. You will be able to do as many queries as you need without getting a "user max connection exceeded" error. ProxySQL will queue all the requests until a connection slot is available.

<em>Sidenote: ProxySQL is not available on Docker instances as we do not manage your Dockerfile.</em>
<h2 id="configure-proxysql">Configure ProxySQL</h2>
To enable ProxySQL for your application, you first need to have a MySQL add-on linked to your application. You then have to set the <code>CC_ENABLE_MYSQL_PROXYSQL=true</code> environment variable.

Once enabled, the <code>CC_MYSQL_PROXYSQL_SOCKET_PATH</code> environment variable will be injected during the deployment phase. It provides a <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix Domain Socket</a> path to use to connect to ProxySQL.

There are also two other environment variables you can set to configure ProxySQL to match your needs:
<ul>
 	<li><code>CC_MYSQL_PROXYSQL_USE_TLS</code>: A boolean (<code>true</code> or <code>false</code>) to enable <code>TLS</code> between ProxySQL and your MySQL add-on. Defaults to <code>true</code>.</li>
 	<li><code>CC_MYSQL_PROXYSQL_MAX_CONNECTIONS</code>: An integer which defines how many maximum connections ProxySQL will open to your MySQL add-on. Defaults to <code>10</code>. You can refer to <a href="https://www.clever.cloud/developers/deploy/addon/mysql/proxysql#scalability">our ProxySQL documentation</a> to learn more about how you should compute the maximum connection value when auto scalability is involved.</li>
</ul>
<h3 id="examples">Examples</h3>
Here are some examples on how to connect to ProxySQL using various languages:
<h4 id="php-using-pdo">PHP using PDO</h4>
Using <a href="https://www.php.net/manual/en/ref.pdo-mysql.connection.php">PDO</a>, you have to use the <code>unix_socket</code> option in your DSN:
<pre><code class="language-php">&lt;?php
// This variable is injected during the deployment
$socket = getenv("CC_MYSQL_PROXYSQL_SOCKET_PATH");
// Get the database name from the environment
$db = getenv("MYSQL_ADDON_DB");
// Get the database user from the environment
$user = getenv("MYSQL_ADDON_USER");
// Get the database password from the environment
$pass = getenv("MYSQL_ADDON_PASSWORD");
$dsn = "mysql:unix_socket=$socket;dbname=$db";
try {
  $pdo = new PDO($dsn, $user, $pass);
} catch (PDOException $e) {
  throw new PDOException($e-&gt;getMessage(), (int)$e-&gt;getCode());
}
</code></pre>
<h4 id="wordpress">Wordpress</h4>
For Wordpress, you can change the <code>DB_HOST</code> variable in your <code>wp-config.php</code>:
<pre><code class="language-php">// To connect using a unix socket, the syntax is: `localhost:/path/to/socket`
define('DB_HOST', "localhost:" . getenv("CC_MYSQL_PROXYSQL_SOCKET_PATH") );
// Get the database user from the environment
define('DB_USER', getenv("MYSQL_ADDON_USER"));
// Get the database password from the environment
define('DB_PASSWORD', getenv("MYSQL_ADDON_PASSWORD"));
// Get the database name from the environment
define('DB_NAME', getenv("MYSQL_ADDON_DB"));
</code></pre>
<h4 id="nodejs">Node.js</h4>
On Node.js, using the <code>mysql</code> npm package, you have to set the <code>socketPath</code> property :
<pre><code class="language-javascript">const mysql      = require('mysql');
const connection = mysql.createConnection({
  // Get ProxySQL unix domain socket path from the environment
  socketPath : process.env["CC_MYSQL_PROXYSQL_SOCKET_PATH"],
  // Get the database user from the environment
  user       : process.env["MYSQL_ADDON_USER"],
  // Get the database password from the environment
  password   : process.env["MYSQL_ADDON_PASSWORD"],
  // Get the database name from the environment
  database   : process.env["MYSQL_ADDON_DB"]
});
connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }

  console.log('connected as id ' + connection.threadId);
});
</code></pre>
<h3 id="metrics">Metrics</h3>
ProxySQL exposes some metrics using the Prometheus format. Those metrics are automatically collected into our Metrics system and can be accessed in the <a href="https://www.clever.cloud/developers/administrate/metrics/overview/#display-metrics">Advanced Metrics</a> view of your application. This allows you to track how effective your connection pool is and how many request your instances are making. You can get the list of metrics we expose in <a href="https://www.clever.cloud/developers/deploy/addon/mysql/proxysql#metrics">our ProxySQL documentation</a>
<h3 id="documentation">Documentation</h3>
You can find more information about this feature in <a href="https://www.clever.cloud/developers/deploy/addon/mysql/proxysql">our ProxySQL documentation</a>.
<h3 id="conclusion">Conclusion</h3>
Using ProxySQL may help decrease the response time of your application if it does a lot of SQL requests. We'd love to hear from you on how ProxySQL's connection pool affected your applications performances.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Setup your Private Parse Server in Production</title>
		<link>https://www.clever.cloud/blog/features/2016/02/02/setup-your-private-parse-server-in-production/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Tue, 02 Feb 2016 15:32:00 +0000</pubDate>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[Nodejs]]></category>
		<category><![CDATA[parse]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2016/02/02/setup-your-private-parse-server-in-production/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/parse-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="parse 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/parse-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><a href="https://parse.com">Parse</a> is a BaaS (Backend as a Service) for mobile applications. They provide a suite of cloud services for developers that are tightly coupled with SDKs for all the major client platforms.

Unfortunately, they are closing their services to new subscriptions and definitely on January 28, 2017. While this is bad news, they open-sourced their <a href="https://github.com/ParsePlatform/parse-server">backend</a> so that the community can continue the project.

<span id="more-2864"></span>

If you are already familiar with Parse, you will be happy to learn that the backend is written in Node.js and uses MongoDB as a database which are both easy to deploy on Clever Cloud.
<h2 id="parse-server">Parse Server</h2>
They published an example of a basic application using their backend <a href="https://github.com/ParsePlatform/parse-server-example">on Github</a>.
<h2 id="deploy-on-clever-cloud">Deploy on Clever Cloud</h2>
<ol>
 	<li>First, you need to clone this repository (or use an existing one) and modify the Parse Server instanciation:
<pre><code class="language-javascript">var api = new ParseServer({
  databaseURI: process.env.MONGODB_ADDON_URI, // Use the MongoDB URI
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.PARSE_APPID, // Use environment variable to set the APP_ID
  masterKey: process.env.PARSE_MASTERKEY // Use environment variable to set the PARSE_MASTERKEY
});
</code></pre>
</li>
 	<li>Open the <a href="https://console.clever-cloud.com">Clever Cloud Console</a>, create an account if you don't have one yet</li>
 	<li>Create a <a href="https://www.clever.cloud/developers/api/howto/">Node.js application and a MongoDB addon</a></li>
 	<li>Add these two <a href="https://www.clever.cloud/developers/doc/administrate/">environment variables</a>: <code>PARSE_APPID: &lt;parseAppID&gt;</code>, <code>PARSE_MASTERKEY: &lt;parseMasterKey&gt;</code></li>
 	<li>Follow the instructions about adding the remote to your local git repository</li>
 	<li>Deploy it: <code>git push clever master</code> and head to your application's logs</li>
</ol>
From there you can setup a custom domain name and start using it as you would on Parse!

Happy mobile development!]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/parse-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="parse 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/parse-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/parse-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><a href="https://parse.com">Parse</a> is a BaaS (Backend as a Service) for mobile applications. They provide a suite of cloud services for developers that are tightly coupled with SDKs for all the major client platforms.

Unfortunately, they are closing their services to new subscriptions and definitely on January 28, 2017. While this is bad news, they open-sourced their <a href="https://github.com/ParsePlatform/parse-server">backend</a> so that the community can continue the project.

<span id="more-2864"></span>

If you are already familiar with Parse, you will be happy to learn that the backend is written in Node.js and uses MongoDB as a database which are both easy to deploy on Clever Cloud.
<h2 id="parse-server">Parse Server</h2>
They published an example of a basic application using their backend <a href="https://github.com/ParsePlatform/parse-server-example">on Github</a>.
<h2 id="deploy-on-clever-cloud">Deploy on Clever Cloud</h2>
<ol>
 	<li>First, you need to clone this repository (or use an existing one) and modify the Parse Server instanciation:
<pre><code class="language-javascript">var api = new ParseServer({
  databaseURI: process.env.MONGODB_ADDON_URI, // Use the MongoDB URI
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.PARSE_APPID, // Use environment variable to set the APP_ID
  masterKey: process.env.PARSE_MASTERKEY // Use environment variable to set the PARSE_MASTERKEY
});
</code></pre>
</li>
 	<li>Open the <a href="https://console.clever-cloud.com">Clever Cloud Console</a>, create an account if you don't have one yet</li>
 	<li>Create a <a href="https://www.clever.cloud/developers/api/howto/">Node.js application and a MongoDB addon</a></li>
 	<li>Add these two <a href="https://www.clever.cloud/developers/doc/administrate/">environment variables</a>: <code>PARSE_APPID: &lt;parseAppID&gt;</code>, <code>PARSE_MASTERKEY: &lt;parseMasterKey&gt;</code></li>
 	<li>Follow the instructions about adding the remote to your local git repository</li>
 	<li>Deploy it: <code>git push clever master</code> and head to your application's logs</li>
</ol>
From there you can setup a custom domain name and start using it as you would on Parse!

Happy mobile development!]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Speeding the Console Up With the Service Worker API</title>
		<link>https://www.clever.cloud/blog/engineering/2015/12/15/speeding-up-the-console-with-service-worker/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Tue, 15 Dec 2015 15:52:00 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[ES6]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[service workers]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2015/12/15/speeding-up-the-console-with-service-worker/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="service workers 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>You may have noticed major updates on the Clever Cloud Console these last weeks. Along with the quick search feature, keyboard shortcuts and a new UI, we introduced the use of service workers to reduce the load time of the Console.</p>
<span id="more-2804"></span>

<h2 id="service-workers-you-said-surely-you-mean-web-workers-right">Service workers you said? Surely you mean Web Workers, right?</h2>
<p>No! Service workers are scripts which are run by your browser, in the background. They are completely separated from the web pages of your site and have multiple uses. You can use them for HTTPS proxying, push notifications, or even background syncing.</p>
<p>Today, we will cover HTTPS proxying.</p>
<h2 id="the-console-should-load-faster">The Console should load faster</h2>
<p>When you load the <a href="https://console.clever-cloud.com">Clever Cloud Console</a>, we need to fetch data (the user, its organisations / apps / addons…) to bootstrap the whole application. If you have a lot of applications / belong to a lot of organisations, this may take a while, up to several seconds (&quot;a lot&quot; can mean ~200 apps for some of our<a href="https://twitter.com/FGRibreau">users</a>). This data isn&#39;t updated a lot. Most of our customers are using the Console to look at the logs or configure their applications. So it needs to be fast for them to access / set the information they want.</p>
<p>Here come the service workers. They can cache the response of any HTTPS request that is emitted from your application (which can be used to build offline apps). What we did is that any huge XHR request done when the Console is loading is now served from the cache if it exists.</p>
<h2 id="how-does-it-work">How does it work?</h2>
<ul>
<li>These new APIs (Service Workers, Cache API, Fetch API) are heavily using <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">ES6 Promises</a>, you should be familiar with them</li>
<li>Incidentally, you can use ES6 because browsers that support service-workers are also implementing mainstream ES6 features</li>
<li>You need to use a recent browser: Chrome 42+, Firefox 44+</li>
<li>Service Workers are HTTPS only, they won&#39;t work on HTTP requests. Chrome will allow <a href="http://localhost">http://localhost</a> as a secure origin though.</li>
</ul>
<h2 id="how-to-debug">How to debug</h2>
<ul>
<li>You can check &quot;Enable Service Workers over HTTP (when toolbox is open)&quot; on Firefox Devtools to use service workers on any HTTP request.</li>
<li>Chrome will only allow localhost or HTTPS urls. Good thing that HTTPS is available on *.cleverapps.io.</li>
<li>Firefox and Chrome have an endpoint to list service workers: Firefox: <code>about:serviceworkers</code>, Chrome: <code>chrome://inspect/#service-workers</code></li>
<li>You can use regular <code>console.log()</code> to log from the service worker.</li>
<li>You won&#39;t be able to see intercepted requests in the Network panel of Firefox (as of Firefox 45.0a1).</li>
</ul>
<h2 id="the-code">The code</h2>
<p>First, we need to setup our service worker and ask the browser to register it (in your existing javascript application):</p>
<pre><code class="language-javascript">  navigator
    .serviceWorker
    .register(&#39;/service-worker.js&#39;)
    .then(navigator.serviceWorker.ready)
    .then(registration =&gt; {
      console.log(&#39;Server worker has been registered&#39;);
    });
</code></pre>
<p>You don&#39;t have to worry about multiple registrations: if a service worker has already been registered, the browser will simply ignore it.</p>
<p>Once this is done, we have to create a service-worker.js file. Service Workers are event based. Two events will be useful in our case: <code>install</code> and <code>fetch</code>. <code>install</code> will allow us to initialize our service worker (like pre-caching assets we haven&#39;t already loaded). <code>fetch</code> will be triggered each time a request is intercepted for the current scope.</p>
<p>We will use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache">Cache API</a> to cache requests / responses.</p>
<pre><code class="language-javascript">&#39;use strict&#39;;

const CACHE_URLS = [
  &quot;/img/img1.png&quot;,
  &quot;/img/img2.png&quot;,
  &quot;/users/me&quot;
];

const CACHE_NAME = &quot;cc-cache-test&quot;;

self.addEventListener(&#39;install&#39;, event =&gt; {
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then(cache =&gt;{
        cache.addAll(CACHE_URLS);
      })
      .catch(e =&gt; console.error(&quot;Couldn&#39;t install the service worker, reason:&quot;, e));
  );
});

self.addEventListener(&quot;fetch&quot;, event =&gt; {});
</code></pre>
<p>Here, during the installation step, the service worker will download and cache the CACHE_URLS urls even before the user requests them. Now, we need to tell our SW to use the cache whenever we have a cached version of the request or to fetch it if we don&#39;t. We can use the great HTML5 <a href="https://developer.mozilla.org/en/docs/Web/API/Fetch_API">Fetch API</a>:</p>
<pre><code class="language-javascript">self.addEventListener(&quot;fetch&quot;, event =&gt; {
  event.respondWith(
    caches.open(CACHE_NAME)
      .then(cache =&gt; cache.match(event.request))
      .then(response =&gt; {
        if(response){
          return Promise.resolve(response);
        } else{
          return fetch(event.request).then(res =&gt; {
            if(res &amp;&amp; res.status === 200){
              caches.open(CACHE_NAME)
                .then(cache =&gt; {
                  cache.put(event.request, res);
                });
            }
            return res.clone();
          });
        }
      })
  );
});
</code></pre>
<p>What we are doing is to open the cache and then try to match the current request. If we have a match, we return the response associated to the request. If we don&#39;t, we fetch the request, check its response code and save it into the cache if it succeeded. Next time, it will load faster!</p>
<p>Note that we have to use <code>res.clone();</code>. This is because the response is a stream which can be read only once. Here, we want to store its data into the cache AND return the same data to the browser. This won&#39;t work unless we <code>.clone()</code> it first.</p>
<p>Now, our service worker is ready to be used.</p>
<h2 id="sounds-perfect-but">Sounds perfect but…</h2>
<p>A major drawback is that you need a quite recent browser and these API may differ between browsers. At the time of writing, this won&#39;t work on Safari (any version), Firefox stable (aurora/dev has some support), Opera, Internet Explorer (Edge does support some features). You will have to handle these incompatibilities yourself.</p>
<p>But, even if service workers are not yet supported by all browsers, your application will still be able to run in a normal way. Only proxying and cache features will be affected, requests will be done as they were before. This is completely backwards compatible.</p>
<h2 id="how-do-we-use-it-at-clever-cloud">How do we use it at Clever Cloud</h2>
<p>We can&#39;t store all of the data or cache invalidation will be a mess to handle. Instead, we only store a few defined requests. When we load the Console, we use the cache, then wipe and update it in the background. The user can use the Console with quite fresh data and the UI will be updated as soon as we have the new one.</p>
<p>This feature allowed us to speed up the initial load of the Console, going well under 1 second if the cache exists. In a near future, we could also use service workers with the Notifications API to display application deployments&#39;s state even when the Console is not open in your browser.</p>
<h2 id="more-reading">More reading</h2>
<p>To learn about service workers, I used a few links:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API">Service Workers</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache">Cache API</a></li>
<li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">ES6 Promises</a></li>
<li><a href="http://www.html5rocks.com/en/tutorials/service-worker/introduction/">HTML5 rocks</a> (may be a little out of date but still accurate and well explained)</li>
<li></li>
</ul>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="service workers 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/service-workers-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>You may have noticed major updates on the Clever Cloud Console these last weeks. Along with the quick search feature, keyboard shortcuts and a new UI, we introduced the use of service workers to reduce the load time of the Console.</p>
<span id="more-2804"></span>

<h2 id="service-workers-you-said-surely-you-mean-web-workers-right">Service workers you said? Surely you mean Web Workers, right?</h2>
<p>No! Service workers are scripts which are run by your browser, in the background. They are completely separated from the web pages of your site and have multiple uses. You can use them for HTTPS proxying, push notifications, or even background syncing.</p>
<p>Today, we will cover HTTPS proxying.</p>
<h2 id="the-console-should-load-faster">The Console should load faster</h2>
<p>When you load the <a href="https://console.clever-cloud.com">Clever Cloud Console</a>, we need to fetch data (the user, its organisations / apps / addons…) to bootstrap the whole application. If you have a lot of applications / belong to a lot of organisations, this may take a while, up to several seconds (&quot;a lot&quot; can mean ~200 apps for some of our<a href="https://twitter.com/FGRibreau">users</a>). This data isn&#39;t updated a lot. Most of our customers are using the Console to look at the logs or configure their applications. So it needs to be fast for them to access / set the information they want.</p>
<p>Here come the service workers. They can cache the response of any HTTPS request that is emitted from your application (which can be used to build offline apps). What we did is that any huge XHR request done when the Console is loading is now served from the cache if it exists.</p>
<h2 id="how-does-it-work">How does it work?</h2>
<ul>
<li>These new APIs (Service Workers, Cache API, Fetch API) are heavily using <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">ES6 Promises</a>, you should be familiar with them</li>
<li>Incidentally, you can use ES6 because browsers that support service-workers are also implementing mainstream ES6 features</li>
<li>You need to use a recent browser: Chrome 42+, Firefox 44+</li>
<li>Service Workers are HTTPS only, they won&#39;t work on HTTP requests. Chrome will allow <a href="http://localhost">http://localhost</a> as a secure origin though.</li>
</ul>
<h2 id="how-to-debug">How to debug</h2>
<ul>
<li>You can check &quot;Enable Service Workers over HTTP (when toolbox is open)&quot; on Firefox Devtools to use service workers on any HTTP request.</li>
<li>Chrome will only allow localhost or HTTPS urls. Good thing that HTTPS is available on *.cleverapps.io.</li>
<li>Firefox and Chrome have an endpoint to list service workers: Firefox: <code>about:serviceworkers</code>, Chrome: <code>chrome://inspect/#service-workers</code></li>
<li>You can use regular <code>console.log()</code> to log from the service worker.</li>
<li>You won&#39;t be able to see intercepted requests in the Network panel of Firefox (as of Firefox 45.0a1).</li>
</ul>
<h2 id="the-code">The code</h2>
<p>First, we need to setup our service worker and ask the browser to register it (in your existing javascript application):</p>
<pre><code class="language-javascript">  navigator
    .serviceWorker
    .register(&#39;/service-worker.js&#39;)
    .then(navigator.serviceWorker.ready)
    .then(registration =&gt; {
      console.log(&#39;Server worker has been registered&#39;);
    });
</code></pre>
<p>You don&#39;t have to worry about multiple registrations: if a service worker has already been registered, the browser will simply ignore it.</p>
<p>Once this is done, we have to create a service-worker.js file. Service Workers are event based. Two events will be useful in our case: <code>install</code> and <code>fetch</code>. <code>install</code> will allow us to initialize our service worker (like pre-caching assets we haven&#39;t already loaded). <code>fetch</code> will be triggered each time a request is intercepted for the current scope.</p>
<p>We will use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache">Cache API</a> to cache requests / responses.</p>
<pre><code class="language-javascript">&#39;use strict&#39;;

const CACHE_URLS = [
  &quot;/img/img1.png&quot;,
  &quot;/img/img2.png&quot;,
  &quot;/users/me&quot;
];

const CACHE_NAME = &quot;cc-cache-test&quot;;

self.addEventListener(&#39;install&#39;, event =&gt; {
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then(cache =&gt;{
        cache.addAll(CACHE_URLS);
      })
      .catch(e =&gt; console.error(&quot;Couldn&#39;t install the service worker, reason:&quot;, e));
  );
});

self.addEventListener(&quot;fetch&quot;, event =&gt; {});
</code></pre>
<p>Here, during the installation step, the service worker will download and cache the CACHE_URLS urls even before the user requests them. Now, we need to tell our SW to use the cache whenever we have a cached version of the request or to fetch it if we don&#39;t. We can use the great HTML5 <a href="https://developer.mozilla.org/en/docs/Web/API/Fetch_API">Fetch API</a>:</p>
<pre><code class="language-javascript">self.addEventListener(&quot;fetch&quot;, event =&gt; {
  event.respondWith(
    caches.open(CACHE_NAME)
      .then(cache =&gt; cache.match(event.request))
      .then(response =&gt; {
        if(response){
          return Promise.resolve(response);
        } else{
          return fetch(event.request).then(res =&gt; {
            if(res &amp;&amp; res.status === 200){
              caches.open(CACHE_NAME)
                .then(cache =&gt; {
                  cache.put(event.request, res);
                });
            }
            return res.clone();
          });
        }
      })
  );
});
</code></pre>
<p>What we are doing is to open the cache and then try to match the current request. If we have a match, we return the response associated to the request. If we don&#39;t, we fetch the request, check its response code and save it into the cache if it succeeded. Next time, it will load faster!</p>
<p>Note that we have to use <code>res.clone();</code>. This is because the response is a stream which can be read only once. Here, we want to store its data into the cache AND return the same data to the browser. This won&#39;t work unless we <code>.clone()</code> it first.</p>
<p>Now, our service worker is ready to be used.</p>
<h2 id="sounds-perfect-but">Sounds perfect but…</h2>
<p>A major drawback is that you need a quite recent browser and these API may differ between browsers. At the time of writing, this won&#39;t work on Safari (any version), Firefox stable (aurora/dev has some support), Opera, Internet Explorer (Edge does support some features). You will have to handle these incompatibilities yourself.</p>
<p>But, even if service workers are not yet supported by all browsers, your application will still be able to run in a normal way. Only proxying and cache features will be affected, requests will be done as they were before. This is completely backwards compatible.</p>
<h2 id="how-do-we-use-it-at-clever-cloud">How do we use it at Clever Cloud</h2>
<p>We can&#39;t store all of the data or cache invalidation will be a mess to handle. Instead, we only store a few defined requests. When we load the Console, we use the cache, then wipe and update it in the background. The user can use the Console with quite fresh data and the UI will be updated as soon as we have the new one.</p>
<p>This feature allowed us to speed up the initial load of the Console, going well under 1 second if the cache exists. In a near future, we could also use service workers with the Notifications API to display application deployments&#39;s state even when the Console is not open in your browser.</p>
<h2 id="more-reading">More reading</h2>
<p>To learn about service workers, I used a few links:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API">Service Workers</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache">Cache API</a></li>
<li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">ES6 Promises</a></li>
<li><a href="http://www.html5rocks.com/en/tutorials/service-worker/introduction/">HTML5 rocks</a> (may be a little out of date but still accurate and well explained)</li>
<li></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Meteor JS on Clever Cloud</title>
		<link>https://www.clever.cloud/blog/engineering/2015/04/22/meteor-js-on-clever-cloud/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Wed, 22 Apr 2015 15:52:00 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[meteor]]></category>
		<category><![CDATA[Nodejs]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2015/04/22/meteor-js-on-clever-cloud/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="meteor banner wide 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Lately, a lot of developpers asked us about Meteorjs support on Clever Cloud. This is indeed a growing technology out there, so I decided to test it myself.</p>
<span id="more-2797"></span>

<h3 id="what-is-meteorjs-">What is Meteorjs ?</h3>
<p>Meteor.js is based on Nodejs and is a real-time cross-platform web application framework (Web, Android and iOS). One of its main features is to automatically propagate data changes to clients in real-time or even query the database from the client (well, the client has a cache of the database which will update the remote one). It is an easy framework to build reactive applications</p>
<h3 id="how-to-deploy-on-clever-cloud">How to deploy on Clever Cloud</h3>
<p>As an example of a large Meteor application, I will use <a href="https://github.com/TelescopeJS/Telescope">TelescopeJS</a>. It&#39;s a social news application you can configure the way you want. I&#39;ll use the version v0.14.2 since it does not require MongoDB 3.0. This is a version we will provide in a near future.</p>
<h4 id="1--clone">1- Clone</h4>
<p>So first, <code>git clone https://github.com/TelescopeJS/Telescope &amp;&amp; cd Telescope &amp;&amp; git checkout v0.14.2</code> and run it: <code>meteor run</code>. Then open <a href="http://localhost:3000">http://localhost:3000</a>, you should see the default page with some examples.</p>
<h4 id="2--install-and-build">2- Install and build</h4>
<p>To make it run on Clever Cloud, we have to make our own install script. This script will run when you deploy your application and build what&#39;s needed. Create an <code>install.sh</code> file and paste the following lines (or download it from <a href="https://raw.githubusercontent.com/CleverCloud/demo-meteorjs/master/install.sh">Github</a>):</p>
<pre><code class="language-bash">#! /bin/bash

# Current path
currentPath=$(realpath ./)

# Install Meteorjs
curl https://install.meteor.com/ | sh
export PATH=/home/bas/.meteor:$PATH

# Install demeteorizer
cd ~/ &amp;&amp; npm install demeteorizer

# Go back to our project
cd &quot;$currentPath&quot;

# Note: When using &quot;meteorhacks:npm&quot;
# to prevent the error: &quot;unknown package: npm-container&quot;
# (described in https://github.com/meteorhacks/npm/issues/49)
# uncomment the two following lines:
#meteor remove npm-container
#meteor run

# demeteorize the app
~/node_modules/.bin/demeteorizer -a &quot;my_app&quot; -o my_app/

# Go inside our demeteorized app to install modules
cd my_app/

# Install modules
npm install
</code></pre>
<p>This script will install Meteorjs on our platform, <a href="https://github.com/onmodulus/demeteorizer">demeteorize</a> the app (i.e. convert it as a regular node.js application) and install its modules. If you are using the package <a href="https://github.com/meteorhacks/npm">npm-container</a> from <code>meteorhacks</code>, you HAVE to uncomment lines 20 and 21 (this is not our case here). Do not forget to do a <code>chmod +x install.sh</code> to give it execution rights.</p>
<p>Now we have to create our package.json (which is the file which describe your application for NPM): <code>npm init</code>. Open it and create a <code>scripts</code> section:</p>
<pre><code class="language-javascript">&quot;scripts&quot;:{
  &quot;install&quot;: &quot;./install.sh&quot;,
  &quot;start&quot;: &quot;node my_app/main.js&quot;
}
</code></pre>
<p>(<code>my_app/main.js</code> is a file generated by demeteorizer, do not modify this line)</p>
<p>Then, you can commit your changes: <code>git add package.json install.sh &amp;&amp; git commit -m &quot;Clever Cloud setup&quot;</code></p>
<h3 id="configuration">Configuration</h3>
<p>Once done, we need to create a Node.js application and a MongoDB addon  and configure it. Open the <a href="https://console.clever-cloud.com">dashboard</a> and:</p>
<h4 id="addon">Addon</h4>
<ul>
<li>Add an addon</li>
<li>Select MongoDB, choose your plan and name it.</li>
<li>Click it in the blue pane on your left, go into its configuration tab and copy somewhere the <code>Connection URI</code> field</li>
</ul>
<h4 id="application">Application</h4>
<ul>
<li>Add an application</li>
<li>Choose node.js for the language</li>
<li>Choose the scalers you want (the default configuration is enough most of the time)</li>
<li>Name it</li>
<li>We don&#39;t need an addon since we&#39;ve just created it</li>
<li>Environment variables: You have to create 2 of them: ROOT_URL (url of you application) and MONGO_URL (the <code>Connection URI</code> field you saved)</li>
<li>Follow instructions to add the remote repository, <code>git push</code> and it will deploy.</li>
</ul>
<p>Your application should now be deployed, feel free to contact our support if you have any troubles!</p>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="meteor banner wide 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/meteor-banner-wide-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Lately, a lot of developpers asked us about Meteorjs support on Clever Cloud. This is indeed a growing technology out there, so I decided to test it myself.</p>
<span id="more-2797"></span>

<h3 id="what-is-meteorjs-">What is Meteorjs ?</h3>
<p>Meteor.js is based on Nodejs and is a real-time cross-platform web application framework (Web, Android and iOS). One of its main features is to automatically propagate data changes to clients in real-time or even query the database from the client (well, the client has a cache of the database which will update the remote one). It is an easy framework to build reactive applications</p>
<h3 id="how-to-deploy-on-clever-cloud">How to deploy on Clever Cloud</h3>
<p>As an example of a large Meteor application, I will use <a href="https://github.com/TelescopeJS/Telescope">TelescopeJS</a>. It&#39;s a social news application you can configure the way you want. I&#39;ll use the version v0.14.2 since it does not require MongoDB 3.0. This is a version we will provide in a near future.</p>
<h4 id="1--clone">1- Clone</h4>
<p>So first, <code>git clone https://github.com/TelescopeJS/Telescope &amp;&amp; cd Telescope &amp;&amp; git checkout v0.14.2</code> and run it: <code>meteor run</code>. Then open <a href="http://localhost:3000">http://localhost:3000</a>, you should see the default page with some examples.</p>
<h4 id="2--install-and-build">2- Install and build</h4>
<p>To make it run on Clever Cloud, we have to make our own install script. This script will run when you deploy your application and build what&#39;s needed. Create an <code>install.sh</code> file and paste the following lines (or download it from <a href="https://raw.githubusercontent.com/CleverCloud/demo-meteorjs/master/install.sh">Github</a>):</p>
<pre><code class="language-bash">#! /bin/bash

# Current path
currentPath=$(realpath ./)

# Install Meteorjs
curl https://install.meteor.com/ | sh
export PATH=/home/bas/.meteor:$PATH

# Install demeteorizer
cd ~/ &amp;&amp; npm install demeteorizer

# Go back to our project
cd &quot;$currentPath&quot;

# Note: When using &quot;meteorhacks:npm&quot;
# to prevent the error: &quot;unknown package: npm-container&quot;
# (described in https://github.com/meteorhacks/npm/issues/49)
# uncomment the two following lines:
#meteor remove npm-container
#meteor run

# demeteorize the app
~/node_modules/.bin/demeteorizer -a &quot;my_app&quot; -o my_app/

# Go inside our demeteorized app to install modules
cd my_app/

# Install modules
npm install
</code></pre>
<p>This script will install Meteorjs on our platform, <a href="https://github.com/onmodulus/demeteorizer">demeteorize</a> the app (i.e. convert it as a regular node.js application) and install its modules. If you are using the package <a href="https://github.com/meteorhacks/npm">npm-container</a> from <code>meteorhacks</code>, you HAVE to uncomment lines 20 and 21 (this is not our case here). Do not forget to do a <code>chmod +x install.sh</code> to give it execution rights.</p>
<p>Now we have to create our package.json (which is the file which describe your application for NPM): <code>npm init</code>. Open it and create a <code>scripts</code> section:</p>
<pre><code class="language-javascript">&quot;scripts&quot;:{
  &quot;install&quot;: &quot;./install.sh&quot;,
  &quot;start&quot;: &quot;node my_app/main.js&quot;
}
</code></pre>
<p>(<code>my_app/main.js</code> is a file generated by demeteorizer, do not modify this line)</p>
<p>Then, you can commit your changes: <code>git add package.json install.sh &amp;&amp; git commit -m &quot;Clever Cloud setup&quot;</code></p>
<h3 id="configuration">Configuration</h3>
<p>Once done, we need to create a Node.js application and a MongoDB addon  and configure it. Open the <a href="https://console.clever-cloud.com">dashboard</a> and:</p>
<h4 id="addon">Addon</h4>
<ul>
<li>Add an addon</li>
<li>Select MongoDB, choose your plan and name it.</li>
<li>Click it in the blue pane on your left, go into its configuration tab and copy somewhere the <code>Connection URI</code> field</li>
</ul>
<h4 id="application">Application</h4>
<ul>
<li>Add an application</li>
<li>Choose node.js for the language</li>
<li>Choose the scalers you want (the default configuration is enough most of the time)</li>
<li>Name it</li>
<li>We don&#39;t need an addon since we&#39;ve just created it</li>
<li>Environment variables: You have to create 2 of them: ROOT_URL (url of you application) and MONGO_URL (the <code>Connection URI</code> field you saved)</li>
<li>Follow instructions to add the remote repository, <code>git push</code> and it will deploy.</li>
</ul>
<p>Your application should now be deployed, feel free to contact our support if you have any troubles!</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
