<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Pustovalov</title>
    <description>The latest articles on DEV Community by Alex Pustovalov (@alex_pustovalov).</description>
    <link>https://dev.to/alex_pustovalov</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%2F694833%2F5a804fee-8c94-4016-ad06-4fb253dd5a82.png</url>
      <title>DEV Community: Alex Pustovalov</title>
      <link>https://dev.to/alex_pustovalov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alex_pustovalov"/>
    <language>en</language>
    <item>
      <title>A Handy Tip for GitHub Pages Custom Domains</title>
      <dc:creator>Alex Pustovalov</dc:creator>
      <pubDate>Sun, 29 Dec 2024 17:23:07 +0000</pubDate>
      <link>https://dev.to/alex_pustovalov/a-handy-tip-for-github-pages-custom-domains-4mfa</link>
      <guid>https://dev.to/alex_pustovalov/a-handy-tip-for-github-pages-custom-domains-4mfa</guid>
      <description>&lt;h3&gt;
  
  
  Have you heard about GitHub Pages?
&lt;/h3&gt;

&lt;p&gt;You probably know that GitHub offers free hosting for technical websites via GitHub Pages. &lt;/p&gt;

&lt;p&gt;But did you know about a useful feature GitHub Pages provides for organizations?&lt;/p&gt;

&lt;h3&gt;
  
  
  Here’s how it works:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create an organization on GitHub.&lt;/li&gt;
&lt;li&gt;Navigate to the organization’s settings and find the Pages section.&lt;/li&gt;
&lt;li&gt;Add your custom domain there and verify it by following the provided instructions.&lt;/li&gt;
&lt;li&gt;Create a repository named .github.io in the organization, where  is your organization’s name.&lt;/li&gt;
&lt;li&gt;Go to the repository settings, find Pages, and set the same custom domain you verified earlier.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it! From now on, all GitHub Pages repositories you create within this organization will automatically use your custom domain. No need to manually configure the domain for each repository!&lt;/p&gt;

&lt;p&gt;I’ve used this setup for a site where I plan to showcase my collection of websites built with TileDocs. &lt;a href="https://hub.tiledocs.com" rel="noopener noreferrer"&gt;https://hub.tiledocs.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s a neat and efficient way to manage custom domains for multiple projects. Give it a try!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>github</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building A Robust Web Platform on AWS: Using Remix in AWS Lambda</title>
      <dc:creator>Alex Pustovalov</dc:creator>
      <pubDate>Fri, 15 Dec 2023 14:09:08 +0000</pubDate>
      <link>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-using-remix-in-aws-lambda-5bi9</link>
      <guid>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-using-remix-in-aws-lambda-5bi9</guid>
      <description>&lt;p&gt;In today's deep dive, I'll be unpacking my journey of deploying &lt;a href="https://remix.run" rel="noopener noreferrer"&gt;Remix&lt;/a&gt; on AWS, specifically as a Lambda function. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For the tech aficionados, dive into the code details in our web platform's repository here: &lt;a href="https://github.com/pagemosaic/pagemosaic-web-platform" rel="noopener noreferrer"&gt;https://github.com/pagemosaic/pagemosaic-web-platform&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Remix Handler
&lt;/h2&gt;

&lt;p&gt;Let's cut through the jargon: Remix is versatile enough to run on various JavaScript runtimes, making it a perfect candidate for AWS Lambda functions.&lt;/p&gt;

&lt;p&gt;Here’s the catch: Remix typically nestles within an HTTP server to handle requests. This requires a specialized adapter to interface with various HTTP servers. So, in a Lambda environment (essentially a JavaScript runtime container), we leverage an HTTP server to fetch web pages as responses.&lt;/p&gt;

&lt;p&gt;In a turn away from conventional servers like Express, I opted for Remix's native solution – the Remix App Server. However, Lambda's distinct request handling interface necessitated a custom adapter for effective Remix integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remix Adapter
&lt;/h2&gt;

&lt;p&gt;The Remix library does offer an AWS Lambda adapter. Yet, it's tied to a framework I sidestepped: &lt;a href="https://www.npmjs.com/package/aws-architect" rel="noopener noreferrer"&gt;AWS Architect&lt;/a&gt;, known for orchestrating Lambda microservices and S3-backed websites. &lt;/p&gt;

&lt;p&gt;So, I extracted the crucial elements from the adapter’s code, creating a bespoke module – the &lt;code&gt;web-adapter&lt;/code&gt; – in my project.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Remix Web Application
&lt;/h2&gt;

