Sign inSign up

tylerlu/demoapp-base

By tylerlu

•Updated about 9 years ago

Image
0

792

tylerlu/demoapp-base repository overview

⁠Azure Web Application for Containers - Developer Finder

The Developer Finder application is a container based application that demonstrates how to make a web application with multiple technologies and containers.

This sample includes a web application that allows users to authenticate and register with their GitHub and LinkedIn accounts, import data into their user profiles from those systems, and supplement their profile with additional information. The web application also provides users the ability to search for developers based on the information in their profile, and even suggests friends based on common profile information.

In addition to the profile and search capabilities, the web application interacts with a custom chat system that allows users to engage in chat conversation on the web site.

The entire application is packaged inside Docker containers and deployed to Microsoft Azure. In addition to the container apps, Azure resources such as a MySQL database, Application Insights, and other Azure services are used to implement the application.

Table of contents

⁠Architecture

The following diagram illustrates the overall system architecture.

The main components of the application are described in subsequent sections in this document.

⁠Containers

2 Docker images implement the system, each runs in its own container and they communicate via HTTP/HTTPS.

The following diagram illustrates the containers.

⁠Web App
⁠Back-end

The back-end is a Python (3.6) App.

  • Uses the Flask microframework⁠ to implement the web app and routing.

  • Uses the Python Social Auth⁠ library to enable GitHub and LinkedIn accounts to login and returns user profile information from these systems.

    The following paths are exposed for authentication:

    PathDescription
    /login/<github|linkedin-oauth2>Navigates users to GitHub/LinkedIn login page
    /complete/<github|linkedin-oauth2>/Endpoint that handles OAuth callback
    /logoutLogout current user
  • Uses Azure Database for MySQL⁠.

  • Uses peewee⁠ for ORM access to the MySQL Database.

  • Exposes the following APIs:

    ActionPathDescription
    GET/api/meGet current user's profile
    POST/api/meUpdate current user's profile
    GET/api/connected-accountsGet current user's connected accounts
    GET/api/friendsGet current user's friend
    POST/api/friendsAdd a friend for current user
    GET/api/profilesGet user profiles
    GET/api/profiles/Get a profile by id
    GET/api/profiles/suggestedGet suggested profiles (friends) for current user
    POST/api/smsSend a SMS
    GET/api/messagesGet new messages sent to current user
    POST/api/messagesSend a message from current user
    GET/api/messages/summaryGet messages summary (unread count)
⁠Font-end

The front-end is an AuglarJS App which provides the following pages:

PagePathDescription
Login/loginAllows users to login with GitHub or LinkedIn account
Connect/connectAllows current user to connect to the other account
My Profile/profileAllows current user to view and edit his/her profile
Search/searchAllows current user to search friends, add friend, and start a chat
Profile/profile/Allows current user to view other devs' profile
Chat/chat/Allows current user to chat with a dev or a friend
⁠Nginx

The Nginx combines the back-end app and front-end app, and exposes them through the same port - 80.

It also works with uwsgi⁠ to serve the back-end Python app.

⁠Chat App

The Chat App is a very simple chat back-end application implemented with Ruby-on-Rails. It does not include an authorization/authentication module, and has no user interface.

The Ruby Chat app exposes the following APIs:

ActionPathDescription
POST/api/messagesSend a new message
GET/api/messages/summary?to=<receiver_id>Get message summary
GET/api/messages/unread?from=<sender_id>&to=<receiver_id>Get unread messages
⁠Azure Services

Azure Services are also used to implement the application. The following services are used.

  1. Function App
  • Logs custom metrics to Application Insights.
  1. Logic App
  • Sends SMS text messages to users.
⁠Databases
⁠MySQL Database

The MySQL Database is used by the Web App. It contains the following tables.

TableDescription
userStores user info, like username and email
usersocialauthStores users' connected social account info, like provider and uid
It contains a foreign key column user_id referencing the primary key column of the user table
profileStores users' profiles
positionStores users' positions
It contains a foreign key column profile_id referencing the primary key column of the profile table.
friendStores friends relationship
Its 2 columns, user_id and friend_id, are foreign keys referencing the primary key column of the user table

