django migrations issues with postgres - django

I'm working on a Django project which dockerized and using Postgres for the database, but we are facing migrations issues, every time someone made changes in the model so if the other dev took a pull from git and try to migrate the migrations using python manage.py migrate because we already have the migrations file so sometimes the error is table already exists or table doesn't exists so every time I need to apply migrations using --fake but I guess that's not a good approach to migrate every time using --fake flag.
docker-compose.yml
version: "3.8"
services:
db:
container_name: db
image: "postgres"
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- dev.env
ports:
- "5432:5432"
environment:
- POSTGRES_DB=POSTGRES_DB
- POSTGRES_USER=POSTGRES_USER
- POSTGRES_PASSWORD=POSTGRES_PASSWORD
app:
container_name: app
build:
context: .
command: bash -c "python manage.py runserver 0.0.0.0:8000"
volumes:
- ./core:/app
- ./data/web:/vol/web
env_file:
- dev.env
ports:
- "8000:8000"
depends_on:
- db
volumes:
postgres_data:
Dockerfile
FROM python:3
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app
EXPOSE 8000
COPY ./core/ /app/
COPY ./scripts /scripts
# installing nano and cron service
RUN apt-get update
RUN apt-get install -y cron
RUN apt-get install nano
RUN pip install --upgrade pip
COPY requirements.txt /app/
# install dependencies and manage assets
RUN pip install -r requirements.txt && \
mkdir -p /vol/web/static && \
mkdir -p /vol/web/media
# files for cron logs
RUN mkdir /cron
RUN touch /cron/django_cron.log
# start cron service
RUN service cron start
RUN service cron restart
RUN chmod +x /scripts/run.sh
CMD ["/scripts/run.sh"]
run.sh
#!/bin/sh
set -e
ls -la /vol/
ls -la /vol/web
whoami
python manage.py collectstatic --noinput
python manage.py migrate
service cron start
service cron restart
python manage.py crontab add
printenv > env.txt
cat /var/spool/cron/crontabs/root >> env.txt
cat env.txt > /var/spool/cron/crontabs/root
uwsgi --socket :9000 --workers 4 --master --enable-threads --module alectify.wsgi

Django offers the ability to create updated migrations when the models change see https://docs.djangoproject.com/en/4.0/topics/migrations/#workflow for more information, but you can generate then apply updated migrations using:
python manage.py makemigrations
python manage.py migrate

Related

run initial commands in a docker-compose service

I followed this tutorial to run my django web-app locally, apart for the web-app the only service is a postgres db.
I wrote a simple script entrypoint.sh to automate the initial operations needed by a django app, like migrate, makemigrations, collectstatic, createsuperuser;
Everything works fine, except that entrypoint.sh runs everytime I use docker-compose up, performing initial operations that should only run once.
How can I set up my Dockerfile or docker-compose.yml so that entrypoint.sh is run just the first time and not everytime I docker-compose down and then docker-compose up again?
Dockerfile
# importing base image
FROM python:3.9
# updating docker host or host machine
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
# changing current working directory to /usr/src/app
WORKDIR /usr/src/app
# copying requirement.txt file to present working directory
COPY requirements.txt ./
# installing dependency in container
RUN pip install -r requirements.txt
# copying all the files to present working directory
COPY . .
# informing Docker that the container listens on the
# specified network ports at runtime i.e 8000.
EXPOSE 8000
ENTRYPOINT ["./entrypoint.sh"]
docker-compose.yml
version: '3.7'
services:
db:
image: postgres
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
app:
build: ./
command: gunicorn sial.wsgi:application --workers=2 --bind 0.0.0.0:8000
volumes:
- ./data/:/usr/src/app/data/
- ./media/:/usr/src/app/media/
ports:
- 8000:8000
- 5432:5432
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- DJANGO_SUPERUSER_EMAIL=admin#email.it
- DJANGO_SUPERUSER_USERNAME=admin#email.it
- DJANGO_SUPERUSER_PASSWORD=passadmin
depends_on:
- db
entrypoint.sh
#!/bin/bash
python3 manage.py migrate;
python3 manage.py makemigrations;
python3 manage.py migrate;
python3 manage.py collectstatic --clear;
python3 manage.py createsuperuser --no-input;
gunicorn sial.wsgi:application --workers=2 --bind 0.0.0.0:8000;
RECAP
In the directory where my Dockerfile and docker-compose.yml file are:
sudo docker-compose build app
sudo docker-compose up -> initial migrations are applied, static files are collected, superuser created
sudo docker-compose down
sudo docker-compose up -> initial migrations are applied, static files are collected, superuser created AGAIN. I'm trying to avoid this.
I'm new to docker-compose and any help is really appreciated thanks.
A dirty but simple way would be to ignore the error of the createsuperuser command by changing it to python3 manage.py createsuperuser --no-input || true;.
This might even be the solution you prefer, because if the variables for docker-compose change, a new superuser would be created with the changed values.
#!/bin/bash
python3 manage.py migrate;
python3 manage.py makemigrations;
python3 manage.py migrate;
python3 manage.py collectstatic --clear;
python3 manage.py createsuperuser --no-input || true;
gunicorn sial.wsgi:application --workers=2 --bind 0.0.0.0:8000;

