Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mysql support and enhance features #62

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b3fa1b4
Merge pull request #51 from befair/master
mjhea0 Feb 17, 2018
5ba669e
feat(docker-compose): update docker-compose.yml to version 3
DahlitzFlorian Apr 1, 2019
d2ceb8d
refactoring(nginx): use COPY instead of ADD as it is more clear
DahlitzFlorian Apr 1, 2019
a6cbea5
feat(web): update to Python 3.7 and latest package versions
DahlitzFlorian Apr 1, 2019
d556ed9
docs(chore): update docker version
DahlitzFlorian Apr 1, 2019
47bc96f
Merge pull request #55 from DahlitzFlorian/feat/update-docker-version
dbader Apr 1, 2019
e1f2ce4
add mysql-connector to requirements
jawabuu Jul 4, 2019
cb53c40
Set workdir in web Dockerfile
jawabuu Jul 4, 2019
8c4a1ca
Change db engine in settings to mysql
jawabuu Jul 4, 2019
9e02d94
update alias directory in nginx
jawabuu Jul 4, 2019
60869ff
replace postgres with mysql
jawabuu Jul 4, 2019
6a83e08
update env variables
jawabuu Jul 4, 2019
1fdea2a
add migrations folder
jawabuu Jul 4, 2019
3f21863
update readme
jawabuu Jul 4, 2019
c968769
update production compose file
jawabuu Jul 4, 2019
b1f5a90
use pycopg-binary to get rid of warnings
jawabuu Jul 5, 2019
6efaf32
set database engine dynamically
jawabuu Jul 5, 2019
9d0b624
update variable names
jawabuu Jul 5, 2019
2af875d
update production compose file
jawabuu Jul 5, 2019
2d7dae3
update local compose file
jawabuu Jul 5, 2019
2180085
update README
jawabuu Jul 5, 2019
07f6da5
update .env file
jawabuu Jul 5, 2019
3ec872b
add .sql files to gitignore
jawabuu Jul 5, 2019
ba1f402
fix database port definitions
jawabuu Jul 5, 2019
dad345d
update .env host port variables
jawabuu Jul 5, 2019
4548e7f
add DB_TYPE env variable to web so it can reload
jawabuu Jul 5, 2019
1025427
add examples to README
jawabuu Jul 5, 2019
8a3ddc2
Restore compose version to 3
jawabuu Jul 5, 2019
c8ea918
add db folders
jawabuu Jul 5, 2019
cdacb31
add wait-for-it script
jawabuu Jul 5, 2019
4dd93a6
Merge branch 'master' into feat-add-mysql-and-enhance
jawabuu Jul 5, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions .env
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
# Add Environment Variables
# Environment variables for django/web service.
SECRET_KEY=5(15ds+i2+%ik6z&!yer+ga9m=e%jcqiz_5wszg)r-z!2--b2d
DB_NAME=django_db
DB_USER=todo
DB_PASS=pass
DB_HOST=database
# Options are: 5432 for postgres, 3306 for mysql, or available remote port for remote database.
DB_PORT=5432
# Options are: postgres, mysql or remote for remote database.
DB_TYPE=postgres
# You must specify this if you set DB_TYPE = remote. Available options are;
# For postgres: django.db.backends.postgresql_psycopg2
# For mysql: mysql.connector.django
# DB_ENGINE=mysql.connector.django

# For mysql
DB_ROOT_PASSWORD=password

SECRET_KEY=5(15ds+i2+%ik6z&!yer+ga9m=e%jcqiz_5wszg)r-z!2--b2d
DB_NAME=postgres
DB_USER=postgres
DB_PASS=postgres
DB_SERVICE=postgres
DB_PORT=5432

# Expose ports on host, e.g. Set HOST_NGINX_PORT=80.
# You will need to change the port if already used on host.
# Note that the production deployment only exposes the database & nginx port.
HOST_WEB_PORT=0
HOST_NGINX_PORT=0
HOST_REDIS_PORT=0
HOST_DATABASE_PORT=0
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ env
__pycache__
.venv
.cache
.sql
64 changes: 58 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,66 @@ Featuring:
- Docker Compose v1.23.2
- Docker Machine v0.16.1
- Python 3.7.3
- Postgresql
- MySQL 5.7

