<?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>Mon, 04 May 2026 15:00:36 +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>Clever Cloud Takes Control of Its IP Prefix Announcements</title>
		<link>https://www.clever.cloud/blog/engineering/2026/05/04/clever-cloud-takes-control-of-its-ip-prefix-announcements/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Mon, 04 May 2026 15:00:35 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=23853</guid>

					<description><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026 03 17 clever cloud banniere blog clever cloud controle lannonce de ses prefixes ip en" decoding="async" fetchpriority="high" srcset="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1368x607.png 1368w" sizes="(max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>This represents a major milestone that culminates three years of preparation and is part of our broader strategy to maintain complete control over our Paris region's network infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why We Made This Change</h2>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="max-width:780px;margin:1.5rem auto;background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size:15px;line-height:1.7;box-shadow:0 1px 2px rgba(0,0,0,0.08);border:1px solid rgba(255,255,255,0.08);">
  <strong style="color:#e5eefc;">Note:</strong> Clever Cloud operates multiple regions worldwide. Paris is our main region — the largest, where we control the full stack: our own hardware, our own network, and now our own IP announcements. Other regions (hosted on OVH, Scaleway, Cloud Temple, Ionos, Oracle) rely on the underlying provider's infrastructure, including their network. The changes described in this article specifically concern our Paris region.
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>In Clever Cloud's early years, we delegated network responsibility to partners. This approach made sense: it allowed us to accelerate development, focus on cloud services, and avoid investing in expertise we hadn't yet mastered. But as our infrastructure grew, the limitations of this dependency became clear. We had no control over strategic decisions — how traffic was routed across the Internet, which paths our packets took, or how quickly we could respond to failures. Every modification, every incident required the involvement of a third party.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We decided to take this responsibility back. In doing so, we gained several concrete advantages. We optimize costs through direct management of our transit and peering relationships. We define our own routing policy instead of following an intermediary's constraints. We resolve incidents ourselves, without waiting for external providers. And we achieve complete control of our network stack — the same way we progressively took control of our servers and datacenters over the past few years.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>But this transition isn't just about our operational independence. It brings immediate, tangible benefits for you. The most critical is resilience. Previously, all traffic was routed through a single provider. Any incident on their side impacted every service we offered. We now maintain four upstream providers across three datacenters in the Paris area. When one link fails — and it has happened over the past year — traffic automatically shifts to available alternatives without customer-impacting interruption. We can even withstand the simultaneous loss of multiple transit links.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Beyond redundancy, we gain control over routing itself. We now decide how your traffic reaches its destination. This allows us to optimize paths for lower latency and better performance, and to adjust those decisions based on your specific needs and our network topology. We respond to congestion, to changing conditions, and to your requirements in real time.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Finally, there is the question of operational responsibility. Network issues no longer require us to wait for an external provider to acknowledge and resolve them. Public network failures fall directly under our responsibility — we detect them, analyze them, and fix them ourselves. This directly reduces the time between problem and resolution, which means less downtime and better reliability for our customers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Operating Your Own Network on the Internet</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To operate as an independent network on the Internet, organizations must work with a Regional Internet Registry (RIR). RIRs are responsible for allocating and managing IP addresses and AS numbers within specific geographical regions.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>There are five RIRs worldwide:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>RIPE NCC</strong> — Europe, Central Asia, and the Middle East</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ARIN</strong> — North America (United States, Canada, and the Caribbean)</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>LACNIC</strong> — Latin America and the Caribbean</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>APNIC</strong> — Asia-Pacific region</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>AFRINIC</strong> — Africa</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>For Clever Cloud, since our infrastructure is primarily in Europe, we work with RIPE NCC (Réseaux Internet Publics Européens).</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Allocated Address Space</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As a member of a RIR, organizations receive allocations of both IPv4 and IPv6 address space. For RIPE NCC members, this typically includes a /24 block of IPv4 addresses (<a href="https://www.ripe.net/manage-ips-and-asns/ipv4/ipv4-waiting-list/">depending on the availability</a> of such a block) and a /29 block of IPv6 addresses. These allocations are managed under your membership and can be used to operate your network globally.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating Our Autonomous System</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The groundwork for this transition began several years ago. In 2019, we created our RIPE NCC account to become a LIR (Local Internet Registry). This gave us access to a /24 IPv4 block (91.208.207.0/24) and a /29 IPv6 block (2a0f:d0c0::/29).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Then, in 2022, we registered our Autonomous System Number (ASN) with the Regional Internet Registry for our region. Our AS number is<a href="https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&amp;key=AS213394&amp;type=aut-num"> AS213394</a>. Here is the aut-num object:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; whois AS213394

aut-num:        AS213394
as-name:        CleverCloud
org:            ORG-CCS42-RIPE
import:         from AS29075 accept ANY
import:         from AS3257 accept ANY
import:         from AS3356 accept ANY
import:         from AS43424 accept ANY
export:         to AS29075 announce AS213394:AS-CLVRCLD
export:         to AS3257 announce AS213394:AS-CLVRCLD
export:         to AS3356 announce AS213394:AS-CLVRCLD
export:         to AS43424 announce AS213394:AS-CLVRCLD
admin-c:        QA171-RIPE
tech-c:         QA171-RIPE
status:         ASSIGNED
mnt-by:         RIPE-NCC-END-MNT
mnt-by:         mnt-fr-clvrcldnet-1
created:        2022-11-28T08:24:23Z
last-modified:  2025-02-25T16:36:15Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>An Autonomous System Number (ASN) is a unique identifier for networks on the Internet. It's required to announce routes via BGP — the protocol that makes inter-network routing possible. Creating an AS early on allowed us to plan for this eventual transition and prepare the necessary infrastructure in advance.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now that we have an ASN, we can start announcing our prefixes to other networks on the Internet using the BGP protocol.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The Role of the RIPE Database</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The RIPE NCC maintains a public database of routing objects (like the aut-num object above). Among these objects are route objects, which specify which AS is authorized to announce a particular IP prefix. In practice, these entries are primarily used by network operators and transit providers to build routing policy and filters (IRR-based filtering) to accept or deny announcements from their peers. This is one way to try to prevent BGP hijacks. By applying those filters to the routes you receive from your peers, you can limit the propagation of a prefix that originates from the wrong ASN.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let's say that Org A owns 192.0.2.0/24 and announces it to Transit X. Transit X applies a filter on routes learned from Org A to only accept the IP prefixes that Org A has in its RIR database. This way, if Org A starts announcing a prefix it doesn't own (let's say our public prefix, 91.208.207.0/24), then Transit X is supposed to reject that route. This helps prevent the bad route from being propagated and traffic from being forwarded to the wrong entity.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>However, not all networks implement IRR filtering. Better mechanisms like ROA (Route Origin Authorization) exist to address this gap.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The BGP Protocol: How the Internet Routes Traffic</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To understand how we announce our prefixes on the Internet, it's essential to understand BGP — the Border Gateway Protocol. BGP is the de facto standard routing protocol of the Internet. It allows networks (Autonomous Systems) to exchange information about which IP prefixes they own and how to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>BGP works in both directions. When we announce to our peers and transit providers "we own 91.208.207.0/24", this announcement travels through the Internet from network to network. Each network that forwards our announcement prepends its own AS number to the AS_PATH — a list showing the sequence of networks a packet traverses to reach us. For example, OVHcloud (AS16276) sees the path [AS29075, AS213394]: traffic goes through one of our transit providers (AS29075), then reaches us (AS213394). Each network that forwards the announcement updates it this way, building a complete path. Here's an example using the<a href="https://lg.ovh.net/prefix_detail/lil1/ipv4?q=91.208.207.0/24"> OVHcloud Looking Glass service</a>:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; show route for 91.208.207.0/24 all

