Skip to content

Commit 16a27d9

Browse files
committed
sample docker image that runs a web server
Signed-off-by: Vishnu Kannan <[email protected]>
0 parents  commit 16a27d9

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

Dockerfile

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# A docker base image based on alpine linux with python 3.6.0 pre-installed.
2+
# Docker images can be stacked on top of each other.
3+
FROM library/python:3.6.0-alpine
4+
5+
# Install tornado library.
6+
RUN pip install tornado
7+
8+
# Copy the webserver python app.
9+
ADD web-server.py /web-server.py
10+
11+
# Set the default execution command for this image.
12+
CMD ["python", "/web-server.py"]

README.md

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# A tornado based sample python webserver in a docker image
2+
3+
`web-server.py` is a sample python application that hosts a simple webserver that responds to `Get` requests http requests on `localhost:8888` with the hostname.
4+
5+
To run the webserver manually,
6+
7+
1. Install python versions `2.7` or `3.3+`.
8+
2. Install Tornado - `pip install tornado`
9+
3. Run `python web-server.py`
10+
4. Try accessing <a href="http://localhost:8888/" target="_blank">http://localhost:8888</a> from your browser.
11+
12+
Sharing and running such a simple app like this `web-server` requires many manual steps.
13+
Imagine packaging a real-life webserver with a lot of web content.
14+
15+
Now, let's see how docker can help.
16+
Take a look at [the Dockerfile](./Dockerfile) before you begin.
17+
Docker allows for stacking of images on top of each other.
18+
Our docker image will be built on top of an existing docker image `library/python` which has python pre-installed.
19+
20+
1. Install Docker following [these instructions](https://docs.docker.com/engine/installation/).
21+
22+
2. Execute `docker build -t "py-web-server:v1" .` to build a docker image with web-server packaged inside of it.
23+
24+
3. Run the webserver
25+
```shell
26+
docker run -d -p 8888:8888 -h my-web-server py-web-server:v1
27+
```
28+
29+
The webserver and all its dependencies including `python` and `tornado library` have been packaged into a single docker image that can now be shared with everyone.
30+
`py-web-server:v1` docker image will function the same way on all docker supported OSes (OS X, Windows & Linux).
31+
32+
Try accessing the webserver again - <a href="http://localhost:8888/" target="_blank">http://localhost:8888</a>
33+
34+
Now let's upload the docker image to your private image repository in Google Cloud Registry (`gcr.io`).
35+
36+
1. Store the GCP project name in an environment variable
37+
```shell
38+
export GCP_PROJECT=<your-project-name>
39+
```
40+
41+
2. Rebuild the docker image with an image name that includes `gcr.io` project prefix.
42+
```shell
43+
docker build -t "gcr.io/${GCP_PROJECT}/py-web-server:v1" .
44+
```
45+
46+
3. Push the image to `gcr.io`
47+
```shell
48+
gcloud docker push -- gcr.io/${GCP_PROJECT}/py-web-server:v1
49+
```
50+
51+
The image is now private and people with access to `$GCP_PROJECT` used above can only access it.
52+
53+
Now, let's make the image accessible to everyone.
54+
Google Container Registry stores its images on Google Cloud storage.
55+
Let's update the permissions on Google Cloud Storage to make our image repository publically accessible.
56+
57+
```shell
58+
gsutil defacl ch -u AllUsers:R gs://artifacts.${GCP_PROJECT}.appspot.com
59+
gsutil acl ch -r -u AllUsers:R gs://artifacts.${GCP_PROJECT}.appspot.com
60+
gsutil acl ch -u AllUsers:R gs://artifacts.${GCP_PROJECT}.appspot.com
61+
```
62+
63+
The docker image can now be executed from any machine by running the following command
64+
```shell
65+
docker run -d -p 8888:8888 -h my-web-server gcr.io/${GCP_PROJECT}/py-web-server:v1
66+
```
67+
68+
Detailed Dockerfile reference is available [here](https://docs.docker.com/engine/reference/builder/).

web-server.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
import tornado.ioloop
3+
import tornado.web
4+
import socket
5+
6+
class MainHandler(tornado.web.RequestHandler):
7+
def get(self):
8+
self.write("Hostname: " + socket.gethostname())
9+
10+
def make_app():
11+
return tornado.web.Application([
12+
(r"/", MainHandler),
13+
])
14+
15+
if __name__ == "__main__":
16+
app = make_app()
17+
app.listen(8888)
18+
tornado.ioloop.IOLoop.current().start()

0 commit comments

Comments
 (0)