&lt;p&gt;What's next? Developing the web application module itself using Remix. Given my preference for Vite or Rollup for module compilation, Vite was my go-to for bundling the web application.&lt;/p&gt;

&lt;p&gt;Here's a twist for Remix web applications: they require dual bundles. One for the client side (sans server-executable code) and another for the server side. &lt;/p&gt;

&lt;p&gt;Thus, the build command for the web application module aligns as &lt;code&gt;vite build &amp;amp;&amp;amp; vite build --ssr&lt;/code&gt;. Peek into the &lt;code&gt;web-app&lt;/code&gt; module's code in our GitHub repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bundle All
&lt;/h2&gt;

&lt;p&gt;Now, deploying the server-side bundle on AWS as a Lambda function means integrating it with the custom &lt;code&gt;web-adapter&lt;/code&gt; module. &lt;/p&gt;

&lt;p&gt;This led to introducing Rollup with a configuration merging dependencies from both modules, resulting in a Lambda-ready JS runtime bundle.&lt;/p&gt;

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

&lt;p&gt;The final build command for my web application stands as &lt;code&gt;vite build &amp;amp;&amp;amp; vite build --ssr &amp;amp;&amp;amp; NODE_ENV='production' rollup -c rollup.config.mjs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But it’s not just about code. I tweaked the Remix directory structure for a streamlined deployment process – separating the server part as a Lambda function and the client part as static files in an S3 bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;The next phase involved crafting CDK constructs for Lambda function creation and HTTP endpoint setup for the web application, alongside another construct for deploying the client's static files.&lt;/p&gt;

&lt;p&gt;You can unearth these construct codes in the infra module files: &lt;code&gt;web-app-api.ts&lt;/code&gt;, &lt;code&gt;system-bucket.ts&lt;/code&gt;, &lt;code&gt;system-bucket-deployment.ts&lt;/code&gt;. Strategically, these are split into distinct constructs for tailored resource initialization sequences on AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entry Point
&lt;/h2&gt;

&lt;p&gt;Finally, I assembled a construct for creating a CloudFront distribution with varied access points for both the web application and static resources. Find this code in &lt;code&gt;enty-point.ts&lt;/code&gt; in the &lt;code&gt;infra&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;That wraps up my Remix utilization saga for our web platform. Keen on taking it for a spin? The launchpad awaits in the readme of our source code repository: &lt;a href="https://github.com/pagemosaic/pagemosaic-web-platform" rel="noopener noreferrer"&gt;https://github.com/pagemosaic/pagemosaic-web-platform&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Follow &lt;a href="https://twitter.com/alex_pustovalov" rel="noopener noreferrer"&gt;Alex Pust&lt;/a&gt; on Twitter for updates on the Page Mosaic Web Platform development.&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>aws</category>
      <category>remix</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Building a Robust Web Platform on AWS: Deploy the website to AWS using the CDK.</title>
      <dc:creator>Alex Pustovalov</dc:creator>
      <pubDate>Mon, 20 Nov 2023 13:41:48 +0000</pubDate>
      <link>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-deploy-the-website-to-aws-using-the-cdk-40g4</link>
      <guid>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-deploy-the-website-to-aws-using-the-cdk-40g4</guid>
      <description>&lt;p&gt;In my previous &lt;a href="https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-a-step-by-step-journey-through-aws-cli-and-iam-identity-center-40f7"&gt;post&lt;/a&gt;, I discussed adding a user to manage AWS resources via the command line. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This user can also manage resources using the AWS console.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this stage of development, my plan was to create infrastructure for deploying a static webpage for a website on AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic setup
&lt;/h2&gt;

&lt;p&gt;Now, I will discuss the basic structure of the project, which I intend to develop gradually.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's important to note that the code will be primarily written in TypeScript, with some JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since the project involves multiple modules, I chose the pnpm package manager, known for its efficiency in multi-module projects or monorepos.&lt;/p&gt;

&lt;p&gt;Setting up pnpm is straightforward. First, create a &lt;code&gt;package.json&lt;/code&gt; file, add the &lt;code&gt;workspaces&lt;/code&gt; option, and list the directories containing your module code.&lt;/p&gt;

