Different DevOps approaches to deploying an app — and — How to Deploy an App using a Self-Hosted Agent in Azure
How can I run my first job on a self-hosted agent?
In this project; Firstly, I would like to explore the several ways to deploy an App. The aim for this, is targetted at beginners who are yet to understand the concepts behind deploying applications, such as deploying the app locally, dockerizing the app, quickly spin the app to the cloud for testing, and finally using CICD pipeline to deploy the app. This is because it is also important and beneficial to learn how to deploy apps locally before migrating to the cloud.
In the last section, in the CICD Pipeline process; we deployed the App using the Self-Hosted Agent configured earlier in the previous project. You can find the previous project here.
Step 1: Deploy the App locally
Deploying an app locally before deployment in the cloud is an essential step in the development process that can help to save time, reduce costs, improve performance, and ensure security and compliance.
a. Open the vscode: Open the “Terminal” by using the shortcut Ctrl + `.
b. Navigate to Your Project Directory: Use the cd
command to navigate to your project directory. In my own case, I will be working on the ./Downloads
directory.
cd ./Downloads
c. Clone the original project:
git clone https://github.com/Azure-Samples/msdocs-python-flask-webapp-quickstart.git
Optional: If you’d like to checkout my github repo too, this is it here > https://github.com/ougabriel/pipeline-hello1.git
d. Navigate to the git
directory
cd msdocs-python-flask-webapp-quickstart.git
As seen in the code below. Here I changed the section app.run()
to enable the app run on a specified port which is 5000. You can do same or leave it as default.
import os
from flask import (Flask, redirect, render_template, request,
send_from_directory, url_for)
app = Flask(__name__)
@app.route('/')
def index():
print('Request for index page received')
return render_template('index.html')
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path , 'static'),
'favicon.ico', mimetype='image/vnd.microsoft.icon')
@app.route('/hello', methods=['POST'])
def hello():
name = request.form.get('name')
if name:
print('Request for hello page received with name=%s' % name)
return render_template('hello.html', name = name)
else:
print('Request for hello page received with no name or blank name -- redirecting')
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
e. Create and Activate the Virtual Environment
python -m venv venv
.\venv\Scripts\Activate
f. Install the required dependencies using pip
pip install -r requirements.txt
g. Run the Flask application: This should start the development server, and you should see output indicating that the server is running.
python app.py
h. Access the App: Open a web browser and go to http://127.0.0.1:5000/ or http://localhost:5000/ to view the running application.
That’s it! You’ve cloned and deployed an app
Step 2: Deploy the App using Azure CLI
In this section, we are going to test its deployment to Azure App Service using a single line command.
a. Install the Azure CLI Tools in your vscode as shown above.
b. Login to Azure, a pop window will open. Input your login credentials to allow access to your azure portal.
az login
c. Run the command below
az webapp up --name gab-py-webapp --sku B1 --resource-group gab-rg1 --runtime "PYTHON|3.9" --logs
The command may take a few minutes to complete. While the command is running, it provides messages about creating the resource group, the App Service plan, and the app resource, configuring logging, and doing ZIP deployment. It then gives the message, “You can launch the app at http://gab-py-webapp.azurewebsites.net
”, which is the app’s URL on Azure.
d. Browse the deployed application in your web browser at the URL http://gab-py-webapp.azurewebsites.net
. From the image below; You can also access the app in your Azure Portal > App Service > gab-py-webapp
Thats it !! You have successfully deployed an App to Azure App Service with just a single line of code.
Step 3: Dockerize and deploy the App locally
Docker provides a consistent environment, making it easy to share and deploy applications across different environments (both local and the cloud)
We already cloned the App in the previous deployment, In this section we will need to add an additional file which will enable us build the docker image needed for this app to function. The name of the file is Dockerfile
a. Add a Dockerfile: Copy and paste the following script into it.
# Use an official Python runtime as a base image
FROM python:3.9
# Set the working directory inside the container
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
This Dockerfile sets up a Python environment, copies the application files into the container, installs dependencies, exposes port 80, sets an environment variable, and runs app.py
.
b. Build the Docker Image: Open a terminal in the same directory as your Dockerfile and run the following command to build the Docker image. Replace gab-app
with a name for your Docker image:
docker build -t gab-app .
c. Run the Docker Container: After the image is built, run the following command to start a Docker container:
docker run -d -p 80:5000 gab-app
This maps port 80 from your local machine to port 5000 in the container.
d. Access the Deployed App: Open a web browser and go to http://127.0.0.1:80/ or http://localhost:80/ to view your Flask app running inside the Docker container.
That’s it! You’ve Dockerized and deployed your Flask app locally.
Step 4: Deploy the App using Azure Devops CICD Pipeline
Here the steps needed to deploy to the app in azure using azure app service and azure devops. In more simple terms; Push the app to github > create ACR > Retrieve the App and push it to ACR as an image > Create a Webapp to browse it > Create a CICD Pipeline Release for the App
a. Push the App to GitHub : From the project folder run the following to initialize git > add the folder files > commit the files > add your github url > push to github
b. Create ACR (Azure Container Registry)
The name of my Azure Container Registry is hello0acr
you can use same name or any other name thats convenient for you.
Before you can build the pipeline image, we must first create the ACR (the ACR has a repository, this is where the image is stored).
Creating an ACR is simple, it has been created in the Step 1 of a previous project and you can find it HERE.
Make sure the Access keys for Admin User
is checked as shown below;
c. Retrieve the App from github and push the Pipeline Image to ACR
NOTE: I used the self-hosted agent for the build process as mentioned earlier.
If you’d like to know how to create a self-hosted agent, click HERE.
How to use the self-hosted agent?
Using the Self-Hosted Agent is very simple, this is done by specyfing the name of the agent in the pipeline script or by simply changing the default agent to the name of your self-hosted agent, in my case the name of my self-hosted agent is Ubuntu-Agent-Pool
a. From the left menu, click pipeline
, in the open page you have to click Create pipeline
b. CONNECT, the GitHub repo. Click on GitHub (yaml) from the list
c. SELECT, the repo from the list. In my case I selected the repo ougabriel/pipeline-hello1
.
d. CONFIGURE, select from the list with the details Docker (Build and push image to azure container registry)
> Select your subscription, click Continue
> From the drop-down menu, select your container registry
which was created earlier. | The image name
will be automatically populated or you can give it your own name. | Leave Dockerfile section as default
> Click Validate and configure
( the yaml file will be configured)
e. REVIEW, leave the azure-pipelines.yml
file as default. We won’t be changing anything here. Click Save and run
NOTE: After the build, go to the azure portal > open the ACR created earlier > Scroll down to repositories to see the new docker image.
Go to your GitHub repo page to see the azure-pipelines.yml
file which has been added.
b. Create an Azure WebApp
Since, we have already deployed our docker image. Next, we will attached this image to an Azure WebApp. When this is attached, the image is deployed into it and then we can browse the python app
a. Navigate to App Services:
- In the Azure portal, click on
Create a resource
, and choose “Web App.”
b. Configure Web App Basics:
In the “Basics” tab of the Web App creation wizard:
Choose a unique App name. > Select your subscription. > Create or select a Resource Group. > Choose an Operating System (Linux). > Choose a Region. > Select a Runtime Stack (e.g., Node.js, Python, .NET Core). > Choose the Docker Container
option under Publish.
c. Configure Container:
- In the “Container” section of the wizard > Choose
Single container >
Provide the Image Source (choose the ACR where your image is located).
d. Configure App Service Plan:
In the “App Service Plan” section:
- Create a new App Service Plan or select an existing one. > Choose the SKU (size) of the plan based on your requirements.
e. Configure Monitoring and Management: (Leave as default)
f. Review your configurations, and click on the “Review + create” button.
Go to configuration > Add New Application setting by clicking the plus sign as shown in the images below
c. Deploying the App using CICD release
a. From the menu Click “Pipelines” section and select “Releases” from the sub-menu.
b. Create a New Release Pipeline >
c. In the pop window. We can either choose empty job
but for the sake of this project, select Azure App Service deployment
(we already created the webapp for this purpose)
d. Add Artifacts: Link the artifacts produced by build pipeline which we did earlier to the release pipeline. Click on “Add an artifact” and select the source type.
Enable Continuous deployment trigger
- Click on the thunderbolt and enable
Continuous deployment trigger
(this will ensure any changes made on the code will automatically be triggered)
e. Add Stage configuration.
Click on the 1job 1task
as shown in the image above. > Select your subscription > for app type
select WebApp for Containers (Linux)
> for app service name
select the name of your WebApp
which was created earlier. > for registry name
copy and paste the url of your ACR. > for the repo
go back to the azure portal on the left menu, select the repo and paste the name on the given field
f. Click Save
and then click Create release
> Once the deployment is done, you can view the logs. and other details as shown above.
Weldone !! You have successfully deployed an APP in four different ways.
Related Topics:
a. How to Deploy a Self-Hosted Agent in Azure Pipeline
b. How to Deploy a JavaScript Tetris-Game-App on Azure CICD Pipeline and App Service
c. My Personal Project GitHub Link > https://github.com/ougabriel/pipeline-hello1.git
#docker #selfhosted #container #python #cicd #GabrielOkom #kubernetes #dockerimage #appservice #webapp #devops #devopsprojects #azure #azuredevops