<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Amir Khaleghi on Medium]]></title>
        <description><![CDATA[Stories by Amir Khaleghi on Medium]]></description>
        <link>https://medium.com/@hat3cker?source=rss-a5cc3a222364------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*smCBYBKpOE6NtCHw20KQ5A.png</url>
            <title>Stories by Amir Khaleghi on Medium</title>
            <link>https://medium.com/@hat3cker?source=rss-a5cc3a222364------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 21:19:55 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@hat3cker/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Automate your development with on-demand Gitea, VS Code, Jenkins, and Amojisys [Part 2]]]></title>
            <link>https://medium.com/@hat3cker/automate-your-development-with-on-demand-gitea-vs-code-jenkins-and-amojisys-part-2-22bd52707d14?source=rss-a5cc3a222364------2</link>
            <guid isPermaLink="false">https://medium.com/p/22bd52707d14</guid>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[jenkins]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Amir Khaleghi]]></dc:creator>
            <pubDate>Fri, 13 Sep 2024 06:40:39 GMT</pubDate>
            <atom:updated>2024-09-13T06:42:30.948Z</atom:updated>
            <content:encoded><![CDATA[<p>Welcome to the second part of our tutorial series on optimizing your development workflow with <a href="https://amojisys.com/">Amojisys</a>. In <a href="https://medium.com/@hat3cker/automate-your-development-with-on-demand-gitea-vs-code-jenkins-and-amojisys-part-1-dd2c1bfa7f48"><strong>Part 1</strong></a>, you set up a Gitea repository, deployed a Visual Studio Code Server, and created a simple Flask application. Now it’s time to take automation to the next level.</p><p>In <strong>Part 2</strong>, we will dive into continuous integration and continuous deployment (CI/CD) by connecting your repository to Jenkins. You’ll learn how to:</p><ul><li>Create a <strong>Jenkinsfile</strong> to define the CI/CD pipeline.</li><li>Write a <strong>Dockerfile</strong> to containerize your Flask application.</li><li>Set up Jenkins to automatically build a Docker image and push it to your repository with every commit to the master branch.</li></ul><p>By the end of this tutorial, you’ll have a fully automated pipeline that streamlines your development process — making every push to the master branch trigger a deployment without any manual intervention.</p><p>Let’s get started</p><p>First, you will need to create the following Dockerfile in your repository to create a Docker image from my application. In this case, my “Dockerfile” would look like this:</p><pre>FROM python:3.11-alpine<br><br># Create a working directory<br>WORKDIR /flaskapp<br><br># Copy requirements<br>COPY requirements.txt .<br><br># Install dependencies<br>RUN pip3 install --no-cache-dir -r requirements.txt<br><br># Copy the application<br>COPY . .<br><br># Expose the port<br>EXPOSE 5000<br><br># Command to start the app<br>CMD [&quot;python3&quot;, &quot;main.py&quot;]</pre><p>Next, I will create a “Jenkinsfile”:</p><pre>node {<br>    def app<br>    <br>    stage(&#39;Clone repository&#39;) {<br>        checkout scm<br>    }<br><br>    stage(&#39;Build image&#39;) {<br>        container(&#39;docker&#39;) {<br>                app = docker.build(&quot;myproduct.gt.amojisys.com/root/myrepo:1.${env.BUILD_NUMBER}&quot;, &quot;--network host .&quot;)<br>        }<br>    }<br>    <br>    stage(&#39;Push image&#39;) {<br>        container(&#39;docker&#39;) {<br>            docker.withRegistry(&#39;https://myproduct.gt.amojisys.com&#39;, &#39;gitea_access_token&#39;) {<br>                app.push(&quot;1.${env.BUILD_NUMBER}&quot;)<br>            }<br>        }<br>    }<br>}</pre><p>In this script, I utilize a Docker container (DinD), which is provided by a Jenkins agent, to build an image and push it to the repository. I am also utilizing Jenkins job’s build number for automatic versioning.</p><p>You can get access to the Docker daemon by utilizing the “docker” container in your pipeline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*umepdexOdcvtCnSuae0syA.png" /><figcaption>Creating Jenkinsfile and Dockerfile in Flask app’s repository</figcaption></figure><p>Once you add “Dockerfile” and “Jenkinsfile”, I can push the changes to the repository.</p><p>You will need a Jenkins server to be able to put all the pieces together. So, I am going to create a Jenkins Cluster service on the Amojisys app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DEN3fHApCbGNxTBhJ6i9dA.png" /><figcaption>Creating a Jenkins Cluster on Amojisys</figcaption></figure><p>When Jenkins server is deployed, you will login using “admin” username and the password I initiated when creating the service.</p><p>To install the requirements for creating a pipeline and building a Docker image, we will need “Pipeline” and “Docker Pipeline” plugins installed. You can install plugins by navigating to “Manage Jenkins”, “Plugins”, and then “Available plugins”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oExBkcfWnLViP_K87JTgjQ.png" /><figcaption>Installing Pipeline and Docker Pipeline plugins on Jenkins</figcaption></figure><p>Next, you will create a global credential for accessing your Gitea repository by going to “Manage Jenkins”, “Credentials”, “System”, and “Global credentials”. In my pipeline, I use this credential as “gitea_access_token” so I will set the same name for the input.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*muXkmbYQRoxUSPwo3yzxkA.png" /><figcaption>Creating Gitea’s global credentials on Jenkins</figcaption></figure><p>Now, you will go back to the dashboard, create a new job, and choose “Pipeline”. In the configuration, you will enable the “Poll SCM” option so this job can check my repository on a schedule, and if there are any changes, it will get triggered. I will choose every 5 minutes as my Schedule “H/5 * * * *”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*h1z_SjM3CcxUUQs0jnfdUA.png" /><figcaption>Scheduling a job on Jenkins</figcaption></figure><p>In the “Definition” section, I choose “Pipeline script from SCM”. I will select “Git” as “SCM” and enter my repository’s url. I will select the Credentials that I defined earlier and choose the master branch to push and build images from. You can add more configurations depending on your needs. This will satisfy all I want to do for now, so I will save my pipeline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LweyMV7z95bQGCTbiusJ6g.png" /><figcaption>Setting up SCM Definition on Jenkins</figcaption></figure><p>Now, I will build the job by clicking on “Build Now” which will assign the agent server to my job to execute my pipeline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UwCU4hhDNmUVJ3jzvcPUZw.png" /><figcaption>Building a Jenkins job</figcaption></figure><p>You can track the progress of my pipeline in detail by clicking on the build number and navigating to “Console Output”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dy776ctmSfQxe_5P7U06QQ.png" /><figcaption>Console Output of a Jenkins build</figcaption></figure><p>Finally, you can go back to yout Gitea server and check if the image was added to “root” user’s packages.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A4hgUFNyLIaqIDfkGC7RTg.png" /><figcaption>Docker image on Gitea repository</figcaption></figure><p>I can see the Docker image under packages with a tag version of 1.1, which will increment on each run. So, the next time I push to the master branch, there will be a new image there with the version 1.2.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/0*-m6Q2cuh9--81sim.gif" /></figure><p>Great job! You have successfully built a complete CI/CD pipeline using Jenkins, Docker, VS Code server, and your Gitea repository. With the <strong>Jenkinsfile</strong> and <strong>Dockerfile</strong> in place, your Flask application can now be automatically built, containerized, and deployed as a Docker image every time you push to the master branch.</p><p>This powerful automation saves you time, reduces errors, and ensures a smoother development-to-deployment process. By integrating these tools with Amojisys, you have created a workflow that is scalable, efficient, and optimized for collaboration.</p><p>As you continue building and refining your applications, your new pipeline will keep everything running smoothly, allowing you to focus on what really matters — creating great software.</p><p>Thank you for following along! Stay tuned for more tutorials as we continue to explore ways to enhance your development processes with Amojisys.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=22bd52707d14" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Automate your development with on-demand Gitea, VS Code, Jenkins, and Amojisys [Part 1]]]></title>
            <link>https://medium.com/@hat3cker/automate-your-development-with-on-demand-gitea-vs-code-jenkins-and-amojisys-part-1-dd2c1bfa7f48?source=rss-a5cc3a222364------2</link>
            <guid isPermaLink="false">https://medium.com/p/dd2c1bfa7f48</guid>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[jenkins]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Amir Khaleghi]]></dc:creator>
            <pubDate>Fri, 13 Sep 2024 06:29:15 GMT</pubDate>
            <atom:updated>2024-09-13T15:29:31.366Z</atom:updated>
            <content:encoded><![CDATA[<p>In today’s fast-paced development environment, efficiency is key to staying ahead. At <a href="https://amojisys.com/">Amojisys</a>, we provide powerful tools to help teams streamline their processes, collaborate more effectively, and accelerate delivery times. In this 2-part tutorial, I will walk you through how to optimize your workflow using our Gitea, Visual Studio Code Server, and Jenkins Cluster services.</p><p>In <strong>Part 1</strong>, I will show you how to:</p><ul><li>Set up a repository on your own <strong>Gitea Server</strong> for easy version control.</li><li>Deploy a <strong>Visual Studio Code Server</strong> to clone the repository and begin coding remotely.</li><li>Build a simple <strong>Flask application</strong>, test it locally, and push the changes back to the repository.</li></ul><p>By the end of this part, you’ll have a fully functional Flask app hosted in your own repository, ready to be integrated with automated processes.</p><p>In <strong>Part 2</strong>, I will take it a step further by integrating <strong>Jenkins</strong> to automatically create Docker images of your application with every push, bringing your workflow full circle.</p><p>Let’s dive in and start simplifying your development process with Amojisys!</p><p>Before you start, you need to register and create an organization on <a href="https://app.amojisys.com/">Amojisys app</a>. You can find the tutorial on this <a href="https://youtu.be/KsplXtdQhSU">YouTube video</a> or the <a href="https://amojisys.com/documentation/">Documentations</a> page.</p><p>Once you are signed in to your organization as an Owner user, you will be able to create services.</p><p>First, you will create a Gitea server to maintain my repository.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pQYHw8IfQwuDXauPsLs0ow.png" /><figcaption>Gitea Server Instance on Amojisys</figcaption></figure><p>When the instance is running, you will click on the URL to set up your Gitea server. You can choose whether to host your repository database on your Gitea server or select an external database to store your data to have more control. I will choose SQLite3 which will store the database on the same container as my Gitea server.</p><p>You can configure your server as you wish. I will change the following values for a simple set up:</p><p>1- Server Domain: “myproduct.gt.amojisys.com”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wNPeS0WHr8ehxRXGNbKtyQ.png" /><figcaption>Amojisys Gitea Server Configuration 1</figcaption></figure><p>2 - Gitea Base URL: “https://myproduct.gt.amojisys.com”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2TOYKWSnkXjDBPOF2TAPoA.png" /><figcaption>Amojisys Gitea Server Configuration 2</figcaption></figure><p>3 - Disable self-registration, so no external user can register.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FtgnC5DzfxK3lQiOuhrGJw.png" /><figcaption>Amojisys Gitea Server Configuration 3</figcaption></figure><p>4 - Create an Admin user and password</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2ABAPPrxpUMaC1gisa5r2g.png" /><figcaption>Amojisys Gitea Server Configuration 4</figcaption></figure><p>After a successful installation, you will log in to your account, click on your profile on the top-right corner of the page, and choose settings. You will then switch to the Applications tab to create an <strong>Access Token</strong> and will store it for future use.</p><p>Now, it is time to create a repository for the Flask application!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kecQr_YwteZAjpW0q_Bhxg.png" /><figcaption>Amojisys Gitea Acess Token</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kPnEmMEq8yIBfOIrJ7O7pw.png" /><figcaption>Amojisys Gitea Repository Creation</figcaption></figure><p>The next step is to create a VS Code server on Amojisys to develop and test your application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0J_Dl3kh9sJ4yQG1ehFM8A.png" /><figcaption>VS Code Server on Amojisys</figcaption></figure><p>Once ready, you will open the online VS Code server and enter your password to login.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qUOwyBtdVrfwnP0Mjx_rvQ.png" /><figcaption>Amojisys’ VS Code Server Login</figcaption></figure><p>Within VS Code you will clone your repository by using a terminal and git command.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*P-fuARYs488H4bGNIoqK4A.png" /></figure><p>You will install Python extension. Also, pip for installing packages by running the following commands in terminal</p><pre>sudo apt-get update<br>sudo apt-get upgrade<br>sudo apt-get install python3-pip</pre><p>You will create a “main.py” file that contains my application code and a “requirements.txt” for any dependencies.</p><p>My main.py file will contain:</p><pre>from flask import Flask<br>app = Flask(__name__)<br><br>@app.route(&quot;/&quot;)<br>def entry():<br>    return &quot;Welcome to my application!&quot;<br><br>if __name__ == &quot;__main__&quot;:<br>    app.run(host=&quot;0.0.0.0&quot;)</pre><p>My requirements.txt will contain:</p><pre>Flask</pre><p>Afterwards, you will run the following command to install the dependencies on terminal:</p><pre>pip3 install -r myrepo/requirements.txt</pre><p>Now you have everything you need to run the app. you will navigate to Run &amp; Debug on the left navigation menu. Create a launch.json file for Python which should look like this:</p><pre>{<br>    // Use IntelliSense to learn about possible attributes.<br>    // Hover to view descriptions of existing attributes.<br>    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387<br>    &quot;version&quot;: &quot;0.2.0&quot;,<br>    &quot;configurations&quot;: [<br>        {<br>            &quot;name&quot;: &quot;Python: Current File&quot;,<br>            &quot;type&quot;: &quot;python&quot;,<br>            &quot;request&quot;: &quot;launch&quot;,<br>            &quot;program&quot;: &quot;${file}&quot;,<br>            &quot;console&quot;: &quot;integratedTerminal&quot;,<br>            &quot;justMyCode&quot;: true<br>        }<br>    ]<br>}</pre><p>Once you have a Python debugger set up, you can run and test your application on the server.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F35rDhT2HyDSaqRwr43e7Q.png" /><figcaption>Simple Flask Application Running on VS Code server</figcaption></figure><p>You can see that the application is running on port 5000 of the following addresses on VS Code server:</p><pre>127.0.0.1<br>10.233.109.124</pre><p>To make sure you can send requests to your application, you can use CURL to send a GET request.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KvYUPXNoe4QNydxY2-fE9g.png" /><figcaption>Testing Flask Application on VS Code server</figcaption></figure><p>You can see the application running and sending a response. Great!</p><p>You need to push your new changes to the repository, but one final step is to configure a name and an email address for your git configuration in the terminal:</p><pre>git config --global user.name &quot;David Smith&quot;<br>git config --global user.email &quot;d.smith@test.com&quot;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n_2ISaDJKuJd_krFZfpaag.png" /><figcaption>Configuring git user email and name</figcaption></figure><p>Finally, you can push your changes to the repo.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yT1hJ597FSOl4cq8tAPqeA.png" /><figcaption>Updated Repository with Flask Application’s Content</figcaption></figure><p>Congratulations! You’ve successfully set up a repository on Gitea, deployed a remote Visual Studio Code Server, and built a simple Flask application. By pushing your changes back to the repository, you’ve laid the groundwork for a more efficient and collaborative development workflow.</p><p>This is just the beginning. In <strong>Part 2</strong>, we will take things further by introducing Jenkins into the mix. You will learn how to automate the creation of Docker images for your Flask application with every push, ensuring faster deployments and a seamless CI/CD pipeline.</p><p><strong>Ready for Part 2? </strong><a href="https://medium.com/@hat3cker/automate-your-development-with-on-demand-gitea-vs-code-jenkins-and-amojisys-part-2-22bd52707d14"><strong>Click here to continue.</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dd2c1bfa7f48" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>