91.208.207.0/24    via 172.18.16.0 on eno1 [lil1_rbx1_bagg1_8k 2025-12-25] * (100/0) [AS213394i]
    Type: BGP unicast univ
    BGP.origin: IGP
    BGP.as_path: 29075 213394
    BGP.next_hop: 172.18.16.0
    BGP.med: 161
    BGP.local_pref: 40
    BGP.community: (0,0) (29075,18000) (65535,65281)
    BGP.23 [t]: 00 00 b8 6e
                   via 172.18.16.64 on eno1 [lil1_rbx8_bagg1_8k 2025-12-25] (100/0) [AS213394i]</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>At the same time, we receive announcements from other networks about their prefixes and the paths to reach them. This builds the opposite view: when we need to send traffic outbound, we know which path to take to reach any given destination. Here's an example with one of OVHcloud prefixes:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; /routing/route/print detail where dst-address=5.39.0.0/17 and active

Ab   afi=ip4 contribution=active dst-address=5.39.0.0/17 routing-table=main pref-src=185.133.116.2 gateway=213.242.111.201 immediate-gw=213.242.111.201%sfp28-6 distance=20 scope=40 target-scope=10 belongs-to="bgp-IP-213.242.111.201"

      bgp.as-path="3356,16276" bgp.communities=3356:2,3356:2066,3356:22,16276:40001,3356:100,65002:7018,3356:123,3356:901,65002:701,65000:64990,65000:64995,65000:64996,3356:502 .med=0 .atomic-aggregate=no .origin=igp</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Here the network path OVHcloud uses to reach us is different from the one we use to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Migration Process</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Our IP prefixes were entirely managed by our historical provider. While we legally owned the addresses, we delegated the technical responsibility of announcing them to the Internet to this single provider. This meant:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Our provider's AS (AS43424) was listed as the origin of our prefixes in the Internet routing tables</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>All traffic destined for our services or outgoing to the Internet had to flow through their infrastructure</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services
   |
   | all inbound/outbound traffic
   v
