Tutoriel erroneousboat Docker Django

tree

git clone https://github.com/erroneousboat/docker-django
Clonage dans 'docker-django'...
remote: Enumerating objects: 536, done.
remote: Total 536 (delta 0), reused 0 (delta 0), pack-reused 536
Réception d'objets: 100% (536/536), 896.74 KiB | 449.00 KiB/s, fait.
Résolution des deltas: 100% (265/265), fait.
tree -L 4
.
├── config
│   ├── environment
│   │   └── development.env
│   └── webserver
│       ├── localhost.crt
│       ├── localhost.key
│       └── nginx.tmpl
├── docker-compose.yml
├── LICENSE
├── README.md
└── webapp
    ├── config
    │   ├── database-check.py
    │   ├── django-uwsgi.ini
    │   ├── requirements.txt
    │   └── start.sh
    ├── Dockerfile
    └── starter
        ├── manage.py
        └── starter
            ├── __init__.py
            ├── settings.py
            ├── urls.py
            └── wsgi.py

7 directories, 17 files

docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#####
# Docker compose YAML file
#
# For documentation see: https://docs.docker.com/compose/yml/
#####

version: "3"

volumes:
  static-files:
    driver: local
  postgres:
    driver: local
    
services:
    db:
      image: postgres:11.1
      volumes:
        - postgres:/var/lib/postgresql/data/pgdata
      env_file:
        - ./config/environment/development.env

    webserver:
      image: nginx:1.15
      ports:
        - "80:80"
        - "443:443"
      depends_on:
        - webapp
      volumes:
        - ./config/webserver/nginx.tmpl:/etc/nginx/conf.d/nginx.tmpl
        - ./config/webserver/localhost.crt:/etc/ssl/certs/localhost.crt
        - ./config/webserver/localhost.key:/etc/ssl/private/localhost.key
        - static-files:/srv/static-files
      env_file:
        - ./config/environment/development.env
      command: /bin/sh -c "envsubst < /etc/nginx/conf.d/nginx.tmpl > /etc/nginx/nginx.conf && exec nginx -g 'daemon off;'"

    webapp:
      build:
        context: webapp
      volumes:
        - ./webapp/starter:/srv/starter
        - static-files:/srv/static-files
      expose:
        - "8000"
      depends_on:
        - db
      env_file:
        - ./config/environment/development.env

webapp/Dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
FROM python:3.7

# Add code
ADD ./starter /srv/starter

# Install application requirements
ADD ./config/requirements.txt /srv/starter/
RUN pip3 install -r /srv/starter/requirements.txt

# Add start script
ADD ./config/start.sh /

# Add uWSGI config
ADD ./config/django-uwsgi.ini /etc/uwsgi/django-uwsgi.ini

# Add database check script
ADD ./config/database-check.py /srv/config/database-check.py

# Create django user, will own the Django app. This is needed
# because we defined this, in the uwsgi.ini file
RUN adduser --no-create-home --disabled-login --group --system django
RUN chown -R django:django /srv/starter

# Execute start script
CMD ["./start.sh"]

README.md

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
Docker Django
=============

## tl;dr
```bash
$ git clone git@github.com:erroneousboat/docker-django.git
$ docker-compose up
```

Now you can access the application at <https://localhost> and the admin site
at <https://localhost/admin>.

A project to get you started with Docker and Django. This is made to
serve as an example for you to hack on, so I don't claim that this is the
correct way to setup a system with Django and Docker. Thus, I advice to also
look at other projects.

Stack and version numbers used:

| Name           | Version  |
|----------------|----------|
| Django         | 2.1.4    |
| Nginx          | 1.15     |
| Postgresql     | 11.1     |
| uWSGI          | 2.0.17.1 |

## Folder structure

```
$ tree -L 1 --dirsfirst
.
├── config              # files needed for configuration
├── webapp              # actual webapp
├── docker-compose.yml  # docker-compose setup with container orchestration instructions
├── LICENSE             # license for this project
└── README.md           # this file
```