Blog post -> https://realpython.com/blog/python/django-development-with-docker-compose-and-machine/
Original Blog post -> https://realpython.com/blog/python/django-development-with-docker-compose-and-machine/

### OS X Instructions
Building on the original repo, this repo adds the following capabilities;

1. Start new machine - `docker-machine create -d virtualbox dev;`
1. Is compatible with the original repo and simplifies running the compose stack
1. Adds flexibility by using environment variables to make the service highly configurable
1. Allows switching between postgres or mysql database.
1. Allows the use of an existing database configured by the DB_TYPE=remote & DB_* environment variables
1. Runs migrations before starting django
1. Adds live reload capability for the django code

### General Instructions

1. Start new machine - `docker-machine create -d virtualbox dev`
1. Configure your shell to use the new machine environment - `eval $(docker-machine env dev)`
1. Build images - `docker-compose build`
1. Start services - `docker-compose up -d`
1. Create migrations - `docker-compose run web /usr/local/bin/python manage.py migrate`
1. (Optional) Update .env to match your requirements e.g. Set HOST_NGINX_PORT=80
1. Build and Start services - `docker-compose up -d`
1. Grab IP - `docker-machine ip dev` - and view in your browser
Example:
```sh
$ docker-machine ip dev
192.168.99.101
```
The app will be available at http://<IP>:<HOST_NGINX_PORT>
1. (Optional) If you did not set HOST_NGINX_PORT i.e. HOST_NGINX_PORT=0, show Ports - `docker-compose ps`
Example:
```sh
$ docker-compose ps
dockerizingdjango_nginx_1 /usr/sbin/nginx Up 0.0.0.0:33126->80/tcp
```
In this example, the app is available at http://192.168.99.101:33126.

### Advanced Usage
To use existing remote database, change the following in .env;
1. DJANGO_DB_* variables to match your remote database
1. DB_TYPE=remote
1. Run `docker-compose up -d`

To switch databases, change the following in .env;
1. DB_TYPE to mysql, postgres or sqlite
1. If database was already started previously, run `docker-compose stop database && docker-compose rm -f database`
1. Run `docker-compose up -d`

To clean up, reset or start over
1. Run `docker-compose down -v`. Note that that this will delete all your containers and volumes defined in the compose file.

### Troubleshooting
If you encounter this error

```sh
Cannot start service web: driver failed programming external connectivity on endpoint
failed: port is already allocated
Encountered errors while bringing up the project.
```

* Modify your env file and change the exposed ports on host
* Alternatively, shut down services on the host that are bound to the ports
* Once done run `docker-compose up -d`


53 changes: 31 additions & 22 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,56 @@ services:
web:
restart: always
build: ./web
expose:
- "8000"
links:
- postgres:postgres
- redis:redis
ports:
- "${HOST_WEB_PORT}:8000"
volumes:
- web-django:/usr/src/app
- web-static:/usr/src/app/static
- ./web:/usr/src/app
entrypoint: ["./wait-for-it.sh", "${DB_HOST}:${DB_PORT}", "--strict", "--timeout=300", "--"]
env_file: .env
environment:
DEBUG: 'true'
command: /usr/local/bin/gunicorn docker_django.wsgi:application -w 2 -b :8000
DB_TYPE: ${DB_TYPE}
command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn docker_django.wsgi:application --reload --log-level=debug -w 2 -b :8000"

nginx:
restart: always
build: ./nginx/
build: ./nginx
ports:
- "80:80"
- "${HOST_NGINX_PORT}:80"
volumes:
- web-static:/www/static
- ./web/static:/www/static
- ./nginx/sites-enabled:/etc/nginx/sites-enabled
links:
- web:web

postgres:
restart: always
image: postgres:latest
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data/

redis:
restart: always
image: redis:latest
ports:
- "6379:6379"
- "${HOST_REDIS_PORT}:6379"
volumes:
- redisdata:/data