Historical Provider (AS43424)
   |
   | originates: 91.208.207.0/24 (origin AS43424)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now want our ASN to be the origin of the announcements. To migrate safely, we planned a three-step migration. The requirements were simple: we could not accept any customer-impacting interruption.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Migrating a prefix between ASNs</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To migrate a prefix from one AS to another, we needed to modify its route object in the RIPE database. The procedure was straightforward but required careful timing.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First, we created a second route object in the RIPE database for our 91.208.207.0/24 prefix. Now both ASNs were registered as authorized to announce the same prefix — both our historical provider's AS and our own AS (213394).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>These routing objects are publicly queryable via the whois command or through the RIPE web interface. For example, running whois -h whois.ripe.net -T route 91.208.207.0/24 returns both registered objects:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">❯ whois -h whois.ripe.net -T route 91.208.207.0/24
% Information related to '91.208.207.0/24AS213394'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
descr:          CleverCloud subnet
origin:         AS213394
created:        2025-01-15T10:29:14Z
last-modified:  2025-01-15T10:29:14Z
source:         RIPE

% Information related to '91.208.207.0/24AS43424'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
mnt-by:         MAGICRETAIL-MNT
descr:          CleverCloud subnet
origin:         AS43424
created:        2020-02-13T09:06:33Z
last-modified:  2020-02-13T09:06:48Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Once this second route object was registered and propagated across the Internet (i.e., network operators pulled an up-to-date version of the RIPE database to build their routing filters), our new transit providers could see that our ASN was authorized to announce this prefix. At that point, we could begin announcing the prefix through our own infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If we didn't create that route object, our route announcement might have been rejected and we could have been flagged as BGP hijackers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Historical Provider</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once the second route object was propagated, we performed the first step during the night of January 16, 2025: we began announcing the prefix ourselves via BGP to our historical provider. This was still using the same transit path, but now with Clever Cloud AS213394 originating the announcements instead of our historical provider. Our historical provider continued to relay the prefix, but now received it from us rather than announcing it directly.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   v
Historical Provider (AS43424)
   |
   | re-announces: 91.208.207.0/24 (origin AS213394)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>This first phase served as validation — if any issues arose, we could quickly revert without impacting other transit paths.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Own Transits</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A few days later, during the night of January 21, 2025, we took the final step: we began announcing the prefix through our own dedicated transit connections.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   |
   +---+---+---+
   |   |   |   |
   v   v   v   v
  T1  T2  T3  HP
