I'm trying to serve a simple Django app over NGINX using Docker Compose. I'm not really sure where the problem is coming from but the build was successful. Any idea why is not serving correctly?
This is the setup:
├── app
│ ├── templates
│ ├── webapp
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── Dockerfile
│ ├── Dockerfile.prod
│ ├── entrypoint.sh
│ ├── entrypoint.prod.sh
│ └── requirements.txt
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
├── .env
├── docker-compose.ci.yml
├── docker-compose.prod.yml
└── docker-compose.yml
app/webapp/settings.py:
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = os.environ.get('SECRET_KEY')
DEBUG = int(os.environ.get('DEBUG', default=0))
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'webapp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'webapp.wsgi.application'
DATABASES = {
'default': {
'ENGINE': os.environ.get('SQL_ENGINE', 'django.db.backends.sqlite3'),
'NAME': os.environ.get('SQL_DATABASE', os.path.join(BASE_DIR, 'db.sqlite3')),
'USER': os.environ.get('SQL_USER', 'user'),
'PASSWORD': os.environ.get('SQL_PASSWORD', 'password'),
'HOST': os.environ.get('SQL_HOST', 'localhost'),
'PORT': os.environ.get('SQL_PORT', '5432'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/staticfiles/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/mediafiles/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles')
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
YOUTUBE_DATA_API_KEY = os.environ.get('YOUTUBE_DATA_API_KEY')
.env
DEBUG=0
SECRET_KEY=<foo>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=webapp_django_prod
SQL_USER=webapp_django
SQL_PASSWORD=<password>
SQL_HOST=db
SQL_PORT=5432
DATABASE=postgres
YOUTUBE_DATA_API_KEY=<foo>
app/Dockerfile
# pull official base image
FROM python:3.9.6-alpine
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install psycopg2
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& pip install psycopg2 \
&& apk del build-deps
# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r /usr/src/app/requirements.txt
# copy entrypoint.sh
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
# copy project
COPY . /usr/src/app/
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
app/entrypoint.sh
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
python manage.py flush --no-input
python manage.py migrate
python manage.py collectstatic --no-input --clear
exec "$#"
app/Dockerfile.prod
# pull official base image
FROM python:3.9.6-alpine
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install psycopg2
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& pip install psycopg2 \
&& apk del build-deps
# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r /usr/src/app/requirements.txt
# copy entrypoint-prod.sh
COPY ./entrypoint.prod.sh /usr/src/app/entrypoint.prod.sh
# copy project
COPY . /usr/src/app/
# run entrypoint.prod.sh
ENTRYPOINT ["/usr/src/app/entrypoint.prod.sh"]
app/entrypoint.prod.sh
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
exec "$#"
nginx/Dockerfile
FROM nginx:1.21-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
nginx/nginx.conf
upstream webapp {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://webapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /staticfiles/ {
alias /usr/src/app/staticfiles/;
}
location /mediafiles/ {
alias /usr/src/app/mediafiles/;
}
}
docker-compose.yml
version: '3.8'
services:
web:
build: ./app
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./app/:/usr/src/app/
ports:
- 8000:8000
environment:
- DEBUG=1
- SECRET_KEY=<foo>
- SQL_ENGINE=django.db.backends.postgresql
- SQL_DATABASE=webapp_django_prod
- SQL_USER=webapp_django
- SQL_PASSWORD=<foo>
- SQL_HOST=db
- SQL_PORT=5432
- DATABASE=postgres
depends_on:
- db
db:
image: postgres:13-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=webapp_django
- POSTGRES_PASSWORD=<foo>
- POSTGRES_DB=webapp_django_prod
volumes:
postgres_data:
docker-compose.ci.yml
version: '3.8'
services:
web:
build:
context: ./app
dockerfile: Dockerfile.prod
cache_from:
- "${WEB_IMAGE}"
image: "${WEB_IMAGE}"
command: gunicorn webapp.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/usr/src/app/staticfiles
- media_volume:/usr/src/app/mediafiles
expose:
- 8000
env_file: .env
nginx:
build:
context: ./nginx
cache_from:
- "${NGINX_IMAGE}"
image: "${NGINX_IMAGE}"
volumes:
- static_volume:/usr/src/app/staticfiles
- media_volume:/usr/src/app/mediafiles
ports:
- 80:80
depends_on:
- web
volumes:
static_volume:
media_volume:
docker-compose.prod.yml
version: '3.8'
services:
web:
image: "${WEB_IMAGE}"
command: gunicorn webapp.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/usr/src/app/staticfiles
- media_volume:/usr/src/app/mediafiles
ports:
- 8000:8000
env_file: .env
nginx:
image: "${NGINX_IMAGE}"
volumes:
- static_volume:/usr/src/app/staticfiles
- media_volume:/usr/src/app/mediafiles
ports:
- 80:80
depends_on:
- web
volumes:
static_volume:
media_volume:
Since I cannot comment still. The easiest way to identify the problem is to look through the logs.
You could check the Docker containers by running this on each instance:
docker logs --follow your-container-name
Or you could add this to your docker-compose file if the docker container gets killed you can access it with journalctl:
mycontainer:
image: myimage
logging:
driver: journald
options:
tag: mytag
And then access it using:
journalctl -u docker CONTAINER_NAME=mycontainer_name
journalctl -u docker CONTAINER_TAG=mytag
Answer taken partially from: https://stackoverflow.com/a/43663253/16891224
Related
I have this project structure:
└── folder
└── my_project_folder
├── my_app
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
├── .env.dev
├── docker-compose.yml
├── entrypoint.sh
├── requirements.txt
└── Dockerfile
docker-compose.yml:
version: '3.9'
services:
web:
build: .
command: python my_app/manage.py runserver 0.0.0.0:8000
volumes:
- .:/usr/src/app/
ports:
- 8000:8000
env_file:
- .env.dev
depends_on:
- db
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=db_admin
- POSTGRES_PASSWORD=db_pass
- POSTGRES_DB=some_db
volumes:
postgres_data:
Dockerfile:
FROM python:3.10.0-alpine
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN pip install --upgrade pip
RUN apk update
RUN apk add postgresql-dev gcc python3-dev musl-dev
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY ./entrypoint.sh .
RUN sed -i 's/\r$//g' /usr/src/app/entrypoint.sh
RUN chmod +x /usr/src/app/entrypoint.sh
COPY . .
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
It's working, but i dont like the line python my_app/manage.py runserver 0.0.0.0:8000 in my docker-compose file.
What should i change to run manage.py from the docker folder?
I mean, how can i use python manage.py runserver 0.0.0.0:8000 (without my_app)?
In your Dockerfile, you can use WORKDIR to change your directory inside docker file:
...
COPY . .
WORKDIR "my_app"
...
Then you are inside my_app dir and you can call your command:
python manage.py ...
Basically whenever I try to upload a file using my website, the file doesn't get saved on the media volume.
I don't think its a code issue as it works perfectly fine without the container even when paired with nginx.
I followed this tutorial to setup my docker containers.
Here is my Dockerfile:
# pull official base image
FROM python:3.9.6-alpine
# set work directory
WORKDIR /home/azureuser/ecommerce3
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# fixing alpine related pip errors
RUN apk update && apk add gcc libc-dev make git libffi-dev openssl-dev python3-dev libxml2-dev libxslt-dev
RUN apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev
# install psycopg2 dependencies
RUN apk update \
&& apk add postgresql-dev gcc python3-dev musl-dev
# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
# copy entrypoint.sh
COPY ./entrypoint.sh .
RUN sed -i 's/\r$//g' ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
# copy project
COPY . .
# running entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
docker-compose.yml:
version: '3.8'
services:
web:
build:
context: ./
dockerfile: Dockerfile
command: sh -c "cd DVM-Recruitment-Task/ && gunicorn DVM_task3.wsgi:application --bind 0.0.0.0:8000"
volumes:
- static_volume:/home/azureuser/ecommerce3/staticfiles:Z
- media_volume:/home/azureuser/ecommerce3/mediafiles:Z
- log_volume:/home/azureuser/ecommerce3/logs
expose:
- 8000
depends_on:
- db
db:
image: postgres:13.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=---
- POSTGRES_PASSWORD=---
- POSTGRES_DB=---
nginx:
image: nginx
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/DVM_task3:/etc/nginx/conf.d/default.conf
- static_volume:/home/azureuser/ecommerce3/staticfiles/:Z
- media_volume:/home/azureuser/ecommerce3/mediafiles/:Z
- log_volume:/home/azureuser/ecommerce3/logs
- (ssl certificate stuff here)
volumes:
postgres_data:
media_volume:
static_volume:
log_volume:
entrypoint.sh:
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
python DVM-Recruitment-Task/manage.py makemigrations ecommerce
python DVM-Recruitment-Task/manage.py migrate --noinput
python DVM-Recruitment-Task/manage.py collectstatic --no-input --clear
exec "$#"
Also my nginx file already has this inside a server block
location /media/ {
autoindex on;
alias /home/azureuser/ecommerce3/mediafiles/;
}
settings.py has this:
MEDIA_URL = '/media/'
MEDIA_ROOT = 'mediafiles'
urls.py already has this line in it
urlpatterns[...] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Also my project structure looks something like this:
.
├── DVM-Recruitment-Task
│ ├── DVM_task3
│ ├── README.md
│ ├── ecommerce
│ ├── manage.py
│ ├── static
│ └── templates
├── Dockerfile
├── docker-compose.yml
├── entrypoint.sh
├── nginx
│ └── DVM_task3
└── requirements.txt
everything inside a directory named 'ecommerce3'.
The mediafiles, staticfiles and logs volume are supposed to be created inside the same directory (ecommerce3).
On running --collectstatic the staticfiles load correctly, the logs work as well but the media files just won't save to the mediafiles folder.
if I go into the web container's shell and manually create a file inside the mediafiles directory, I am able to view in the /media url so I assume nginx is pointing in the right direction. However when it comes to saving the files, the files never get saved on this volume.
I am very new to django and docker so any help or nudge in the right direction will be greatly appreciated.
Try to create the mediafiles folder in your dockerfile
RUN mkdir $APP_HOME/mediafiles
where $APP_HOME is where your app is located: /home/azureuser/ecommerce3
I am trying to deploy my app to Heroku, am using amazon s3 bucket for static but the static icon is not showing on the website, and I need help setting up a worker for celery and celery beat to work on Heroku.
This is my Dockerfile:
# pull the official base image
FROM python:3.8.3-alpine as builder
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install psycopg2 dependencies
RUN apk update \
&& apk add postgresql-dev gcc python3-dev musl-dev
RUN apk add zlib libjpeg-turbo-dev libpng-dev \
freetype-dev lcms2-dev libwebp-dev \
harfbuzz-dev fribidi-dev tcl-dev tk-dev
# lint
RUN pip install --upgrade pip
RUN pip install flake8
COPY . .
# install dependencies
COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
# pull official base image
FROM python:3.8.3-alpine
# create directory for the app user
RUN mkdir -p /home/app
# create the app user
RUN addgroup -S app && adduser -S app -G app
# create the appropriate directories
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/static
RUN mkdir $APP_HOME/media
WORKDIR $APP_HOME
# install dependencies
RUN apk update && apk add libpq
RUN apk add zlib libjpeg-turbo-dev libpng-dev \
freetype-dev lcms2-dev libwebp-dev \
harfbuzz-dev fribidi-dev tcl-dev tk-dev
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN pip install --no-cache /wheels/*
# copy entrypoint.sh
COPY ./entrypoint.sh $APP_HOME
# copy project
COPY . $APP_HOME
# chown all the files to the app user
RUN chown -R app:app $APP_HOME
# change to the app user
USER app
# run entrypoint.prod.sh
ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]
CMD gunicorn my_proj.wsgi:application --bind 0.0.0.0:$PORT ```
This is my docker-compose file
```version: "3.8"
services:
web:
build:
context: .
dockerfile : Dockerfile
container_name: django
command: gunicorn my_proj.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
expose:
- 8000
depends_on:
- pgdb
- redis
celery-worker:
build: .
command: celery -A my_proj worker -l INFO
volumes:
- .:/usr/src/app
environment:
- DEBUG=1
- DJANGO_ALLOWED_HOSTS=['localhost', '127.0.0.1', 'app_name.herokuapp.com']
- CELERY_BROKER=redis://redis:6379/0
- CELERY_BACKEND=redis://redis:6379/0
depends_on:
- web
- redis
celery-beat:
build: .
command: celery -A my_proj beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler
volumes:
- .:/usr/src/app
environment:
- DEBUG=1
- DJANGO_ALLOWED_HOSTS=['localhost', '127.0.0.1', 'app_name.herokuapp.com']
- CELERY_BROKER=redis://redis:6379/0
- CELERY_BACKEND=redis://redis:6379/0
depends_on:
- web
- redis
- celery-worker
pgdb:
image: postgres
container_name: pgdb
environment:
- POSTGRES_DB=databasename
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
volumes:
- pgdata:/var/lib/postgresql/data/
redis:
image: "redis:alpine"
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
ports:
- 1337:80
depends_on:
- web
volumes:
pgdata:
static_volume:
media_volume: ```
Here are the steps I followed to deploy on Heroku
heroku container:login
docker build -t registry.heroku.com/app name/web .
docker push registry.heroku.com/app name/web
heroku container:release -a app name web
Also, I ran this below and it is starting but I want it to work on its own.
heroku run celery -A my_proj worker -l INFO -a <app name>
heroku run celery -A my_proj beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler -a <app name>
Issue:
How do I set up celery to work as a worker.
How do I also set up a worker for celery-beat
Please I need help, in development, I usually use docker-compose up -d --build, and all images are built and working together. I feel it's only the Django container that is just working, and others were not built.
Okay, so this is what I did that worked for me, so for any new developer like me coming up on the Django web framework.
The best way I used in deploying the app on Heroku was using the Heroku build manifest. I created a heroku.yml file on the root directory of my project.
#This is the Build Manifest for creating web and worker.
build:
docker:
web: Dockerfile
worker: Dockerfile
run:
web: gunicorn my_proj.wsgi:application --bind 0.0.0.0:$PORT
worker: celery -A my_proj worker -l INFO --beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler
release:
image: web
command:
- python manage.py collectstatic --noinput
For the Database, I used the Heroku Postgres add-on also for the Redis message broker, I used Heroku Redis.
I didn't Use Nginx to serve Staticfiles instead I used Whitenoise, pretty easy to set up but nasty bug when you turn off Debug. There are lots of help on here to help you fix that.
Best you create a static and staticfiles folder in your root directory and in your settings.py file
add these, worked for me
INSTALLED_APP = [
...,
'whitenoise.runserver_nostatic',
#BEFORE THE 'django.contrib.staticfiles',
]
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
WHITENOISE_MANIFEST_STRICT = False
This is how I learned and resolved the issue.
Any better implementation am always open to learning.
Try setting up CORS in AWS S3 bucket permission to get the fonts working.
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET",
"PUT",
"POST",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
I am developing on a windows and trying to run the Django application in Linux container with Gunicorn and Nginx to deploy it to Linux machine in production.
I mostly used this Connect docker python to SQL server with pyodbc post as a guide but I think I have tried every solution found online about this error.
If I ping DB server from container it gets connected so the port 1433 is open and everything should be good to go. But for some reason I'm getting error django.db.utils.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]Login failed for user
Django settings.py
DATABASES = {
'default': {
'ENGINE': "sql_server.pyodbc",
'NAME': 'database1',
'HOST': '123.45.6.78',
'PORT':'1433',
'USER': "user",
'PASSWORD': "pswd",
'OPTIONS': {
"driver": "FreeTDS",
"host_is_server": True,
"unicode_results": True,
"extra_params": "tds_version=7.3",
}
}
}
Dockerfile
# start from an official image
FROM python:3
# arbitrary location choice: you can change the directory
RUN mkdir -p /opt/services/djangoapp/src
WORKDIR /opt/services/djangoapp/src
#Install FreeTDS and dependencies for PyODBC
RUN apt-get update \
&& apt-get install unixodbc -y \
&& apt-get install unixodbc-dev -y \
&& apt-get install freetds-dev -y \
&& apt-get install freetds-bin -y \
&& apt-get install tdsodbc -y \
&& apt-get install --reinstall build-essential -y
# populate "ocbcinst.ini"
RUN echo "[FreeTDS]\n\
TDS_Version = '7.3'\n\
Description = FreeTDS unixODBC Driver\n\
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so\n\
Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so" >> /etc/odbcinst.ini
# modify "freetds.conf"
RUN echo "[mssql]\n\
host = 172.30.2.18\n\
port = 1433\n\
tds version = 7.3" >> /etc/freetds/freetds.conf
RUN echo MinProtocol = TLSv1.0 >> /etc/ssl/openssl.cnf
RUN echo CipherString = DEFAULT#SECLEVEL=1 >> /etc/ssl/openssl.cnf
# install our dependencies
# we use --system flag because we don't need an extra virtualenv
COPY Pipfile Pipfile.lock /opt/services/djangoapp/src/
RUN pip install pipenv && pipenv install --system
# copy our project code
COPY . /opt/services/djangoapp/src
# expose the port 8000
EXPOSE 8000
# define the default command to run when starting the container
CMD ["gunicorn", "--chdir", "app", "--bind", ":8000", "config.wsgi:application"]
docker-compose.yml
version: '3'
services:
djangoapp:
build: .
volumes:
- .:/opt/services/djangoapp/src
- /static:/static
networks: # <-- here
- nginx_network
nginx:
image: nginx:1.13
ports:
- 8000:80
volumes:
- ./config/nginx/conf.d:/etc/nginx/conf.d
- /static:/static
depends_on:
- djangoapp
networks: # <-- here
- nginx_network
networks: # <-- and here
nginx_network:
driver: bridge
Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
django = "==2.1.0"
pyodbc = "==4.0.28"
django-pyodbc-azure = "*"
django-datatables-view = "*"
gunicorn = "*"
whitenoise = "*"
[requires]
python_version = "3.8"
I finally solved it myself. Had to add port 1433 to nginx in .yml file.
Like this
nginx:
image: nginx:1.13
ports:
- 8000:80
- 1433:1433
volumes:
- ./config/nginx/conf.d:/etc/nginx/conf.d
- /static:/static
depends_on:
- djangoapp
networks: # <-- here
- nginx_network
I'm trying to create a docker setup such that I can easily build and deploy a geodjango app (with postgis backend). I have the following folder structure:
|-- Dockerfile
|-- Pipfile
|-- Pipfile.lock
|-- README.md
|-- app
| |-- manage.py
| |-- app
| `-- app_web
In my Dockerfile to setup Django I have the following:
# Pull base image
FROM python:3.7
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
RUN pip install pipenv
COPY . /code
WORKDIR /code/
RUN pipenv install --system
# Setup GDAL
RUN apt-get update &&\
apt-get install -y binutils libproj-dev gdal-bin python-gdal python3-gdal
# set work directory
WORKDIR /code/app
CMD ["python", "manage.py", "migrate", "--no-input"]
In my docker-compose.yml file:
version: '3.7'
services:
postgis:
image: kartoza/postgis:12.1
volumes:
- postgres_data:/var/lib/postgresql/data/
web:
build: .
command: python /code/app/manage.py runserver 0.0.0.0:8000
ports:
- 8000:8000
volumes:
- .:/code
depends_on:
- postgis
volumes:
postgres_data:
And finally in settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'postgis',
},
}
Now when I: run docker-compose up --build
It all seems to work (both the database as well as the django app spin up their containers). But whenever I try to actually work with the database (the app is blank rightnow, so I still need to migrate) django doesn't seem to recognize the database.
Can anybody tell me what is going wrong?
run docker-compose up --build It all seems to work (both the database as well as the django app spin up their containers)
Make sure to check the logs because containers not necessarily stop after finding an error.
docker-compose logs
Also you're already setting your working dir in Dockerfile
WORKDIR /code/app
so take a look at the command you execute in docker-compose.yml:
command: python /code/app/manage.py runserver 0.0.0.0:8000
Did you install the app?
INSTALLED_APPS = [
# [...]
'django.contrib.gis'
]
In settings.py, PASSWORD needs to be specified:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'postgis',
},
}