## Setting up

### Docker
See installation instructions at: [docker documentation](https://docs.docker.com/install/)
### Docker Compose
Install [docker compose](https://github.com/docker/compose), see installation
instructions at [https://docs.docker.com/compose/install/](https://docs.docker.com/compose/install/)

### Django
Create django project in the `webapp` folder or copy a project to the `webapp`
folder or use the sample project enclosed in this project and go directly to
the section 'Fire it up':

```bash
# Be sure you have Django installed on your system
$ django-admin startproject <name_project>
```

Edit `config/environment/development.env` file and add the name of your
project at `DJANGO_PROJECT_NAME` or just leave it as is to start the default
application.


Edit the `settings.py` file with the correct database credentials and static
root:

```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.environ.get('POSTGRES_NAME'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': os.environ.get('POSTGRES_HOST'),
        'PORT': os.environ.get('POSTGRES_PORT'),
    }
}

STATIC_ROOT = '/srv/static-files'
```

### Environment variables
The file `config/environment/development.env` contains the environment
variables needed in the containers. You can edit this as you see fit, and at
the moment these are the defaults that this project uses. However when you
intend to use this, keep in mind that you should keep this file out of version
control as it can hold sensitive information regarding your project. The file
itself will contain some commentary on how a variable will be used in the
container.

## Fire it up
Start the container by issuing one of the following commands:
```bash
$ docker-compose up             # run in foreground
$ docker-compose up -d          # run in background
```

## Other commands
Build images:
```bash
$ docker-compose build
$ docker-compose build --no-cache       # build without cache
```

See processes:
```bash
$ docker-compose ps                 # docker-compose processes
$ docker ps -a                      # docker processes (sometimes needed)
$ docker stats [container name]     # see live docker container metrics
```

See logs:
```bash
# See logs of all services
$ docker-compose logs

# See logs of a specific service
$ docker-compose logs -f [service_name]
```

Run commands in container:
```bash
# Name of service is the name you gave it in the docker-compose.yml
$ docker-compose run [service_name] /bin/bash
$ docker-compose run [service_name] python /srv/starter/manage.py shell
$ docker-compose run [service_name] env
```

Remove all docker containers:
```bash
docker rm $(docker ps -a -q)
```

Remove all docker images:
```bash
docker rmi $(docker images -q)
```

### Some commands for managing the webapp
To initiate a command in an existing running container use the `docker exec`
command.

```bash
# Find container_name by using docker-compose ps

# restart uwsgi in a running container.
$ docker exec [container_name] touch /etc/uwsgi/reload-uwsgi.ini

# create migration file for an app
$ docker exec -it [container-name] \
    python /srv/[project-name]/manage.py makemigrations scheduler

# migrate
$ docker exec -it [container-name] \
    python3 /srv/[project-name]/manage.py migrate

# get sql contents of a migration
$ docker exec -it [container-name] \
    python3 /srv/[project-name]/manage.py sqlmigrate [appname] 0001

# get to interactive console
$ docker exec -it [container-name] \
    python3 /srv/[project-name]/manage.py shell

# testing
docker exec [container-name] \
    python3 /srv/[project-name]/manage.py test
```

## Troubleshooting
Q: I get the following error message when using the docker command:

```
FATA[0000] Get http:///var/run/docker.sock/v1.16/containers/json: dial unix /var/run/docker.sock: permission denied. Are you trying to connect to a TLS-enabled daemon without TLS? 

```

A: Add yourself (user) to the docker group, remember to re-log after!

```bash
$ usermod -a -G docker <your_username>
$ service docker restart
```

Q: Changes in my code are not being updated despite using volumes.

A: Remember to restart uWSGI for the changes to take effect.

```bash
# Find container_name by using docker-compose ps
$ docker exec [container_name] touch /etc/uwsgi/reload-uwsgi.ini
```