<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Emil Privér</title>
    <description>The latest articles on Forem by Emil Privér (@emil_priver).</description>
    <link>https://forem.com/emil_priver</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F93412%2Ff1f447c5-0408-4242-9c2e-1fb599b4a172.jpg</url>
      <title>Forem: Emil Privér</title>
      <link>https://forem.com/emil_priver</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/emil_priver"/>
    <language>en</language>
    <item>
      <title>Running schema/database migrations using Geni</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Wed, 17 Apr 2024 13:53:01 +0000</pubDate>
      <link>https://forem.com/emil_priver/running-schemadatabase-migrations-using-geni-32jh</link>
      <guid>https://forem.com/emil_priver/running-schemadatabase-migrations-using-geni-32jh</guid>
      <description>&lt;p&gt;A while ago, I developed &lt;a href="https://github.com/emilpriver/geni"&gt;Geni&lt;/a&gt;, a CLI database migration tool. The goal of the app was to make migrations to &lt;a href="https://turso.tech/"&gt;Tursos&lt;/a&gt; databases easier. When I developed Geni, I also decided to add support for Postgres, MariaDB, MySQL, and SQLite. The goal of this post is to describe what database/schema migrations are and how to perform them via Geni.&lt;/p&gt;

&lt;p&gt;A schema within a database describes its current structure, which includes elements such as tables, indexes, and constraints. When you connect to a PostgreSQL database and run &lt;code&gt;\\d+&lt;/code&gt;, you'll see something like this:&lt;/p&gt;

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

&lt;p&gt;The image above shows the current structure of my &lt;code&gt;job&lt;/code&gt; table. Essentially, migrations are used to modify the database structure. In other words, a migration is a set of instructions for making changes to your database.&lt;/p&gt;

&lt;p&gt;Suppose you receive a new task at work that requires you to add a table and a new column to another table. One approach is to connect to the database and make these changes manually. Alternatively, you could use a tool, such as Geni, for this task.&lt;/p&gt;

&lt;p&gt;Using Geni offers several advantages. It provides a reproducible database structure, useful for deploying to different environments or running tests within a CI. Because they are just normal SQL files, you can version control them within your repository. Additionally, Geni allows for programmatically making changes to your database without human input.&lt;/p&gt;

&lt;p&gt;I've applied this within a project running on Kubernetes. When we released a new version of our app within the Kubernetes cluster, we spun up a &lt;a href="https://github.com/emilpriver/geni/pkgs/container/geni"&gt;geni container&lt;/a&gt; in the same Kubernetes namespace. This container checked for any migrations and, if found, ran them before terminating itself.&lt;/p&gt;

&lt;p&gt;You can utilize migrations in your integration tests to evaluate the entire application against its actual structure.&lt;/p&gt;

&lt;p&gt;There are specific requirements for using this type of tool. Firstly, each migration can only be executed once; if a migration has been applied, it cannot be reapplied. Secondly, migrations need to be run in the correct sequence; for instance, migration 3 cannot be executed before migration 2.&lt;/p&gt;

&lt;p&gt;Geni handles this by checking if the table &lt;code&gt;schema_migrations&lt;/code&gt; exists in your database before executing each migration. If it doesn't, Geni creates the table and inserts the migration id. This table is used to keep track of which migrations have been applied.&lt;/p&gt;

&lt;p&gt;When Geni creates migrations, it uses timestamp as the ID, followed by the name of the migration. The format for a migration is &lt;code&gt;{TIMESTAMP}_{NAME}.sql&lt;/code&gt;. Geni orders each migration based on the ID because it's incremental, preventing migrations from being run in the wrong order.&lt;/p&gt;

&lt;p&gt;This is why Geni scales effectively with your projects. It allows you to track each migration within your version control. Simultaneously, you can view the current database structure by reading the schema.sql file that Geni also produces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;There are several ways to install Geni:&lt;/p&gt;

&lt;h3&gt;
  
  
  Github
&lt;/h3&gt;

&lt;p&gt;You can download the official binaries directly from Github here: &lt;a href="https://github.com/emilpriver/geni/releases"&gt;https://github.com/emilpriver/geni/releases&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Homebrew
&lt;/h3&gt;

&lt;p&gt;You can install Geni using the Homebrew package manager with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;brew&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;emilpriver&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;geni&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;geni&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cargo
&lt;/h3&gt;

&lt;p&gt;You can also install Geni using Cargo with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;cargo&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;geni&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PKGX
&lt;/h3&gt;

&lt;p&gt;Alternatively, you can run Geni using PKGX with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;pkgx&lt;/span&gt; &lt;span class="nx"&gt;geni&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Migration
&lt;/h2&gt;

&lt;p&gt;Creating a migration is straightforward. Start by running the following command in your repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;geni&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;new_table&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Geni will create two new files in the &lt;code&gt;./migrations&lt;/code&gt; folder. These files end with .up.sql and .down.sql respectively.&lt;/p&gt;

&lt;p&gt;The .up.sql file is where you write new changes. For instance, if you want to create a new users table, you could add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The .down.sql file is for rolling back changes. Ideally, the SQL code in the .down.sql file should revert the changes made in the .up.sql file. An example is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the migration
&lt;/h2&gt;

&lt;p&gt;After creating your new migration, execute &lt;code&gt;geni up&lt;/code&gt; to apply the migrations. This command will prompt geni to read the migrations folders and apply them.&lt;/p&gt;

&lt;p&gt;You can also run Geni directly via GitHub Actions as part of your CI flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;emilpriver&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;geni&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;
  &lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;migrations_folder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"./migrations"&lt;/span&gt;
    &lt;span class="n"&gt;wait_timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"30"&lt;/span&gt;
    &lt;span class="n"&gt;migrations_table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"schema_migrations"&lt;/span&gt;
    &lt;span class="n"&gt;database_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"&amp;lt;https://localhost:3000&amp;gt;"&lt;/span&gt;
    &lt;span class="n"&gt;database_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"X"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can include it as a container in your docker-compose file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;"3.8"&lt;/span&gt;

&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;luigi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;
      &lt;span class="n"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;
      &lt;span class="n"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;development&lt;/span&gt;
    &lt;span class="n"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;"7432:5432"&lt;/span&gt;
    &lt;span class="k"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unless&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stopped&lt;/span&gt;

  &lt;span class="n"&gt;migration&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ghcr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;emilpriver&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;geni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;luigi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;development&lt;/span&gt;
    &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrations&lt;/span&gt;
    &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;
    &lt;span class="n"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I use Geni as a container for projects where I want others to easily set up and run an environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The end
&lt;/h2&gt;

&lt;p&gt;I hope this article has inspired you to use migrations for your databases, and perhaps even try Geni.&lt;/p&gt;

&lt;p&gt;If you're interested in tracking the development of Geni, I recommend starring it on GitHub: &lt;a href="https://github.com/emilpriver/geni"&gt;https://github.com/emilpriver/geni&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more of my content, consider following me on Twitter: &lt;a href="https://twitter.com/emil_priver"&gt;https://twitter.com/emil_priver&lt;/a&gt;&lt;/p&gt;

</description>
      <category>migrations</category>
      <category>database</category>
      <category>turso</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Geni, A database migration CLI tool</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Thu, 28 Dec 2023 08:34:58 +0000</pubDate>
      <link>https://forem.com/emil_priver/geni-a-database-migration-cli-tool-3jdn</link>
      <guid>https://forem.com/emil_priver/geni-a-database-migration-cli-tool-3jdn</guid>
      <description>&lt;p&gt;I'm excited to introduce Geni, a user-friendly CLI migration tool for databases written in Rust. It currently supports LibSQL, Postgres, MariaDB, MySQL, and SQLite, and I have plans to add support for more databases in the future. The concept behind Geni is simple: it can seamlessly integrate with your code as a plugin for your CI, or as a sidebar in Kubernetes, without causing any disruptions or requiring you to use a specific programming language.&lt;/p&gt;