database:
build: ./${DB_TYPE}
image: ${DB_TYPE}_db
environment:
# POSTGRES SPECIFIC
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASS}
# MYSQL SPECIFIC
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASS}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
ports:
- "${HOST_DATABASE_PORT}:${DB_PORT}"
volumes:
- mysql-vol:/var/lib/mysql
- pgdata:/var/lib/postgresql/data/

volumes:
web-django:
web-static:
mysql-vol:
pgdata:
redisdata:
1 change: 1 addition & 0 deletions mysql/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM mysql:5.7
2 changes: 1 addition & 1 deletion nginx/sites-enabled/django_project
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ server {
charset utf-8;

location /static {
alias /usr/src/app/static;
alias /www/static;
}

location / {
Expand Down
1 change: 1 addition & 0 deletions postgres/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM postgres:latest
45 changes: 28 additions & 17 deletions production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,26 @@ services:
web:
restart: always
build: ./web
expose:
ports:
- "8000"
links:
- postgres:postgres
- redis:redis
entrypoint: ["./wait-for-it.sh", "${DB_HOST}:${DB_PORT}", "--strict", "--timeout=300", "--"]
volumes:
- web-static:/usr/src/app/static
env_file: .env
command: /usr/local/bin/gunicorn docker_django.wsgi:application -w 2 -b :8000
environment:
DB_TYPE: ${DB_TYPE}
command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn docker_django.wsgi:application -w 2 -b :8000"

nginx:
restart: always
build: ./nginx/
build: ./nginx
ports:
- "80:80"
- "${HOST_NGINX_PORT}:80"
volumes:
- web-static:/www/static
links:
- web:web

postgres:
restart: always
image: postgres:latest
ports:
- "5432"
volumes:
- pgdata:/var/lib/postgresql/data/

redis:
restart: always
image: redis:latest
Expand All @@ -40,7 +32,26 @@ services:
volumes:
- redisdata:/data

database:
build: ./${DB_TYPE}
image: ${DB_TYPE}_db
environment:
# POSTGRES SPECIFIC
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASS}
# MYSQL SPECIFIC
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASS}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
ports:
- "${HOST_DATABASE_PORT}:${DB_PORT}"
volumes:
- mysql-vol:/var/lib/mysql
- pgdata:/var/lib/postgresql/data/

volumes:
web-static:
pgdata:
mysql-vol:
redisdata:
web-static:
4 changes: 4 additions & 0 deletions remote/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This is an idle image to dynamically replace any component if disabled.

FROM alpine:3.7
CMD sleep 1000000d
2 changes: 2 additions & 0 deletions web/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ FROM python:3.7-slim

RUN python -m pip install --upgrade pip

WORKDIR /usr/src/app
COPY requirements.txt requirements.txt

RUN python -m pip install -r requirements.txt

COPY . .
Empty file.
18 changes: 15 additions & 3 deletions web/docker_django/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,26 @@
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
def get_engine():
'''
Set database engine based on DB_TYPE environment variable.
Default Engine is 'django.db.backends.postgresql_psycopg2'
This will be overridden by specifying DB_ENGINE environment variable
'''
db_type = os.getenv('DB_TYPE', 'postgres').lower()
if db_type in ('mysql', 'mariadb'):
return 'mysql.connector.django'
if 'sqlite' in db_type:
return 'django.db.backends.sqlite3'
return 'django.db.backends.postgresql_psycopg2'

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': os.getenv('DB_ENGINE', get_engine()),
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASS'],
'HOST': os.environ['DB_SERVICE'],
'HOST': os.environ['DB_HOST'],
'PORT': os.environ['DB_PORT']
}
}
Expand All @@ -116,4 +128,4 @@
# os.path.join(BASE_DIR, 'static'),
# )
# print(STATICFILES_DIRS)
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
3 changes: 2 additions & 1 deletion web/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Django==2.1.7
gunicorn==19.9.0
psycopg2==2.7.7
redis==3.2.1
psycopg2-binary
mysql-connector-python==8.0.16
Loading