Note: In a true production environment, the data in the usersocialauth table would most likely be stored in a separate database to make the solution more secure. In this sample, it is stored in the same database to simplify the solution and the deployment process.

The profile table contains several columns which are divided into 5 groups:

  • Primary key:
    • id: matches the id column value in the user table
  • Values managed by My Profile page:
    • phone_number: user’s phone number
    • skills: comma separated string, for example: c#, Python, Ruby
  • Values retrieved from GitHub and LinkedIn accounts:
    • company: user’s current company
    • location: user's location
    • name: user display name
  • Values are retrieved from GitHub only:
    • github_profile_url: the URL to user’s GitHub profile page
    • blog_url: the URL to user's blog
    • hireable: boolean indicating if the user is hireable
    • bio: user's biography
    • public_repos: the number of public repos
    • public_gists: the number of public gists
    • followers: the number of followers
    • following: the number of users the user is following
    • avatar_url: the URL to the user’s avatar
  • Values are retrieved from LinkedIn only:
    • industry: The industry the member belongs to
    • num_connections: the number of LinkedIn connections the member has, capped at 500. See 'num-connections-capped' to determine if the value returned has been capped.
    • num_connections_capped: returns 'true' if the member's 'num-connections' value has been capped at 500', or 'false' if 'num-connections' represents the user's true value
    • linkedin_standard_profile_url: the URL to the member's authenticated profile on LinkedIn. You must be logged into LinkedIn to view this URL.
    • linkedin_public_profile_url: the URL to the member's public profile on LinkedIn
⁠PostgreSQL Database

The PostgreSQL database is used by the Chat App. It is very simple and only contains 2 tables:

TableDescription
messagesStores all the messages
message_read_recordsRecords users' last read message id
⁠Application Insights

Throughout the application, custom events are logged to Application Insights.

The following table describes the custom events logged to Application Insights at a high level.

SourceTriggers
Python Web AppPython REST API, Function, and Logic App Calls
Python REST APIPython REST API, Function, and Logic App Calls
Logic AppStart, Events Taking Place In Logic App, Complete

This image shows custom events logged to Application Insights.

The following image shows the detail of a custom event. In this example, the /api/messages/summary Python REST API was successfully invoked.

⁠Geo-Replication

Because this is a sample application that is designed for anyone in the world to deploy their own isolated instance, the databases in the application are created each time the ARM template deploys the solution. The web apps are tied directly to the databases that are deployed.

Since this is the case, if you Geo-Replicate the solution, each Geo-Location will have a separate copy of the databases. You are still able to demonstrate Geo-Replicating the app as part of the demo, but if you Geo-Replicate the solution then subsequently logged into an instance of the app in the US with one user, and logged into an instance of the App in China with another user, they would not be able to see each other in search results or chat because they are interacting with separate databases.

In a real production scenario, there would be a common database, or multiple databases with a database sync. This would provide the ability to use the Traffic Manager to load balance traffic across multiple Geo-Locations and achieve global scale with the solution. You can re-architect the solution to provide these capabilities.

⁠Deployment

⁠Choose a name for the app

The name of the application is 'Developer Finder'. We suggest you follow the naming convention below when creating your instance of the application:

​ developer-finder-[suffix]

The suffix is used to avoid Azure resource naming conflicts.

IMPORTANT NOTE: Only use lowercase letters (a-z), numbers (0-9), and hyphens (-). Uppercase letters will cause errors to occur.

Below are some examples:

  • developer-finder-contoso (company name is used)
  • developer-finder-0901-1200 (date and time are used)

In this document, we use the first example to show you how to deploy the solution to Azure. When you are finished with the deployment, you will be able to browse to the web application by navigating to this URL in a web browser:

https://developer-finder-[suffix].azurewebsites.net

​ Example that matches the example in this document:

https://developer-finder-contoso.azurewebsites.net
⁠Register OAuth applications

To start, you must register OAuth applications for GitHub and LinkedIn. These OAuth applications allow the application to authenticate to GitHub and LinkedIn and download user profile information stored in these systems.