&lt;p&gt;Personally, I'm a big fan of &lt;a href="https://github.com/amacneil/dbmate"&gt;dbmate&lt;/a&gt; and I rely on it for both my professional and personal projects to handle migrations. It's an excellent tool. However, when they declined my &lt;a href="https://github.com/amacneil/dbmate/pull/470"&gt;PR&lt;/a&gt; to add LibSQL support, I decided to develop my own CLI tool. I couldn't find any satisfactory migration tools, although I did come across &lt;a href="https://atlasgo.io/"&gt;Atlas&lt;/a&gt;. However, Atlas handles migrations in a way that doesn't align with my preferences, and it also appears to be closely tied to Kubernetes. &lt;/p&gt;

&lt;p&gt;Geni became my Christmas project with the goal of being a small component for your workspaces. One common issue with migrations is not keeping track of which migrations have been executed. Geni (and dbmate, for that matter) solves this problem by storing all migrated migrations in the database. This ensures that developers won't overwrite or re-run the same migrations. &lt;/p&gt;

&lt;p&gt;The application is developed using Rust and relies on the &lt;a href="https://github.com/libsql/libsql-client-rs"&gt;libsql-client-rs&lt;/a&gt; library for SQLite and LibSQL. Moreover, it makes use of &lt;a href="https://github.com/launchbadge/sqlx"&gt;SQLX&lt;/a&gt; to support Postgres, MariaDB, and MySQL databases. As this is written in rust is it lighting fast, blazingly fast, tiny, ultra fast and memory safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Databases:

&lt;ul&gt;
&lt;li&gt;Postgres&lt;/li&gt;
&lt;li&gt;MariaDB&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;li&gt;LibSQL&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Generating migrations using &lt;code&gt;geni new &lt;strong&gt;name&lt;/strong&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Migrating using &lt;code&gt;geni up&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Rollback using &lt;code&gt;geni down&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create database using &lt;code&gt;geni create&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Dropping database using &lt;code&gt;geni drop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Timestamp based migrations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Github
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fsSL&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/emilpriver/geni/releases/latest/download/geni-linux-amd64&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;chmod&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;geni&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Homebrew
&lt;/h3&gt;

&lt;p&gt;TBA(check &lt;a href="https://github.com/emilpriver/geni"&gt;github&lt;/a&gt; for more information). Will be added when we are out of beta&lt;/p&gt;

&lt;h3&gt;
  
  
  Scoop
&lt;/h3&gt;

&lt;p&gt;TBA(check &lt;a href="https://github.com/emilpriver/geni"&gt;github&lt;/a&gt; for more information). Will be added when we are out of beta&lt;/p&gt;

&lt;h3&gt;
  
  
  PKGX
&lt;/h3&gt;

&lt;p&gt;Run using PKGX&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pkgx geni up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Docker
&lt;/h3&gt;

