I am trying to dockerize my existing Django Rest project. I am using MySQL database instead of default SqlLite.
My Dockerfile looks like following:
FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY . /code/
RUN pip install -r requirements.txt
and Docker-compose:
version: '3'
services:
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: docker
MYSQL_DATABASE: docker
MYSQL_USER: docker
MYSQL_PASSWORD: docker
ports:
- "3306:3306"
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
I did not run docker-compose run web python manage.py migrate
docker-compose build is successful
However docker-compose up fails eventually saying Can't connect to local MySQL server. I am guessing that I need to install MySQl in my container as well, but do not know how. What am I missing in my Dockerfile or docker-compose?
UPDATE: My settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', #django.db.backends.mysql
'NAME': 'libraries', #local: libraries #server:
'USER': 'root', #root #root
'PASSWORD': 'root', #local: root #server:
'HOST': 'localhost', #local: localhost #server:
'PORT': '3306',
}
}
Change the HOST in the database settings from localhost to db. There's no MySQL in the web container so the Python code couldn't connect to the db.
Related
Dockerfile
FROM python:3.8
ENV PYTHONUNBUFFERED 1
ENV WORKDIR /usr/src/app
WORKDIR ${WORKDIR}
RUN pip install --upgrade pip && pip install pipenv
COPY ./Pipfile* ${WORKDIR}/
RUN pipenv lock --requirements > requirements.txt
RUN pip install -r requirements.txt
ADD . ${WORKDIR}/
docker-compose.yml
version: '3'
services:
database:
image: postgres:latest
environment:
POSTGRES_PASSWORD: development
POSTGRES_USER: development
POSTGRES_DB: dev_db
ports:
- 5432:5432
backend:
build: .
command: python /usr/src/app/manage.py runserver 0.0.0.0:8000
volumes:
- .:/usr/src/app
ports:
- 8000:8000
depends_on:
- database
Django database configurations
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'dev_db',
'USER': 'development',
'PASSWORD': 'development',
'HOST': 'database',
'PORT': 5432,
}
}
However, when I start docker compose, it gives the following message:
> Is the server running on host "database" (172.29.0.2) and accepting
TCP/IP connections on port 5432?
Can anyone provide some guidance on why I'm getting this error? As far as I know both services are inside the same network
This is probably because when the Django instance is ready, Postgres is still starting up.
A common solution is to use a script like wait-for to delay the execution of a command until a service is replying on a specific host/port.
Take a look at the Docker documentation about controlling the startup order of multiple containers.
I think you are missing the hostname in the yml file. See below
services:
database:
image: postgres:latest
hostname: database
environment:
POSTGRES_PASSWORD: development
POSTGRES_USER: development
POSTGRES_DB: dev_db
ports:
- 5432:5432
I've been hitting the following error for awhile now and can't seem to fix it...
django.db.utils.OperationalError: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
Multiple resources stated it was simply due to the HOST setting within my DATABASES, but the following is what I am working with and still can't get it to work:
DATABASES = {
'default': {
'HOST': 'db',
'ENGINE': 'django_postgrespool2',
'NAME': os.environ.get('PROJECT_HEARSAY_DB_NAME'),
'USER': os.environ.get('PROJECT_HEARSAY_DB_USER'),
'PASSWORD': os.environ.get('PROJECT_HEARSAY_DB_PASSWORD'),
'PORT': os.environ.get('PROJECT_HEARSAY_DB_PORT'),
}
}
Here is the Dockerfile for my Django app:
FROM python:3
ENV PYTHONUNBUFFERED 1
COPY . /app
WORKDIR /app
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
Here is the Dockerfile for my Postgresql DB:
FROM postgres
And here is the docker-compose.yml that I am working with:
version: "3"
services:
postgresql:
build:
context: ./db
container_name: db.postgresql
ports:
- 5432:5432
environment:
POSTGRES_DB: "db_name"
POSTGRES_USER: "username"
POSTGRES_PASSWORD: "password"
django:
restart: always
build:
context: ./api
command: bash -c "./manage.py migrate && ./manage.py runserver 0.0.0.0:8000"
container_name: api.django
ports:
- 8000:8000
depends_on:
- postgresql
I'm curious if anyone here could shed some light on what I am doing wrong.
Thank you.
Your container name is db.postgresql, so your connection string should be db.postgresql or postgresql in the host name.
DATABASES = {
'default': {
'HOST': 'db.postgresql',
'ENGINE': 'django_postgrespool2',
'NAME': os.environ.get('PROJECT_HEARSAY_DB_NAME'),
'USER': os.environ.get('PROJECT_HEARSAY_DB_USER'),
'PASSWORD': os.environ.get('PROJECT_HEARSAY_DB_PASSWORD'),
'PORT': os.environ.get('PROJECT_HEARSAY_DB_PORT'),
}
}
you can verify the connection
docker exec api.django bash -c "nslookup db.postgresql"
You will get the Postgres container IP inside your Django container.
I'm running into problems when using Docker. To connect from Django application to the Postgres database I have to use:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
However to run tests via pytest in my Pipenv shell I have to change 'Host': from db to localhost. Is there a way that I can always use localhost?
Docker-Compose:
version: '3'
services:
db:
image: postgres
ports:
- "5432:5432"
web:
build: .
env_file: .env
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
container_name: test
Dockerfile:
# Pull base image
FROM python:3
# Set environment varibles
ENV PYTHONUNBUFFERED 1
# Set work directory
RUN mkdir /code
WORKDIR /code
# Install dependencies
RUN pip install --upgrade pip
RUN pip install pipenv
COPY ./Pipfile /code/Pipfile
RUN pipenv install --deploy --system --skip-lock --dev
# Define ENTRYPOINT
COPY ./docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
# Copy project
COPY . /code/
When I try to execute the following command:
sudo docker-compose up
I get the following error inside my terminal:
Here is what my docker file looks like:
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /agent-technologies
WORKDIR /agent-technologies
COPY . /agent-technologies
RUN pip install -r requirements.txt
EXPOSE 8000
Here is what my docker-compose.yml looks like:
version: '3'
services:
db:
image: postgres
environment:
- POSTGRES_USER=stefan_radonjic
- POSTGRES_PASSWORD=cepajecar995
- POSTGRES_DB=agent_technologies_db
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/agent-technologies
ports:
- "8000:8000"
links:
- db
depends_on:
- db
And finally here are settings of PostgresSQL DB I have previously created :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'agent_technologies_db',
'USER': 'stefan_radonjic',
'PASSWORD': 'cepajecar995',
'HOST': 'db',
'PORT': '',
}
}
The error is quite self explanatory.. You didn't set your ip in your ALLOWED_HOSTS setting. Try adding these to your settings file:
ALLOWED_HOSTS = ['*'] # wildcard, allows all
Or if you want to be explicit:
ALLOWED_HOSTS = ['0.0.0.0'] # explicit
Your django app is trying to connect to 'localhost' database, but as it is inside its own container -- localhost is not right uri to reach database.
Dockercompose will resolve your namequeries to database if you will refer to is by db container name. In your case it is "db"
As text on picture reads -- you have to add "0.0.0.0" into your ALLOWED_HOSTS variable inside your settings module.
Be sure that you've read django documentation carefully. It is pretty vigorous.
First attempt into docker and I've hit a wall.
I don't understand how the docker works and when my local machine is "detached" from the container. At the end the project runs with docker-compose run, but doesn't with docker run because it cannot connect to postgres.
When I run docker-compose run with these settings everything works:
settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'db',
'PORT': '5432',
}
}
docker-compose.yml
version: '2'
services:
db:
image: postgres
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
ports:
- '5432:5432'
redis:
image: redis
ports:
- '6379:6379'
celery:
build:
context: .
dockerfile: Dockerfile
env_file: common.env
command: celery -A saleor worker --app=saleor.celeryconf:app --loglevel=info
volumes:
- .:/app:Z
links:
- redis
depends_on:
- redis
search:
image: elasticsearch:5.4.3
mem_limit: 512m
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- '127.0.0.1:9200:9200'
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
env_file: common.env
depends_on:
- db
- redis
- search
ports:
- '8000:8000'
volumes:
- .:/app:Z
makemigrations:
build: .
command: python manage.py makemigrations --noinput
volumes:
- .:/app:Z
migration:
build: .
command: python manage.py migrate --noinput
volumes:
- .:/app:Z
However, if I run
docker build -t db_test .
docker run -p 4000:8000 db_test
Dockerfile:
FROM python:3.5
ENV PYTHONUNBUFFERED 1
RUN \
apt-get -y update && \
apt-get install -y gettext && \
apt-get clean
ADD requirements.txt /app/
RUN pip install -r /app/requirements.txt
ADD . /app
WORKDIR /app
EXPOSE 8000
ENV PORT 8000
CMD ["uwsgi", "/app/saleor/wsgi/uwsgi.ini"]
I am getting an exception:
OperationalError at / could not translate host name "db" to address: Name or service not known
If I change the DB settings to:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres',
'USER': 'user',
'PASSWORD': 'password',
'HOST': '**localhost**',
'PORT': '5432',
}
}
the build and run I get:
could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432? could not connect to server: Cannot assign requested address Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432?
This is the postgres port on my machine. Then if I turn of postgres and the port is free nothing changes.
Any help will be highly appreciated!