<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Anas El Husseini on Medium]]></title>
        <description><![CDATA[Stories by Anas El Husseini on Medium]]></description>
        <link>https://medium.com/@linostar?source=rss-9711370ec04------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*gZgVDU-mgqalhSBYimPQLA.png</url>
            <title>Stories by Anas El Husseini on Medium</title>
            <link>https://medium.com/@linostar?source=rss-9711370ec04------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 08 Jun 2026 22:28:22 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@linostar/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Open Source and Survival of the FAANGest]]></title>
            <link>https://medium.com/@linostar/open-source-and-survival-of-the-faangest-b85204dc8108?source=rss-9711370ec04------2</link>
            <guid isPermaLink="false">https://medium.com/p/b85204dc8108</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[licensing]]></category>
            <category><![CDATA[free]]></category>
            <category><![CDATA[faang]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Anas El Husseini]]></dc:creator>
            <pubDate>Tue, 29 Jul 2025 17:27:17 GMT</pubDate>
            <atom:updated>2025-07-29T17:30:47.254Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*C6_5aibPEvkmFopWPtljgg.avif" /><figcaption>Open does not mean misuse</figcaption></figure><h3>Is Open Source licensing holding us back?!</h3><p>This sounds like an outrageous question, coming from me, a<strong><em> </em>top-100</strong> software developer in the world!<br>Ok, I may have omitted a zero or two in the number above. Maybe three, don’t push it!<br>Nevertheless, hear me out till the end.</p><p>I am not against open source software at all.<br>I am not against giving everybody the ability to read a code, learn from it, modify it and derive their own variant out of it.<br>After all, I am one of so many developers who learned so much from open source projects.</p><h3>Free numbers do not lie!</h3><p>Did you know this about open source maintainers?<br>- about 60% are <strong>UNPAID</strong><br>- only 13% are paid enough to be dependent on their project as a sufficient source of income<br>- the rest are paid, but not enough to live off</p><p>Open source licensing was initially created to fight against the monopoly of knowledge. Trying to maintain the maximum amount of freedom, open source licensing accidentally deprived many of the OSS maintainers of one important freedom: the freedom to financially benefit from their works.</p><h3>Free like free food, but is free always good?</h3><p>You would argue against that by saying:</p><p><strong>Argument: </strong>OSS projects get funding.<br><strong>Refutation:</strong> We already established that the largest chunk of OSS projects are underfunded.</p><p><strong>Argument:</strong> OSS can earn money through support services, training, certifications and lots of other stuff.<br><strong>Refutation:</strong> But those earnings are from the side services and not the main product. Imagine owning one of the fanciest restaurants, and disclosing your recipes for free, but you can’t charge your customers for anything except for the optional use of the premium silverware!</p><p><strong>Argument:</strong> Big companies sponsor OSS and their events.<br><strong>Refutation:</strong> Indeed, those big companies fiercely fought against OSS in the beginning. Later on, they discovered that the pros of OSS outweigh the cons for them. Not only tons of their projects became dependent on OSS, ultimately contributing to more profit, but they also get the credit by becoming the “<strong><em>gigantic philanthropists</em></strong>”. They give back a small chunk of their earnings to the geese that lay golden eggs.</p><h3>Cut it free, but cut me in!</h3><p>No doubt that Open Source licensing had, and still have, contributed so much to the software development world. But we have been clinging to the same model of licensing for decades, depriving ourselves from well-deserved opportunities, in a harsh world where survival is for the FAANGest!</p><p>Is it unthinkable to create or adopt a license that allows freedom of access/modification/contribution/redistribution of the source code, but monetize the derivation? The derived works of such sources can opt for getting some royalty if the corresponding revenues are above a certain threshold.</p><p>Did we become so afraid of using a license that does not stick to the perfect model of the open source license? Are we ashamed of imperfection to the extent of endangering our own sustainability and survival?</p><p>Would you support something like an <strong>OpenRoyalty</strong> license? Curious to hear your take.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b85204dc8108" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Django Beats Scissors, Stands Up to Paper]]></title>
            <link>https://levelup.gitconnected.com/django-beats-scissors-stands-up-to-paper-cdb7a3e3e55f?source=rss-9711370ec04------2</link>
            <guid isPermaLink="false">https://medium.com/p/cdb7a3e3e55f</guid>
            <category><![CDATA[django]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[containerization]]></category>
            <category><![CDATA[ubuntu]]></category>
            <dc:creator><![CDATA[Anas El Husseini]]></dc:creator>
            <pubDate>Tue, 28 May 2024 22:28:48 GMT</pubDate>
            <atom:updated>2024-05-28T22:28:48.821Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*l8s672hGPNPsEBh8" /><figcaption>What if Django becomes a “rock” and beats both scisoors and paper</figcaption></figure><p>Ever wondered what will happen if we combine one of the most promising Python web frameworks with a <strong><em>rock</em></strong>?!</p><p>In my <a href="https://medium.com/@linostar/a-journey-with-rock-crafting-e3cc4970dfb2">previous article</a>, I introduced <strong><em>Rockcraft</em></strong> and its ability to create minimalistic and secure container images, known as <strong><em>rocks</em></strong>. Today, we delve deeper into this evolving tool, highlighting its latest feature: Extensions. This powerful addition allows for effortless deployment of apps like <em>Flask</em> and <em>Django</em> without the need for custom scripts or manual intervention. Let’s explore how to leverage this feature effectively.</p><h3>Install or update Rockcraft</h3><p>First, let’s make sure we have the latest version of <strong><em>Rockcraft</em></strong> by running the following update command in terminal:</p><pre>$ sudo snap refresh rockcraft</pre><p>If that is your first time using <strong><em>Rockcraft</em></strong> and you don’t have it installed, you can install it by running:</p><pre>$ sudo snap install rockcraft --classic</pre><h3>Get the rocket ready!</h3><p>Now, I will initiate our rockcraft project in an empty folder called /home/ubuntu/django. Pick your own empty folder then run:</p><pre>$ rockcraft init</pre><p>This will create rockcraft.yaml with placeholder values:</p><pre>name: django<br>base: ubuntu@22.04 # the base environment for this rock<br>version: &#39;0.1&#39; # just for humans. Semantic versioning is recommended<br>summary: Single-line elevator pitch for your amazing rock # 79 char long summary<br>description: |<br>    This is oci-factory&#39;s description. You have a paragraph or two to tell the<br>    most important story about it. Keep it under 100 words though,<br>    we live in tweetspace and your description wants to look good in the<br>    container registries out there.<br>license: GPL-3.0 # your application&#39;s SPDX license<br>platforms: # The platforms this rock should be built on and run on<br>    amd64:<br>    arm64:<br><br>parts:<br>    my-part:<br>        plugin: nil</pre><p>Change the values of version, summary, description, license and platforms to your linkings and needs, and remove the my-part subsection under parts:. You have to change two important fields:</p><ul><li><strong>name:</strong> should match with your Django project name</li><li><strong>base:</strong> only bare and ubuntu@22.04 are currently supported for this extension</li></ul><p>One last thing! Since extensions are still experimental, we need to say the<em> SECRET WORD</em>! Without the following environment variable, <strong><em>Rockcraft</em></strong> won’t allow us to build our image:</p><pre>$ export ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true</pre><h3>Django unchained, and initialized!</h3><p>Now, let’s create a very simple django project. Assuming you already have Python 3.x installed, create and activate a virtualenv first by running:</p><pre>$ virtualenv .env<br>$ source .env/bin/activate</pre><p>Proceed then to install the latest version of Django:</p><pre>$ pip install django</pre><p>The django-framework extension that we are going to use requires us to store the list of our python packages in a requirements.txt file, so create that file in the django/ folder and write in it:</p><pre>django</pre><p>Create a new Django project:</p><pre>$ django-admin startproject djangoproject</pre><p>Remember to change the name field in rockcraft.yaml to become djangoproject as well.</p><p>Next, let’s create a Django app within our project:</p><pre>$ cd djangoproject<br>$ python manage.py startapp django_app</pre><p>By default, a Django project used sqlite as database. We will leave it at that for now and proceed to create the database without altering settings.py. To create the database and an admin user, we run the following commands in terminal (the second command is an interactive one):</p><pre>$ python manage.py migrate<br>$ python manage.py createsuperuser</pre><p>Now, to have an actual application, we will modify two of the django files to have the bare minimum functionality. First, change the file djangoproject/django_app/views.py so it becomes:</p><pre>from django.http import HttpResponse<br><br>def index(request):<br>    return HttpResponse(&quot;&lt;h1&gt;Hello World!&lt;/h1&gt;&quot;)</pre><p>Next, change the file djangoproject/djangoproject/urls.py so it becomes:</p><pre>from django.contrib import admin<br>from django.urls import path<br>from django_app import views<br><br>urlpatterns = [<br>    path(&#39;admin/&#39;, admin.site.urls),<br>    path(&#39;&#39;, views.index),<br>]</pre><p>With this, we implemented a “Hello World” index page in our Django web application. Let’s test by running the development web server:</p><pre>$ python manage.py runserver</pre><p>We can access the Hello World page from any browser by navigating to <a href="http://localhost:8000">http://localhost:8000</a>. We should be able to see the infamous <strong>Hello World!</strong></p><h3>Watch the clock, it’s time to rock!</h3><p>Finally, since our Django app is all set up, we are ready to build our <strong><em>rock</em></strong>!</p><p>Interesting enough, we only need to add 2 more lines to our rockcraft.yaml to make everything magically work. Actually, our final yaml file will look like this:</p><pre>name: djangoproject<br>base: bare<br>build-base: ubuntu@22.04<br>version: &#39;1.0&#39;<br>summary: Django app rock<br>description: Django app rock<br>license: MIT<br>platforms:<br>  amd64:<br><br>extensions:<br>  - django-framework</pre><blockquote>Notice how simple the yaml file is and how it is void of any scripting/coding contents.</blockquote><p><em>NOW, LET’S ROCK! LET’S PACK AND BUILD THE ROCK!</em></p><pre>$ rockcraft pack</pre><p>If you receive no error with this command, but obtain no .rock file at the end of it, make sure you have set the environment variable that I have mentioned before properly.</p><blockquote>Hint: it’s called ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSION</blockquote><p>If everything cooks well, your output should be like this:</p><pre>deleting current features configuration<br>*EXPERIMENTAL* extension &#39;django-framework&#39; enabled                                                                                                                                   <br>deleting current features configuration                                                                                                                                               <br>*EXPERIMENTAL* extension &#39;django-framework&#39; enabled                                                                                                                                   <br>Packed djangoproject_1.0_amd64.rock</pre><p>We did it! Our trophy is a rock and it’s called djangoproject_1.0_amd64.rock!</p><h3>Ready… Set… Run!</h3><p>Let’s give the rock a test drive with a docker run command.</p><p>First convert it to a docker image by running:</p><pre>$ rockcraft.skopeo --insecure-policy copy oci-archive:djangoproject_1.0_amd64.rock docker-daemon:djangoproject:1.0</pre><blockquote>Reminder: skopeo is tool, shipped within Rockcraft’s snap, that allows you to convert an OCI image to a Docker image and vice versa.</blockquote><p>Then create and run the container:</p><pre>$ docker run -d --name mydjango -p 8000:8000 djangoproject:1.0</pre><p>We can finally access our Django we app in the browser by navigating to <a href="http://localhost:8000">http://localhost:8000</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/799/1*vBk-0XCdEHyMNmonsHRqjA.png" /><figcaption>Even a text-based browser (lynx) is happy to serve our django-flavored coffee</figcaption></figure><p><em>Pretty straightforward, huh?</em> You can just close your eyes and let the magic happen automatically. Or, if you are a bit curious how things are working under the hood, the rock’s process manager called <strong><em>pebble</em></strong> allows you to do just so!</p><p>To see the services running using <strong><em>pebble</em></strong>:</p><pre>$ docker exec mydjango pebble services<br><br>Service          Startup  Current  Since<br>django           enabled  active   today at 17:43 UTC<br>statsd-exporter  enabled  active   today at 17:43 UTC</pre><p>You can even see the changes happening while running the image:</p><pre>$ docker exec mydjango pebble changes<br><br>ID   Status  Spawn               Ready               Summary<br>1    Done    today at 17:43 UTC  today at 17:43 UTC  Autostart service &quot;statsd-exporter&quot; and 1 more</pre><p>And more importantly, you can see the logs of your running services:</p><pre>$ docker exec mydjango pebble logs<br><br>2024-05-24T17:43:51.738Z [statsd-exporter] ts=2024-05-24T17:43:51.738Z caller=main.go:300 level=info msg=&quot;Starting StatsD -&gt; Prometheus Exporter&quot; version=&quot;(version=, branch=, revision=2c7fd1edd4bdf01982a648b689da10e5bcff860d-modified)&quot;<br>2024-05-24T17:43:51.739Z [statsd-exporter] ts=2024-05-24T17:43:51.738Z caller=main.go:301 level=info msg=&quot;Build context&quot; context=&quot;(go=go1.22.3, platform=linux/amd64, user=, date=, tags=unknown)&quot;<br>2024-05-24T17:43:51.739Z [statsd-exporter] ts=2024-05-24T17:43:51.738Z caller=main.go:350 level=info msg=&quot;Accepting StatsD Traffic&quot; udp=localhost:9125 tcp=localhost:9125 unixgram=<br>2024-05-24T17:43:51.739Z [statsd-exporter] ts=2024-05-24T17:43:51.738Z caller=main.go:351 level=info msg=&quot;Accepting Prometheus Requests&quot; addr=:9102<br>2024-05-24T17:43:52.855Z [django] [2024-05-24 17:43:52 +0000] [19] [INFO] Starting gunicorn 22.0.0<br>2024-05-24T17:43:52.855Z [django] [2024-05-24 17:43:52 +0000] [19] [INFO] Listening at: http://0.0.0.0:8000 (19)<br>2024-05-24T17:43:52.855Z [django] [2024-05-24 17:43:52 +0000] [19] [INFO] Using worker: sync<br>2024-05-24T17:43:52.857Z [django] [2024-05-24 17:43:52 +0000] [20] [INFO] Booting worker with pid: 20</pre><p>This was just a glance at one of <strong><em>Rockcraft</em></strong>’s new capability. There is so much you can still do with this extension feature. If you want to experiment more, try switching Django settings to use a mysql database, and modify your rockcraft.yaml so that it has a part and a service that installs, configures and run the mysql daemon. If you get stuck or need help, check <a href="https://canonical-rockcraft.readthedocs-hosted.com/en/latest/">the official documentation</a> or ask here in the comments section.</p><h3>Meet the rockstars!</h3><p>Want to learn more about rocks, the team behind them, or stay up-to-date with the rock ecosystem?</p><ul><li>Subscribe to the <a href="https://discourse.ubuntu.com/c/rocks">Rocks Discourse</a> to stay updated with rock news!</li><li>Hop in the <a href="https://matrix.to/#/%23rockcraft:ubuntu.com">Rocks Matrix</a> server to talk to Rockstars, seek help or just to say hello!</li><li>Join the <a href="https://ubuntu.com/community/governance/teams/rocks">Rocks Community</a> and help creating and maintaining rocks!</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cdb7a3e3e55f" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/django-beats-scissors-stands-up-to-paper-cdb7a3e3e55f">Django Beats Scissors, Stands Up to Paper</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Journey With Rock Crafting]]></title>
            <link>https://medium.com/@linostar/a-journey-with-rock-crafting-e3cc4970dfb2?source=rss-9711370ec04------2</link>
            <guid isPermaLink="false">https://medium.com/p/e3cc4970dfb2</guid>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[canonical]]></category>
            <category><![CDATA[lxd]]></category>
            <category><![CDATA[ubuntu]]></category>
            <dc:creator><![CDATA[Anas El Husseini]]></dc:creator>
            <pubDate>Fri, 16 Feb 2024 11:44:04 GMT</pubDate>
            <atom:updated>2024-02-16T13:26:37.169Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KF3kNYaubpg7NN4i" /><figcaption>A “Cool Rock” Photo by <a href="https://unsplash.com/@emilegt?utm_source=medium&amp;utm_medium=referral">Emile Guillemot</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In a journey to a achieving better container images, let’s stop in a cozy corner where we will dive into the fascinating world of <em>Rockcraft</em>. If you’re a bit of a container enthusiast, which I’m guessing you are, you are in for a treat. Today, we are going to unravel some of the secrets of building secure and mini-sized images, affectionately known as <em>“rocks”</em>, using <em>Rockcraft</em>.</p><p>So, what’s <em>Rockcraft</em>, I hear you ask? It is a very crafty tool in your developer’s toolkit, something like a Swiss Army knife for creating super-efficient and secure container images. It is like a professional cook that you gives the recipe (aka <strong>rockcraft.yaml</strong>), then proceeds to fetch the ingredients, then cook, and finally produce the cake. The only drawback is you may lose a tooth or two if you try a bite, as that cake will be as hard as a <em>“rock”</em>.</p><h3>Get Ready for the Hike!</h3><p>And if you are wondering what makes <em>“rocks”</em> special, there are 3 main reasons: <br>- It is based on Ubuntu LTS images for a higher security.<br>- It uses chiselled packages to include only necessary files and binaries.<br>- It has a cute embedded service manager called <em>Pebble</em>!</p><p>Before we start, we’ll will make a checklist of the items we need in our little journey:<br>- <a href="https://ubuntu.com">Ubuntu system</a> or one of its flavors/derivatives<br>- <a href="https://www.docker.com/">Docker</a> needed to test and run our <em>rock</em><br>- <a href="https://documentation.ubuntu.com/lxd/en/latest/installing/">LXD</a> required internally by <em>Rockcraft</em></p><p>Next, let’s install Rockcraft on our system. The most recommended way is by using snap, ensure that we will get the latest stable Rockcraft version:</p><pre>snap install rockcraft --classic</pre><p>Next let’s create an empty folder and move inside it. We will proceed to initiate our first rock:</p><pre>mkdir my-first-rock<br>cd my-first-rock<br>rockcraft init</pre><h3>One YAML to Conquer Them All!</h3><p><em>Rockcraft’</em>s init command will create a <strong>rockcraft.yaml</strong> file in our folder, containing a template ready to be filled in. This yaml file is the recipe to cook our <em>rock</em>. You could think of it as a Dockerfile, but unlike a Dockerfile, it uses a declarative language, allowing for a more efficient image building.</p><p>Looking at our auto-created <strong>rockcraft.yaml</strong>, it should look like this:</p><pre>name: my-rock-name # the name of your rock<br>base: ubuntu@22.04 # the base environment for this rock<br>version: &#39;0.1&#39; # just for humans. Semantic versioning is recommended<br>summary: Single-line elevator pitch for your amazing rock # 79 char long summary<br>description: |<br>  This is my my-rock-name&#39;s description. You have a paragraph or two to tell the<br>  most important story about it. Keep it under 100 words though,<br>  we live in tweetspace and your description wants to look good in the<br>  container registries out there.<br>license: GPL-3.0 # your application&#39;s SPDX license<br>platforms: # The platforms this rock should be built on and run on<br>  amd64:<br>parts:<br>  my-part:<br>    plugin: nil</pre><p>Fields like <strong>name</strong>, <strong>version</strong>, <strong>summary</strong>, <strong>description</strong> and <strong>license</strong> are informative fields and can be changed according to the rock we are trying to make.</p><h3>Secure The Base!</h3><p>Moving on, the <strong>base</strong> field allows us to choose which LTS version we want to base our rock on. At the time of writing this article, the supported versions are <strong>ubuntu@20.04</strong>, <strong>ubuntu@22.04</strong> and <strong>ubuntu@24.04</strong>.</p><p>But wait! <strong>base</strong> also allows for a very cool value called <strong>bare</strong>. Imagine you want to put only your application files inside your rock, and include only the required libraries for your application to run, and not the whole system. With Docker, you would go about that with something like the following in your Dockerfile:</p><pre>FROM ubuntu:22.04 AS builder<br>RUN mkdir /rootfs<br># do things in your /rootfs folder<br><br>FROM scratch<br>COPY --from=builder=/rootfs /<br>ENTRYPOINT […]</pre><p>However with <em>Rockcraft</em>, just use <strong>base: bare.</strong> Along with another field called <strong>build-base</strong>, <strong>base: bare</strong> will do the same magic as above. <strong>build-base</strong> will tell <em>Rockcraft</em> which Ubuntu image will be used to create your<em> rock</em>, but other than that, your image will be stripped out from all other unnecessary files:</p><pre>base: bare<br>build-base: ubuntu@22.04</pre><p><strong><em>Pretty neat, huh?</em></strong></p><blockquote><strong>build-base</strong> supports an extra value called <strong>devel</strong>, which points to the next Ubuntu version that is yet to be released.</blockquote><p>The next field that may have caught your attention is <strong>platforms</strong>. It allows you to build rocks for multiple architectures at the same time (if your system allows it). You will get a separate rock file for each architecture you build for. There are several architectures supported: <strong>amd64,</strong> <strong>arm64</strong>, <strong>armhf</strong>, <strong>i386</strong>, <strong>riscv64</strong>, <strong>ppc64el</strong> and <strong>s390x</strong>.</p><h3>Plug-in-Part!</h3><p>Now let’s come to juicy part, the part where you make the sauce! Conveniently, that part is called <strong>parts</strong>. This is where you put the files and packages you want to have in your <em>rock</em>. You can have multiple parts, each with a different name, and each part needs to have a <strong>plugin</strong>, which can be <strong>nil</strong>.</p><h4>Secret Agent nil</h4><p>If you want just to install packages inside your <em>part</em>, either apt packages from ubtunu repositories or slices (but not both at the same time), then the <strong>nil</strong> plugin is your friend. For instance:</p><pre>parts:<br>  nodejs:<br>  plugin: nil<br>  stage-packages:<br>    - nodejs_bins</pre><p>This will install the <strong>nodejs_bins</strong> slice inside your <em>part</em>, which contains all the necessary files to run Nodejs. By the way, you can discern a slice from an apt package by the underscore, since slice names must have an underscore. <strong>stage-packages </strong>field means that we are asking for that package to be installed in the <em>stage</em> step. There are 5 steps involved in <em>rock</em> packing process, but let’s not delve too deep into that right now.</p><h4>Other Plugins to Explore</h4><p>Unsurprisingly, the <strong>nil</strong> plugin is not the only plugin you can use in your <em>part</em>. But what’s a plugin, I hear you say? It is a build environment already prepared for your configuration and use. If you want to build a python application in your <em>rock</em>, the python plugin will do that for you, courtesy of <em>Rockcraft</em>’s parts model.</p><blockquote>There are a variety of plugins currently supported in Rockcraft parts. The list includes, but is not limited to: nil, python, npm, make, qmake, cmake, go, rust, java and dotnet.</blockquote><p>Another example is the <strong>python</strong> plugin, you can also have it come pre-installed with whatever python packages you need with a plugin property called <strong>python-packages</strong>. Alternatively, you can use <strong>python-requirements</strong> to point to the location(s) of your <strong>requirements</strong> file(s).</p><p>Let’s try that right away, shall we? Let’s create a simple <a href="https://docs.djangoproject.com/en/5.0/intro/tutorial01/">Flask project</a> in a new folder called <strong>src</strong> inside <strong>my-first-rock</strong> folder. We tell it to install <strong>flask</strong> package via <strong>python-packages</strong>. Furthermore, we will need the <strong>python3-venv</strong> installed through <strong>stage-packages</strong>.</p><pre>parts:<br>  python-runtime:<br>    plugin: python<br>    source: src/<br>    python-packages: <br>      - flask<br>    stage-packages:<br>      - python3-venv</pre><p>However, for our first journey we want to try something simple, like running a single python file. The <strong>python</strong> plugin is made to build Python projects, so it will look for something like <strong>setup.py</strong> and <strong>pyproject.toml</strong> and build accordingly. Since we aren’t going that far, we are just using the <strong>python</strong> plugin as a quick way to install Python and Flask.</p><p>Inside the <strong>src</strong> folder, create a file called <strong>hello.py</strong> with the following contents:</p><pre>from flask import Flask<br><br>app = Flask(__name__)<br><br>@app.route(&quot;/&quot;)<br>def hello_world():<br>  return &quot;&lt;p&gt;Hello, World!&lt;/p&gt;&quot;</pre><p>Finally, we want to copy the contents of our local <strong>src</strong> folder to the root of our image. That can be done by adding a second <em>part</em> that uses the <strong>dump</strong> plugin:</p><pre>parts:<br>  python-runtime:<br>    plugin: python<br>    source: src/<br>    python-packages:<br>      - flask<br>    stage-packages:<br>      - python3-venv<br> <br>  hello-app-files:<br>    plugin: dump<br>    source: src/</pre><p>Et voilà! <strong><em>It is simplicity itself, my dear Watson!</em></strong></p><h3>Thank You for Your Service!</h3><p>Now that we have our files and packages already well-tidied in our <em>rock</em> image, we need to run our Flask application. Our tiny friend <em>Pebble</em> comes to shine at this moment, because it will take care of running everything under the hood through the field <strong>services</strong>. In our case, we will use something as simple as:</p><pre>services:<br>  flask-service:<br>  startup: enabled<br>  override: replace<br>  command: flask --app /hello run --host=0.0.0.0</pre><p>This will make Flask runs the single application file we have at <strong>/hello.py</strong> inside the rock.</p><p>Now our complete <strong>rockcraft.yaml</strong> should look like this:</p><pre>name: my-first-rock<br>base: ubuntu@22.04<br>version: &#39;1.0&#39;<br>summary: My first amazing rock<br>description: |<br>  This is my first rock. Deal with it.<br>license: MIT<br>platforms:<br>  amd64:<br><br>services:<br>  flask-service:<br>    startup: enabled<br>    override: replace<br>    command: flask --app /hello run --host=0.0.0.0<br><br>parts:<br>  python-runtime:<br>    plugin: python<br>    source: src/<br>    python-packages:<br>      - flask<br>    stage-packages:<br>      - python3-venv<br> <br>  hello-app-files:<br>    plugin: dump<br>    source: src/</pre><h3>Cook It Nice and Slow!</h3><p>We are ready to cook as all the ingredients are ready in the pot. Start the fire by running:</p><pre>rockcraft pack</pre><p>This may take a couple of minutes, so lay back and contemplate the beauty of the nature around or your incomparable genius, whichever way you swing.</p><p>When <em>Rockcraft</em> successfully finishes packing, you will get your prize: a nice rock image named <strong>my-first-rock_1.0_amd64.rock</strong>.</p><h3>Run It for Your Life!</h3><p>Unfortunately, we cannot run the rock image directly in a container manager such as Docker. However, a nifty tool called <em>skopeo</em> can convert our rock, an oci archive, to a Docker image. Luckily for us, <em>skopeo</em> comes installed within the <em>Rockcraft</em> snap. Run the following command:</p><pre>skopeo --insecure-policy copy oci-archive:my-first-rock_1.0_amd64.rock docker-daemon:my-first-rock:1.0</pre><p>Let’s run this Docker image right away:</p><pre>docker run -d -p 5000:5000 --name first-rock my-first-rock:1.0</pre><p>This will launch our flask app in our <em>rock</em>, which we can access on a browser at <a href="http://localhost:5000">http://localhost:5000</a>.</p><h3>Rock Hard!</h3><p>After this rather, hopefully, enjoyable journey, I hope we learned together a thing or two about rocks and how to craft them. There is much more to discover about them rocks, so here are a few tips on what to do next:</p><p>- Subscribe to the <a href="https://discourse.ubuntu.com/c/rocks">Rocks Discourse</a> to stay updated with rock news!<br>- Hop in the <a href="https://matrix.to/#/%23rockcraft:ubuntu.com">Rocks Matrix</a> server to talk to Rockstars, seek help or just to say hello!<br>- Learn more about Rockraft through <a href="https://canonical-rockcraft.readthedocs-hosted.com/en/latest/">its official documentation</a>!<br>- Join the <a href="https://ubuntu.com/community/governance/teams/rocks">Rocks Community</a> and help creating and mainting rocks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e3cc4970dfb2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Archnemesis of Listicles]]></title>
            <link>https://medium.com/the-haven/the-archnemesis-of-listicles-51f25ed474ee?source=rss-9711370ec04------2</link>
            <guid isPermaLink="false">https://medium.com/p/51f25ed474ee</guid>
            <category><![CDATA[writing-tips]]></category>
            <category><![CDATA[humor]]></category>
            <category><![CDATA[stories]]></category>
            <category><![CDATA[writing]]></category>
            <category><![CDATA[listicles]]></category>
            <dc:creator><![CDATA[Anas El Husseini]]></dc:creator>
            <pubDate>Mon, 14 Nov 2022 22:01:57 GMT</pubDate>
            <atom:updated>2022-11-14T22:01:57.706Z</atom:updated>
            <content:encoded><![CDATA[<p>Let’s first agree that listicles are attractive. If you aren’t familiar with the name, it means articles that have a clickbait titles like <strong><em>“x things to make this do that”</em></strong>, and the article contents will be a list that enumerate those breathtaking meaningless points.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*EX887ExZhU12RQ1OlcCs8g.jpeg" /><figcaption>Captivated by numbers. Courtesy of iStock.</figcaption></figure><p>So, what’s the secret behind listicles? We find them anywhere and everywhere, and fall in the trap of clicking on their titles again and again, because numbers are so magical and so mesmerizing. After all, we can’t resist the temptation of knowing <strong><em>31 ways that spaghetti can make us more attractive to the other sex</em></strong>, or the <strong><em>17 life hacks that will make squirrels salute us on our way to work</em></strong>, can we? Mind that we often end disappointed and almost gaining nothing useful after reading those listicles, but the addiction is just too strong, just like the <strong><em>23 non-addicitive substances we use daily to survive in our tough lives</em></strong>.</p><p>Prolific writers like listicles. They allow them to write more with less words, plus they gain more attraction, so more money. That made our environment full of nearly useless content, shining like beautiful balloons, but containing nothing but mere cheap air. With the help of our smart devices constantly spying on us, you can expect that the next time you stumble and fall down the stairs, you will find waiting for you a listicle titled <strong><em>“11 steps to heal your broken bones fast”</em></strong>. Yes, they are even accomodating you by counting the number of the steps you fell over.</p><p>So, what can replace those silly listicles? It’s an old nemesis that existed long before them: <strong>stories</strong>. You can read hundreds of listicles, with none leaving any traces over in your memory, but you can never forget that nice story that your cousin told you over a sleepover night when you were 9 years old. Whether it is funny, dramatic, full of wisdom, or scares the shit of you; whether it was told by your grandma, your friend, or by that great movie you watched; a good story will stay with you, and can even shape a part of what you are. But <strong>good stories are rare</strong>, and very hard to come up with. Nonetheless, you don’t need to write great stories all the time, or even create one out of your imagination. You can tell one of your own, based on a real event taht happened with you, and by picking your own narrative and telling it your own way. It doesn’t have to be accurate, and it doesn’t even have to be interesting to everyone. What’s important that it has meaning to you, and that <strong>you enjoy voicing it over to others by writing</strong>.</p><p>Now you know about this little secret. When you’re about to write something next time, remember to review my article <strong><em>“7 ways to avoid being beaten by clickbaits full of repetitive contents”</em></strong>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=51f25ed474ee" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-haven/the-archnemesis-of-listicles-51f25ed474ee">The Archnemesis of Listicles</a> was originally published in <a href="https://medium.com/the-haven">The Haven</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The 5 Underrated Tips to Become a Millionaire Writer]]></title>
            <link>https://medium.com/the-haven/the-5-underrated-tips-to-become-a-millionaire-writer-504389017cd7?source=rss-9711370ec04------2</link>
            <guid isPermaLink="false">https://medium.com/p/504389017cd7</guid>
            <category><![CDATA[writing-tips]]></category>
            <category><![CDATA[clickbait]]></category>
            <category><![CDATA[writing]]></category>
            <category><![CDATA[millionaire]]></category>
            <category><![CDATA[satire]]></category>
            <dc:creator><![CDATA[Anas El Husseini]]></dc:creator>
            <pubDate>Wed, 28 Apr 2021 18:16:12 GMT</pubDate>
            <atom:updated>2021-04-28T18:16:12.961Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*iJNQOfDw0VDlxrkG" /><figcaption>Photo by <a href="https://unsplash.com/@kenziem?utm_source=medium&amp;utm_medium=referral">Mackenzie Marco</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Scientists often stand bewildered in front of this grayish-green banknote. Is it the ink-rich smell? Is it the non-balanced layout that triggers OCD to many people? Is it the mysterious Franklin smile that beats that of the Mona Lisa? Whichever it is, and despite Franklin’s apparent discontent, everyone loves to swim in a pool of those notes, so here are 5 tips on how to mass produce them through a writing career:</p><h3>1. A Word Is Worth a Thousand Pictures</h3><p>Just stack those words together in endless sentences. Make your readers dizzy with the uninterruptible flow of letters. Put everything together in one super long paragraph, minimize line spacing if possible, and put away any form of separation that let the readers take a break. After all, quality is measured in mm cube of ink per inch (or black pixels per inch), so squeeze every pixel you can in the reader’s face.</p><h3>2. Clickbait With Numbers</h3><p>You probably noticed how much a fancy number in an article title attracts people, even when they already assume it’s a clickbait. On a platform like Medium, those clickbait articles seem to find their way more easily to the front page.</p><p>Numbers are magical; they tell so much with less symbols. Imagine that you’d have to draw 78 sticks in order to represent the same corresponding number otherwise. Therefore, exploiting their incurable weakness, humans will almost always fall victim to this simple trick. You know that firsthand since you’re already here, don’t you?</p><h3>3. Proofreading Is For the Unprofessional</h3><p>Writing about controversial topics is a sure way to invite an infinite stream of commentators. If you can’t write about such topics, worry not! A lack of proofreading will definitely attract a herd of special grammar nazis instead. Just remember to write in an inconsistent style. Ignore those red-lined words pointed out by Microsoft Word spellchecker; they only prove how much envy Microsoft has for your unparalleled writing talent.</p><h3>4. Everyone Can Google</h3><p>Wasting hours on research before writing? Nah, that’s not us! Readers can use Google to verify any crazy stuff you published. If they find anything wrong, then it’s for the better: negative comments are comments after all.</p><p>Sometimes you need to rely on other sources of information, either due to your total ignorance of the topic or because you are too tired to make things up. In such cases, you better hide the references you have used. How much you “borrowed” from those references should stay a top secret to the very end.</p><h3>5. Be a Lonely Wolf</h3><p>You may have contemplated the idea of posting your article in a publication. I’m glad I got to you just in time then. You are already a well-established writer, having reached your peak of 7 claps on Medium just last week. Are you really going to endanger your fame and image by collaborating with a publication? You don’t need to think twice about it.</p><p>Imagine those cunning editor-in-chiefs lurking in the darkness of their offices behind old screens waiting for you to submit your article to them. They swore they’re not after your money, but if they suddenly changed their terms and decided they wanted a share of your earnings? Can your risk losing a portion of the $3.57 you earned over the few last months? Hell no!</p><h3>To Wrap It Up</h3><p>By the time you’ve reached this section, the effect of applying the techniques above must be driving six-figure numbers to your bank account. You can finally stare back fearlessly at your life partner who has been financially supporting you for so long.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=504389017cd7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-haven/the-5-underrated-tips-to-become-a-millionaire-writer-504389017cd7">The 5 Underrated Tips to Become a Millionaire Writer</a> was originally published in <a href="https://medium.com/the-haven">The Haven</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>