⁠Register GitHub OAuth application
  1. Sign into GitHub.

  2. Open https://github.com/settings/applications/new⁠

  3. Fill the form with the following information:

  4. Click Register application.

  5. Copy aside the ClientID and Client Secret.

    Note: These values will be used for the OAuth GitHub Client Id and OAuth GitHub client Secret ARM template parameters.

⁠Register LinkedIn OAuth application
  1. Sign into LinkedIn.

  2. Open https://www.linkedin.com/developer/apps/new⁠

  3. Fill the form with the following information:

    • Name: Developer Finder

    • Application Logo: download and use the image below

    • Website URL: https://developer-finder-[suffix].azurewebsites.net⁠

      Note: Replace the [suffix] placeholder with the one you choose to use. Use this same value throughout the deployment process.

      Example:

      https://developer-finder-contoso.azurewebsites.net
      
  4. Input the other required fields, then click Submit.

  5. Add the OAuth 2 Authorized Redirect URL:

    https://developer-finder-[suffix].azurewebsites.net/complete/linkedin-oauth2/⁠

    Note: Replace the [suffix] placeholder with the one you choose to use. Use this same value throughout the deployment process.

    Example:

    https://developer-finder-contoso.azurewebsites.net/complete/linkedin-oauth2/⁠

  6. Click Update.

  7. Copy aside the ClientID and Client Secret.

    Note: These values will be used for the OAuth LinkedIn Client Id and OAuth LinkedIn Client Secret ARM template parameters.

⁠GitHub Authorization
  1. Generate Token:

    • Open https://github.com/settings/tokens⁠ in your web browser.

    • Sign into GitHub.

    • Fork this repository to your GitHub account.

    • Click Generate Token.

    • Enter a value in the Token description text box.

    • Select the following scopes (your selections should match the screenshot below):

      • repo -> repo:status, repo_deployment, public_repo

      • user -> read:user, user:emial, user:follow

        Note: the user scope itself must be selected.

  2. Add the GitHub Token to Azure in the Azure Resource Explorer:

⁠[OPTIONAL STEP] Register a Twilio account to send SMS

When a chat is started between two users in the application, the app will send an SMS to notify the user the message was sent to them.

This app uses a Twilio trial account to send SMS.

If you wish to enable the SMS capabilities in the application you must create a Twilio trial account and register and verify a phone number to send SMS.

⁠Create and configure a Twilio trial account
  1. Register a trial account

    • Open https://www.twilio.com/⁠, then click Get a free API key.
    • You will be redirected to Sign up for free page. Fill in the form, then click Get Started.
    • Twilio will show a page verify you're a human. Finish it.
  2. Create a project

    After the human verification is complete, you will be redirected to a page to let you create a project.

    • Input a name, for example: Developer Finder, then click Create Project.

    • After the project is created, copy aside the ACCOUNT ID and AUTH TOKEN values.

      Note: These 2 values will be used for the Twilio Account SID and Twilio Auth Token ARM template parameters.

  3. Get a phone number:

    • In the Phone Numbers section, click Manage Numbers.

    • Twilio will redirect you to the Phone Numbers Dashboard.

    • Click Get Started.

    • Click Get you first Twilio phone number.

      Note: Twilio will pre-select a phone number. Use the number it gives you.

    • Click Choose this number:

    • Copy aside the phone number.

      Note: This phone number will be used for the Twilio From Phone Number ARM template parameter.

⁠Verify a phone number
  1. Click Verified Caller IDs on the Phone Numbers page:

  2. Click the red ⊕:

  3. Follow the instructions to verify the phone number.