&lt;p&gt;Docker images are published to GitHub Container Registry (&lt;a href="https://ghcr.io/emilpriver/geni"&gt;ghcr.io/emilpriver/geni&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run --rm -it --network=host ghcr.io/emilpriver/geni --help

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you wish to create or apply migrations, you will need to use Docker's &lt;a href="https://docs.docker.com/storage/bind-mounts/"&gt;bind mount&lt;/a&gt; feature to make your local working directory (&lt;code&gt;pwd&lt;/code&gt;) available inside the geni container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="s"&gt;"./migrations:./migrations"&lt;/span&gt; &lt;span class="n"&gt;ghcr&lt;/span&gt;&lt;span class="py"&gt;.io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;emilpriver&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Commands
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;    &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Generate&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;migrations&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;     &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Run&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;pending&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt;
&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;down&lt;/span&gt;   &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Rollback&lt;/span&gt; &lt;span class="n"&gt;migrations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;speify&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;many&lt;/span&gt; &lt;span class="nf"&gt;migrations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;works&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Postgres&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MariaDB&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;MySQL&lt;/span&gt;&lt;span class="py"&gt;. If&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;SQLite&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;migrations&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;sqlite&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;don&lt;/span&gt;&lt;span class="nv"&gt;'t&lt;/span&gt; &lt;span class="n"&gt;exist&lt;/span&gt;&lt;span class="py"&gt;. LibSQL&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="n"&gt;respective&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="py"&gt;.
geni&lt;/span&gt; &lt;span class="nb"&gt;drop&lt;/span&gt;   &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;
&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;   &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Print&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example usage
&lt;/h2&gt;

&lt;p&gt;First, make sure you have installed Geni CLI using one of the installation methods mentioned above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a New Migration
&lt;/h3&gt;

&lt;p&gt;To create a new migration, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"x"&lt;/span&gt; &lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;hello_world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate two files, one ending with &lt;code&gt;.up.sql&lt;/code&gt; and the other with &lt;code&gt;.down.sql&lt;/code&gt;. The &lt;code&gt;.up.sql&lt;/code&gt; file is used for creating migrations, while the &lt;code&gt;.down.sql&lt;/code&gt; file is used for rolling back migrations. The path to the generated files will be displayed in the console.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding SQL to the Migration
&lt;/h3&gt;

&lt;p&gt;Open the &lt;code&gt;.up.sql&lt;/code&gt; file and add your SQL code to create the desired database table or make any other changes you need. For example, to create a table named &lt;code&gt;Persons&lt;/code&gt;, you can add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="nf"&gt;Persons&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;PersonID&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to include the corresponding rollback code in the &lt;code&gt;.down.sql&lt;/code&gt; file. In this case, the rollback code would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;DROP&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Persons&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the Migration
&lt;/h3&gt;

&lt;p&gt;To run the migration and apply the changes to the database, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;geni&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will execute all pending migrations and update the database accordingly.&lt;/p&gt;

&lt;p&gt;That's it! You have now successfully created a migration, added SQL code to it, and executed the migration using Geni CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  End
&lt;/h2&gt;

&lt;p&gt;That’s it. Hope this CLI might be useful to you :D  If you find any bugs then I would love to hear about them here &lt;a href="https://github.com/emilpriver/geni/issues"&gt;https://github.com/emilpriver/geni/issues&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't forget to follow me on twitter: &lt;a href="https://twitter.com/emil_priver"&gt;https://twitter.com/emil_priver&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Elixir: Introduction</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Tue, 13 Dec 2022 11:58:16 +0000</pubDate>
      <link>https://forem.com/emil_priver/elixir-introduction-1nm2</link>
      <guid>https://forem.com/emil_priver/elixir-introduction-1nm2</guid>
      <description>&lt;p&gt;I did recently visit a small Elixir and Erlang talk in Varberg, Sweden and I learned some stuff that is something I want to share in this article. The first impression I got was that elixir is a language that is made to be easily understood by developers (short time to get started) but is also built quite smart when it comes to stuff such as spreading running code over multiple cores. But also do elixir have support for releasing a new update to the server without needing to restart the server (hot swap).&lt;br&gt;
Erlang also comes with soft real-time computing meaning that when Elixir is computing real-time data does Elixir allows tasks to be sent after the task's deadline without the system handling the tasks as a failure as long as the task is completed. &lt;/p&gt;
&lt;h2&gt;
  
  
  What is Elixir
&lt;/h2&gt;

&lt;p&gt;Elixir is a functional, concurrent, fault-tolerance and general-purpose programming language running in Erlang VM, built to make it easy to develop scalable and maintainable applications, also a language that gives a guarantee to know if another process is killed or stuck. The language comes with support for hot-swapping code, meaning that you can swap out running code and use the new functionality without interrupting the service. Ericsson did build the language erlang and erlang-VM to be able to hot swap code which is running without interrupting or closing phone calls. With other languages could this mean downtime which is something that telecom can't have as important calls could be active when a bug needs to be fixed urgently. &lt;/p&gt;

&lt;p&gt;Elixir runs your code in lightweight threads when your code is executed, called processes. Each process is isolated but talks (exchange information) to another process via what Elixir calls "Messages". It's not uncommon that Elixir is running 100 thousands of processes concurrently without impacting another process. As all the processes are running isolated, each process has its garbage collection, meaning that 1 process doesn't need to stop other processes from running. In languages such as JavaScript could this mean that the whole script is not running as Node needs to handle its garbage, in elixir case would this mean that the code you are serving your users won't stuck or be slow. This is generally called the actor model. The Actor model is a mathematical model of concurrent computation that treats the actor as the universal primitives of concurrent computation. When an Actor receives a message is it able to make its own decisions such as creating more actors, sending more messages, and telling the system how to respond to the next message. An actor can modify its state but no other process states directly, but can modify other processes states by messaging. As each process can communicate with another process does also Elixir provide fault-tolerance functionality by creating what Elixir calls "supervisors". The supervisor is used to telling the system how to restart parts of your system when things go bad and revert it to its initial state which is guaranteed to work, this is also how Elixir can guarantee fault tolerance. To make Elixir able to run concurrently does it need BEAM or Bogdan Erlang Abstract Machine which is Erlangs Virtual Machine.&lt;/p&gt;

&lt;p&gt;Erlangs OTP could you say is a part of the code of Erlang which is providing modules, libraries, and behaviors that represent standard implementations of common practices like message passing or spawning tasks. This means that instead of inventing the wheel again for common services like GenServer, Elixirs OTP provides these tools for you to just grab and use. BEAM uses 1 OS thread per core and runs a scheduler on every os thread to schedule tasks to be executed on that core.&lt;/p&gt;

&lt;p&gt;An OTP that Erlang provides which can be used in Elixir is called GenServer. A library that Erlang provides which can be used in Elixir is called GenServer which is a long-running stateful process allowed to send and receive messages. As GenServer or generic server process is that you can keep GenServer always up to date but also execute code async, create a standard set of functions that can be re-used, and also a good way to log errors via GenServer. But it does also provide a good way to handle monitoring events and system messages. GenServer is part of a supervisor and works as a client-server relation between your code and the GenServer. But GenServer is not the only way to work with a state in your application, Erlang also provides ETS or Erlang Term Storage which is a robust in-memory storage store built into OTP which makes it usable within Elixir.  ETS can store large amounts of data available to processes.&lt;/p&gt;

&lt;p&gt;Outside of platform and language features does also Elixir provide good tooling features which are built to help you develop your application. The mix is the tool used to create, build, manage tasks, and run tests in your application. But Elixir does also provide tooling to interact with your code, the same way Django has interactive tooling. Here are you able to run different functionality such as code reloading, reading formatted docs, or debugging a problem by executing functions in a shell environment. But these interactive tools are also reachable from a website that enables you to run functionality in your code from a website called Livebook.&lt;/p&gt;
&lt;h2&gt;
  
  
  Atoms
&lt;/h2&gt;

&lt;p&gt;An atom is a constant whose value is its name with no static type assigned to the atom as Elixir is a dynamic language. Some of those are defined by the system to create a standard for how the code is running. One of these atoms is ":ok" which can be used to tell a function that the execution of the function was ok and no error happened. To be able to create an atom in another language would you need to create a constant and assign a value to it with a static type. Meaning that a language that is strict on types would probably create problems as you could check if a return value which is a string is the same as a constant which is a number, but with the same data in both the return and the constant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;:apple&lt;/span&gt;
&lt;span class="ss"&gt;:apple&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;:orange&lt;/span&gt;
&lt;span class="ss"&gt;:orange&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;:apple&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:apple&lt;/span&gt;
&lt;span class="no"&gt;true&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;:apple&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:orange&lt;/span&gt;
&lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Phoenix
&lt;/h2&gt;

&lt;p&gt;Phoenix is a web framework built on Elixir which implements a server-sided Model View Controller. For people that know what Pythons Django is, then Phoenix is the similarity but for Elixir with some extra features such as LiveView. But it also comes with features such as PubSub and Swoosh which are 2 great libraries providing value when developing your Phoenix application. PubSub is used to develop real-time functionality on your website and Swoosh is a feature to help you compose, deliver and test emails sent from your application. As Phoenix comes with a lot out of the box it makes you able to get up and running fast but also that you don't need to reinvent the wheel as Phoenix has a lot of tools already created for you.&lt;/p&gt;

&lt;p&gt;More info about Phoenix &lt;a href="https://www.phoenixframework.org/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Phoenix's LiveView
&lt;/h3&gt;

&lt;p&gt;The first thought I had when I first did see Phoenix's live view was that it looked like React Server Components which is not the case. It's more like Blazor's live view. Phoenix live view works by listening to a WebSocket which broadcasts messages to the socket telling it to re-render parts of the HTML/template. This means that if you make a change to the server side for example, that an SMS is sent into the system and your users need this information without reloading the page then phoenix can show that message without reloading the page by sending the message into the socket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Livebook
&lt;/h2&gt;

&lt;p&gt;Livebook is Elixir's version of Jupyter but with some extra cool functions. Livebook is a library of markdown files where you can add executable Elixir code which can for example be used to discover more about your program or work with data but they also give you LiveView and Beam which allows you to write code in 1 place and re-use it in another place. But also to collaborate in a team within your&lt;br&gt;
Livebook. Livebook is both available to run locally on your machine and also in the cloud to enable multiple people to use the same Livebook server and work together.&lt;/p&gt;

&lt;p&gt;Livebook is also able to let you investigate problems within your running project. This means that if your customers are experiencing problems and you want to find out what the problem is, then you can within Livebook test certain functionality even if the application is still serving your users. But also a good way to document your application to enable others in your team to understand and work with your application easier.&lt;/p&gt;

&lt;p&gt;More info about Livebook &lt;a href="https://livebook.dev/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern Matching
&lt;/h2&gt;

&lt;p&gt;I've heard that pattern matching was something good within Elixir, so I looked into it.  In elixir is &lt;code&gt;=&lt;/code&gt; a match operator which you can compare to the equal sign in algebra, where the goal is that the value on the left side of &lt;code&gt;=&lt;/code&gt; is the same as the value on the right side of &lt;code&gt;=&lt;/code&gt;. And if the values match does Elixir return the value, or it throws an error if it fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MatchError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;hand&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="ss"&gt;value:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we see that in the first 2 examples both values did match as 1 &lt;code&gt;=&lt;/code&gt; x and x &lt;code&gt;=&lt;/code&gt; 1 but when we tried to check if 2 = x then the execution failed as 2 != 1. Now, this is a basic example that in many other languages works the same, but pattern matching in elixir also works with for example tuples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="ss"&gt;:hello&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="s2"&gt;"world"&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MatchError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;hand&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="ss"&gt;value:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning that we can use this when we for example want to match the return value of a function. We are also able to pattern match on lists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we can use a pipeline to add the rest of the values to 1 variable&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And append values to an array in an easy way with the pipeline&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But Elixir also supports the pin operator which is used to do pattern matching to a variable with an existing variable rather than rebinding the variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MatchError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;hand&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="ss"&gt;value:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we did earlier pinned value of x to 1 is the equivalent of the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MatchError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;hand&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="ss"&gt;value:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use-cases of Elixir or Erlang in production
&lt;/h2&gt;

&lt;p&gt;There are plenty of use cases for Elixir or Erlang by companies but most of the companies I've seen using the languages in production use it for real-time communication or messages queues and some of these companies are Spotify, Discord, Klarna, Ericsson, and WhatsApp. But Elixir is also popular in e-commerce, banking, advertising, and IoT maybe because it has plenty of libraries and frameworks built on top of it, such as Phoenix. And one of the main reasons is that Elixir handles a lot of traffic concurrently and scales easily due to Erlang's VM. Elixir, on the other hand, will probably not be the fastest choice, but it handles tons of traffic on a high level.&lt;/p&gt;

&lt;p&gt;More use-cases at &lt;a href="https://elixir-lang.org/cases.html" rel="noopener noreferrer"&gt;Elixirs website&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Discord
&lt;/h3&gt;

&lt;p&gt;Discord has been using Elixir since the beginning and handling the core of its products which is the chat infrastructure. Discord is a real-time communication service with both voice and messaging support which as of 8 October 2020 handles 100 million active users each month. Elixir was picked to power relaying messages, real-time applications, and Discord's WebSocket which is used for real-time communication within all apps they provide. While Discord uses Python to power its API. While the Python part of the infrastructure is a monolith while the Elixir part has multiple services distributed to multiple servers running each task concurrently with GenServer and GenStage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cars.com
&lt;/h3&gt;

&lt;p&gt;Cars.com is one of the leading platforms for selling cars and buying cars online serving more than 400 million visitors annually. Adopting Elixir as the primary language for its application enabled developers to get started faster and understand the code faster helping cars.com to grow faster and enabling 0 downtimes with a scalable and reliable platform. Cars.com uses Phoenix for its front end enabling Cars.com to show real-time data for its users.&lt;/p&gt;

&lt;h3&gt;
  
  
  All Aboard
&lt;/h3&gt;

&lt;p&gt;All Aboard is a Swedish company selling train tickets all over the world.  They use Elixir to run their backend in a pretty cool way. As All Aboard needs to fetch information from multiple APIs could this mean that they need to way a long time for the response they need for their users, and sometimes they fetch APIs returning links to other APIs which need to also be fetched. They solved this by creating a struct that returns&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:async&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fetch_the_other_thing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the whole struct is built do they go through each value and put them into a queue in GenServer which creates tasks with the respective function and executes it and as fast as a new task is done will a new task start. And as fast as they have a new response, they add a new message to their WebSocket which updates user's view.&lt;br&gt;
In this case, does Elixirs Concurrency work really well as some responses could take a really long time and still don't interrupt other tasks that are running.&lt;/p&gt;

&lt;p&gt;I did ask Patrik at All Aboard for a comment on what he thought about Elixir and how they use Elixir. Patrik told that as he comes from Python and Ruby and thinks this quite magical because it's easy to understand Elixir, and it's model, but also works really well.&lt;/p&gt;

&lt;p&gt;Thanks to Patrik at All Aboard for wanting to share his experience and how he use Elixir. You can find more information about All Aboard on their &lt;a href="https://allaboard.eu/" rel="noopener noreferrer"&gt;website&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My thoughts
&lt;/h2&gt;

&lt;p&gt;I think Elixir is a great language that can handle tons of work at the same time due to its concurrent model but also how easy it is to get started with Elixir and get up and running. I don't think programming should be hard, and many languages make it hard to get up and running quickly, but also hard to write your program in general. This is something that Elixir doesn't have due to the tooling they have created and the way the language is written. Something I don't like is that it doesn't come as required, mostly because I think types help prevent problems and enable us to remove some tests that we don't need to write as we typed them and tested all cases by using the types. On the other hand are you able to use types in Elixir and could set a standard for the project to type the code. &lt;/p&gt;

&lt;p&gt;I think the way I would use Elixir is with real-time data or message queues. For example, building a notification queue for apps and using Elixir to concurrently send all the messages to the devices as I think this would be the best use-case for it, but I want to explore it in more areas than queues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;Thanks to Lars Wikman for the great Elixir talk he had, But also for wanting to read this post and give feedback. Lars is doing great things for the Elixir community. I recommend checking him out at &lt;a href="https://underjord.io/" rel="noopener noreferrer"&gt;https://underjord.io/&lt;/a&gt; or his &lt;a href="https://www.youtube.com/c/Underjord" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Also want to thank the community at Kodsnack for answering my questions regarding the language and sharing information on how they use it. Great community with great people.&lt;/p&gt;

&lt;h2&gt;
  
  
  End
&lt;/h2&gt;

&lt;p&gt;Do you have any input or stuff I could add or change? I would love feedback! I am using a Twitter post for comments here: &lt;a href="https://twitter.com/emil_priver/status/1589632749446438912" rel="noopener noreferrer"&gt;https://twitter.com/emil_priver/status/1589632749446438912&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Deploy Django to AWS Lamda with Zappa</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Fri, 09 Oct 2020 22:28:44 +0000</pubDate>
      <link>https://forem.com/emil_priver/deploy-django-to-aws-lamda-with-zappa-588a</link>
      <guid>https://forem.com/emil_priver/deploy-django-to-aws-lamda-with-zappa-588a</guid>
      <description>&lt;p&gt;Originally posted at &lt;a href="https://emilpriver.com/posts/deploy-django-to-aws-lamda-with-zappa"&gt;https://emilpriver.com/posts/deploy-django-to-aws-lamda-with-zappa&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Information
&lt;/h2&gt;

&lt;p&gt;Django is a popular CMS for building a website. Many companies and people use Django to power big APIs for their services, Ex Instagram. This article helps you as a developer to set up Django on AWS Lambda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Django
&lt;/h3&gt;

&lt;p&gt;Django is a python based web application framework that comes with a lot of stuff out of the box, ex Security or Object-relational mapping. Django’s main goal is to ease the creation of complex, database-driven websites. Django is a popular framework used by many computes, for example, Instagram. Django is maintained by DSF (Django Software Foundation).&lt;/p&gt;

&lt;h3&gt;
  
  
  What is AWS Lambda
&lt;/h3&gt;

&lt;p&gt;AWS Lambda is serverless(Function as a service) computing and makes you able to run code without thinking about servers and downtime. Pretty much deploy code to AWS Lambda with a small config and you are ready to use it. More info about AWS Lambda here: &lt;a href="https://aws.amazon.com/lambda/"&gt;https://aws.amazon.com/lambda/&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zappa
&lt;/h3&gt;

&lt;p&gt;Zappa is a Python package that bundles up your code written in Django or Flask and with a command deploys the package to AWS Lambda and handling everything from creating a zip of your code to deploy it to Amazon S3 and then to AWS Lambda. Zappa only requires an AWS config on the machine that is used to deploy the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0vsa7z03492okbmjr7ip.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0vsa7z03492okbmjr7ip.gif" alt="Alt Text" width="720" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need to get started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python installed on your computer (&lt;a href="https://www.python.org/downloads/"&gt;https://www.python.org/downloads/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Virtualenv installed (&lt;a href="https://docs.python.org/3/library/venv.html"&gt;https://docs.python.org/3/library/venv.html&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Have AWS CLI configured on your computer with a profile that is allowed to configure Lambda and S3 ( &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html"&gt;https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;A Django application ready to use (&lt;a href="https://docs.djangoproject.com/en/1.8/intro/tutorial01/"&gt;https://docs.djangoproject.com/en/1.8/intro/tutorial01/&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Beginning
&lt;/h2&gt;

&lt;p&gt;Start off by entering a virtualenv and enter it. Then install all needed packages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vitualenv venv
source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Zappa will then ask you for an environment name. Example production or dev. Those environments are you then able to use in a CI/CD or something similar to test your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Zappa configuration can support multiple production stages, like 'dev', 'staging', and 'production'.
What do you want to call this environment (default 'dev'): 
Answer with your desired environment name. You will be able to add more environments later on.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zappa will then ask you for the profile that will be used to push and deploy the lambda function. The profile needs to be the profile that is allowed to create lambda functions and upload to and create an S3 bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Lambda and API Gateway are only available in certain regions. Let's check to make sure you have a profile set up in one that will work.
We found the following profiles: default, and hdx. Which would you like us to use? (default 'default'): 
Zappa will now ask you which S3 bucket that will be used to upload your code and then deploy it to lambda.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Zappa deployments will need to be uploaded to a private S3 bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If you don't have a bucket yet, we'll create one for you too.
What do you want call your bucket? (default 'zappa-108wqhyn4'): django-zappa-sample-bucket
Answer with the name of the bucked you will use.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next question will either be that Zappa asks for the Django settings path or the main function path depending on if Zappa finds a Django installation in the folder you typed "Zappa init" in. If Zappa doesn't find a Django installation is it not a big deal, you can change to Django set up after the "Zappa init" questions is finished. If Zappa doesn't find a Django installation then type the path to your Django main settings file.&lt;/p&gt;

&lt;p&gt;The next questions will be if you want to deploy this Lambda function worldwide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If you are using Zappa for the first time, you probably don't want to do this!
Would you like to deploy this application globally? (default 'n') [y/n/(p)rimary]: 
If the config looks good then press y and Zappa will generate a Zappa_settings.json file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Zappa didn't find a Django installation then change "app_function" to "django_settings" in your zappa_settings.json file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying your AWS Lambda function
&lt;/h2&gt;

&lt;p&gt;Deploying your AWS Lambda function is not hard. You only need 1 command to deploy the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Zappa deploy $ENV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;** $ENV **, in this case, is the environment you created earlier when running the Zappa init command.&lt;/p&gt;

&lt;p&gt;Zappa will not make a zip of your code, Send it to s3, and then deploy it to AWS Lambda and return a URL with the deployed and running code. You can now try your code by accessing the full URL including /admin at the end (If you run you Django admin at /admin".&lt;/p&gt;

&lt;p&gt;You will probably not be able to access your website as you need to configure a remote database as your code is running in a Lambda function. Connecting Django to a database as AWS RDS is a good move that will work with your Lambda Django code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uploading updates of your Django code
&lt;/h2&gt;

&lt;p&gt;Doing updates with Zappa is easy as you only need 1 command as well to deploy your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zappa update $env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;$env is the environment name you want to update.&lt;br&gt;
Zappa will not make a zip of your code, Send it to s3, and then deploy it to AWS Lambda and return a URL with the deployed and running code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect a custom domain to your AWS Lambda function
&lt;/h2&gt;

&lt;p&gt;Start off by setting up a certificate for your custom domain at AWS Certificate Manager and verify your domain. You will, later on, use this certificate you created to connect to your API gateway. Now go you AWS API Gateway and create an API if Zappa has not created an API gateway for you. Now go to "Custom domain names" in API Gateway and press create. Add the domain you want to use. For example api.doimain.tld, and select TLS 1.2 and the endpoint type which depends on the settings you made when running "Zappa init" and press "Create domain name". You should now be able to see a generated "API Gateway domain name" which you point the domain to with a CNAME. Go to the tab "API mappings" and press "Configure API mappings" and map the paths you need for your application. For example /admin and /graphql.&lt;/p&gt;

&lt;p&gt;If everything is set up correctly would you now be able to enter the domain with the added mapping and use it for your service.&lt;/p&gt;

&lt;h2&gt;
  
  
  My thoughts on using Django with AWS Lambda.
&lt;/h2&gt;

&lt;p&gt;Using AWS Lambda with Django has only been great for me so far. Its cheap, and fast. The startup time when the application goes from frozen to warm is fast as well. Most of the request I make is bellow 300ms when the function is warm and when the function is going from cold to warm are the requests served under 800ms. The current setup I have includes Lambda for running the code, RDS for database, and S3 with Cloudfront for all the media. What I like about Lambda is the part of not thinking about scaling and downtime as Lambda scale my application automatic and start my application if is stops(unless the downtime is caused by something else)&lt;/p&gt;

&lt;p&gt;I am using a CI/CD which deploys my code to AWS Lambda and handles all the migrations. And if I need to roll back my code am I able to do that with Zappa as well. Zappa has thought of a lot of stuff, for example, CRON jobs(Zappa call CRON jobs "schedule"), Being able to roll back to older versions of the code, and more. More information and commands can be found here: &lt;a href="https://github.com/Miserlou/Zappa"&gt;https://github.com/Miserlou/Zappa&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only "problem" I have with Zappa and AWS, in general, is that Zappa is building for AWS if I want to use most of the tools which Zappa gives me. For example rollback or schedule. And that I don't know a tool which works pretty much the same with another cloud platform example Google Cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4wpr051vi1b0bk6ba4gq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4wpr051vi1b0bk6ba4gq.gif" alt="Alt Text" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Twitter if anything: &lt;a href="https://twitter.com/emil_priver"&gt;https://twitter.com/emil_priver&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>django</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Sitemap with Nextjs after 9.4 update</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Sun, 09 Aug 2020 18:02:26 +0000</pubDate>
      <link>https://forem.com/emil_priver/sitemap-with-nextjs-after-9-4-update-2bfl</link>
      <guid>https://forem.com/emil_priver/sitemap-with-nextjs-after-9-4-update-2bfl</guid>
      <description>&lt;p&gt;Nextjs have done some changes since last post that I wrote. Since then was getStaticProps, getStaticPaths and getServerSidedProps introduced(You can read more about that here: &lt;a href="https://nextjs.org/blog/next-9-4"&gt;https://nextjs.org/blog/next-9-4&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;One way to generate a sitemap with nextjs after the update on SSG and SSR with a dynamic output based on the pages the application have is to create an API route that fetches data and return it as XML which could be used to read what pages you have on your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the code that generate the XML feed:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// import functions from the package&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SitemapStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;streamToPromise&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sitemap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Fetch data from a source which will be used to render the sitemap.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;graphlqlFetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    query getSitemapData {
      projects: allWorks {
        slug {
          current
        }
        publishedAt
      }
    }
  `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Create the a stream to write to with a hostname which will be used for all links&lt;/span&gt;
&lt;span class="c1"&gt;// Your are able to add more settings to the stream. I recommend to look a the npm package for more information.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;smStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SitemapStream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://priver.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// Add frontpage&lt;/span&gt;
&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// Add a static url to ex: about page&lt;/span&gt;
&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// add all dynamic url to the sitemap which is fetched from a source.&lt;/span&gt;
&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lastmod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publishedAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// tell sitemap that there is nothing more to add to the sitemap&lt;/span&gt;
&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// generate a sitemap and add the XML feed to a url which will be used later on.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sitemap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;streamToPromise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They way I generated my sitemap is with a package named "sitemap" which is an awesome package to generate a sitemap with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The generation of the sitemap looked like this:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// import functions from the package&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SitemapStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;streamToPromise&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sitemap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Fetch data from a source which will be used to render the sitemap.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;graphlqlFetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    query getSitemapData {
      projects: allWorks {
        slug {
          current
        }
        publishedAt
      }
    }
  `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Create the a stream to write to with a hostname which will be used for all links&lt;/span&gt;
&lt;span class="c1"&gt;// Your are able to add more settings to the stream. I recommend to look a the npm package for more information.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;smStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SitemapStream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://priver.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// Add frontpage&lt;/span&gt;
&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// Add a static url to ex: about page&lt;/span&gt;
&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// add all dynamic url to the sitemap which is fetched from a source.&lt;/span&gt;
&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lastmod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publishedAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// tell sitemap that there is nothing more to add to the sitemap&lt;/span&gt;
&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// generate a sitemap and add the XML feed to a url which will be used later on.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sitemap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;streamToPromise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is only the code that generates the sitemap.&lt;br&gt;
They sitemap const will later on be used to send data to the user or an service which want to read the sitemap/xml feed.&lt;/p&gt;

&lt;p&gt;Send the sitemap to the user:&lt;br&gt;
Nextjs have a build in way to return data to a user or service when an api route is generated. Which means we dont need any external packages like express.&lt;/p&gt;

&lt;p&gt;They way I returned data to the user or service when using an api route is this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// here is the generation of the sitemap happening&lt;/span&gt;

  &lt;span class="c1"&gt;// tell the output that we will output XML&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/xml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// write the generate sitemap to the output&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sitemap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// end and send the data to the user or service.&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the user will have a sitemap that is dynamic generated and outputed in a way that a service like Goole Search Engine is able to read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to use domain.ltd/sitemap.xml as url for your sitemap?
&lt;/h2&gt;

&lt;p&gt;To use domain.ltd/sitemap.xml in this solution do you basic add a rewrite from /sitemap.xml to /api/sitemap in the next.config.js. More about rewrites here: &lt;a href="https://nextjs.org/docs/api-reference/next.config.js/rewrites"&gt;https://nextjs.org/docs/api-reference/next.config.js/rewrites&lt;/a&gt;&lt;br&gt;
Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;rewrites&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/sitemap.xml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/sitemap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The full code:
&lt;/h2&gt;

&lt;p&gt;This is the whole code I used to generate a dynamic sitemap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// import functions from the package&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SitemapStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;streamToPromise&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sitemap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// A custom function I use to fetch data from a backend. I will keep the import to make it more clear why "graphlqlFetch" is used in the code&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;graphlqlFetch&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib/apollo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch data from a source which will be used to render the sitemap.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;graphlqlFetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    query getSitemapData {
      projects: allWorks {
        slug {
          current
        }
        publishedAt
      }
    }
  `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Create the a stream to write to with a hostname which will be used for all links&lt;/span&gt;
  &lt;span class="c1"&gt;// Your are able to add more settings to the stream. I recommend to look a the npm package for more information.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;smStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SitemapStream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://priver.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Add frontpage&lt;/span&gt;
  &lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Add a static url to ex: about page&lt;/span&gt;
  &lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// add all dynamic url to the sitemap which is fetched from a source.&lt;/span&gt;
  &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lastmod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publishedAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// tell sitemap that there is nothing more to add to the sitemap&lt;/span&gt;
  &lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// generate a sitemap and add the XML feed to a url which will be used later on.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sitemap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;streamToPromise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smStream&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="c1"&gt;// here is the generation of the sitemap happening&lt;/span&gt;
  &lt;span class="c1"&gt;// tell the output that we will output XML&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/xml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// write the generate sitemap to the output&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sitemap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// end and send the data to the user or service.&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Github gist with the same code: &lt;a href="https://gist.github.com/emilpriver/d037fa56ddb3f450132ba6efe7b0c217"&gt;https://gist.github.com/emilpriver/d037fa56ddb3f450132ba6efe7b0c217&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this help you to generate a dynamic sitemap for your Nextjs application.&lt;/p&gt;

&lt;p&gt;Twitter if anything: &lt;a href="https://twitter.com/emil_priver"&gt;https://twitter.com/emil_priver&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>sitemap</category>
      <category>webdev</category>
      <category>seo</category>
    </item>
    <item>
      <title>What is your go to CSS-in-JSS library?</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Sat, 30 May 2020 11:26:22 +0000</pubDate>
      <link>https://forem.com/emil_priver/what-is-your-go-to-css-in-jss-library-35j4</link>
      <guid>https://forem.com/emil_priver/what-is-your-go-to-css-in-jss-library-35j4</guid>
      <description>&lt;p&gt;There is many great CSS-in-JS libraries on the internet, Which one do you use and why?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Sitemap with Next.js</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Mon, 03 Feb 2020 19:29:34 +0000</pubDate>
      <link>https://forem.com/emil_priver/sitemap-with-next-js-539</link>
      <guid>https://forem.com/emil_priver/sitemap-with-next-js-539</guid>
      <description>&lt;h1&gt;
  
  
  OUTDATED! NEW WAY: &lt;a href="https://emilpriver.com/blog/sitemap-with-nextjs-after-9-4-update"&gt;https://emilpriver.com/blog/sitemap-with-nextjs-after-9-4-update&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Originally written at: &lt;a href="//://emilpriver.com/posts/sitemap-with-next-js"&gt;My website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, Nextjs is really hyped and a really good framework for developing. Nextjs is shiped with alot of stuffs, but not an generated sitemap (Which i understand is not added by default in Nextjs).&lt;/p&gt;

&lt;p&gt;This is 1 way to create an dynamic sitemap without creating a server to handle Nextjs and use getInitialProps instead as normal pages does.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL
&lt;/h2&gt;

&lt;p&gt;I wanted to be able to use /sitemap.xml as its a standard for sitemaps. &lt;/p&gt;

&lt;p&gt;By testing out different type of filename did i later on understand that you are able to use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sitemap.xml.js 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as name and it will be rendered when entering /sitemap.xml in your browser.&lt;/p&gt;

&lt;p&gt;Something we will use in this small article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developing the XML feed.
&lt;/h2&gt;

&lt;p&gt;Create a new file in pages/ folder in your projects map, the name of the file will be used when you want to access your sitemap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sitemapXML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;latestPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;projectsXML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modified&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;latestPost&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;postDate&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;latestPost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;latestPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;postDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projectURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://domain.ltd/project/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;projectsXML&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`
      &amp;lt;url&amp;gt;
        &amp;lt;loc&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;projectURL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/loc&amp;gt;
        &amp;lt;lastmod&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;postDate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/lastmod&amp;gt;
        &amp;lt;priority&amp;gt;0.50&amp;lt;/priority&amp;gt;
      &amp;lt;/url&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
    &amp;lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&amp;gt;
      &amp;lt;url&amp;gt;
        &amp;lt;loc&amp;gt;https://domain.ltd/&amp;lt;/loc&amp;gt;
        &amp;lt;lastmod&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;latestPost&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/lastmod&amp;gt;
        &amp;lt;priority&amp;gt;1.00&amp;lt;/priority&amp;gt;
      &amp;lt;/url&amp;gt;
      &amp;lt;url&amp;gt;
        &amp;lt;loc&amp;gt;https://domain.ltd/about/&amp;lt;/loc&amp;gt;
        &amp;lt;priority&amp;gt;0.80&amp;lt;/priority&amp;gt;
      &amp;lt;/url&amp;gt;
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;projectsXML&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    &amp;lt;/urlset&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First part of the code.&lt;br&gt;
Here we create the XML feed with dynamic data. &lt;br&gt;
We have some statics paths which is / and /about which we add manually.&lt;br&gt;
but we also have some dynamic data, in my case is the dynamic data all my projects. So in the code do we loop thrue all my projects from an external source and add xml data to a variable which we later on uses to display the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Sitemap extends React.Component {
  static async getInitialProps({ res }) {
    const data = await axios
      .get(
        "https://domain.ltd/some/url/"
      )
      .then(response =&amp;gt; response.data);

    res.setHeader("Content-Type", "text/xml");
    res.write(sitemapXML(data));
    res.end();
  }
}

export default Sitemap;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the last part do we use axios to fetch data from an api. This works exactly the same way we do normally fetch data when using SSR with Next.JS. &lt;br&gt;
But instead of using render() or return() do we directly send the XML feed to the client. So now we have working XML feed which is rendered SSR and ready when you need it.&lt;/p&gt;

&lt;p&gt;And exempel using the method is my website: &lt;a href="https://priver.dev/sitemap.xml"&gt;https://priver.dev/sitemap.xml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/emilpriver/16b4781263b5d2403c5c4f30a61a2db9"&gt;Github GIST if you want to copy the code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this helps you :D&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>sitemap</category>
      <category>seo</category>
    </item>
    <item>
      <title>Working with Django in Docker</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Sun, 12 Jan 2020 20:36:38 +0000</pubDate>
      <link>https://forem.com/emil_priver/working-with-django-in-docker-mg3</link>
      <guid>https://forem.com/emil_priver/working-with-django-in-docker-mg3</guid>
      <description>&lt;p&gt;Originally written at: &lt;a href="https://emilpriver.com/posts/working-with-django-in-docker-during-development"&gt;My website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Django is an awesome framework which powers alot of website, ex Instagram. Working with Django inside an docker image is like heaven. This small article will tell you how to install, build, and run a docker image o your machine. Both production and for development with Docker-compose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Information:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Django
&lt;/h3&gt;

&lt;p&gt;Django is an pytho based web application framework that comes with alot of stuffs out of the box, ex Security or Object-relational mapper. Djangos main goal is to ease the creation of complex, database-driven websites. Django is a popular framework used by many computes, for exempel Instagram. Django is maintained by DSF(Django Software Foundation).&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker
&lt;/h3&gt;

&lt;p&gt;Docker is an set coupled SaaS(Software-as-a-service) and PaaS(Platform-as-a-service) products that are using Operating-System-Level Virtualization. This systems or projects that are hosted as a package inside docker are called containers. Multiple Containers are able to to run on the same machine and share the OS kernel that the operativ system provide. Container compared to and Virtual Machine use less space and can handle more applications and require fewer VMs and Operating systems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YUZtHLpf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/2gl9vajzm5wv2qnz2ch4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YUZtHLpf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/2gl9vajzm5wv2qnz2ch4.png" alt="Alt Text" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What you need in order to start:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Django installed on your computer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Folder structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DnS-a_YY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/w1po4456gaulwoa4hj0j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DnS-a_YY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/w1po4456gaulwoa4hj0j.png" alt="Alt Text" width="255" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install django
&lt;/h2&gt;

&lt;p&gt;To create a new django application do you need to have Django installed. If you dont have django installed run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;Django&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be able to run django inside our Docker image do we need to start a django project. In the folder run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;startproject&lt;/span&gt; &lt;span class="n"&gt;backend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use "backend" as our project name, you can change that to anything you want. But later in this text do you need to change backend to the name you provided when creating the project. This will create a folder named "backend" or the name you provided.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dockerfile:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pull docker image 
FROM python:3.7.4-alpine3.10

# add need modules
RUN apk add --no-cache --virtual .build-deps gcc musl-dev
RUN apk add --no-cache mariadb-connector-c-dev gettext python-dev py-pip jpeg-dev zlib-dev libpq postgresql-dev

# Define env:
# PYTHONDONTWRITEBYTECODE tels python to not write .pyc files on the import of source modules
ENV PYTHONDONTWRITEBYTECODE=TRUE

# If this is set to a non-empty string it is equivalent to specifying the -u option.
ENV PYTHONUNBUFFERED=TRUE

# copy our code to docker images path
COPY /backend /usr/app/backend

# tell docker we work in our codes map
WORKDIR /usr/app/backend

# Install all dependencies our image require
RUN pip install -r requirements.txt

# remove uneedeed build dependencies
RUN apk del .build-deps

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Docker-compose:
&lt;/h2&gt;

&lt;p&gt;Docker-compose in this case is good for development&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# define docker-compose cersion
version: "3"
services:
    django:
        build: .
        command: python /usr/app/backend/manage.py runserver 0.0.0.0:8080
        volumes:
        - ./backend:/usr/app/backend
        ports:
        - "8080:8080"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  You are now able to start building :D If you use docker-compose just run "docker-compose up" and the image will be build and start.
&lt;/h3&gt;

&lt;p&gt;Browse Django by open localhost:8080 in your browser &lt;/p&gt;

&lt;p&gt;Good luck :) Hit me up if you have any questions.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>Docker(Docker-compose) + Wordpress/Bedrock</title>
      <dc:creator>Emil Privér</dc:creator>
      <pubDate>Tue, 06 Aug 2019 17:36:40 +0000</pubDate>
      <link>https://forem.com/emil_priver/docker-docker-compose-wordpress-bedrock-2lh2</link>
      <guid>https://forem.com/emil_priver/docker-docker-compose-wordpress-bedrock-2lh2</guid>
      <description>&lt;p&gt;Originally written at: &lt;a href="https://priver.se/wordpress/docker-docker-compose-wordpress-bedrock/"&gt;My website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a small article on how you can work with Docker and Wordpress(bedrock) to be able to host an wordpress site inside a docker machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Information
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Wordpress&lt;/strong&gt;:&lt;br&gt;
Wordpress are one of the most used CMS system for websites. Wordpress is baded on &lt;strong&gt;PHP&lt;/strong&gt; and &lt;strong&gt;MySQL&lt;/strong&gt;. Wordpress was released fist time May 27 2003 by WordpressFoundation. As Wordpress are a big CMS system does a lot of people create plugins, themes and so on for Wordpress which later on, Other people can use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bedrock&lt;/strong&gt;:&lt;br&gt;
Bedrock are an "WordPress boilerplate with modern development tools, easier configuration, and an improved folder structure" - Roots. Bedrock makes it possible to easy handle a Wordpress installation and plugins through an PHP dependency manager named &lt;a href="https://getcomposer.org/"&gt;Composer&lt;/a&gt;. Bedrock is using Dotenv to be able to easy work with different environments for different purpose. This makes you able to work with production, staging and dev environments etc.&lt;br&gt;
Bedrock is also providing security by isolate web root to limit access to non-web files and also more secure passwords by working with &lt;a href="https://github.com/roots/wp-password-bcrypt"&gt;wp-password-bcrypt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt;:&lt;br&gt;
Docker is an set coupled SaaS(Software-as-a-service) and PaaS(Platform-as-a-service) products that are using Operating-System-Level Virtualization. This systems or projects that are hosted as a package inside docker are called containers. Multiple Containers are able to to run on the same machine and share the OS kernel that the operativ system provide. Container compared to and Virtual Machine use less space and can handle more applications and require fewer VMs and Operating systems. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wKck9hVb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.docker.com/sites/default/files/d8/2018-11/docker-containerized-and-vm-transparent-bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wKck9hVb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.docker.com/sites/default/files/d8/2018-11/docker-containerized-and-vm-transparent-bg.png" alt="Container vs Virtual Machine" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Composer&lt;/strong&gt;:&lt;br&gt;
Composer is a Dependency Manager(Not a Package Manager). Composer makes it possible, in this scenario, to be able to install plugins through command line. More information about composer can you read &lt;a href="https://getcomposer.org/doc/00-intro.md"&gt;here&lt;/a&gt;&lt;/p&gt;



