1- title: First Steps with Bottle Apps in Docker Containers on macOS
1+ title: Running Bottle Apps in Docker Containers on macOS
22slug: first-steps-bottle-web-apps-docker-containers
33meta: Learn how to set up and develop a new Bottle web application within a Docker container.
44category: post
55date: 2018-06-04
6- modified: 2018-06-04
6+ modified: 2018-06-05
77newsletter: False
88headerimage: /img/180604-bottle-docker/header.jpg
99headeralt: Bottle, Docker and Apple logos, copyright their respective owners.
@@ -54,14 +54,13 @@ On your Mac,
5454[ download the Docker Community Edition (CE) for Mac] ( https://www.docker.com/community-edition#/download )
5555installer.
5656
57- <img src="https://github.com/img/180309-flask -docker/docker-ce.jpg" width="100%"
57+ <img src="https://github.com/img/180604-bottle -docker/docker-ce.jpg" width="100%"
5858 class="shot rnd" alt="Download the Docker Community Edition for Mac.">
5959
60- Find the newly-downloaded install within Finder and double click on the file.
61- Follow the installation process, which includes granting administrative privileges
62- to the installer.
60+ Open Finder and go to the downloads folder where the installation file is located.
61+ Follow the installation steps and open Terminal when the installer finishes.
6362
64- Open Terminal when the installer is done. Test your Docker installation with the
63+ Test your Docker installation by running the ` docker ` command along with the
6564` --version ` flag:
6665
6766```
@@ -71,29 +70,25 @@ docker --version
7170If Docker is installed correctly you should see the following output:
7271
7372```
74- Docker version 17.12.0 -ce, build c97c6d6
73+ Docker version 18.03.1 -ce, build 9ee9f40
7574```
7675
7776Note that Docker runs through a system agent you can find in the menu bar.
7877
79- <img src="https://github.com/img/180309-flask -docker/docker-agent.png" width="100%"
80- class="shot rnd" alt="Docker agent in the menu bar.">
78+ <img src="https://github.com/img/180604-bottle -docker/docker-agent.png" width="100%"
79+ class="shot rnd" alt="Docker agent in the menu bar.">
8180
82- I have found the Docker agent to take up some precious battery life
83- on my Macbook Pro. If I am not developing and need to max battery time I will
84- close down the agent and start it back up again when I am ready to code.
85-
86- Now that Docker is installed let's get to running a container and writing
87- our Flask application.
81+ Docker is now installed so we can run a container and write a simple
82+ Bottle application to test running an app within the container.
8883
8984
9085## Dockerfile
91- Docker needs to know what we want in a container, which is where the
92- ` Dockerfile ` comes in.
86+ Docker needs to know what we want in our container so we specify an
87+ image using a ` Dockerfile ` .
9388
9489```
9590# this is an official Python runtime, used as the parent image
96- FROM python:3.6.4 -slim
91+ FROM python:3.6.5 -slim
9792
9893# set the working directory in the container to /app
9994WORKDIR /app
@@ -104,73 +99,116 @@ ADD . /app
10499# execute everyone's favorite pip command, pip install -r
105100RUN pip install --trusted-host pypi.python.org -r requirements.txt
106101
107- # unblock port 80 for the Flask app to run on
102+ # unblock port 80 for the Bottle app to run on
108103EXPOSE 80
109104
110105# execute the Flask app
111106CMD ["python", "app.py"]
112107```
113108
114- Save the Dockerfile so that we can run our next command with the completed
115- contents of the file. On the commandline run:
109+ Save the Dockerfile and then on the commandline run:
116110
117111```
118- docker build -t flaskdock .
112+ docker build -t bottledock .
119113```
120114
121115The above ` docker build ` file uses the ` -t ` flag to tag the image with
122- the name of ` flaskdock ` .
116+ the name of ` bottledock ` .
117+
118+ If the build worked successfully the [ shell] ( /shells.html ) will show
119+ some completed output like the following:
120+
121+ ```
122+ $ docker build -t bottledock .
123+ Sending build context to Docker daemon 16.38kB
124+ Step 1/6 : FROM python:3.6.5-slim
125+ 3.6.5-slim: Pulling from library/python
126+ f2aa67a397c4: Pull complete
127+ 19cc085bc22b: Pull complete
128+ 83bd7790bc68: Pull complete
129+ 8b3329adba1b: Pull complete
130+ d0a8fd6eb5d0: Pull complete
131+ Digest: sha256:56100f5b5e299f4488f51ea81cc1a67b5ff13ee2f926280eaf8e527a881afa61
132+ Status: Downloaded newer image for python:3.6.5-slim
133+ ---> 29ea9c0b39c6
134+ Step 2/6 : WORKDIR /app
135+ Removing intermediate container 627538eb0d39
136+ ---> 26360255c163
137+ Step 3/6 : ADD . /app
138+ ---> 9658b91b29db
139+ Step 4/6 : RUN pip install --trusted-host pypi.python.org -r requirements.txt
140+ ---> Running in f0d0969f3066
141+ Collecting bottle==0.12.13 (from -r requirements.txt (line 1))
142+ Downloading https://files.pythonhosted.org/packages/bd/99/04dc59ced52a8261ee0f965a8968717a255ea84a36013e527944dbf3468c/bottle-0.12.13.tar.gz (70kB)
143+ Building wheels for collected packages: bottle
144+ Running setup.py bdist_wheel for bottle: started
145+ Running setup.py bdist_wheel for bottle: finished with status 'done'
146+ Stored in directory: /root/.cache/pip/wheels/76/a0/b4/2a3ee1a32d0506931e558530258de1cc04b628eff1b2f008e0
147+ Successfully built bottle
148+ Installing collected packages: bottle
149+ Successfully installed bottle-0.12.13
150+ Removing intermediate container f0d0969f3066
151+ ---> 0534575c8067
152+ Step 5/6 : EXPOSE 80
153+ ---> Running in 14e49938d3be
154+ Removing intermediate container 14e49938d3be
155+ ---> 05e087d2471d
156+ Step 6/6 : CMD ["python", "app.py"]
157+ ---> Running in ca9738bfd06a
158+ Removing intermediate container ca9738bfd06a
159+ ---> 9afb4f01e0d3
160+ Successfully built 9afb4f01e0d3
161+ Successfully tagged bottledock:latest
162+ ```
123163
124- If the build worked successfully we can see the image in with the
125- ` docker image ls ` command. Give that a try now:
164+ We can also see the image with the ` docker image ls ` command. Give that
165+ a try now:
126166
127167```
128168docker image ls
129169```
130170
131- We should then see our tag name in the images list:
171+ Our tag name should appear in the images list:
132172
133173```
134174REPOSITORY TAG IMAGE ID CREATED SIZE
135- flaskdock latest 24045e0464af 2 minutes ago 165MB
175+ bottledock latest 9afb4f01e0d3 About a minute ago 145MB
136176```
137177
138- Our image is ready to load up as a container so we can write a quick
139- Flask app that we will use to test our environment by running it within
140- the container.
178+ Our image is ready to load as a container so we can code a short
179+ Bottle web app for testing and then further development.
141180
142181
143- ## Coding A Simple Flask app
144- Time to put together a super simple "Hello, World!" Flask web app to test
182+ ## Coding A Bottle Web App
183+ It is time to code a simple "Hello, World!"-style Bottle app to test
145184running Python code within our Docker container. Within the current
146185project directory, create a file named ` app.py ` with the following contents:
147186
148187``` python
149- from flask import Flask, Response
188+ import bottle
189+ from bottle import route, run
150190
151191
152- app = Flask( __name__ )
192+ app = bottle.default_app( )
153193
154194
155- @app. route (" / " )
156- def hello ():
157- return Response( " Hi from your Flask app running in your Docker container! " )
195+ @route (' / ' )
196+ def hello_world ():
197+ return " Hello, world! (From Full Stack Python) "
158198
159199
160200if __name__ == " __main__" :
161- app. run(" 0.0.0.0" , port = 80 , debug = True )
201+ run(host = " 0.0.0.0" , port = 8080 , debug = True , reloader = True )
162202```
163203
164- The above 7 lines of code (not counting blank PEP8-compliant lines) in
165- [ app.py] ( https://github.com/fullstackpython/blog-code-examples/blob/master/docker-flask-mac/app.py )
166- allow our application to return a simple message when run with the
167- Flask development server.
204+ The above code returns a simple "Hello, world!" message when
205+ executed by the Bottle development server and contacted by a client.
168206
169- We need just one more file to specify our ` Flask ` dependency. Create
207+ We need just one more file to specify our ` bottle ` dependency. Create
170208a ` requirements.txt ` file within the same directory as ` app.py ` :
171209
172210```
173- flask==1.0.2
211+ bottle==0.12.13
174212```
175213
176214Make sure both the ` app.py ` and ` requirements.txt ` file are saved then
@@ -184,32 +222,29 @@ the following command, making sure to replace the absolute path for the
184222volume to your own directory.
185223
186224```
187- docker run -p 5000:80 --volume=/Users/matt/devel/py/flaskdocker:/app flaskdock
225+ docker run -p 5000:8080 --volume=/Users/matt/devel/py/blog-code-examples/docker-bottle-macapp bottledock
188226```
189227
190228If you receive the error
191229` python: can't open file 'app.py': [Errno 2] No such file or directory ` then
192- you likely forgot to chance ` /Users/matt/devel/py/flaskdocker ` to the
230+ you likely did not change ` /Users/matt/devel/py/bottledocker ` to the
193231directory where your project files, especially ` app.py ` , are located.
194232
195233
196- <img src="https://github.com/img/180309-flask -docker/flask -app-response.png" width="100%"
197- class="shot rnd" alt="Flask app responding to requests from within a Docker container.">
234+ <img src="https://github.com/img/180604-bottle -docker/bottle -app-response.png" width="100%"
235+ class="shot rnd" alt="Bottle web app responding to requests from within a Docker container.">
198236
199237Everything worked when you see a simple text-based HTTP response like what
200238is shown above in the screenshot of my Chrome browser.
201239
202240
203241## What's Next?
204- We just installed Docker and configured a Flask application to run inside a
242+ We just installed Docker and wrote a Bottle web app to run inside a
205243container. That is just the beginning of how you can integrate Docker into
206- your workflow. I strongly recommend reading the
207- [ Django with PostgreSQL quickstart] ( https://docs.docker.com/compose/django/ )
208- that will introduce you to Docker Swarm as well as the core Docker container
209- service.
244+ your workflow.
210245
211- Next up take a look at the [ Docker] ( /docker.html ) and
212- [ deployment] ( /deployment.html ) pages for more related tutorials.
246+ Next up take a look at the [ Bottle ] ( /bottle.html ) , [ Docker] ( /docker.html )
247+ and [ deployment] ( /deployment.html ) pages for more tutorials.
213248
214249Questions? Let me know via a GitHub
215250[ issue ticket on the Full Stack Python repository] ( https://github.com/mattmakai/fullstackpython.com/issues ) ,
@@ -219,6 +254,6 @@ or [@mattmakai](https://twitter.com/mattmakai).
219254
220255Do you see a typo, syntax issue or just something that's confusing in this
221256blog post? Fork
222- [ this page's source on GitHub] ( https://github.com/mattmakai/fullstackpython.com/blob/master/content/posts/180309-flask -docker-macos.markdown )
257+ [ this page's source on GitHub] ( https://github.com/mattmakai/fullstackpython.com/blob/master/content/posts/180604-bottle -docker-macos.markdown )
223258and submit a pull request with a fix or
224259[ file an issue ticket on GitHub] ( https://github.com/mattmakai/fullstackpython.com/issues ) .
0 commit comments