Docker-compose executes django twice

I am running in windows 10, and trying to set up a project via docker-compose and django.
If you are interested, It will take you 3 minutes to follow this tutorial and you will get the same error as me. docs.docker.com/samples/django –
When I run
docker-compose run app django-admin startproject app_settings .
I get the following error
CommandError: /app /manage.py already exists. Overlaying a project into an existing directory won't replace conflicting files.
Or when I do this
docker-compose run app python manage.py startapp core
I get the following error
CommandError: 'core' conflicts with the name of an existing Python module and cannot be used as an
app name. Please try another name.
Seems like the command is maybe executed twice? Not sure why?
Docker file
FROM python:3.9-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apt-get update && apt-get install
RUN apt-get install -y \
libpq-dev \
gcc \
&& apt-get clean
COPY ./requirements.txt .
RUN pip install -r requirements.txt
RUN mkdir /app
WORKDIR /app
COPY ./app /app
Docker-compose
version: "3.9"
compute:
container_name: compute
build: ./backend
# command: python manage.py runserver 0.0.0.0:8000
# volumes:
# - ./backend/app:/app
ports:
- "8000:8000"
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
depends_on:
- db
Try running your image without any arguments, you are already using the command keyword in your docker-compose or just remove that line from the file.

How to start cron service on Dockerfile [duplicate]