(Transit providers + historical provider)
   |   |   |   |
   +---+---+---+
   |
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now announce our prefixes directly to four upstream providers (three transit providers, T1/T2/T3, plus our historical provider HP). Traffic flows across all paths, and we have full control over routing decisions and redundancy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Throughout both phases, we observed no customer-impacting interruption. The BGP protocol's built-in redundancy and the gradual nature of the transition ensured that traffic flowed smoothly regardless of which path was preferred at any given moment.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Complete Internet Routing Visibility</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As part of Phase 2, our three primary transit providers began sending us a "full view" of the Internet's routing table. This is the complete set of all publicly announced IPv4 and IPv6 prefixes — roughly ~1 million IPv4 routes and ~220,000 IPv6 routes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A full view gives us unprecedented visibility into how the Internet is structured and allows us to make sophisticated routing decisions. Rather than relying on a single provider's perspective, we now see all available paths to reach any destination on the Internet.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With this information, we are able to:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Choose optimal paths</strong> for our outbound traffic based on our network topology and preferences</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Implement traffic engineering</strong> to direct flows through specific transit providers</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Respond dynamically</strong> to network conditions and congestion</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Balance load</strong> across our four transit connections based on real-time routing data</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>This fine-grained control over our routing policy is a direct result of operating our own AS and managing our own announcements — exactly the kind of operational independence we sought when we began this transition.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">One Year Later</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Nearly a year into operating our own network announcements, the transition has proven successful. We have experienced no major incidents, and our infrastructure has proven resilient. When minor issues have occurred — such as packet loss through a specific transit provider or the temporary loss of a transit link — traffic has automatically rebalanced across our remaining connections. We have been able to detect and respond to these issues directly, without waiting for a third-party provider to take action. Our customers experienced no customer-impacting interruption. This ability to own our problems and resolve them quickly is perhaps the greatest benefit we've gained.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What's Next</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This transition is far from finished. We have several roadmap items ahead of us:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Increased network capacity</strong> to handle growing traffic demands</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>BGP peering</strong> with other networks to optimize traffic locally without paying for transit</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ROA (Route Origin Authorization)</strong> deployment to cryptographically sign our route announcements and prevent unauthorized parties from hijacking our prefixes</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RPKI (Resource Public Key Infrastructure) validation</strong> to ensure the legitimacy of announcements we receive from other networks and protect against prefix hijacking attacks</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>IPv6 expansion</strong>, both inbound (accepting IPv6 traffic) and outbound (sending IPv6 traffic) — a transition we will roll out in phases</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In early 2025, Clever Cloud completed its transition to fully independent network operations. We now announce our own IP prefixes through four upstream providers, giving us full authority over how traffic flows in and out of our infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For our customers, this translates to better reliability and faster problem resolution in our Paris region. When network issues occur, we handle them directly — and our multi-provider redundancy ensures traffic keeps flowing even when incidents occur.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This milestone is just the beginning. We're already working on BGP peering to optimize local traffic, ROA signing and RPKI validation to strengthen routing security, and IPv6 expansion to fully embrace dual-stack connectivity. We're building a network as robust and self-sufficient as the rest of our infrastructure — and we're excited about what comes next.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026 03 17 clever cloud banniere blog clever cloud controle lannonce de ses prefixes ip en" decoding="async" srcset="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1368x607.png 1368w" sizes="(max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>This represents a major milestone that culminates three years of preparation and is part of our broader strategy to maintain complete control over our Paris region's network infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why We Made This Change</h2>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="max-width:780px;margin:1.5rem auto;background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size:15px;line-height:1.7;box-shadow:0 1px 2px rgba(0,0,0,0.08);border:1px solid rgba(255,255,255,0.08);">
  <strong style="color:#e5eefc;">Note:</strong> Clever Cloud operates multiple regions worldwide. Paris is our main region — the largest, where we control the full stack: our own hardware, our own network, and now our own IP announcements. Other regions (hosted on OVH, Scaleway, Cloud Temple, Ionos, Oracle) rely on the underlying provider's infrastructure, including their network. The changes described in this article specifically concern our Paris region.
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>In Clever Cloud's early years, we delegated network responsibility to partners. This approach made sense: it allowed us to accelerate development, focus on cloud services, and avoid investing in expertise we hadn't yet mastered. But as our infrastructure grew, the limitations of this dependency became clear. We had no control over strategic decisions — how traffic was routed across the Internet, which paths our packets took, or how quickly we could respond to failures. Every modification, every incident required the involvement of a third party.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We decided to take this responsibility back. In doing so, we gained several concrete advantages. We optimize costs through direct management of our transit and peering relationships. We define our own routing policy instead of following an intermediary's constraints. We resolve incidents ourselves, without waiting for external providers. And we achieve complete control of our network stack — the same way we progressively took control of our servers and datacenters over the past few years.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>But this transition isn't just about our operational independence. It brings immediate, tangible benefits for you. The most critical is resilience. Previously, all traffic was routed through a single provider. Any incident on their side impacted every service we offered. We now maintain four upstream providers across three datacenters in the Paris area. When one link fails — and it has happened over the past year — traffic automatically shifts to available alternatives without customer-impacting interruption. We can even withstand the simultaneous loss of multiple transit links.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Beyond redundancy, we gain control over routing itself. We now decide how your traffic reaches its destination. This allows us to optimize paths for lower latency and better performance, and to adjust those decisions based on your specific needs and our network topology. We respond to congestion, to changing conditions, and to your requirements in real time.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Finally, there is the question of operational responsibility. Network issues no longer require us to wait for an external provider to acknowledge and resolve them. Public network failures fall directly under our responsibility — we detect them, analyze them, and fix them ourselves. This directly reduces the time between problem and resolution, which means less downtime and better reliability for our customers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Operating Your Own Network on the Internet</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To operate as an independent network on the Internet, organizations must work with a Regional Internet Registry (RIR). RIRs are responsible for allocating and managing IP addresses and AS numbers within specific geographical regions.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>There are five RIRs worldwide:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>RIPE NCC</strong> — Europe, Central Asia, and the Middle East</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ARIN</strong> — North America (United States, Canada, and the Caribbean)</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>LACNIC</strong> — Latin America and the Caribbean</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>APNIC</strong> — Asia-Pacific region</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>AFRINIC</strong> — Africa</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>For Clever Cloud, since our infrastructure is primarily in Europe, we work with RIPE NCC (Réseaux Internet Publics Européens).</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Allocated Address Space</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As a member of a RIR, organizations receive allocations of both IPv4 and IPv6 address space. For RIPE NCC members, this typically includes a /24 block of IPv4 addresses (<a href="https://www.ripe.net/manage-ips-and-asns/ipv4/ipv4-waiting-list/">depending on the availability</a> of such a block) and a /29 block of IPv6 addresses. These allocations are managed under your membership and can be used to operate your network globally.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating Our Autonomous System</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The groundwork for this transition began several years ago. In 2019, we created our RIPE NCC account to become a LIR (Local Internet Registry). This gave us access to a /24 IPv4 block (91.208.207.0/24) and a /29 IPv6 block (2a0f:d0c0::/29).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Then, in 2022, we registered our Autonomous System Number (ASN) with the Regional Internet Registry for our region. Our AS number is<a href="https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&amp;key=AS213394&amp;type=aut-num"> AS213394</a>. Here is the aut-num object:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; whois AS213394

aut-num:        AS213394
as-name:        CleverCloud
org:            ORG-CCS42-RIPE
import:         from AS29075 accept ANY
import:         from AS3257 accept ANY
import:         from AS3356 accept ANY
import:         from AS43424 accept ANY
export:         to AS29075 announce AS213394:AS-CLVRCLD
export:         to AS3257 announce AS213394:AS-CLVRCLD
export:         to AS3356 announce AS213394:AS-CLVRCLD
export:         to AS43424 announce AS213394:AS-CLVRCLD
admin-c:        QA171-RIPE
tech-c:         QA171-RIPE
status:         ASSIGNED
mnt-by:         RIPE-NCC-END-MNT
mnt-by:         mnt-fr-clvrcldnet-1
created:        2022-11-28T08:24:23Z
last-modified:  2025-02-25T16:36:15Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>An Autonomous System Number (ASN) is a unique identifier for networks on the Internet. It's required to announce routes via BGP — the protocol that makes inter-network routing possible. Creating an AS early on allowed us to plan for this eventual transition and prepare the necessary infrastructure in advance.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now that we have an ASN, we can start announcing our prefixes to other networks on the Internet using the BGP protocol.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The Role of the RIPE Database</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The RIPE NCC maintains a public database of routing objects (like the aut-num object above). Among these objects are route objects, which specify which AS is authorized to announce a particular IP prefix. In practice, these entries are primarily used by network operators and transit providers to build routing policy and filters (IRR-based filtering) to accept or deny announcements from their peers. This is one way to try to prevent BGP hijacks. By applying those filters to the routes you receive from your peers, you can limit the propagation of a prefix that originates from the wrong ASN.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let's say that Org A owns 192.0.2.0/24 and announces it to Transit X. Transit X applies a filter on routes learned from Org A to only accept the IP prefixes that Org A has in its RIR database. This way, if Org A starts announcing a prefix it doesn't own (let's say our public prefix, 91.208.207.0/24), then Transit X is supposed to reject that route. This helps prevent the bad route from being propagated and traffic from being forwarded to the wrong entity.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>However, not all networks implement IRR filtering. Better mechanisms like ROA (Route Origin Authorization) exist to address this gap.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The BGP Protocol: How the Internet Routes Traffic</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To understand how we announce our prefixes on the Internet, it's essential to understand BGP — the Border Gateway Protocol. BGP is the de facto standard routing protocol of the Internet. It allows networks (Autonomous Systems) to exchange information about which IP prefixes they own and how to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>BGP works in both directions. When we announce to our peers and transit providers "we own 91.208.207.0/24", this announcement travels through the Internet from network to network. Each network that forwards our announcement prepends its own AS number to the AS_PATH — a list showing the sequence of networks a packet traverses to reach us. For example, OVHcloud (AS16276) sees the path [AS29075, AS213394]: traffic goes through one of our transit providers (AS29075), then reaches us (AS213394). Each network that forwards the announcement updates it this way, building a complete path. Here's an example using the<a href="https://lg.ovh.net/prefix_detail/lil1/ipv4?q=91.208.207.0/24"> OVHcloud Looking Glass service</a>:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; show route for 91.208.207.0/24 all

