Giter Site home page Giter Site logo

alpine-flask's Introduction

Alpine OS running Python Flask (with Python 2.7 or 3.5)

Tags:

  • latest - flask running on python 2.7
  • python3 - flask running on python 3.6

This image is used to run flask applications. To start a container use

docker run --name flaskapp --restart=always \
	-p 80:80 \
	-v /path/to/app/:/app \
	-d jazzdd/alpine-flask

-v /path/to/app/:/app - specifies the path to the folder containing a file named app.py, which should be your main application

-p 80:80 - the image exposes port 80, in this example it is mapped to port 80 on the host


Installing additional python or flask packages

This image comes with a basic set of python packages and the basic flask and python-pip installation.

If you need any non-default python or flask packages, the container will install them on its first run using python pip and a requirements.txt file. Save a requirements.txt file in the root folder of your app, which is mounted to the /app folder of the container. The format of the file is described in the pip documentation. After that you can create a new container with the above docker command. The entrypoint script will take care of the package installation listed in the requirements file.

If an additional package is needed during runtime of the container it can be installed with following command.

docker exec YOUR_CONTAINER_ID/NAME /bin/bash -c "pip install package-name"

Installing additional Alpine packages

Sometimes, additional python or flask packages need to build some dependecies. Additional Alpine packages can be installed into the container using a requirements file similar to the python requirements file. Listed packages will be installed on the first run of the container.

You need to save a file named requirements_image.txt into the root folder of your app, which is mounted to the /app folder of the container. Just write the packages separated with space or a new line into the file.


Internals

The flask application is started using a UWSGI socket.

Nginx is used to map the socket to port 80 within the image. This image does not offer any SSL capability, please use a nginx proxy for this. Nginx will deliver static content (e.g. CSS or JS Files) directly without going through flask or uwsgi.

Log messages

Logs can be displayed using docker logs -f CONTAINER_ID/NAME


Using this image to control docker with flask

This image can be used to create a privileged container, which can control your docker server. Therfore the docker socket must be mounted as volume within this container and an additional option is needed to run the container.

docker run --name flaskapp --restart=always \
    -p 80:80 \
    -v /path/to/app/:/app \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -d jazzdd/alpine-flask -o gid

-o gid enables the docker option (docker will be installed into the container on the first run). GID is the docker group id of your host system. The container matches the gid of the docker group and adds the nginx user (this user is running nginx and uwsgi) to the docker group.

Now you could use:

from subprocess import call
call(["docker", "run", "-p 80" ,"-v /path/to/app/:/app", "-d jazzdd/alpine-flask"])

to get another container running with the flask app.

Debug mode

Debug mode means the container doesn't use uwsgi and nginx but starts the flask app with a simple python app.py. So you can make use of the build-in flask development webserver and the automated reload system after editing the application.

To start a container in debug mode use:

docker run --name flaskapp --restart=always \
	-p 80:80 \
	-v /path/to/app/:/app \
	-d jazzdd/alpine-flask -d

Your app.py file must have a section similiar to the following example to start the app within the debug mode.

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

To get the command line output of your app use docker logs -f CONTAINER_ID/NAME.

alpine-flask's People

Contributors

jazzdd86 avatar jmartens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alpine-flask's Issues

I can't use Docker in my Flask app

I ran the alpine-flask container:

docker run --name flaskapp -p 8083:80 -v /path/to/app/:/app -v /var/run/docker.sock:/var/run/docker.sock -d jazzdd/alpine-flask:python3 -o gid

... and then executed a docker info on it with docker exec -it flaskapp docker info, and it just works perfectly:

Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 12
[...]

But, when I execute this same command from my Flask app, it seems that the docker daemon is not running. Here is the app log:

fetch http://dl-cdn.alpinelinux.org/alpine/v3.5/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.5/community/x86_64/APKINDEX.tar.gz
(1/8) Installing libmnl (1.0.4-r0)
(2/8) Installing libnftnl-libs (1.0.7-r0)
(3/8) Installing iptables (1.6.0-r0)
(4/8) Installing xz (5.2.2-r1)
(5/8) Installing libseccomp (2.3.1-r0)
(6/8) Installing docker (1.12.6-r0)
Executing docker-1.12.6-r0.pre-install
(7/8) Installing linux-pam (1.2.1-r0)
(8/8) Installing shadow (4.2.1-r8)
Executing busybox-1.25.1-r0.trigger
OK: 191 MiB in 42 packages
groupmod: invalid group ID 'gid'
Adding user nginx to group docker
Running app in production mode!
2017/05/19 16:52:17 [notice] 15#15: using the "epoll" event method
2017/05/19 16:52:17 [notice] 15#15: nginx/1.10.3
2017/05/19 16:52:17 [notice] 15#15: OS: Linux 4.4.0-78-generic
2017/05/19 16:52:17 [notice] 15#15: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2017/05/19 16:52:17 [notice] 16#16: start worker processes
2017/05/19 16:52:17 [notice] 16#16: start worker process 18
2017/05/19 16:52:17 [notice] 16#16: start worker process 19
2017/05/19 16:52:17 [notice] 16#16: start worker process 20
2017/05/19 16:52:17 [notice] 16#16: start worker process 21
[uWSGI] getting INI configuration from /app.ini
*** Starting uWSGI 2.0.14 (64bit) on [Fri May 19 16:52:17 2017] ***
compiled with version: 6.2.1 20160822 on 22 February 2017 22:05:04
os: Linux-4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017
nodename: b4ea444303ed
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 12
current working directory: /app
writing pidfile to /run/.pid
detected binary path: /usr/sbin/uwsgi
setgid() to 101
set additional group 82 (www-data)
set additional group 103 (docker)
setuid() to 100
chdir() to /app
*** WARNING: you are running uWSGI without its master process manager ***
your memory page size is 4096 bytes
detected max file descriptor number: 1048576
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to UNIX address /run/uwsgiApp.sock fd 3
Python version: 3.5.2 (default, Dec 22 2016, 10:15:38)  [GCC 6.2.1 20160822]
Python main interpreter initialized at 0x564065903000
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 332288 bytes (324 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x564065903000 pid: 17 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (pid: 17, cores: 2)
spawned uWSGI worker 2 (pid: 22, cores: 2)
spawned uWSGI worker 3 (pid: 23, cores: 2)
spawned uWSGI worker 4 (pid: 24, cores: 2)
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
[pid: 24|app: 0|req: 1/1] 172.17.0.1 () {40 vars in 520 bytes} [Fri May 19 16:52:21 2017] GET / => generated 2 bytes in 28 msecs (HTTP/1.1 200) 2 headers in 78 bytes (1 switches on core 0)
172.17.0.1 - - [19/May/2017:16:52:21 +0000] "GET / HTTP/1.1" 200 2 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0"

I think it's because I am logged as root with docker exec and as nginx on the Flask app... But I'm new to both Docker and Flask and I don't really know how to deal with it...


Note that I also tried with :latest but the containers stops immediatly with this error:

touch: /debug0: Permission denied
ERROR: Unable to lock database: Permission denied
ERROR: Failed to open apk database: Permission denied
/entrypoint.sh: line 23: groupmod: command not found
/entrypoint.sh: line 24: gpasswd: command not found
Running app in production mode!
nginx: [alert] could not open error log file: open() "/var/lib/nginx/logs/error.log" failed (13: Permission denied)
2017/05/19 16:55:40 [warn] 11#11: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1
2017/05/19 16:55:40 [emerg] 11#11: bind() to 0.0.0.0:80 failed (13: Permission denied)
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

And fyi here is my very simple app.py used for this test:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask import Flask
from subprocess import call

app = Flask(__name__)


@app.route('/', methods=['GET'])
def update():
    call(["docker", "info"])
    return 'ok'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

Is that a bug or just a newbie issue?

Calling docker stop on image results in exit 137

I have created an image based on alpine-flask.
When I run the image in either debug or production modes and call docker stop it waits for a while (around 10 seconds) and then exits.
When I use docker ps -a to check I find that it has exited with code 137.

I believe this is because docker sends a term signal to process ID 1, it will then wait for 10 seconds and if it hasn't ended will then kill the process.

I have checked this out in the python3 debug mode.
The problem here is that this image uses a script to execute python3. The term signal is sent to process id 1 (the bash script) not the python process. A solution to this is described here:
https://veithen.github.io/2014/11/16/sigterm-propagation.html

Is this a possible enhancement to this project?

Installing flask-ask throws error code 1

Tried to use this image with a flask-ask app, but it throws the following error when it tries to install "cffi-1.11.2" (dependency):
Command "python setup.py egg_info failed with error code 1 in /tmp/pip-build-_CC3oO/cffi
Image: https://i.imgur.com/fWeYkb8.png

Edit: Installing these packages solves the issue. Possible to include them? :)
apk add --no-cache openssl-dev libffi-dev gcc python-dev musl-dev

Unable to install folium

In either python2.7 or 3.5 builds running pip install pandas or folium results in many errors

Volume use?

Am trying to give my dev co-workers a common base image for our python apps. Is that more or less your intent by using with VOLUME [${APP_DIR}] ?

How do I add nodejs to this container?

Can you give me some advice on how to add nodejs to this container? I tried adding node to the requirements.txt file and that installs, but I cannot get a node command to run. Seems to be a path issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.