This question already has answers here:
How to run a cron job inside a docker container?
(29 answers)
Docker Compose - How to execute multiple commands?
(20 answers)
Closed last year.
I have installed django-crontab==0.7.1 and added to INSTALLED_APPS Django configuration. I'm trying to start cron service on the Docker image build and add the command cron task with python manage.py crontab add but nothing occurs.
Dockerfile:
FROM python:3.8-slim-buster
LABEL maintainer="info#albertosanmartinmartinez.es" version="1.0.0"
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apt-get update -y && apt-get install -y build-essential postgresql python-scipy python-numpy python-pandas libgdal-dev && apt-get clean && rm -rf /var/lib/apt/lists/*
RUN mkdir /industrialareas
COPY ./project /industrialareas/
COPY ./requirements.txt /industrialareas/
WORKDIR /industrialareas
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8000
CMD service cron start
docker-compose.yml:
version: '3.7'
services:
django:
container_name: industrialareas_django_ctnr
build:
context: .
dockerfile: Dockerfile-django
restart: unless-stopped
env_file: ./project/project/settings/.env
command: python manage.py check
command: python manage.py collectstatic --noinput
command: python manage.py runserver 0.0.0.0:8000
command: python manage.py crontab add
volumes:
- ./project:/industrialareas
depends_on:
- postgres
ports:
- 8000:8000
But when I go into the container and run the service cron status command, I get the error.
[FAIL] cron is not running ... failed!
Anybody could help me please ?
Thanks in advance.

"sqlite3.OperationalError: attempt to write a readonly database" even after chmod 777

I' m running a Django application within a docker container. I'm getting this error sqlite3.OperationalError: attempt to write a readonly database. I've tried everything in the Dockerfile
RUN chown username db.sqlite3
RUN chmod 777 db.sqlite3
I tried also to run the application as root user, but I still get the same error.
Here is my Dockerfile
FROM python:3.9.5-alpine
RUN addgroup -S apigroup && adduser -S weatherapi -G apigroup
WORKDIR /app
ADD requirements.txt .
RUN apk update && apk upgrade
RUN python3 -m pip install --upgrade pip && python3 -m pip install --no-cache-dir -r requirements.txt
COPY . .
USER root
EXPOSE 8000
RUN chmod 777 db.sqlite3
USER weatherapi
RUN python3 manage.py migrate
CMD ["sh", "-c", "python3 manage.py runserver 0.0.0.0:8000"]
And my docker-compose
version: '3.7'
networks:
weather_api_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
services:
web:
restart: unless-stopped
image: weatherapi:1.0
container_name: weatherapi
ports:
- "8000:8000"
volumes:
- .:/app
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
order: start-first
rollback_config:
parallelism: 2
delay: 10s
failure_action: continue
monitor: 60s
order: stop-first
restart_policy:
condition: on-failure
networks:
- weather_api_net
I just had to change the base image to a Debian based image.
FROM python:3.8-buster
Apparently Alpine doesn't like SQLite.

How to attach graph-tool to Django using Docker

I need to use some graph-tool calculations in my Django project. So I started with docker pull tiagopeixoto/graph-tool and then added it to my Docker-compose file:
version: '3'
services:
db:
image: postgres
graph-tool:
image: dcagatay/graph-tool
web:
build: .
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
- graph-tool
When I up my docker-compose I got a line:
project_graph-tool_1_87e2d144b651 exited with code 0
And finally when my Django projects starts I can not import modules from graph-tool, like:
from graph_tool.all import *
If I try work directly in this docker image using:
docker run -it -u user -w /home/user tiagopeixoto/graph-tool ipython
everything goes fine.
What am I doing wrong and how can I fix it and finally attach graph-tool to Django? Thanks!
Rather than using a seperate docker image for graphtool, i think its better to use it within the same Dockerfile which you are using for Django. For example, update your current Dockerfile:
FROM ubuntu:16.04 # using ubuntu image
ENV PYTHONUNBUFFERED 1
ENV C_FORCE_ROOT true
# python3-graph-tool specific requirements for installation in Ubuntu from documentation
RUN echo "deb http://downloads.skewed.de/apt/xenial xenial universe" >> /etc/apt/sources.list && \
echo "deb-src http://downloads.skewed.de/apt/xenial xenial universe" >> /etc/apt/sources.list
RUN apt-key adv --keyserver pgp.skewed.de --recv-key 612DEFB798507F25
# Install dependencies
RUN apt-get update \
&& apt-get install -y python3-pip python3-dev \
&& apt-get install --yes --no-install-recommends --allow-unauthenticated python3-graph-tool \
&& cd /usr/local/bin \
&& ln -s /usr/bin/python3 python \
&& pip3 install --upgrade pip
# Project specific setups
# These steps might be different in your project
RUN mkdir /code
WORKDIR /code
ADD . /code
RUN pip3 install -r requirements.pip
Now update your docker-compose file as well:
version: '3'
services:
db:
image: postgres
web:
build: .
container_name: djcon # <-- preferred over generated name
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
Thats it. Now if you go to your web service's shell by docker exec -ti djcon bash(or any generated name instead of djcon), and access the django shell like this python manage.py shell. Then type from graph_tool.all import * and it will not throw any import error.