91.208.207.0/24    via 172.18.16.0 on eno1 [lil1_rbx1_bagg1_8k 2025-12-25] * (100/0) [AS213394i]
    Type: BGP unicast univ
    BGP.origin: IGP
    BGP.as_path: 29075 213394
    BGP.next_hop: 172.18.16.0
    BGP.med: 161
    BGP.local_pref: 40
    BGP.community: (0,0) (29075,18000) (65535,65281)
    BGP.23 [t]: 00 00 b8 6e
                   via 172.18.16.64 on eno1 [lil1_rbx8_bagg1_8k 2025-12-25] (100/0) [AS213394i]</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>At the same time, we receive announcements from other networks about their prefixes and the paths to reach them. This builds the opposite view: when we need to send traffic outbound, we know which path to take to reach any given destination. Here's an example with one of OVHcloud prefixes:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; /routing/route/print detail where dst-address=5.39.0.0/17 and active

Ab   afi=ip4 contribution=active dst-address=5.39.0.0/17 routing-table=main pref-src=185.133.116.2 gateway=213.242.111.201 immediate-gw=213.242.111.201%sfp28-6 distance=20 scope=40 target-scope=10 belongs-to="bgp-IP-213.242.111.201"

      bgp.as-path="3356,16276" bgp.communities=3356:2,3356:2066,3356:22,16276:40001,3356:100,65002:7018,3356:123,3356:901,65002:701,65000:64990,65000:64995,65000:64996,3356:502 .med=0 .atomic-aggregate=no .origin=igp</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Here the network path OVHcloud uses to reach us is different from the one we use to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Migration Process</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Our IP prefixes were entirely managed by our historical provider. While we legally owned the addresses, we delegated the technical responsibility of announcing them to the Internet to this single provider. This meant:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Our provider's AS (AS43424) was listed as the origin of our prefixes in the Internet routing tables</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>All traffic destined for our services or outgoing to the Internet had to flow through their infrastructure</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services
   |
   | all inbound/outbound traffic
   v
