{"id":1901,"date":"2017-04-22T20:27:24","date_gmt":"2017-04-22T14:57:24","guid":{"rendered":"http:\/\/ramkulkarni.com\/blog\/?p=1901"},"modified":"2017-04-27T20:23:50","modified_gmt":"2017-04-27T14:53:50","slug":"docker-project-for-python3-djaongo-and-apache2-setup","status":"publish","type":"post","link":"http:\/\/ramkulkarni.com\/blog\/docker-project-for-python3-djaongo-and-apache2-setup\/","title":{"rendered":"Docker project for Python3, Django and Apache2 setup"},"content":{"rendered":"<p>I was working on a Django project and it took me some time to make\u00a0Django\u00a0work with Apache2. So I thought I would create a Docker project for this setup.\u00a0You can find the project\u00a0at\u00a0<a href=\"https:\/\/github.com\/ramkulkarni1\/django-apache2-docker\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/ramkulkarni1\/django-apache2-docker<\/a>. It sets up Python3, Django, Apache2 and a sample Django site too.<\/p>\n<p>All configurations for making Django work with Apache2 are created when you create a Docker container using this project. Simply run following command from the project folder.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ <span style=\"color: #1060b6;\">docker-compose<\/span> <span style=\"color: #1060b6;\">up<\/span>\r\n<\/pre>\n<p>(See my post <a href=\"http:\/\/ramkulkarni.com\/blog\/docker-notes\/\" target=\"_blank\" rel=\"noopener noreferrer\">Docker Notes<\/a> on information about setting up Docker and docker commands). One the container is up, browse to http:\/\/localhost:8005.<\/p>\n<p>Here is a quick summary of what <a href=\"https:\/\/github.com\/ramkulkarni1\/django-apache2-docker\/blob\/master\/Dockerfile\" target=\"_blank\" rel=\"noopener noreferrer\">Dockerfile<\/a> does &#8211;<!--more--><\/p>\n<ul>\n<li>Installs apache2 and utils on the base image of Ubuntu<\/li>\n<li>Installs python3 and mod-wsgi. A simlink is created for python3 as python so that you could run python scripts\u00a0just by typing python at the command line, instead of python3<\/li>\n<li>Installs <a href=\"https:\/\/pypi.python.org\/pypi\/pip\" target=\"_blank\" rel=\"noopener noreferrer\">pip<\/a> for Python3 and creates pip simlink for pip3<\/li>\n<li>Installs <a href=\"https:\/\/www.djangoproject.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">django<\/a> and <a href=\"https:\/\/pypi.python.org\/pypi\/ptvsd\" target=\"_blank\" rel=\"noopener noreferrer\">ptvsd<\/a>\u00a0(remote debugging server for Visual Studio Code). I will explain how to remote debug Djajgo application using Visual Studio Code in my next post.<\/li>\n<li>Copies <a href=\"https:\/\/github.com\/ramkulkarni1\/django-apache2-docker\/blob\/master\/demo_site.conf\" target=\"_blank\" rel=\"noopener noreferrer\">demo_site.config<\/a> from the project folder as\/etc\/apache2\/sites-available\/000-default.conf in the container. The configuration file has setting for apache2 virtual host to run Django site. It is configured to run on port 80, which is exposed as 8005 outside the container (see <a href=\"https:\/\/github.com\/ramkulkarni1\/django-apache2-docker\/blob\/master\/docker-compose.yml\" target=\"_blank\" rel=\"noopener noreferrer\">docker-compose.yml<\/a>). Note following mod-wsgi settings\u00a0in demo_site.config (see <a href=\"https:\/\/docs.djangoproject.com\/en\/1.11\/howto\/deployment\/wsgi\/modwsgi\/\" target=\"_blank\" rel=\"noopener noreferrer\">docs<\/a> for more details)\n<ul>\n<li>WSGIPythonPath \/var\/www\/html\/django_demo_app\/demo_site.<br \/>\nThis tell mod-wsgi to looks for python files in this folder.\u00a0\/var\/www\/html is the document root for apache2. We are going to map folder (mount volume) &lt;project_folder&gt;\/www to \/var\/www\/html in the container.&lt;project_folder&gt;\/www contains folder django_demo_app. This is a the main project folder. Within this project there is the demo Django site called demo_site. So the folder structure on the host machine is as follows&lt;project_folder&gt;<br \/>\n&#8211; www<br \/>\n&#8211; django_demo_app<br \/>\n&#8211; demo_site<br \/>\n&#8211; demo_site.conf<br \/>\n&#8211; docker-compose.yml<br \/>\n&#8211; Dockerfile<\/li>\n<li>DocumentRoot \/var\/www\/html\/django_demo_app<br \/>\nSets document root for this virtual host.<\/li>\n<li>\n<div>\n<div>Alias \/static &#8220;\/var\/www\/html\/django_demo_app\/demo_site\/static&#8221;<br \/>\nSets alias for accessing static files. Django docs recommends serving static files from a separate server and suggests executing<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ <span style=\"color: #1060b6;\">python<\/span> <span style=\"color: #1060b6;\">manage.py<\/span> <span style=\"color: #1060b6;\">collectstatic<\/span>\r\n<\/pre>\n<p>to collect all static\u00a0files (like static html, css, javascript\u00a0and image files). However I have kept this simple and using the same server (apache) to serve static files. I am also using the same folder for serving static files by apache and Django dev server. \u00a0So there is not need to run collectstatic command above in this set-up.<\/p>\n<p>See <a href=\"https:\/\/docs.djangoproject.com\/en\/1.11\/ref\/contrib\/staticfiles\/\" target=\"_blank\" rel=\"noopener noreferrer\">docs<\/a> for handling static files in django.<\/p>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<div>\n<div>WSGIScriptAlias \/ \/var\/www\/html\/django_demo_app\/demo_site\/demo_site\/wsgi.py<br \/>\nSets path to wsgi.py for the site.<\/div>\n<\/div>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/ramkulkarni1\/django-apache2-docker\/blob\/master\/docker-compose.yml\" target=\"_blank\" rel=\"noopener noreferrer\">docker-compose-yml\u00a0<\/a>is very simple &#8211; it maps ports and mounts www folder as volume\u00a0\/var\/www\/html in the container.<\/p>\n<p>If you want to create your own Django site, say my_new_site, then follow these steps &#8211;<\/p>\n<ol>\n<li>Open a bash shell in the container\n<pre style=\"color: #000020; background: #f6f8ff;\">$ <span style=\"color: #1060b6;\">docker<\/span> <span style=\"color: #1060b6;\">exec<\/span> <span style=\"color: #074726;\">-it<\/span> <span style=\"color: #1060b6;\">django-apache2<\/span>\r\n<\/pre>\n<\/li>\n<li>Go to folder \/var\/www\/html\/django_demo_app folder and execute command\n<pre style=\"color: #000020; background: #f6f8ff;\">$ <span style=\"color: #1060b6;\">django-admin<\/span> <span style=\"color: #1060b6;\">startproject<\/span> <span style=\"color: #1060b6;\">my_new_site<\/span>\r\n<\/pre>\n<p>Replace my_new_site with the name of site you want to create.<\/li>\n<li>Edit demo_site.conf and change references to demo_site withmy_new_site (or name of the site you entered in the above command).\n<ul>\n<li>WSGIPythonPath \/var\/www\/html\/django_demo_app\/<b>my_new_site<\/b><\/li>\n<li>Alias \/static &#8220;\/var\/www\/html\/django_demo_app\/<b>my_new_site<\/b>\/static&#8221;<\/li>\n<li>WSGIScriptAlias \/ \/var\/www\/html\/django_demo_app\/<b>my_new_site<\/b>\/<b>my_new_site<\/b>\/wsgi.pyMake sure you create static folder under \/var\/www\/html\/my_new_site to store your site specific static filesSet STATICFILES_DIRS variable in my_new_site\/my_new_site\/settings.py file\n<pre style=\"color: #000020; background: #f6f8ff;\">STATICFILES_DIRS <span style=\"color: #308080;\">=<\/span> <span style=\"color: #308080;\">[<\/span>\r\n    os<span style=\"color: #308080;\">.<\/span>path<span style=\"color: #308080;\">.<\/span>abspath<span style=\"color: #308080;\">(<\/span>os<span style=\"color: #308080;\">.<\/span>path<span style=\"color: #308080;\">.<\/span>join<span style=\"color: #308080;\">(<\/span>BASE_DIR<span style=\"color: #308080;\">,<\/span> <span style=\"color: #1060b6;\">\"static\"<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">,<\/span>\r\n<span style=\"color: #308080;\">]<\/span>\r\n<\/pre>\n<p>If you are creating a new app (for example by running command &#8211; python manage.py startapp app1) then don&#8217;t forget to add the name of the app to INSTALLED_APPS array in settings.py. Also configure paths for the new app.<\/li>\n<\/ul>\n<\/li>\n<li>Stop docker-compose (CTRL+C) and run\n<pre style=\"color: #000020; background: #f6f8ff;\">$ <span style=\"color: #1060b6;\">docker-compose<\/span> <span style=\"color: #1060b6;\">build<\/span>\r\n<\/pre>\n<p>to rebuild the image. This is very important. Make sure you rebuild the image after you make any changes to the Docker configuration. Only restarting container is not enough in such cases.<\/li>\n<li>Then start the container\n<pre style=\"color: #000020; background: #f6f8ff;\">$ <span style=\"color: #1060b6;\">docker-compose<\/span> <span style=\"color: #1060b6;\">up<\/span>\r\n<\/pre>\n<\/li>\n<\/ol>\n<p>I will write about debugging Django application running in Docker container in my next post.<\/p>\n<p>-Ram Kulkarni<\/p>\n<p>PS: My video of how to setup Django and Apache in Docker<\/p>\n<p><span class=\"embed-youtube\" style=\"text-align:center; display: block;\"><iframe loading=\"lazy\" class=\"youtube-player\" width=\"525\" height=\"296\" src=\"https:\/\/www.youtube.com\/embed\/OtZmCBR7J-k?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;wmode=transparent\" allowfullscreen=\"true\" style=\"border:0;\" sandbox=\"allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox\"><\/iframe><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was working on a Django project and it took me some time to make\u00a0Django\u00a0work with Apache2. So I thought I would create a Docker project for this setup.\u00a0You can find the project\u00a0at\u00a0https:\/\/github.com\/ramkulkarni1\/django-apache2-docker. It sets up Python3, Django, Apache2 and a sample Django site too. All configurations for making Django work with Apache2 are created &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/ramkulkarni.com\/blog\/docker-project-for-python3-djaongo-and-apache2-setup\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Docker project for Python3, Django and Apache2 setup&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[115],"tags":[113,136,133,137,116],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2g9O8-uF","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1901"}],"collection":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/comments?post=1901"}],"version-history":[{"count":9,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1901\/revisions"}],"predecessor-version":[{"id":1914,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1901\/revisions\/1914"}],"wp:attachment":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/media?parent=1901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/categories?post=1901"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/tags?post=1901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}