&lt;h1&gt;
  
  
  Bedrock and Wordpress
&lt;/h1&gt;
&lt;h3&gt;
  
  
  What you need in order to start
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Composer&lt;/li&gt;
&lt;li&gt;A MySQL database setup.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;From a folder you like run the &lt;/p&gt;

&lt;p&gt;&lt;code&gt; composer create-project roots/bedrock &lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command will create a Bedrock folder with necessary files and folders. &lt;/p&gt;

&lt;p&gt;Files and folder inside the Bedrock folder:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MgswEQi---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/qev5i2kx7tcjxlllrvss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MgswEQi---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/qev5i2kx7tcjxlllrvss.png" alt="Bedrock-folder" width="768" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Information about the folders&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Config: 
&lt;p&gt;
Inside the config folder do you have application.php and env files.
The &lt;strong&gt;application.php&lt;/strong&gt; have the same functions as &lt;strong&gt;wp-config.php&lt;/strong&gt; has in an normal wordpress installation. Inside the application.php do you for exempel define database information or auth keys and much more. 
The env files are used to override some of the code inside &lt;strong&gt;application.php&lt;/strong&gt; file or add more code to the project which you for exempel will use when your developing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tKop7Ful--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ygvuz6cee2plymzqheqf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tKop7Ful--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ygvuz6cee2plymzqheqf.png" width="724" height="222"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;Web:
&lt;p&gt; The web folder have 2 sub folders, index.php and wp-config.php. The app folder contains are the only folder that needed when developing. App folder contains themes, plugins, mu(Most use)-plugins and uploads.&lt;/p&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wVyg6Cj_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/kdeus7ds792l0qgb83lu.png" width="328" height="476"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Working with environments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As &lt;strong&gt;Bedrock&lt;/strong&gt; supports use of env, is it really simple to use different .env files. If you add an environments folder with different .env are you able to load different .env files depending of which docker-compose file you will choose(Use of different docker-compose file will come later in this post).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exempel of .env file&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
DB_NAME=database_name
DB_USER=database_user
DB_PASSWORD=database_password