Historical Provider (AS43424)
   |
   | originates: 91.208.207.0/24 (origin AS43424)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now want our ASN to be the origin of the announcements. To migrate safely, we planned a three-step migration. The requirements were simple: we could not accept any customer-impacting interruption.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Migrating a prefix between ASNs</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To migrate a prefix from one AS to another, we needed to modify its route object in the RIPE database. The procedure was straightforward but required careful timing.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First, we created a second route object in the RIPE database for our 91.208.207.0/24 prefix. Now both ASNs were registered as authorized to announce the same prefix — both our historical provider's AS and our own AS (213394).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>These routing objects are publicly queryable via the whois command or through the RIPE web interface. For example, running whois -h whois.ripe.net -T route 91.208.207.0/24 returns both registered objects:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">❯ whois -h whois.ripe.net -T route 91.208.207.0/24
% Information related to '91.208.207.0/24AS213394'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
descr:          CleverCloud subnet
origin:         AS213394
created:        2025-01-15T10:29:14Z
last-modified:  2025-01-15T10:29:14Z
source:         RIPE

% Information related to '91.208.207.0/24AS43424'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
mnt-by:         MAGICRETAIL-MNT
descr:          CleverCloud subnet
origin:         AS43424
created:        2020-02-13T09:06:33Z
last-modified:  2020-02-13T09:06:48Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Once this second route object was registered and propagated across the Internet (i.e., network operators pulled an up-to-date version of the RIPE database to build their routing filters), our new transit providers could see that our ASN was authorized to announce this prefix. At that point, we could begin announcing the prefix through our own infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If we didn't create that route object, our route announcement might have been rejected and we could have been flagged as BGP hijackers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Historical Provider</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once the second route object was propagated, we performed the first step during the night of January 16, 2025: we began announcing the prefix ourselves via BGP to our historical provider. This was still using the same transit path, but now with Clever Cloud AS213394 originating the announcements instead of our historical provider. Our historical provider continued to relay the prefix, but now received it from us rather than announcing it directly.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   v
Historical Provider (AS43424)
   |
   | re-announces: 91.208.207.0/24 (origin AS213394)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>This first phase served as validation — if any issues arose, we could quickly revert without impacting other transit paths.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Own Transits</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A few days later, during the night of January 21, 2025, we took the final step: we began announcing the prefix through our own dedicated transit connections.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   |
   +---+---+---+
   |   |   |   |
   v   v   v   v
  T1  T2  T3  HP
