The below example is from Coding With Mosh and I have built it via Docker, Docker-Compose using VS Code and a Linux build PC to create this Docker build environment with full maria DB and nice Adminer db viewer. This project show another way to use Docker to containerize the development of Python scripts and projects. See Coding with Mosh for full example. See Setting up Docker here. My build machine was based on this.
Storefront Django project from Coding With Mosh
This is step 1 of Coding with Mosh Django project. The source code for this is available here on my gitlab.
Build steps
These are the steps that I followed to build this in Docker Compose
Step 1 - Create Ignore Files
This has two files needed to setup both Docker and git to ignore data, cache, and databases. .dockerignore file
data/
__pycache*/
db.sqlite3
.gitignore file
data/
__pycache*/
db.sqlite3
Step 2 - Create src Directory
Simple where the src is going to be compiled also created
mkdir -p mariadb/sql
Added file createdb.sql to this folder to create base users
CREATE USER IF NOT EXISTS myuser@'%' IDENTIFIED BY 'thisismyuserpassword';
CREATE DATABASE IF NOT EXISTS myproject;
GRANT ALL ON myproject.* TO myuser@'%';
So far so good? This is the base idea I will have for every project.
Step 3 - Create requirements.txt
So, in the root storefront dir create a file called requirements.txt
This file will be used by the Dockerfile to load python packages needed to build this project.
For the start of this project all I am going to load are django and mysqlclient. There are more;
however, I am just keeping simple for now. The rest require modifying associated elements of
django; so, I will add as we get to associated training areas focused on the features.
django
mysqlclient
Step 4 - Create Dockerfile
Now, it is time to create the Dockerfile in the base storefront dir this is the basis for all
Added sudo user followed this
FROM python:3.12-slim-bookworm
ARG DOCKER_USER=debian
RUN apt-get update && \
apt-get -y install sudo python3-dev default-libmysqlclient-dev build-essential pkg-config
RUN adduser --disabled-password \
--gecos '' ${DOCKER_USER} \
&& adduser ${DOCKER_USER} sudo \
&& echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER ${DOCKER_USER}
WORKDIR /code
COPY ./requirements.txt ./
RUN sudo pip install --no-cache-dir -r requirements.txt
COPY . /code/
RUN sudo chown -R $DOCKER_USER:$DOCKER_USER /code
Step 5 - Create docker-compose.yml
So this is the last step in the config part of the project once this is done you will have all
that is needed to run this project in docker and start building it from there.
Almost done, create docker-compose.yml
services:
db:
image: mariadb:11.3.2-jammy
restart: always
environment:
- MARIADB_ROOT_PASSWORD=Mysql!sql
- MARIADB_PORT=3306
ports:
- 3307:3306
volumes:
- ./data:/var/lib/mysql
- ./src/mariadb/sql:/docker-entrypoint-initdb.d
adminer:
image: adminer
restart: always
ports:
- 8888:8080
depends_on:
- db
web:
build: .
#Use interacive shell with lines below which prevented the crash of container when bad code was hit...
stdin_open: true
tty: true
# TODO: Use Entrypoint instead of command? Not sure but I think so... Anyway above lines take care of needs for now...
#command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./src:/code
ports:
- "9000:8000"
environment:
- DB_NAME=myproject
- DB_USER=myuser
- DB_PASSWORD=thisismyuserpassword
- DB_HOST=db
depends_on:
- db
Also note run interactive shell via example here There are other mysql types I have tried too like this
services:
db:
# image: 'bitnami/mariadb:11.2-debian-12'
# restart: always
# environment:
# - MARIADB_ROOT_PASSWORD=Hpy@7400sql
# ports:
# - 3307:3306
# volumes:
# - ./data:/bitnami/mariadb
# - ./src/mariadb/sql:/docker-entrypoint-startdb.d
#.
#.
#.
For now, I am using the upper one as it is working well. Then run to build *usb
docker compose run --build web django-admin startproject storefront .
This of coarse would fail because manage.py is not there yet; so, take it down. Last, run docker-compose up -d
docker-compose up -d
Step 6 - Connect to VS code Via Docker and Do Real Work in That Env.
Now, that the env is up you can connect via docker extension in VS Code.
This is called Dev Containers
Oh, and I may have forgot to mention VS Code Remote - SSH and Remote - SSH: Editing Configuration Files. Extentions as well Here is my config stored in ~/.ssh/config folder
Host 192.168.0.46
HostName 192.168.0.46
IdentityFile ~/.ssh/id-rsa
User root
Host 192.168.2.15
HostName 192.168.2.15
Port 2222
IdentityFile ~/.ssh/id-rsa
User debian
Host builder
HostName builder
IdentityFile ~/.ssh/id-rsa
User debian
Yes, builder is the one I installed docker on and used to do all my builds.
This is the docker container that I connect to. That is the far left option on VS code for example here
Step 7 - Setup database connection. First let's make sure the db is happy. In my case I am connecting to [adminer]http://builder:8888
In there I have confirmed that I have a database called myproject and I have a user call myuser
this goes in settings.py under the storefront dir in the VS Code that is running in docker. This can also be modified via
src/storefront/settings.py in from the builder's VS Code if so desired. Note: it is best to work in Docker VS Code as it
has full code completion and knows the python env and all install modules. So, modify there!!!
if os.environ.get('DB_PORT') != None:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('DB_NAME'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': os.environ.get('DB_HOST'),
'PORT': os.environ.get('DB_PORT'),
}
}
else: # no port so more than likely docker.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('DB_NAME'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': os.environ.get('DB_HOST'),
}
}
Note: this option provides two database maps based on DB port the better way would be to do an inline one and add DB_PORT when needed This allows the code to run a DB from outside the Docker env if DB_PORT is specified. Most of the time I would think the Docker DB would be used.
Also notice the os.environ.get commands all pull from the env variables defined in the docker compose and also the lack of DB_PORT defined in said compose file:
environment:
- DB_NAME=myproject
- DB_USER=myuser
- DB_PASSWORD=thisismyuserpassword
- DB_HOST=db
Oh, and for now mariadb/sql/createdb.sql defines them in there too. TODO: Find out if there is a way to pass ENV_VARIABLES into sql scripts