# Optionally, you can use a data source name (DSN)
# When using a DSN, you can remove the DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST variables
# DATABASE_URL=mysql://database_user:database_password@database_host:database_port/database_name

# Optional variables
# DB_HOST=localhost
# DB_PREFIX=wp_

WP_ENV=development
WP_HOME=http://example.com
WP_SITEURL=${WP_HOME}/wp

# Generate your keys here: https://roots.io/salts.html
AUTH_KEY='s]Ae(9f!]KK.hYej(:m6qQ.S[xYQAoA&amp;amp;1IJ1S2P3$pU(5.OQxR*7t3Zcm+0;bjEX'
SECURE_AUTH_KEY='N#1;&amp;amp;qR+eESza?AHsE`:}vHpitkG5|x&amp;lt;{bprQNS3%x;Q*hti=}Li?_Z@?%X;w*E4'
LOGGED_IN_KEY='%-SrP^&amp;amp;lx{#;{,m]2(;J!O^E4Noi{TRf9L_CY-B2XeOB7[D&amp;gt;gh6v&amp;amp;q.Z4YHit%mv'
NONCE_KEY='8ncSeT1eS5X,q&amp;gt;a4y`*=XvczTi&amp;gt;&amp;amp;P92fK4naUmvxEM66;(X1_3kE7qYkRnxoFxFN'
AUTH_SALT='(JGfH8,6P}+&amp;gt;]I+3gyo-Q(KpFN_T&amp;amp;fe[]K+5X!jq}]Cw3l'
SECURE_AUTH_SALT='j&amp;gt;O{0B(94Cy_d!=oLJC$1t&amp;amp;T&amp;amp;7z5A&amp;gt;5&amp;amp;kV:]EdN,!ZNOH&amp;gt;QdVLq`!QTDj&amp;amp;VUj1gG'
LOGGED_IN_SALT='X2WjCA1.?&amp;gt;S+8KT9M19fxD4c#TQ0W&amp;gt;Mdn9`P2X1p)NZ%lS+RuXlI$N5323,?}&amp;gt;L}'
NONCE_SALT='fGcv0C0wk3}+L&amp;lt;&amp;amp;`}{?O;&amp;amp;=$!J3_By$WfnH[Iankm4M*q=)1x/%f5;b(K#^sogUl'