(Transit providers + historical provider)
   |   |   |   |
   +---+---+---+
   |
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now announce our prefixes directly to four upstream providers (three transit providers, T1/T2/T3, plus our historical provider HP). Traffic flows across all paths, and we have full control over routing decisions and redundancy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Throughout both phases, we observed no customer-impacting interruption. The BGP protocol's built-in redundancy and the gradual nature of the transition ensured that traffic flowed smoothly regardless of which path was preferred at any given moment.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Complete Internet Routing Visibility</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As part of Phase 2, our three primary transit providers began sending us a "full view" of the Internet's routing table. This is the complete set of all publicly announced IPv4 and IPv6 prefixes — roughly ~1 million IPv4 routes and ~220,000 IPv6 routes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A full view gives us unprecedented visibility into how the Internet is structured and allows us to make sophisticated routing decisions. Rather than relying on a single provider's perspective, we now see all available paths to reach any destination on the Internet.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With this information, we are able to:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Choose optimal paths</strong> for our outbound traffic based on our network topology and preferences</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Implement traffic engineering</strong> to direct flows through specific transit providers</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Respond dynamically</strong> to network conditions and congestion</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Balance load</strong> across our four transit connections based on real-time routing data</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>This fine-grained control over our routing policy is a direct result of operating our own AS and managing our own announcements — exactly the kind of operational independence we sought when we began this transition.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">One Year Later</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Nearly a year into operating our own network announcements, the transition has proven successful. We have experienced no major incidents, and our infrastructure has proven resilient. When minor issues have occurred — such as packet loss through a specific transit provider or the temporary loss of a transit link — traffic has automatically rebalanced across our remaining connections. We have been able to detect and respond to these issues directly, without waiting for a third-party provider to take action. Our customers experienced no customer-impacting interruption. This ability to own our problems and resolve them quickly is perhaps the greatest benefit we've gained.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What's Next</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This transition is far from finished. We have several roadmap items ahead of us:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Increased network capacity</strong> to handle growing traffic demands</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>BGP peering</strong> with other networks to optimize traffic locally without paying for transit</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ROA (Route Origin Authorization)</strong> deployment to cryptographically sign our route announcements and prevent unauthorized parties from hijacking our prefixes</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RPKI (Resource Public Key Infrastructure) validation</strong> to ensure the legitimacy of announcements we receive from other networks and protect against prefix hijacking attacks</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>IPv6 expansion</strong>, both inbound (accepting IPv6 traffic) and outbound (sending IPv6 traffic) — a transition we will roll out in phases</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In early 2025, Clever Cloud completed its transition to fully independent network operations. We now announce our own IP prefixes through four upstream providers, giving us full authority over how traffic flows in and out of our infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For our customers, this translates to better reliability and faster problem resolution in our Paris region. When network issues occur, we handle them directly — and our multi-provider redundancy ensures traffic keeps flowing even when incidents occur.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This milestone is just the beginning. We're already working on BGP peering to optimize local traffic, ROA signing and RPKI validation to strengthen routing security, and IPv6 expansion to fully embrace dual-stack connectivity. We're building a network as robust and self-sufficient as the rest of our infrastructure — and we're excited about what comes next.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<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" 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" loading="lazy" 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="auto, (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" 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.]]></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>