⁠Deploy the Azure Components
  1. In your web browser, navigate to your fork of this repository.

  2. Click the Deploy to Azure button below:

    Deploy to Azure

  3. Fill in the values in the deployment page:

  • Resource group:

    We suggest you create a new resource group and name it DeveloperFinderRG.

  • Location:

    Web Apps on Linux are currently (2017/08) only available in the following regions. So, you must choose one of the regions below:

    • West US
    • East US
    • West Europe
    • North Europe
    • South Central US
    • North Central US
    • Southeast Asia
    • East Asia
    • Australia East
    • Japan East
    • Brazil South
    • South India

  • Web App Name:

    Use the name you chose at the start of these instructions that follows the developer-finder-[suffix] naming convention.

  • No-Linux Web App Location:

    You MUST choose a different region for the non-Linux web apps, because they cannot be created in the same region and the same resource group.

  • OAuth Git Hub Client Id & Secret:

    Use the client id and secret of the GitHub OAuth app.

  • OAuth LinkedIn Client Id & Secret:

    Use the client id and secret of the LinkedIn OAuth app.

  • Database Admin Login Name:

    It cannot be 'azure_superuser', 'admin', 'administrator', 'root', 'guest' or 'public'.

  • Database Admin Login Password:

    This field should be between 8 and 128 characters long. Your password must contain characters from three of the following categories – English uppercase letters, English lowercase letters, numbers (0-9), and non-alphanumeric characters (!, $, #, %, etc.).

  • Ruby Chat Docker Image:

    Please keep the default value: appsvc/demoapp-rubychat.

  • Twilio Account SID & Auth Token & From Phone Number.

    Use the values you got from you Twilio account.

  • Source Code Repository URL:

    Use the URL of the repository you just cloned.

  1. Check I agree to the terms and conditions stated above.

  2. Click Purchase.

  3. Wait until the ARM template deployment process completes.

⁠Configure TrackCustomEvent function URL
  1. Get TrackCustomEvent function URL from the Function App.

    • Open the Function App in the Resource Group:

    • Expand the functions, then click TrackCustomEvent. Click Get function URL at the right.

    • Copy the URL on the popup.

  2. Configure application settings of the Web App.

    • Open the Web App in the Resource Group:

    • Click Application settings

    • Find the TRACK_CUSTOM_EVENT_FUNCTION_URL setting, paste the function URL you just copied to its value inputbox.

    • Click Save.

⁠Set up CI/CD
  1. Navigate to the resource group you just created and deployed, then click the developer-finder-[suffix] Web App:

  2. Click Continuous Delivery, then click Configure:

  3. Click Choose container registry, the pre-configured private registry will be loaded:

  4. Click OK (the right one).

  5. Click Configure continuous delivery:

    • Code repository: choose GitHub.
    • Repository: choose this GitHub repository that you forked.
    • Branch: choose master.
    • Dockerfile path: change it to Dockerfile.
  6. Click OK (the right one).

  7. Click Select a Team Service account:

    • Create a new account or using an existing one.
    • Create a new project or using an existing one.
  8. Click OK (the right one).

  9. Click OK.

    Note: It takes a few minutes to finish:

⁠Validate deployment

Open the https://developer-finder-[suffix].azurewebsites.net web app.

Note:

  1. Make sure you use https instead of http.

  2. Make sure you replace the [suffix] placeholder with the value you have used throughout the deployment process.

Example: https://developer-finder-contoso.azurewebsites.net⁠

You will see the login page:

Note: If you get a "502 Bad Gateway" error, please wait for a few minutes and try again.

⁠Demo scenario overview and flow

See the Demo Script⁠ slide deck.

⁠Running the demo

Follow the steps in Demo Script⁠ slide deck.

⁠Contributors

RolesAuthor(s)
Project Lead / ArchitectTodd Baginski (Microsoft MVP, Canviz) @tbag
Architect / Developer LeadTyler Lu (Canviz) @TylerLu
DeveloperAlbert Xie (Canviz)
DeveloperHubert Sui (Canviz)
DesignJustin So (Canviz)
TestingCindy Yan (Canviz)
Sponsor / SupportAhmed Elnaby (Microsoft)
Sponsor / SupportStella Lin (Microsoft)

⁠Version history

VersionDateComments
1.0August 31, 2017Initial release

⁠Disclaimer

THIS CODE IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

Tag summary

Content type

Image

Digest

Size

350.3 MB

Last updated

about 9 years ago

docker pull tylerlu/demoapp-base