&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;This file are you able to clone into for exempel .env.staging or .env.production to be able to work with different environments. You can add any env variable and load this variable into &lt;strong&gt;application.php&lt;/strong&gt; and the project by defining an variable in the application.php and use the env variable as value. Exempel:&lt;/p&gt;

&lt;pre&gt;
Inside .env.production:
&lt;code&gt;
TWITTER_URL = https://twitter.com/emil_priver
&lt;/code&gt;

And load the env variable inside application.php with:
&lt;code&gt; Config::define('TWITTER_URL', env('TWITTER_URL')); &lt;/code&gt;

Then you are able to call the new defined variable with TWITTER_URL
&lt;/pre&gt;

&lt;h2&gt;
  
  
  Creating the theme.
&lt;/h2&gt;

&lt;p&gt;Developing your theme are the same as with an normal installation. Create your folder inside &lt;strong&gt;themes&lt;/strong&gt; folder and code your theme.&lt;/p&gt;

&lt;p&gt;I recommend to work with &lt;a href="https://roots.io/sage-9/"&gt;Roots Sage9&lt;/a&gt; which are an theme creator framework that are using &lt;a href="https://laravel.com/docs/5.8/blade"&gt;Laravel Blade&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with plugins
&lt;/h2&gt;

&lt;p&gt;As you use composer to create the Bedrock/Wordpress installation, is it an great idea to work with composer to install plugins aswell. When you create an bedrock installation does bedrock provide a &lt;strong&gt;composer.json&lt;/strong&gt; file inside the installation. This &lt;strong&gt;composer.json&lt;/strong&gt; file does already have &lt;a href="https://wpackagist.org/"&gt;WordPress Packagist&lt;/a&gt; which are a great repository to use to install and download plugins to Wordpress.&lt;/p&gt;

