Add Docker deployment configuration

- Add Dockerfile for production (multi-stage build)
- Add Dockerfile.dev for development with hot reload
- Add docker-compose.yml with 5 services (web, mariadb, redis, celery-worker, celery-beat)
- Add docker-compose.dev.yml for development overrides
- Add .dockerignore for optimized builds
- Add docker/entrypoint.sh startup script
- Add .env.docker.example template
- Add Makefile for common commands
- Add deploy.sh for one-command deployment
- Update config/settings/selfhosted.py to support MariaDB via DATABASE_URL
- Add mysqlclient to requirements.txt for MariaDB support
- Update .gitignore to exclude .env.docker

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Keith Smith
2025-12-26 15:59:09 -07:00
co-authored by Claude Sonnet 4.5
parent a2097dcad3
commit 71399e54b8
12 changed files with 865 additions and 12 deletions
+103
View File
@@ -0,0 +1,103 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}KeepItGoing Docker Entrypoint${NC}"
echo -e "${GREEN}========================================${NC}"
# Extract database host from DATABASE_URL or use DB_HOST env var
DB_HOST=${DB_HOST:-mariadb}
# Wait for MariaDB to be ready
echo -e "${YELLOW}Waiting for MariaDB at ${DB_HOST}...${NC}"
max_attempts=30
attempt=0
while ! mysqladmin ping -h"${DB_HOST}" --silent 2>/dev/null; do
attempt=$((attempt + 1))
if [ $attempt -eq $max_attempts ]; then
echo -e "${RED}ERROR: MariaDB did not become available in time${NC}"
exit 1
fi
echo "Waiting for MariaDB... ($attempt/$max_attempts)"
sleep 2
done
echo -e "${GREEN}✓ MariaDB is ready!${NC}"
# Function to run migrations
run_migrations() {
echo -e "${YELLOW}Running database migrations...${NC}"
python manage.py migrate --noinput
echo -e "${GREEN}✓ Migrations complete${NC}"
}
# Function to collect static files
collect_static() {
echo -e "${YELLOW}Collecting static files...${NC}"
python manage.py collectstatic --noinput
echo -e "${GREEN}✓ Static files collected${NC}"
}
# Determine which service to start based on command argument
case "$1" in
"gunicorn")
echo -e "${GREEN}Starting Gunicorn WSGI server...${NC}"
run_migrations
collect_static
# Get Gunicorn config from environment or use defaults
WORKERS=${GUNICORN_WORKERS:-3}
TIMEOUT=${GUNICORN_TIMEOUT:-60}
echo -e "${GREEN}Configuration:${NC}"
echo " Workers: $WORKERS"
echo " Timeout: $TIMEOUT"
echo " Bind: 0.0.0.0:8000"
exec gunicorn config.wsgi:application \
--bind 0.0.0.0:8000 \
--workers $WORKERS \
--timeout $TIMEOUT \
--access-logfile - \
--error-logfile - \
--log-level info
;;
"celery-worker")
echo -e "${GREEN}Starting Celery worker...${NC}"
# Wait a bit more for web service to run migrations
sleep 5
exec celery -A config worker \
--loglevel=info \
--concurrency=2
;;
"celery-beat")
echo -e "${GREEN}Starting Celery beat scheduler...${NC}"
# Wait for web service to run migrations and create database tables
sleep 10
exec celery -A config beat \
--loglevel=info \
--scheduler django_celery_beat.schedulers:DatabaseScheduler
;;
"runserver")
echo -e "${GREEN}Starting Django development server...${NC}"
run_migrations
collect_static
exec python manage.py runserver 0.0.0.0:8000
;;
*)
# If command is not recognized, just execute it
echo -e "${YELLOW}Executing custom command: $@${NC}"
exec "$@"
;;
esac