-
-
Notifications
You must be signed in to change notification settings - Fork 29
Deployment
The TDM project deployment environment consists of:
- A Microsoft SQL Server database, and
- A Node/Express web server that serves as both a web api server servicing AJAX request from the client browser and a static page server to HTML pages to the client browser, including react.js and other assets required for running the client application in a web browser. This is packaged and deployed as a Docker image to an Azure App Service for Containers.
Assuming that an environment is already set up, deployment consists of
- Applying database migrations to the database as described in Database Deployment, and
- Building the docker image of the web server, publishing the image to Docker Hub, and loading this image into the hosted docker daemon as described in this document.
We can build and run the application (express and react) in a single container using the database connection parameters supplied when the docker container is run by building and running the build instructions in the Dockerfile image.
To build the docker image tdmcalc/tdmapp
from the project root directory:
docker build -t tdmcalc/tdmapp .
This will use the instructions in the file Dockerfile
to build a docker image named tdmcalc/tdmapp
. By default, docker looks for the file named Dockerfile
for instructions, the -t option allows us to tag the image with a friendly name tdmcalc/tdmapp
, and the period tells docker to start from the current (i.e. root) directory. Note that this will use the connection parameters from the .env file to connect to a database, and build the connection parameters into the docker image.
To create a container from this image and run it on the local docker engine:
- Check to see if there is already a container named
tdmtest
running:
docker ps --all --filter name=tdmtest
This will find all containers where the name contains the string 'tdmtest', you are only interested in the one where the whole name is 'tdmtest'.
- If an existing container was found, remove it:
docker rm --force tdmtest
- Create an container from the tdmcalc/tdmapp image and run it with environment variables that connect to the desired postgres instance.
If you want to use the shared development postgres instance on AWS, first make sure the correct connection string information is uncommented in the server/.env file, then use:
docker run -p 5001:5001 --env-file server/.env tdmcalc/tdmapp
If postgres is installed directly on your native (Windows) machine, use:
docker run -it -p 5001:5000 --name tdmtest \
-e SQL_SERVER_NAME=host.docker.internal \
-e SQL_SERVER_INSTANCE=SQLEXPRESS \
-e SQL_SERVER_PORT= \
-e SQL_DATABASE_NAME=tdmdev \
-e SQL_USER_NAME=sa \
-e SQL_PASSWORD=Dogfood1! \
-e SQL_ENCRYPT=true \
tdmcalc/tdmapp
If postgres is installed in a separate docker container as described in the Local Database instructions, use:
docker run -d -p 5001:5000 --name tdmtest \
-e SQL_SERVER_NAME=host.docker.internal \
-e SQL_SERVER_INSTANCE= \
-e SQL_SERVER_PORT=1434 \
-e SQL_DATABASE_NAME=tdmdev \
-e SQL_USER_NAME=sa \
-e SQL_PASSWORD=Dogfood1! \
tdmcalc/tdmapp
In either case, note that:
-
The -d option allows the container to run as a daemon in the background.
-
The port mapping
-p 5001:5000
allows you to run the application from the url http://localhost:5001 -
Since our database has a servername of localhost, and we need to access the localhost on our native machine (Mac or Windows) from within the node container, there is a special docker alias of
host.docker.internal
that refers to localhost outside the container. This apparently does not work on Linux see this article. If the database was not hosted on localhost, the SQL_SERVER_NAME would be the normal server name of the MS SQL server. -
The container will have a name of
tdmtest
, so you can list or remove the container by name as described in the previous 2 steps, or inspect the running container withdocker container inspect tdmtest
To dig into the running container, you can execute the sh command on the running instance:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b2977675949 tdmcalc/tdmapp "/usr/local/bin/node…" 33 seconds ago Up 26 seconds 0.0.0.0:5001->5001/tcp sad_edison
johnc@John-ThinkPad MINGW64 /c/git/hackforla/tdm-calculator (develop)
$ docker exec -it 6b2977 sh
/ # ls
app package-lock.json
bin package.json
client proc
dev root
etc run
home sbin
lib server.js
media srv
middleware sys
mnt tmp
node_modules usr
opt var
/ #
In this example, you first use the ps command to get the Container Id of the running container, then use the exec command to run the shell command inside the container. Then you can execute linux shell commands at the prompt.
There are two options for publishing the TDM container to Docker Hub: Manual and Github Action:
When the release manager merges changes into the Github repo's
develop
branch, a Github action found in the script
/.github/workflows/docker.yaml
will detect the merge
and build the container from scratch on a Github-hosted
build server and push the tdmcalc/tdmapp container, tagging
it as tdmcalc/tdmapp:latest for deployment.
If there are problems with the Github action described in Option 1, you may publish the container manually as follows:
To publish the application as a single full-stack container to Docker Hub, you must first build the image as described in the previous section if you haven't done so already:
docker build -t tdmcalc/tdmapp .
We can then push this image to the Docker Hub container under our tdmcalc team by:
docker tag tdmcalc/tdmapp tdmcalc/tdmapp:deploy
docker push tdmcalc/tdmapp:deploy
This publishes the application to Docker Hub under the tdmcalc account with the
image name tdmapp and the tag latest
, so the fully-qualified container name
on Docker Hub will be tdmcalc/tdmapp:latest.
For a UAT or production release, we want to use the release version number as the tag, instead of latest
. This will make the UAT image available in Docker Hub for deployment to the UAT environment. As with publishing for the development environment, there are two options:
When the release manager merges changes into the Github repo's
main
branch, the Github action found in the script
/.github/workflows/docker.yaml
will detect the merge
and build the container from scratch on a Github-hosted
build server and push the tdmcalc/tdmapp container.
The workflow checks out the GitHub repository, and uses the build-push-action action to build and push the Docker image. It sets the build-push-action option tag_with_ref to automatically tag the built Docker image with the Git reference of the workflow event. This workflow is triggered on publishing a GitHub release, so the reference will be the Git tag for the release. To wit, the
container will be tagged with the release tag, e.g. tdmcalc/tdmapp:2.0.14
.
If there are problems with the Github action described in Option 1, you may publish the container manually as follows:
To publish the application as a single full-stack container to Docker Hub, you must first build the image as described in the previous section if you haven't done so already:
docker build -t tdmcalc/tdmapp .
You then tag the image with the release number:
docker tag tdmcalc/tdmapp tdmcalc/tdmapp:2.0.14
and then publish this image to Docker Hub:
docker push tdmcalc/tdmapp:2.0.14
The final step in deploying the application is to deploy the container to the hosting environment. The TDM project is for the Los Angeles Department of Transportation, and all three environments (DEV, UAT, PROD) have their server-side deployment on the City's Azure account. Lon Soh is the contact at the City's ITA department for managing access to the Azure resources.
The wiki page Azure Deployment has a walk-through of how to create an Azure account and set up deployment.
The current environments are deployed to:
- DEV: tdm-dev.azurewebsites.net
- UAT: tdm-uat.azurewebsites.net
- PROD: tdm.ladot.lacity.org