&lt;h4&gt;
  
  
  WordPress Packagist
&lt;/h4&gt;

&lt;p&gt;Wordpress Packagist are a Composer repository build to be able to install plugins from command line. Wordpress Packagist makes it possible to install plugins easy via an CI/CD and version controll.&lt;/p&gt;

&lt;h4&gt;
  
  
  So you know.
&lt;/h4&gt;

&lt;p&gt;Bedrock ads an .gitignore file that are excluding all folder and files inside the &lt;strong&gt;plugins&lt;/strong&gt;, &lt;strong&gt;mu-plugins&lt;/strong&gt;, &lt;strong&gt;uploads&lt;/strong&gt; folders. If you adding custom plugins or files then you need to add that folder to not be excluded inside the .gitignore.&lt;/p&gt;



&lt;h1&gt;
  
  
  Docker setup
&lt;/h1&gt;
&lt;h4&gt;
  
  
  Nginx
&lt;/h4&gt;

&lt;p&gt;Lets go thrue the nginx folder we have in the root directory. This folder have a nginx.conf file and host.conf file. Nginx.conf are a settings file for nginx where you can add custom settings and host.conf are the host file for the site to use. This folder also have an Dockerfile that tells docker which image it should use, but also we're to mount the .conf files.&lt;/p&gt;

