Part 14: GCP: How to create docker container in GCP ?
In GCP, we can create a container for our application and can deploy it in five simple steps.
Lets have a look at these steps below.
I. Steps involved in creating Container
1. Code our Application
2. Dockerfile Creation
3. Build Container
4. Register our Container
5. Deploy and Run our Container
Here we will see the usage of Cloud Shell for this.
II. Understanding Basics
Lets understand few concepts involved in GCP below.
a. DockerFile – A file contains a set of commands to build the container automatically.
b. Cloud Shell – Its a lightweight VM preinstalled with utilities like docker, gcloud, etc.
c. Container Image – Image file of docker container containing the executable application code.
d. Registering Container – Saving container images on central online repository.
e. Cloud Deploy and Run – Completely GCP managed service to deploy and run our container online.
III. Activate Cloud Shell
We can activate cloud shell by clicking on below icon at top right corner below.
As soon as you click this, the shell will be activated and below screen is visible.
IV. Code our Application
saketalwar2@cloudshell:~ (second-abacus-334712)$ pwd
/home/saketalwar2
saketalwar2@cloudshell:~ (second-abacus-334712)$ mkdir ngelinux_gcp_docker
saketalwar2@cloudshell:~ (second-abacus-334712)$ ls
ngelinux_gcp_docker README-cloudshell.txt
saketalwar2@cloudshell:~ (second-abacus-334712)$ cd ngelinux_gcp_docker
saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$
saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ cat container1.py
import os
from flask import Flask
app=Flask(__name__)
@app.route('/')
def gcp_ngelinux():
target = os.environ.get('TARGET', 'WELCOME TO NGELINUX')
return format(target)
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT',8080)))
saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$
Flask is the web interface that provides features to run this application on browser.
V. Creating DockerFile
saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ cat dockerfile FROM python:3.7-slim ENV CONT_HOME /app WORKDIR $CONT_HOME COPY . ./ RUN pip install Flask gunicorn CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$
VI. Make files executable.
saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ ls -ltr total 8 -rw-r--r-- 1 saketalwar2 saketalwar2 277 Dec 29 15:47 container1.py -rw-r--r-- 1 saketalwar2 saketalwar2 180 Dec 29 16:08 dockerfile ### Make the files executable saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ chmod +x * saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ ls -ltr total 8 -rwxr-xr-x 1 saketalwar2 saketalwar2 277 Dec 29 15:47 container1.py -rwxr-xr-x 1 saketalwar2 saketalwar2 180 Dec 29 16:08 dockerfile saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$
VII. Building Container Image
saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ gcloud builds submit --tag gcr.io/second-abacus-334712/gcp_ngelinux ERROR: (gcloud.builds.submit) Invalid value for [source]: Dockerfile required when specifying --tag saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ mv dockerfile Dockerfile saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ gcloud builds submit --tag gcr.io/second-abacus-334712/gcp_ngelinux ERROR: (gcloud.builds.submit) You do not currently have an active account selected. Please run: $ gcloud auth login to obtain new credentials. If you have already logged in with a different account: $ gcloud config set account ACCOUNT to select an already authenticated account to use. #### We need to authorize GCP for this. I have a GUI prompt appeared so i authorized in that. saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ gcloud builds submit --tag gcr.io/second-abacus-334712/gcp_ngelinux Creating temporary tarball archive of 3 file(s) totalling 12.4 KiB before compression. Uploading tarball of [.] to [gs://second-abacus-334712_cloudbuild/source/1640794813.234216-2ad2b16c74484386a66caaa151440067.tgz] API [cloudbuild.googleapis.com] not enabled on project [601986027583]. Would you like to enable and retry (this will take a few minutes)? (y/N)? y Enabling service [cloudbuild.googleapis.com] on project [601986027583]... Operation "operations/acf.p2-601986027583-cce8fe3d-5d8e-4e8d-8abd-bfae09738c56" finished successfully. Created [https://cloudbuild.googleapis.com/v1/projects/second-abacus-334712/locations/global/builds/6d6d5f04-30b6-4ae4-a508-d80bf22369f2]. Logs are available at [https://console.cloud.google.com/cloud-build/builds/6d6d5f04-30b6-4ae4-a508-d80bf22369f2?project=601986027583]. --------------------------------------------------------------------- REMOTE BUILD OUTPUT --------------------------------------------------------------------- starting build "6d6d5f04-30b6-4ae4-a508-d80bf22369f2" FETCHSOURCE Fetching storage object: gs://second-abacus-334712_cloudbuild/source/1640794813.234216-2ad2b16c74484386a66caaa151440067.tgz#1640794815734604 Copying gs://second-abacus-334712_cloudbuild/source/1640794813.234216-2ad2b16c74484386a66caaa151440067.tgz#1640794815734604... / [1 files][ 751.0 B/ 751.0 B] Operation completed over 1 objects/751.0 B. BUILD Already have image (with digest): gcr.io/cloud-builders/docker Sending build context to Docker daemon 15.87kB Step 1/6 : FROM python:3.7-slim 3.7-slim: Pulling from library/python a2abf6c4d29d: Pulling fs layer 625294dad115: Pulling fs layer 2d55109ef858: Pulling fs layer 8f7394e7143f: Pulling fs layer 8571408494af: Pulling fs layer 8f7394e7143f: Waiting 8571408494af: Waiting 625294dad115: Download complete 8f7394e7143f: Verifying Checksum 8f7394e7143f: Download complete 2d55109ef858: Verifying Checksum 2d55109ef858: Download complete a2abf6c4d29d: Verifying Checksum a2abf6c4d29d: Download complete 8571408494af: Download complete a2abf6c4d29d: Pull complete 625294dad115: Pull complete 2d55109ef858: Pull complete 8f7394e7143f: Pull complete 8571408494af: Pull complete Digest: sha256:f7f072342e7c29b0fb035057368dfdce5221550c48aa5421bafed0ad1da5a435 Status: Downloaded newer image for python:3.7-slim d3c9ad326043 Step 2/6 : ENV CONT_HOME /app Running in 8918d3102af0 Removing intermediate container 8918d3102af0 424e0c9de10a Step 3/6 : WORKDIR $CONT_HOME Running in 5e7ddc0311fd Removing intermediate container 5e7ddc0311fd 41f5b8a827ff Step 4/6 : COPY . ./ 1317bf6055bb Step 5/6 : RUN pip install Flask gunicorn Running in 3346a9bffe41 Collecting Flask Downloading Flask-2.0.2-py3-none-any.whl (95 kB) Collecting gunicorn Downloading gunicorn-20.1.0-py3-none-any.whl (79 kB) Collecting itsdangerous>=2.0 Downloading itsdangerous-2.0.1-py3-none-any.whl (18 kB) Collecting click>=7.1.2 Downloading click-8.0.3-py3-none-any.whl (97 kB) Collecting Jinja2>=3.0 Downloading Jinja2-3.0.3-py3-none-any.whl (133 kB) Collecting Werkzeug>=2.0 Downloading Werkzeug-2.0.2-py3-none-any.whl (288 kB) Requirement already satisfied: setuptools>=3.0 in /usr/local/lib/python3.7/site-packages (from gunicorn) (57.5.0) Collecting importlib-metadata Downloading importlib_metadata-4.10.0-py3-none-any.whl (17 kB) Collecting MarkupSafe>=2.0 Downloading MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (31 kB) Collecting typing-extensions>=3.6.4 Downloading typing_extensions-4.0.1-py3-none-any.whl (22 kB) Collecting zipp>=0.5 Downloading zipp-3.6.0-py3-none-any.whl (5.3 kB) Installing collected packages: zipp, typing-extensions, MarkupSafe, importlib-metadata, Werkzeug, Jinja2, itsdangerous, click, gunicorn, Flask Successfully installed Flask-2.0.2 Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 gunicorn-20.1.0 importlib-metadata-4.10.0 itsdangerous-2.0.1 typing-extensions-4.0.1 zipp-3.6.0 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: You are using pip version 21.2.4; however, version 21.3.1 is available. You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command. Removing intermediate container 3346a9bffe41 3e1589d4a0d1 Step 6/6 : CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app Running in d8f258b25091 Removing intermediate container d8f258b25091 64f624e68e9e Successfully built 64f624e68e9e Successfully tagged gcr.io/second-abacus-334712/gcp_ngelinux:latest PUSH Pushing gcr.io/second-abacus-334712/gcp_ngelinux The push refers to repository [gcr.io/second-abacus-334712/gcp_ngelinux] 2d256058bb2b: Preparing c0f2abe34197: Preparing 2ef0a9581e5a: Preparing 25ad0307b4c1: Preparing 874b45955cb1: Preparing 85c923303735: Preparing d0fa20bfdce7: Preparing 2edcec3590a4: Preparing 85c923303735: Waiting d0fa20bfdce7: Waiting 2edcec3590a4: Waiting 874b45955cb1: Layer already exists 25ad0307b4c1: Layer already exists 85c923303735: Layer already exists d0fa20bfdce7: Layer already exists 2edcec3590a4: Layer already exists c0f2abe34197: Pushed 2ef0a9581e5a: Pushed 2d256058bb2b: Pushed latest: digest: sha256:bb695af31f42bb97ffe7e04b6b00ee7d7e0a3ec0ab40e3c7542e5d49fe28f849 size: 1995 DONE --------------------------------------------------------------------------------------------------------------------------------------------------------------- ID: 6d6d5f04-30b6-4ae4-a508-d80bf22369f2 CREATE_TIME: 2021-12-29T16:20:34+00:00 DURATION: 25S SOURCE: gs://second-abacus-334712_cloudbuild/source/1640794813.234216-2ad2b16c74484386a66caaa151440067.tgz IMAGES: gcr.io/second-abacus-334712/gcp_ngelinux (+1 more) STATUS: SUCCESS saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$
VIII. Verify the gs i.e. Google Cloud Storage if new bucket is created and new app is created there.
Here you can see the new bucket is created.
IX. Now deploy and run our new Application tar file created.
saketalwar2@cloudshell:~ (second-abacus-334712)$ cd ngelinux_gcp_docker/ saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ ls -ltr total 8 -rwxr-xr-x 1 saketalwar2 saketalwar2 277 Dec 29 15:47 container1.py -rwxr-xr-x 1 saketalwar2 saketalwar2 180 Dec 29 16:08 Dockerfile saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$ gcloud run deploy --image gcr.io/second-abacus-334712/gcp_ngelinux Service name (gcpngelinux): Please specify a region: [1] asia-east1 [2] asia-east2 [3] asia-northeast1 [4] asia-northeast2 [5] asia-northeast3 [6] asia-south1 [7] asia-south2 [8] asia-southeast1 [9] asia-southeast2 [10] australia-southeast1 [11] australia-southeast2 [12] europe-central2 [13] europe-north1 [14] europe-west1 [15] europe-west2 [16] europe-west3 [17] europe-west4 [18] europe-west6 [19] northamerica-northeast1 [20] northamerica-northeast2 [21] southamerica-east1 [22] southamerica-west1 [23] us-central1 [24] us-east1 [25] us-east4 [26] us-west1 [27] us-west2 [28] us-west3 [29] us-west4 [30] cancel Please enter your numeric choice: 1 To make this the default region, run `gcloud config set run/region asia-east1`. Allow unauthenticated invocations to [gcpngelinux] (y/N)? y Deploying container to Cloud Run service [gcpngelinux] in project [second-abacus-334712] region [asia-east1] OK Deploying new service... Done. OK Creating Revision... Initializing project for the current region. OK Routing traffic... OK Setting IAM Policy... Done. Service [gcpngelinux] revision [gcpngelinux-00001-xaq] has been deployed and is serving 100 percent of traffic. Service URL: https://gcpngelinux-2n2cfvtw3q-de.a.run.app saketalwar2@cloudshell:~/ngelinux_gcp_docker (second-abacus-334712)$
X. Now you can visit the above URL for our application to see its running.
https://gcpngelinux-2n2cfvtw3q-de.a.run.app/![]()