Blueprint: Deploy a Multi-tiered Web application to Spinup Container Service

In this tutorial, we will walk through a real-life example of deploying a multi-tiered web application as a in the Spinup Container Service.

ProGet (ProGet Documentation) is a centralized software artifact repository that allows teams of developers to host third party packages such as NuGet packages, npm modules, PowerShell modules, and Chocolatey packages.

It is deployed as a Docker image hosted at Inedo's Docker registry.

A complete implementation comprises the following components:

We will use Yale Spinup to host this application.

Creating the Spinup Space

We will create a new Space in Spinup to contain the resources for this solution.

Log into Yale Spinup. Create a new space and name it Dev:

 

We will be adding the following resources:

  1. A Microsoft SQL Express database backend.

  2. A secret that will store the database connection string and will be assigned to the runtime environment of the application.

  3. A persistent storage volume accessible via Network File System (NFS) for storing the ProGet artifacts.

  4. A container service task to run the application with the following containers:

    1. ProGet application server

    2. Nginx reverse proxy

Creating the Database Backend

ProGet requires the use of Microsoft SQL. For our purposes, MS SQL Express hosted on AWS RDS is sufficient.

Add a new MS SQL Express resource in Spinup:

 

Use the following values:

  1. Size: db.t3.small

  2. Administrator username: sqladmin

  3. Disk size: 20

  4. Generate a new Administrator password and stash it away as text (preferably in a password safe like KeepassXC). You will need this to construct the connection string.

It will take a few minutes for the database to be fully provisioned. When it’s ready, note the Endpoint URL, as we’ll need that to connect.

 

Creating the Database Connection String Secret

Next, we need to create a secret parameter which will be used by the container service to connect to the MS SQL database backend.

Select the Secrets tab in the space and click Add secret:

Enter the following values (replacing {{ .msSQLExpressEndpointUrl }} and {{ .administratorPassword }} with the values specific to the Spinup database created previously):

 

NOTE: the SQL_CONNECTION_STRING is specific to the ProGet application’s execution environment. Different applications will require different environment secrets and values, but the principle remains the same.

Creating the Persistent Storage Volume

A persistent storage volume will be used by the ProGet docker container to hold packages.

Create a new NFS File System in Spinup:

Use all the default values and use data for the Name.

A new NFS file system resource spinup-xxxxxx-data will be created

 

Creating the Container Service Task: Application and Reverse Proxy

Our container service will comprise two docker containers: the ProGet application and an Nginx reverse proxy to handle SSL termination for the application.

Begin by creating a new Container Service resource in Spinup.

In the first tab, we will configure the ProGet application container service:

Enter a Service Name; this name will identify the application or service running in the containers to be defined shortly. Select a Size. Expand the Volumes section by clicking the + sign. Click Persistent. Select the volume spinup-nnnnnn-data created earlier.

ProGet Docker Container Configuration

We will configure the task definition for ProGet next. Select the Definitions tab.

We will configure the ProGet application docker container. Enter ProGet for the Name.

Click the green pencil/notepad icon to expand the Image configuration section.

Select the External container source radio button and enter the image resource location proget.inedo.com/productimages/inedo/proget:latest in the corresponding text box. Click the green checkmark icon to save the Image configuration.

Scroll down the page to the Secret Environment Variables section and click the pencil icon:

Click the + sign to add a secret environment variable.

 

Enter SQL_CONNECTION_STRING for the Name of the secret. Select ** SQL_CONNECTION_STRING (ProGet MS SQL Connection String) under Value From drop down.

Click the green checkmark to save this section.

Scroll down to the Mount Points section and click the green pencil icon:

Click the + sign and select the previously created Volume; enter /var/proget/packages in the corresponding Options text box.

(We will not configure a Port for the ProGet container, as we will be configuring a reverse proxy in the following section.)

To complete the ProGet container configuration, click the add container button.

The summary will be updated with the ProGet container entry, and a new container dialog will be presented.

Nginx Reverse Proxy Container Configuration

We will be creating an Nginx reverse proxy. The Spinup team has created a docker image for this purpose. Again, we create a new container. Use the following values for the Image:

  1. Name: Nginx

  2. External container source

  3. Image resource location: yalespinup/nginxproxy:latest

Click the green check mark to save the configuration.

Scroll to the Ports section and click the green pencil. Click the + sign in the TCP section and enter 443

Click the green check mark to save the Ports configuration.

The Nginx docker container requires a few environment variables to be set. Scroll to the Environment Variables section. Create the following environment variables:

  • LISTEN_PORT: 443

  • BACKEND_URL: http://127.0.0.1:80

  • CERT_SUBJECT: /CN=proget.local

Click the green check mark to commit the changes.

Next, we will configure load balancing to enable access to the ProGet application from on-campus source IP addresses.

Important Note: Enabling Public Campus or Internet Access for the Application

If you require public access from internal or external source addresses, please contact the Spinup team before proceeding with the following steps.

The task containing the docker containers of the ProGet application will be attached to an elastic network interface assigned a private IP address in the Spinup private network. An application load balancer is required to route traffic to this private IP address from public internal (private campus) or external (internet).

A limitation in the task definition requires the creation of an empty load balancer target group prior to the creation of the container service. The Spinup platform will populate this target group with the IP address of the network interface assigned to the ProGet task.

Scroll to the Advanced Options section and click the green pencil:

Scroll to the Load Balancers section at the bottom, click the + sign, and select the load balancer pre-provisioned by the Spinup team to the Dev space. Use port 443.

Scroll back to the top of the Advanced Options selection and click the green check mark to commit the load balancer configuration.

Scroll back to the bottom and click the Add Container button to finalize the Nginx container definition.

The top of this page will list the configured containers:

Click the Summary button to advance to the Summary tab. Review to make sure the details look like what you expect and click Create Service.

Spinup starts deploying the container and you will see the management page for the container service - you will know when it’s ready when the yellow dot in the upper left corner turns green.

 

Firewall

But before we can do that, there’s one final step - we need to open the port that the Container Service is listening on (in this case 443). This is done from the Firewall tab for the space. You will notice that by default the only ports allowed are 22 and 3389 for administrator access. Click Add rule to open another port.

Select Other (custom) from the Service drop-down, then enter the port number (e.g. 443) and click the Anywhere toggle to allow access from anywhere on campus. Click Add rule and after a few seconds you should see it in the list of open ports.

 

If everything worked, you should now be able to access the app from a web browser using the Endpoint of the Container Service and the specified port.

In our example we can do that at http://spinup-0018a5-nocodbexample.svc.spinup.yale.edu:8080

Note that the above URL is only available on the Yale network and if you need to expose it to the Internet, you need to request that from the Spinup team. It involves setting up an additional web proxy (ALB) and a custom DNS name (e.g. nocodbexample.yale.edu) with SSL certificate. There is an additional monthly cost for this service.