&lt;p&gt;Exempel of Dockerfile:&lt;/p&gt;

&lt;pre&gt; &lt;code&gt;
FROM nginx:latest
COPY /vhost.conf /etc/nginx/conf.d/default.conf
COPY /nginx.conf /etc/nginx/nginx.conf
&lt;/code&gt; &lt;/pre&gt;

Exempel of nginx.conf:

&lt;pre&gt; &lt;code&gt;
user nginx;
worker_processes auto;

pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    include /etc/nginx/conf.d/*.conf;
}
&lt;/code&gt; &lt;/pre&gt;

Exempel of host.conf:

&lt;pre&gt;&lt;code&gt;
server {
    listen 80;
    server_name localhost;
    charset utf-8;
    index index.php;
    root /var/www/html/web;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9000;
        fastcgi_index index.php;
        fastcgi_read_timeout 300s;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
&lt;/code&gt; &lt;/pre&gt;


&lt;h3&gt;PHP &lt;/h3&gt;

In order to execute our Wordpress PHP code do we need an PHP image. As this is an basic guide will we keep it simple. Inside our docker-compose file can we easy add 
&lt;pre&gt; &lt;code&gt; image: php:7.3.6-fpm-alpine3.9 &lt;/code&gt; &lt;/pre&gt;
which will add the php library we need, but this is not the only thing we need to do. If we start our app with docker-compose and going to localhost:8080 will we probably see an 404 page. why? As we haven't mounted the code into PHP so PHP can't access the code. How to fix? By adding volume which mounts the code into docker, like this:

&lt;pre&gt; &lt;code&gt; 
volumes:
      - ./website/bedrock:/var/www/html 
&lt;/code&gt; &lt;/pre&gt;

The PHP part of the docker-compose file should look like this now:

&lt;pre&gt; &lt;code&gt;
 php:
    image: php:7.3.6-fpm-alpine3.9
    volumes:
      - ./website/bedrock:/var/www/html
&lt;/code&gt; &lt;/pre&gt;

&lt;h3&gt;Docker &lt;/h3&gt;

Docker are an awesome tool to use and makes alot possible while developing with Bedrock and Wordpress. With an CI/CD make this setup it possible to easy deploy multiple container to different servers and use the same database and so on.

So how does our final docker-compose file look? Like this:

&lt;pre&gt;
&lt;code&gt;
version: '3'
services:
  nginx:
    build: ./nginx
    volumes:
      - ./website/bedrock:/var/www/html
    ports:
      - '8080:80'
    depends_on:
      - php
  php:
    image: php:7.3.6-fpm-alpine3.9
    volumes:
      - ./website/bedrock:/var/www/html
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;What if we want to use an different .env file then the one we have inside our bedrock folder? No problem, this is really simple:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
version: '3'
services:
  nginx:
    build: ./nginx
    volumes:
      - ./website/bedrock:/var/www/html
    ports:
      - '8080:80'
    depends_on:
      - php
  php:
    image: php:7.3.6-fpm-alpine3.9
    env_file:
      - ./path/to/custom/env-file/.env

    volumes:
      - ./website/bedrock:/var/www/html
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;By adding env_file into &lt;strong&gt;PHP&lt;/strong&gt; settings of the docker-compose file are we able mount an env file into Bedrock.&lt;br&gt;
If you want to use different env for different enviornments(exempel production or development). Then copy the docker-compose file we have into something else, ex: &lt;strong&gt;docker-compose.production.yml&lt;/strong&gt; and start docker-compose using this file, like this:&lt;/p&gt;

&lt;pre&gt; &lt;code&gt; docker-compose -f docker-compose.production.yml up --build &lt;/code&gt; &lt;/pre&gt;

&lt;p&gt;Or if you want to start the normal docker-compose file use:&lt;/p&gt;

&lt;pre&gt; &lt;code&gt; docker-compose up --build &lt;/code&gt; &lt;/pre&gt;

&lt;h1&gt;End &lt;/h1&gt;

&lt;p&gt;This should be all the stuffs needed to get started with Docker + Bedrock/Wordpress. As this is an basic guide did I want to have everything at a basic level. Docker and Bedrock are great and with adding some information to all this are you able to use different enviornments, use different php.ini and so on.&lt;/p&gt;

&lt;p&gt;An exempel of an site using this setup are &lt;a href="https://leagueshop.com"&gt;Leagueshop&lt;/a&gt;. This website have Gitlabs CI/CD connected so we never need to login to the server to build the website. The main reason we are using this setup are to be able to scale when more users comes. If many users visits the website, are we able to connect the server we have to an Load Balancer and then startup more servers to be able to run many Wordpress projects on many servers to work against downtime but also have redundancy when alot of users are visiting the site. &lt;/p&gt;

&lt;p&gt;DM me for any questions.&lt;/p&gt;

&lt;p&gt;Github project that you can use as template: &lt;a href="https://github.com/emilpriver/wordpress-docker-bedrock-starter"&gt;https://github.com/emilpriver/wordpress-docker-bedrock-starter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Twitter for DMs: &lt;a href="https://twitter.com/emil_priver"&gt;https://twitter.com/emil_priver&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>wordpress</category>
      <category>php</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
