Last active
May 1, 2018 21:48
-
-
Save toolness/751b32c0bdcdc4affef025f8322d0c40 to your computer and use it in GitHub Desktop.
Super simple scaffolding for building a Django app using Docker.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: '3' | |
services: | |
app: | |
build: . | |
volumes: | |
- .:/stuff | |
working_dir: /stuff |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM python:3.6 | |
COPY requirements.txt . | |
RUN pip install -r requirements.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
django==2.0.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is a very simple setup to start playing with Django using Docker (i.e., without having to go through installing Python and dealing with this whole mess locally).
If you haven't already, you should install Docker Community Edition.
Instructions
Put all the files in this gist in a directory. Maybe call it
stuff
.Run
docker-compose build
. This will fetch the official Docker python image off the internet and then run theDockerfile
on top of it, which will install Django. What you have now is a Docker image. It's kind of like a pristine VM that contains Debian Linux, Python 3.6, and Django.Run
docker-compose run app bash
. You should see a bash shell, and you'll be in a directory called/stuff
, which is mapped to the directory your files are in.You are now "inside" a Docker container, which is a temporary instantiation of the Docker image created in step 2. From here, you can run
python
,pip
,django-admin
, or a bunch of other things. You'll probably want to start following the official Django tutorial from here, if you're unfamiliar with Django itself. You can also go ahead and just use sqlite as the database for now.Wait, did you say "temporary"?
Yup. This is one of the most unintuitive and confusing things about Docker.
Docker containers are meant to be fairly ephemeral. If you install anything via
apt-get
orpip
while in a bash session in your container, for example, you'll notice that once you exit that bash session and start a new one withdocker-compose run app bash
, the thing you just installed is gone. That's because every time you rundocker-compose run
it creates a brand-new container, with the filesystem based off the pristine docker image created in step 2 above.There's one exception, though: if you look at your
docker-compose.yml
, you'll see avolumes
section. That sets up a sort of "volume mount" on the otherwise temporary filesystem:/stuff
in the container is mapped to the directory with your stuff on your computer, so any changes you make to files in that directory will be reflected in your container and vice versa. That makes it persistent, unlike everything else on the filesystem.What is this "docker-compose" thing? I thought I was going to use Docker.
There is a
docker
command-line tool, but it's super low-level and you will almost never need to use it.docker-compose
, on the other hand, is a higher-level tool that comes built-in with the rest of Docker Community Edition, and you will be using it a lot.You might even find it useful to make a bash alias that aliases
dcr
todocker-compose run
, because you'll be using that one in particular a ton.Networking
Eventually, once you've created a Django project, you'll want to start running its development server. This is where things get a bit tricky, because by default, Docker containers' network ports aren't accessible from your web browser. To make them accessible, we'll have to do a few things:
Tell Docker to map port 8000 of your localhost to port 8000 of your docker container. One way to do this is by running
docker-compose run -p 8000:8000 app bash
. Note this is the same thing you've been running, just with-p 8000:8000
added on, which tells Docker to do the port mapping.Tell Django to bind to all network interfaces. Normally, Django's development server only binds to 127.0.0.1 on the host system, but that's not very useful when done in a Docker container. So when you run
python manage.py runserver
inside the Docker container, you'll want to add the argument0.0.0.0:8000
.Once you've done those things, you should be able to visit http://localhost:8000 on your web browser and see your Django project.
Note that this is kind of cumbersome, and not very easy to remember. That's why most projects will modify their
docker-compose.yml
to includecommand
andports
directives, so that a developer just has to rundocker-compose up
to get their server up and running. I'm leaving that as an exercise to the reader, though!Going further
To maintain some degree of dev/prod parity you might want to use a production database backend like Postgres instead of sqlite. Actually setting this up is out of scope of this little tutorial, though, so I'll just give you some pointers on how this is done:
You'll want to add a new service, probably called
db
to yourdocker-compose.yml
. It will probably use theimage
directive to pull directly from the official Postgres Docker image. Now runningdocker-compose up
should also start up a postgres server in a separate Docker container, which is nifty.The Postgres docker container started in
docker-compose up
has a hostname on the little mini Docker network that exists inside your computer. The hostname is the same as the service name, so if you useddb
, then telling Django to connect to a Postgres server on the hostdb
should do the trick. You might need to tweak a few things on the Postgres side, but the documentation for the official Postgres Docker image has all kinds of details on environment variables you can set to configure things differently.You might be wondering where your Postgres container is storing all its data. That's a very good question, and the answer is out of scope of this little tutorial. This time I'm not even going to post a link for further information because I have to go to a meeting.