&lt;p&gt;I placed all modules in the &lt;code&gt;platform&lt;/code&gt; directory and thus specified it in &lt;code&gt;workspaces&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“workspaces”: [
    "platform/*"
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, I created a &lt;code&gt;pnpm-workspaces.yml&lt;/code&gt; file, also specifying the module directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages:
    - 'platform/*'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Website module
&lt;/h2&gt;

&lt;p&gt;Next, I started creating the modules. For the website module, I created &lt;code&gt;platform/web-app&lt;/code&gt;. Despite the name, this directory will eventually host a web application on &lt;strong&gt;remix.run&lt;/strong&gt;, not just a static site.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;platform/web-app&lt;/code&gt;, I added an &lt;code&gt;index.html&lt;/code&gt; page for my website.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Infrastructure setup
&lt;/h2&gt;

&lt;p&gt;Following this, I began creating the AWS infrastructure for the website.&lt;/p&gt;

&lt;p&gt;I started by installing the AWS CDK Toolkit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g aws-cdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I created &lt;code&gt;platform/infra&lt;/code&gt;, inspired by the Astro aws-astro adapter library. I used the following command to generate CDK code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cdk init sample-app --language typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reference: &lt;a href="https://cdkworkshop.com/20-typescript/20-create-project/100-cdk-init.html" rel="noopener noreferrer"&gt;CDK Workshop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I customized the generated code and file names, resulting in a specific directory structure.&lt;/p&gt;

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

&lt;p&gt;Let's briefly discuss how the CDK works. It's a toolset for defining AWS cloud infrastructure in code, like TypeScript. This code compiles into CloudFormation stacks, which AWS uses to create the required infrastructure.&lt;/p&gt;

&lt;p&gt;CDK mainly deals with two objects: Construct and Stack. A Construct can contain several other Constructs, while a Stack, responsible for generating the CloudFormation stack, can also contain several Constructs.&lt;/p&gt;

&lt;p&gt;This approach simplifies describing infrastructure as a tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure construction
&lt;/h2&gt;

&lt;p&gt;Inside &lt;code&gt;src&lt;/code&gt;, I created &lt;code&gt;constructs&lt;/code&gt; for CDK Constructs and &lt;code&gt;stacks&lt;/code&gt; for CDK Stacks. I then created a &lt;code&gt;PlatformStack&lt;/code&gt; class in &lt;code&gt;src/platform-stack.ts&lt;/code&gt; and a &lt;code&gt;WebsiteConstruct&lt;/code&gt; class in &lt;code&gt;src/website-construct.ts&lt;/code&gt; for the website's infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WebsiteConstruct&lt;/code&gt; manages the S3 Bucket (without public access), access rights, a CloudFront distribution, and uploads the contents of &lt;code&gt;platform/web-app&lt;/code&gt; to the bucket.&lt;/p&gt;

&lt;p&gt;For deployment, I used &lt;code&gt;bin/infra.ts&lt;/code&gt;, executed by the CDK Toolkit.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cdk.json&lt;/code&gt; file specifies the path for &lt;code&gt;bin/infra.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"app": "npx ts-node --prefer-ts-exts bin/infra.ts"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Deployment is initiated using:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deployment specifics
&lt;/h2&gt;

&lt;p&gt;For first-time AWS deployments, bootstrapping CDK resources in your account is required. This is a one-time process, with additional bootstrapping needed for new regions.&lt;/p&gt;

&lt;p&gt;I aimed to integrate deployment commands into the project's build flow. To avoid writing OS-specific scripts, I created JavaScript files for bootstrapping, deploying, and destroying the AWS stack, and included them in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Run deployment
&lt;/h2&gt;

&lt;p&gt;User authentication in AWS before running these commands is crucial. I developed a &lt;code&gt;run-command&lt;/code&gt; module for authorization checks and setting AWS session credentials in &lt;code&gt;process.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This module reads from a &lt;code&gt;.env&lt;/code&gt; file at the project root, containing the AWS administrative user's name and deployment region.&lt;/p&gt;

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

&lt;p&gt;Scripts in &lt;code&gt;package.json&lt;/code&gt; can now be executed through &lt;code&gt;run-command&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;run-command node ./scripts/deploy.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To manage the build and launch various modules in sequence, I added the &lt;code&gt;turbo&lt;/code&gt; tool to the project.&lt;/p&gt;

&lt;p&gt;The entire project code at this stage is available at &lt;a href="https://github.com/pagemosaic/pagemosaic-website-starter/tree/stage-1" rel="noopener noreferrer"&gt;PageMosaic GitHub&lt;/a&gt; in the &lt;code&gt;stage-1&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;While the setup may seem basic, it provides a fundamental understanding of AWS infrastructure deployment and programming simplicity, avoiding complex AWS console manipulations.&lt;/p&gt;

&lt;p&gt;You can try deploying this single-page site on your AWS by following the instructions in the repository's &lt;a href="https://github.com/pagemosaic/pagemosaic-website-starter/blob/stage-1/README.md" rel="noopener noreferrer"&gt;README.md&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;In my next post, I'll describe replacing the static webpage with a full-fledged web application on remix.run.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>Building a Robust Web Platform on AWS: A Step-by-Step Journey Through AWS CLI and IAM Identity Center</title>
      <dc:creator>Alex Pustovalov</dc:creator>
      <pubDate>Sun, 19 Nov 2023 13:30:15 +0000</pubDate>
      <link>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-a-step-by-step-journey-through-aws-cli-and-iam-identity-center-40f7</link>
      <guid>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-a-step-by-step-journey-through-aws-cli-and-iam-identity-center-40f7</guid>
      <description>&lt;p&gt;This article continues the story of creating the Page Mosaic Web Platform project.&lt;/p&gt;

&lt;p&gt;I have already created an account on the AWS platform. It's not difficult, everything is done quickly. However, before using CDK to create or configure anything on AWS, it's necessary to set up a user with administrative rights and programmatic access to resources.&lt;/p&gt;

&lt;p&gt;This means that I don't want to use the root user on my AWS account for manipulating resources. I'm already experienced in this.&lt;/p&gt;

&lt;p&gt;Therefore, I enabled IAM Identity Center on my AWS account. As far as I understand, this is a new mechanism for user management, and AWS recommends using it instead of managing IAM users individually.&lt;/p&gt;

&lt;p&gt;First, I created a user in IAM Identity Center as described in the instruction at &lt;a href="https://docs.aws.amazon.com/singlesignon/latest/userguide/get-started-use-identity-center-directory-create-user-in-identity-center.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/singlesignon/latest/userguide/get-started-use-identity-center-directory-create-user-in-identity-center.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, I added administrative rights to the permission set in my IAM Identity Center, following the instructions at &lt;a href="https://docs.aws.amazon.com/singlesignon/latest/userguide/get-started-create-an-administrative-permission-set.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/singlesignon/latest/userguide/get-started-create-an-administrative-permission-set.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And finally, I linked the administrative rights to the user in my account, as outlined at &lt;a href="https://docs.aws.amazon.com/singlesignon/latest/userguide/get-started-assign-account-access-admin-user.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/singlesignon/latest/userguide/get-started-assign-account-access-admin-user.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, I needed to check if I could connect to AWS from the command line because I would be running CDK scripts from there.&lt;/p&gt;

&lt;p&gt;I installed AWS CLI on my MacBook, following the instructions at &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, I needed to configure my user's access. First, I set up the user configuration on my local computer by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure sso —profile [user name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used the profile option to separate different user configurations on my computer.&lt;/p&gt;

&lt;p&gt;Then I specified the &lt;code&gt;session name&lt;/code&gt;, which the session token, issued for a certain duration when the user works with resources from the command line, would be linked to.&lt;/p&gt;

&lt;p&gt;Next, I authorized on the website in the browser and completed the required forms. The terminal itself opened the browser, and I went through the authorization process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Step 1:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fggxpgpuzhaupey3ajnup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fggxpgpuzhaupey3ajnup.png" alt="Image description" width="800" height="1020"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 2:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxew54vi88o08ex0f572.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxew54vi88o08ex0f572.png" alt="Image description" width="800" height="793"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 3:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5cgr6p4e118ied7wwfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5cgr6p4e118ied7wwfz.png" alt="Image description" width="800" height="1012"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 4:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fglfkcw42rqdfjazphx5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fglfkcw42rqdfjazphx5l.png" alt="Image description" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 5:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1va5ja80bo98in209q6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1va5ja80bo98in209q6r.png" alt="Image description" width="800" height="719"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After successful authorization, I returned to the terminal window and specified the region the user would use and the default format.&lt;/p&gt;

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

&lt;p&gt;After that, I could already execute commands like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws s3 ls --profile sitebud-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the next post, I will create the initial structure of the codebase of the platform project and add CDK scripts for deploying and configuring resources for a static website on AWS.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>development</category>
      <category>serverless</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Building a Robust Web Platform on AWS</title>
      <dc:creator>Alex Pustovalov</dc:creator>
      <pubDate>Sat, 18 Nov 2023 21:36:18 +0000</pubDate>
      <link>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-22hn</link>
      <guid>https://dev.to/alex_pustovalov/building-a-robust-web-platform-on-aws-22hn</guid>
      <description>&lt;p&gt;In this post, I'm starting a series where I will share my progress on an ambitious system project. The project is a comprehensive, open-source web platform offering a range of features like &lt;strong&gt;subscription&lt;/strong&gt; and &lt;strong&gt;membership&lt;/strong&gt; management, &lt;strong&gt;email&lt;/strong&gt; communication, &lt;strong&gt;payment&lt;/strong&gt; processing, and &lt;strong&gt;file storage&lt;/strong&gt;, all hosted on Amazon Web Services (AWS).&lt;/p&gt;

&lt;p&gt;The project is called &lt;code&gt;Page Mosaic&lt;/code&gt;. The name doesn't fully reflect the system's purpose, but other names I considered were already taken.&lt;/p&gt;

&lt;p&gt;I plan to develop a system that can be launched on AWS, utilizing its resources to the fullest.&lt;/p&gt;

&lt;p&gt;AWS is an excellent platform for creating the backend of any online service. It's affordable, flexible, and complex.&lt;/p&gt;

&lt;p&gt;Launching a container or a server instance on AWS is straightforward. However, setting up the system for automatic scaling based on load is complex and requires a deep understanding of how AWS works.&lt;/p&gt;

&lt;p&gt;In this project, ChatGPT will be a valuable tool that I'll use extensively.&lt;/p&gt;

&lt;p&gt;To deploy the system on AWS without delving too deep into the AWS console, I'll use the Cloud Development Kit (CDK).&lt;/p&gt;

&lt;p&gt;CDK allows you to script nearly all the administrative tasks for creating and configuring AWS resources.&lt;/p&gt;

&lt;p&gt;CDK is a very powerful tool, comparable to having an excellent AWS dev-ops on your team.&lt;/p&gt;

&lt;p&gt;Currently, my task is to create a web page or website to host a landing page for the project, drawing attention to it.&lt;/p&gt;

&lt;p&gt;I'm doing this as part of the project development because the site will run on this system, making it the foundational element of the system. The system's site will run on the system itself – &lt;strong&gt;&lt;em&gt;it makes sense to use what we build&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In my next post, I'll detail how I'm doing this. As a teaser, the site will run on Remix.run and will be entirely serverless.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>aws</category>
      <category>cdk</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Create an admin panel full-stack app for your database in minutes.</title>
      <dc:creator>Alex Pustovalov</dc:creator>
      <pubDate>Sat, 28 Aug 2021 12:44:41 +0000</pubDate>
      <link>https://dev.to/alex_pustovalov/create-an-admin-panel-full-stack-app-for-your-database-in-minutes-1e65</link>
      <guid>https://dev.to/alex_pustovalov/create-an-admin-panel-full-stack-app-for-your-database-in-minutes-1e65</guid>
      <description>&lt;p&gt;If you store information in a relational database, I bet you wish you had a handy application through which you could view or edit that data. Then, as far as I can guess, you started making this app or even made it.&lt;/p&gt;

&lt;p&gt;In any case, if you've ever created an application for working with a database, you know that it's not easy at all.&lt;/p&gt;

&lt;p&gt;You have to choose a technology stack. Then you have to design the architecture of the application to ensure security, speed, and accuracy of data, etc.&lt;/p&gt;

&lt;p&gt;Fortunately, there are already numerous frameworks and libraries that can be used as building blocks for full-stack applications.&lt;/p&gt;

&lt;p&gt;But still, writing and debugging code takes a lot of time. Even if you are a very experienced software engineer.&lt;/p&gt;

&lt;p&gt;So we decided to create a tool that would generate application code for your database using these "blocks". We wanted to make the generated source code usable right out of the box. If not, you could use it as a seed for your own application.&lt;/p&gt;

&lt;p&gt;And we did it! Meet &lt;a href="https://ikodix.com" rel="noopener noreferrer"&gt;IKODIX&lt;/a&gt;, an online source code generator for full-stack applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IKODIX does not require access to your database&lt;/strong&gt; to generate code. It uses a declarative approach.&lt;/p&gt;

&lt;p&gt;I hate to give a long and tedious description of IKODIX - let's go straight to creating a small application. This should take you no more than 50-60 minutes.&lt;/p&gt;

&lt;p&gt;Even if you already have some test databases available, let's run the MySQL database in Docker to speed up the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the database
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://www.docker.com/products/docker-desktop" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; on your localhost. We need it not only to run the database but also to run the generated application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;todo-db&lt;/code&gt; directory, go into it, and create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Copy the following code into this file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:8.0.19&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/var/lib/mysql&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./init.sql:/init.sql&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_ROOT_PASSWORD=root_password&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_DATABASE=todo&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER=myuser&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD=mypassword&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="m"&gt;3306&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3306:3306&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--init-file /init.sql&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create an &lt;code&gt;init.sql&lt;/code&gt; file and copy the following code into it
&lt;/li&gt;
&lt;/ul&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;DATABASE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="nv"&gt;`employee`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;`employee`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`full_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;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&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="nv"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="nv"&gt;`task_status`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;`task_status`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`status_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;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&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="nv"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="nv"&gt;`task`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;`task`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`description`&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;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`to_date`&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`assignee_id`&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`status_id`&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&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="nv"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="nv"&gt;`task_employee_id_fk`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`assignee_id`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="nv"&gt;`task_task_status_id_fk`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`status_id`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="nv"&gt;`task_employee_id_fk`&lt;/span&gt; &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`assignee_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="nv"&gt;`employee`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="nv"&gt;`task_task_status_id_fk`&lt;/span&gt; &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`status_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="nv"&gt;`task_status`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`id`&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;ul&gt;
&lt;li&gt;Create another &lt;code&gt;data&lt;/code&gt; directory inside the &lt;code&gt;todo-db&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Run the command in terminal: &lt;code&gt;docker-compose up -build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Wait until the container reports that it is ready…&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;You now have a Docker container running on your computer with the &lt;code&gt;todo&lt;/code&gt; database. It contains 3 tables: &lt;code&gt;employee&lt;/code&gt;, &lt;code&gt;task&lt;/code&gt;, &lt;code&gt;task_status&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open IKODIX
&lt;/h2&gt;

&lt;p&gt;We can start describing tables in IKODIX. &lt;a href="https://app.ikodix.com" rel="noopener noreferrer"&gt;Open IKODIX&lt;/a&gt;. Go to &lt;strong&gt;Data Tables&lt;/strong&gt;, and add tables with columns as described below.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;employee&lt;/strong&gt; table&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the &lt;code&gt;employee&lt;/code&gt; table. By default, it will already have a mandatory &lt;code&gt;Primary Key&lt;/code&gt; column with type &lt;code&gt;Long&lt;/code&gt; and name &lt;code&gt;id&lt;/code&gt;. This is fine for us because the real table &lt;code&gt;employee&lt;/code&gt; has a primary key column named &lt;code&gt;id&lt;/code&gt;. &lt;strong&gt;This applies to all other tables in our database.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;full_name&lt;/code&gt; column with &lt;code&gt;String&lt;/code&gt; type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;task_status&lt;/strong&gt; table&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the &lt;code&gt;task_status&lt;/code&gt; table.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;status_name&lt;/code&gt; column with the type &lt;code&gt;String&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;task&lt;/strong&gt; table&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the &lt;code&gt;task&lt;/code&gt; table.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;description&lt;/code&gt; column of type &lt;code&gt;String&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;assignee_id&lt;/code&gt; column of &lt;code&gt;Long&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;status_id&lt;/code&gt; column as a &lt;code&gt;Long&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;to_date&lt;/code&gt; column of type &lt;code&gt;Date&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Once we have a list of tables we can start creating projections.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;projection&lt;/strong&gt; is data from some linked tables. This data will be displayed on the front-end on a separate page in the &lt;strong&gt;Data Grid&lt;/strong&gt;. You can make an analogy with the SQL query that you write to select some records from the database.&lt;/p&gt;

&lt;p&gt;As you may have guessed, our database contains information about some tasks. The first thing we need to see is all the tasks and the employees assigned to them.&lt;/p&gt;

&lt;p&gt;Create the &lt;strong&gt;Task&lt;/strong&gt; projection.&lt;/p&gt;

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

&lt;p&gt;A diagram will open in front of us, where we need to add tables that we want to see records from.&lt;/p&gt;

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

&lt;p&gt;We will add the &lt;code&gt;task&lt;/code&gt; table first. The first table is the &lt;strong&gt;root table&lt;/strong&gt; in the diagram and we will link the other tables to it. This is very similar to how we write a SQL query.&lt;/p&gt;

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

&lt;p&gt;Let's add the &lt;code&gt;task_status&lt;/code&gt; table. Link the &lt;code&gt;status_id&lt;/code&gt; column from the &lt;code&gt;task&lt;/code&gt; table to the &lt;code&gt;id&lt;/code&gt; column in the &lt;code&gt;task_status&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Add the &lt;code&gt;employee&lt;/code&gt; table. Link the &lt;code&gt;assignee_id&lt;/code&gt; column from the &lt;code&gt;task&lt;/code&gt; table to the &lt;code&gt;id&lt;/code&gt; column in the &lt;code&gt;employee&lt;/code&gt; table.&lt;/p&gt;

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

&lt;p&gt;Let's go to the &lt;strong&gt;View&lt;/strong&gt; tab. Here we should mark as &lt;code&gt;Visible&lt;/code&gt; all columns from the tables in the diagram, which we want to see on the front-end.&lt;/p&gt;

&lt;p&gt;Mark the &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;to_date&lt;/code&gt; columns from the task table. Set any suitable names for these columns in the &lt;strong&gt;Grid Column Title&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Set visible the &lt;code&gt;full_name&lt;/code&gt; column from the &lt;code&gt;employee&lt;/code&gt; table, and the &lt;code&gt;status_name&lt;/code&gt; column from the &lt;code&gt;task_status table&lt;/code&gt;. Give them names, too.&lt;/p&gt;

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

&lt;p&gt;You can rearrange the order of the columns that will be displayed in the &lt;strong&gt;Data Grid&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Next, go to the &lt;strong&gt;Create&lt;/strong&gt; tab. On this tab, we configure the form for creating a record for the &lt;strong&gt;root table&lt;/strong&gt; in the diagram. That is, the record will be created only in the &lt;code&gt;task&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Let's mark &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;to_date&lt;/code&gt; fields as visible, give them names and corresponding field types.&lt;/p&gt;

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

&lt;p&gt;But besides these fields, we have linked fields with other tables: &lt;code&gt;assignee_id&lt;/code&gt; and &lt;code&gt;status_id&lt;/code&gt;. Let's mark them as visible, name them, and choose &lt;code&gt;Select&lt;/code&gt; type.&lt;/p&gt;

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

&lt;p&gt;Once we mark them as visible, we have the option in the &lt;strong&gt;Select Control Settings&lt;/strong&gt; section to customize the drop-down lists. We can specify the column from the linked table that will be used for the names in the drop-down list.&lt;/p&gt;

&lt;p&gt;Select the &lt;code&gt;status_name&lt;/code&gt; column for &lt;code&gt;status_id&lt;/code&gt;, and the &lt;code&gt;full_name&lt;/code&gt; column for &lt;code&gt;assignee_id&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Go to the &lt;strong&gt;Update&lt;/strong&gt; tab and do the same as in the &lt;strong&gt;Create&lt;/strong&gt; tab.&lt;/p&gt;

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

&lt;p&gt;We have the first projection ready. Now IKODIX will be able to generate an application where we will have a page with all the tasks and the employees assigned to them. And we will be able to add tasks through the input form.&lt;/p&gt;

&lt;p&gt;But we don't have a page and input form to add employees to the list. In addition, there is no page and form for entering job statuses.&lt;/p&gt;

&lt;p&gt;This is easy to fix. Create two projections for employees and for statuses: &lt;strong&gt;Employees&lt;/strong&gt; and &lt;strong&gt;Statuses&lt;/strong&gt;. Add to each projection one table on the diagram: &lt;code&gt;employee&lt;/code&gt; and &lt;code&gt;task_status&lt;/code&gt;, respectively.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It would probably be preferable if you try to configure &lt;strong&gt;Data Grid&lt;/strong&gt; and forms in the tabs &lt;strong&gt;View&lt;/strong&gt;, &lt;strong&gt;Create&lt;/strong&gt; and &lt;strong&gt;Update&lt;/strong&gt; for each projection by yourself.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;When you have completed all the settings in the new projections, we can start generating the source code for the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating the source code
&lt;/h2&gt;

&lt;p&gt;But there is one more thing not finished - we need to choose the type of database MySQL. Let's go to the &lt;strong&gt;System Settings&lt;/strong&gt; section and set the database type we want.&lt;/p&gt;

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

&lt;p&gt;Click the &lt;strong&gt;Download Source Code&lt;/strong&gt; button and name the application something like "ToDo Admin".&lt;/p&gt;

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

&lt;p&gt;Save the archive to the localhost in the empty &lt;code&gt;todo-app&lt;/code&gt; directory. Unzip the archive in this directory.&lt;/p&gt;

&lt;p&gt;Now we can get started with our application. We don't need to install anything extra to start the application.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;README.txt&lt;/code&gt; file and read carefully what is written there.&lt;/p&gt;

&lt;p&gt;According to the manual, there are two modes of running the application: &lt;strong&gt;demo&lt;/strong&gt; and &lt;strong&gt;dev&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt; is when a ready-to-use application is built and run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt; is when the application is launched for development. The &lt;strong&gt;Hot Reloading&lt;/strong&gt; for the front-end works in this mode.&lt;/p&gt;

&lt;p&gt;Let's run the application in demo mode to see how it works out of the box.&lt;/p&gt;

&lt;p&gt;Before we start, we need to configure access to our database. This can be done in the &lt;code&gt;.env&lt;/code&gt; file. Find there the variable &lt;code&gt;dataSource.url&lt;/code&gt; and replace its value with &lt;strong&gt;jdbc:mysql://host.docker.internal:3306/todo&lt;/strong&gt;. Then replace the username (&lt;code&gt;dataSource.username&lt;/code&gt;) with &lt;strong&gt;myuser&lt;/strong&gt; and the password (&lt;code&gt;dataSource.password&lt;/code&gt;) with &lt;strong&gt;mypassword&lt;/strong&gt;. Save the file.&lt;/p&gt;

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

&lt;p&gt;Two Docker containers are used to run all the parts of the application. But all we need to do is run the command &lt;code&gt;app.sh demo&lt;/code&gt; (or &lt;code&gt;app.cmd demo&lt;/code&gt; for Windows). And wait for the application to start.&lt;/p&gt;

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

&lt;p&gt;Since the containers with the application run in the background, we need to keep track of them. Let's run the two commands &lt;code&gt;app.sh client-log&lt;/code&gt; and &lt;code&gt;app.sh service-log&lt;/code&gt; in separate terminals.&lt;/p&gt;

&lt;p&gt;Once we see that everything is up and running, we can open the browser with the address &lt;strong&gt;&lt;a href="http://localhost:3030" rel="noopener noreferrer"&gt;http://localhost:3030&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is one user with administrative rights by default in the system. So we will log in under his account, username: &lt;strong&gt;administrator&lt;/strong&gt;, and password: &lt;strong&gt;administrator_password&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;There are no records in our tables, so let's try to get new employees, new statuses, and create tasks.&lt;/p&gt;

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

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

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

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

&lt;p&gt;Even though the app works out of the box, we need to change the company name in the upper left corner.&lt;/p&gt;

&lt;p&gt;In order to do this, let's run the application in development mode. Simply run the command &lt;code&gt;app.sh dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's wait for all Docker containers to start. To ensure that they are ready, use the commands: &lt;code&gt;app.sh client-log&lt;/code&gt; and &lt;code&gt;app.sh service-log&lt;/code&gt; in separate terminals.&lt;/p&gt;

&lt;p&gt;When ready let's open the browser with the address &lt;strong&gt;&lt;a href="http://localhost:3030" rel="noopener noreferrer"&gt;http://localhost:3030&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, find the &lt;code&gt;WorkspacePage.tsx&lt;/code&gt; file in the front-end code in the &lt;code&gt;to-do-admin-client/src/features/layout&lt;/code&gt; directory, and replace the text "Company Name" with the value we need: "ToDo Admin".&lt;/p&gt;

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

&lt;p&gt;Save the changes in the file.... and see the page in your browser. The value should automatically change.&lt;/p&gt;

&lt;p&gt;Docker containers for the front-end are made so that &lt;strong&gt;Hot Reloading&lt;/strong&gt; works.&lt;/p&gt;

&lt;p&gt;After the final changes you need to run the &lt;code&gt;app.sh demo&lt;/code&gt; again - then the parts of the application will be built for use in the production. You will find the distributions in &lt;code&gt;to-do-admin-client/build&lt;/code&gt; and in &lt;code&gt;to-do-admin-service/target&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are going to extend the functionality of the application, first read the &lt;code&gt;README.md&lt;/code&gt; files with a detailed description of the code structure in the &lt;code&gt;to-do-admin-client&lt;/code&gt; and &lt;code&gt;to-do-admin-service&lt;/code&gt; directories. This will help you to understand the code without difficulty.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hope you are not too tired and enjoy building with &lt;a href="https://ikodix.com" rel="noopener noreferrer"&gt;IKODIX&lt;/a&gt;. In any case, it is much faster and more comfortable than developing such applications by yourself.&lt;/p&gt;

&lt;p&gt;If you have any comments or questions, do not hesitate to post them on our forum: &lt;a href="https://github.com/ikodix/ikodix/discussions" rel="noopener noreferrer"&gt;IKODIX forum&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also follow new IKODIX releases on our Twitter account: &lt;a href="https://twitter.com/ikodix" rel="noopener noreferrer"&gt;@kodix&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Thank you!!!
&lt;/h4&gt;

</description>
    </item>
  </channel>
</rss>
