devcontainer.json
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose
{"name": "web",// Update the 'dockerComposeFile' list if you have more compose files or use different names.// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make."dockerComposeFile": ["docker-compose.yml"],// The 'service' property is the name of the service for the container that VS Code should// use. Update this value and .devcontainer/docker-compose.yml to the real service name."service": "web",// The optional 'workspaceFolder' property is the path VS Code should open by default when// connected. This is typically a file mount in .devcontainer/docker-compose.yml"workspaceFolder": "/${localWorkspaceFolderBasename}",// Features to add to the dev container. More info: https://containers.dev/features."features": {"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},"ghcr.io/devcontainers/features/github-cli:1": {}},// Use 'forwardPorts' to make a list of ports inside the container available locally."forwardPorts": [8000],// Uncomment the next line if you want start specific services in your Docker Compose config.// "runServices": [],// Uncomment the next line if you want to keep your containers running after VS Code shuts down.// "shutdownAction": "none",// Uncomment the next line to run commands after the container is created.// "postCreateCommand": "cat /etc/os-release",// Configure tool-specific properties.// "customizations": {},// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.// "remoteUser": "devcontainer""onCreateCommand": "./.devcontainer/init.sh","postCreateCommand": "./.devcontainer/setup-aliases.sh","containerEnv": {"DD_ENV": "dev","DD_SERVICE": "django","DD_LOGS_INJECTION": "false","DD_AGENT_HOST": "datadog","DD_CELERY_DISTRIBUTED_TRACING": "false","DD_DOGSTATSD_DISABLE": "true","DD_APM_ENABLED": "false","DD_TRACE_ENABLED": "false"},"customizations": {"vscode": {"extensions": ["ms-python.python","charliermarsh.ruff"]},"codespaces": {"extensions": ["ms-python.python","charliermarsh.ruff"]},"editor": {"defaultFormatter": "charliermarsh.ruff","formatOnSave": true}}
}
docker-compose.yml
services:redis:image: redis:7.0.7-alpinerestart: alwayslabels:com.datadoghq.ad.logs: '[{"service": "redis", "env": "dev"}]'ports:- '6379:6379'command: redis-server --save 20 1 --loglevel warning --requirepass eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81volumes:- cache:/datadb:image: mysql:8# --default-authentication-plugin=mysql_native_password works with mysql 8.0 # deprecated in higer version of mysql 8# command: --default-authentication-plugin=mysql_native_passwordrestart: alwayslabels:com.datadoghq.ad.logs: '[{"service": "db", "env": "dev"}]'volumes:- data:/var/lib/mysqlports:- "3306:3306"environment:MYSQL_DATABASE: exampleMYSQL_USER: exampleMYSQL_PASSWORD: exampleMYSQL_ROOT_PASSWORD: exampleweb:build: ../command: /bin/sh -c "while sleep 1000; do :; done"environment:- DD_AGENT_HOST=datadog- DJANGO_SUPERUSER_EMAIL=local@creatify.ai- DJANGO_SUPERUSER_PASSWORD=localhostlabels:com.datadoghq.ad.logs: '[{"service": "web", "env": "dev"}]'com.datadoghq.ad.tags: '["service:web", "env:dev"]'volumes:- ..:/webserver:cachedports:- "8000:8000"depends_on:- db- redisenv_file:- ${ENV_FILE:-../webserver.env}
volumes:data:driver: localcache:driver: local
init.sh
#!/bin/bash# Wait for MySQL to be ready maxAttempts=20 counter=1until python manage.py migrate &> /dev/null doif [ $counter -gt $maxAttempts ]; thenecho "Failed to connect to MySQL after $maxAttempts attempts. Exiting..."exit 1fiecho "Attempt $counter: MySQL not ready, waiting 5 seconds..."sleep 5counter=$((counter+1)) doneecho "MySQL is ready!"# Run migrations uv pip install -r requirements-dev.txt --system pre-commit install dmypy start python manage.py migrate# a bunch of fixtures that are needed for the app to work python manage.py loaddata assets/fixtures/data_backup_cleaned.json python manage.py loaddata accounts/fixtures/price.json python manage.py scene_import_command# create superuser local@creatify.ai with password localhost python manage.py createsuperuser --noinput || true# stripe related; normally no need unless you work on payment. curl -s https://packages.stripe.dev/api/security/keypair/stripe-cli-gpg/public | gpg --dearmor | tee /usr/share/keyrings/stripe.gpg echo "deb [signed-by=/usr/share/keyrings/stripe.gpg] https://packages.stripe.dev/stripe-cli-debian-local stable main" | tee -a /etc/apt/sources.list.d/stripe.list apt update apt install stripe -y# Install Node.js and npm curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - apt-get install -y nodejs npm install -g npm@latest npm install -g @anthropic-ai/claude-code node --version npm --version
setup-aliases.sh
# .devcontainer/setup-aliases.sh echo "alias ll='ls -la'" >> ~/.bashrc echo "alias g='git'" >> ~/.bashrc echo 'alias gp="git pull"' >> ~/.bashrc echo 'alias gpo="git push"' >> ~/.bashrc git config --global push.default current git config --global alias.co checkout git config --global alias.go checkout git config --global alias.cob "checkout -b" git config --global alias.gob "checkout -b" git config --global alias.cam "commit -a -m" git config --global alias.s "status -s"
Dockerfile
# syntax=docker/dockerfile:1
FROM python:3.11.9-slim-bookworm
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /webserver# Install uv using pip
RUN pip install --no-cache-dir uvCOPY requirements.txt /webserver/# Use uv to install dependencies
RUN uv pip install -r requirements.txt --systemRUN python -m nltk.downloader punkt_tab
# COPY . {PACKAGE}
