mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-12-09 21:42:31 -05:00
this
This commit is contained in:
28
Dockerfile
28
Dockerfile
@@ -52,6 +52,7 @@ RUN apt-get update -y && \
|
|||||||
libxmlsec1-dev \
|
libxmlsec1-dev \
|
||||||
libxmlsec1-openssl \
|
libxmlsec1-openssl \
|
||||||
libpq-dev \
|
libpq-dev \
|
||||||
|
gosu \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
@@ -92,11 +93,26 @@ WORKDIR /home/mediacms.io/mediacms
|
|||||||
COPY config/imagemagick/policy.xml /etc/ImageMagick-6/policy.xml
|
COPY config/imagemagick/policy.xml /etc/ImageMagick-6/policy.xml
|
||||||
|
|
||||||
# Copy local_settings.py from config to cms/ for default Docker config (if exists)
|
# Copy local_settings.py from config to cms/ for default Docker config (if exists)
|
||||||
RUN cp config/local_settings.py cms/local_settings.py 2>/dev/null || true
|
RUN if [ -f config/local_settings.py ]; then \
|
||||||
|
cp config/local_settings.py cms/local_settings.py && \
|
||||||
|
chown www-data:www-data cms/local_settings.py && \
|
||||||
|
echo "Docker local_settings.py applied"; \
|
||||||
|
else \
|
||||||
|
echo "No config/local_settings.py found, using default settings"; \
|
||||||
|
fi
|
||||||
|
|
||||||
# Create www-data user directories and set permissions
|
# Create www-data user directories and set permissions
|
||||||
RUN mkdir -p /var/run/mediacms && \
|
RUN mkdir -p /var/run/mediacms && \
|
||||||
chown www-data:www-data /var/run/mediacms
|
chown -R www-data:www-data /home/mediacms.io/mediacms/logs \
|
||||||
|
/home/mediacms.io/mediacms/media_files \
|
||||||
|
/home/mediacms.io/mediacms/static_files \
|
||||||
|
/var/run/mediacms
|
||||||
|
|
||||||
|
# Copy and set up entrypoint script
|
||||||
|
COPY scripts/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||||
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||||
|
|
||||||
############ WEB IMAGE (Django/uWSGI) ############
|
############ WEB IMAGE (Django/uWSGI) ############
|
||||||
FROM base AS web
|
FROM base AS web
|
||||||
@@ -107,8 +123,6 @@ RUN uv pip install uwsgi
|
|||||||
# Copy uWSGI configuration
|
# Copy uWSGI configuration
|
||||||
COPY config/uwsgi/uwsgi.ini /home/mediacms.io/mediacms/uwsgi.ini
|
COPY config/uwsgi/uwsgi.ini /home/mediacms.io/mediacms/uwsgi.ini
|
||||||
|
|
||||||
USER www-data
|
|
||||||
|
|
||||||
EXPOSE 9000
|
EXPOSE 9000
|
||||||
|
|
||||||
CMD ["/home/mediacms.io/bin/uwsgi", "--ini", "/home/mediacms.io/mediacms/uwsgi.ini"]
|
CMD ["/home/mediacms.io/bin/uwsgi", "--ini", "/home/mediacms.io/mediacms/uwsgi.ini"]
|
||||||
@@ -116,19 +130,13 @@ CMD ["/home/mediacms.io/bin/uwsgi", "--ini", "/home/mediacms.io/mediacms/uwsgi.i
|
|||||||
############ WORKER IMAGE (Celery) ############
|
############ WORKER IMAGE (Celery) ############
|
||||||
FROM base AS worker
|
FROM base AS worker
|
||||||
|
|
||||||
USER www-data
|
|
||||||
|
|
||||||
# CMD will be overridden in docker-compose for different worker types
|
# CMD will be overridden in docker-compose for different worker types
|
||||||
|
|
||||||
############ FULL WORKER IMAGE (Celery with extra codecs) ############
|
############ FULL WORKER IMAGE (Celery with extra codecs) ############
|
||||||
FROM worker AS worker-full
|
FROM worker AS worker-full
|
||||||
|
|
||||||
USER root
|
|
||||||
|
|
||||||
COPY requirements-full.txt ./
|
COPY requirements-full.txt ./
|
||||||
RUN mkdir -p /root/.cache/ && \
|
RUN mkdir -p /root/.cache/ && \
|
||||||
chmod go+rwx /root/ && \
|
chmod go+rwx /root/ && \
|
||||||
chmod go+rwx /root/.cache/ && \
|
chmod go+rwx /root/.cache/ && \
|
||||||
uv pip install -r requirements-full.txt
|
uv pip install -r requirements-full.txt
|
||||||
|
|
||||||
USER www-data
|
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ POST_UPLOAD_AUTHOR_MESSAGE_UNLISTED_NO_COMMENTARY = ""
|
|||||||
CANNOT_ADD_MEDIA_MESSAGE = "User cannot add media, or maximum number of media uploads has been reached."
|
CANNOT_ADD_MEDIA_MESSAGE = "User cannot add media, or maximum number of media uploads has been reached."
|
||||||
|
|
||||||
# mp4hls command, part of Bento4
|
# mp4hls command, part of Bento4
|
||||||
MP4HLS_COMMAND = "/home/mediacms.io/mediacms/Bento4-SDK-1-6-0-637.x86_64-unknown-linux/bin/mp4hls"
|
MP4HLS_COMMAND = "/home/mediacms.io/bento4/bin/mp4hls"
|
||||||
|
|
||||||
# highly experimental, related with remote workers
|
# highly experimental, related with remote workers
|
||||||
ADMIN_TOKEN = ""
|
ADMIN_TOKEN = ""
|
||||||
@@ -370,41 +370,30 @@ FILE_UPLOAD_HANDLERS = [
|
|||||||
"django.core.files.uploadhandler.TemporaryFileUploadHandler",
|
"django.core.files.uploadhandler.TemporaryFileUploadHandler",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGS_DIR = os.path.join(BASE_DIR, "logs")
|
|
||||||
|
|
||||||
error_filename = os.path.join(LOGS_DIR, "debug.log")
|
|
||||||
if not os.path.exists(LOGS_DIR):
|
|
||||||
try:
|
|
||||||
os.mkdir(LOGS_DIR)
|
|
||||||
except PermissionError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not os.path.isfile(error_filename):
|
|
||||||
open(error_filename, 'a').close()
|
|
||||||
|
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"disable_existing_loggers": False,
|
"disable_existing_loggers": False,
|
||||||
|
"formatters": {
|
||||||
|
"verbose": {
|
||||||
|
"format": "%(levelname)s %(asctime)s %(module)s "
|
||||||
|
"%(process)d %(thread)d %(message)s"
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers": {
|
"handlers": {
|
||||||
"file": {
|
"console": {
|
||||||
"level": "ERROR",
|
"level": "DEBUG",
|
||||||
"class": "logging.FileHandler",
|
"class": "logging.StreamHandler",
|
||||||
"filename": error_filename,
|
"formatter": "verbose",
|
||||||
},
|
}
|
||||||
},
|
|
||||||
"loggers": {
|
|
||||||
"django": {
|
|
||||||
"handlers": ["file"],
|
|
||||||
"level": "ERROR",
|
|
||||||
"propagate": True,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
"root": {"level": "INFO", "handlers": ["console"]},
|
||||||
}
|
}
|
||||||
|
|
||||||
DATABASES = {"default": {"ENGINE": "django.db.backends.postgresql", "NAME": "mediacms", "HOST": "127.0.0.1", "PORT": "5432", "USER": "mediacms", "PASSWORD": "mediacms", "OPTIONS": {'pool': True}}}
|
DATABASES = {"default": {"ENGINE": "django.db.backends.postgresql", "NAME": "mediacms", "HOST": "db", "PORT": "5432", "USER": "mediacms", "PASSWORD": "mediacms", "OPTIONS": {'pool': True}}}
|
||||||
|
|
||||||
|
|
||||||
REDIS_LOCATION = "redis://127.0.0.1:6379/1"
|
REDIS_LOCATION = "redis://redis:6379/1"
|
||||||
CACHES = {
|
CACHES = {
|
||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "django_redis.cache.RedisCache",
|
"BACKEND": "django_redis.cache.RedisCache",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
user www-data;
|
user nginx;
|
||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
pid /run/nginx.pid;
|
pid /run/nginx.pid;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ threads = 2
|
|||||||
|
|
||||||
master = true
|
master = true
|
||||||
|
|
||||||
socket = 127.0.0.1:9000
|
socket = 0.0.0.0:9000
|
||||||
|
|
||||||
workers = 2
|
workers = 2
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
ADMIN_USER: 'admin'
|
ADMIN_USER: 'admin'
|
||||||
ADMIN_EMAIL: 'admin@localhost'
|
ADMIN_EMAIL: 'admin@localhost'
|
||||||
# ADMIN_PASSWORD: 'uncomment_and_set_password_here'
|
ADMIN_PASSWORD: # ADMIN_PASSWORD: 'uncomment_and_set_password_here'
|
||||||
restart: "no"
|
restart: "no"
|
||||||
depends_on:
|
depends_on:
|
||||||
redis:
|
redis:
|
||||||
@@ -51,7 +51,7 @@ services:
|
|||||||
celery_beat:
|
celery_beat:
|
||||||
image: mediacms/mediacms-worker:7.3
|
image: mediacms/mediacms-worker:7.3
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: ["/home/mediacms.io/bin/celery", "-A", "cms", "beat", "--loglevel=INFO"]
|
command: ["/home/mediacms.io/bin/celery", "-A", "cms", "beat", "--loglevel=INFO", "--schedule=/home/mediacms.io/mediacms/logs/celerybeat-schedule"]
|
||||||
depends_on:
|
depends_on:
|
||||||
migrations:
|
migrations:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ urlpatterns = [
|
|||||||
re_path(r"^manage/users$", views.manage_users, name="manage_users"),
|
re_path(r"^manage/users$", views.manage_users, name="manage_users"),
|
||||||
# Media uploads in ADMIN created pages
|
# Media uploads in ADMIN created pages
|
||||||
re_path(r"^tinymce/upload/", tinymce_handlers.upload_image, name="tinymce_upload_image"),
|
re_path(r"^tinymce/upload/", tinymce_handlers.upload_image, name="tinymce_upload_image"),
|
||||||
re_path("^(?P<slug>[\w.-]*)$", views.get_page, name="get_page"), # noqa: W605
|
re_path(r"^(?P<slug>[\w.-]*)$", views.get_page, name="get_page"),
|
||||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
scripts/docker-entrypoint.sh
Normal file
12
scripts/docker-entrypoint.sh
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Fix permissions on volume mounts
|
||||||
|
chown -R www-data:www-data \
|
||||||
|
/home/mediacms.io/mediacms/logs \
|
||||||
|
/home/mediacms.io/mediacms/media_files \
|
||||||
|
/home/mediacms.io/mediacms/static_files \
|
||||||
|
2>/dev/null || true
|
||||||
|
|
||||||
|
# Run as www-data user
|
||||||
|
exec gosu www-data "$@"
|
||||||
19
scripts/entrypoint.sh
Normal file
19
scripts/entrypoint.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Fix permissions on mounted volumes if running as root
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
echo "Fixing permissions on data directories..."
|
||||||
|
chown -R www-data:www-data /home/mediacms.io/mediacms/logs \
|
||||||
|
/home/mediacms.io/mediacms/media_files \
|
||||||
|
/home/mediacms.io/mediacms/static_files \
|
||||||
|
/var/run/mediacms 2>/dev/null || true
|
||||||
|
|
||||||
|
# If command starts with python or celery, run as www-data
|
||||||
|
if [ "${1:0:1}" != '-' ]; then
|
||||||
|
exec gosu www-data "$@"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute the command
|
||||||
|
exec "$@"
|
||||||
@@ -5,18 +5,22 @@ echo "========================================="
|
|||||||
echo "MediaCMS Migrations Starting..."
|
echo "MediaCMS Migrations Starting..."
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
|
|
||||||
# Wait for database to be ready
|
# Ensure virtualenv is activated
|
||||||
until python manage.py migrate --check 2>/dev/null; do
|
export VIRTUAL_ENV=/home/mediacms.io
|
||||||
echo "Waiting for database to be ready..."
|
export PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
sleep 2
|
|
||||||
done
|
# Use explicit python path from virtualenv
|
||||||
|
PYTHON="$VIRTUAL_ENV/bin/python"
|
||||||
|
|
||||||
|
echo "Using Python: $PYTHON"
|
||||||
|
$PYTHON --version
|
||||||
|
|
||||||
# Run migrations
|
# Run migrations
|
||||||
echo "Running database migrations..."
|
echo "Running database migrations..."
|
||||||
python manage.py migrate
|
$PYTHON manage.py migrate
|
||||||
|
|
||||||
# Check if this is a new installation
|
# Check if this is a new installation
|
||||||
EXISTING_INSTALLATION=$(echo "from users.models import User; print(User.objects.exists())" | python manage.py shell)
|
EXISTING_INSTALLATION=$(echo "from users.models import User; print(User.objects.exists())" | $PYTHON manage.py shell)
|
||||||
|
|
||||||
if [ "$EXISTING_INSTALLATION" = "True" ]; then
|
if [ "$EXISTING_INSTALLATION" = "True" ]; then
|
||||||
echo "Existing installation detected, skipping initial data load"
|
echo "Existing installation detected, skipping initial data load"
|
||||||
@@ -24,14 +28,14 @@ else
|
|||||||
echo "New installation detected, loading initial data..."
|
echo "New installation detected, loading initial data..."
|
||||||
|
|
||||||
# Load fixtures
|
# Load fixtures
|
||||||
python manage.py loaddata fixtures/encoding_profiles.json
|
$PYTHON manage.py loaddata fixtures/encoding_profiles.json
|
||||||
python manage.py loaddata fixtures/categories.json
|
$PYTHON manage.py loaddata fixtures/categories.json
|
||||||
|
|
||||||
# Create admin user
|
# Create admin user
|
||||||
RANDOM_ADMIN_PASS=$(python -c "import secrets;chars = 'abcdefghijklmnopqrstuvwxyz0123456789';print(''.join(secrets.choice(chars) for i in range(10)))")
|
RANDOM_ADMIN_PASS=$($PYTHON -c "import secrets;chars = 'abcdefghijklmnopqrstuvwxyz0123456789';print(''.join(secrets.choice(chars) for i in range(10)))")
|
||||||
ADMIN_PASSWORD=${ADMIN_PASSWORD:-$RANDOM_ADMIN_PASS}
|
ADMIN_PASSWORD=${ADMIN_PASSWORD:-$RANDOM_ADMIN_PASS}
|
||||||
|
|
||||||
DJANGO_SUPERUSER_PASSWORD=$ADMIN_PASSWORD python manage.py createsuperuser \
|
DJANGO_SUPERUSER_PASSWORD=$ADMIN_PASSWORD $PYTHON manage.py createsuperuser \
|
||||||
--no-input \
|
--no-input \
|
||||||
--username=${ADMIN_USER:-admin} \
|
--username=${ADMIN_USER:-admin} \
|
||||||
--email=${ADMIN_EMAIL:-admin@localhost} \
|
--email=${ADMIN_EMAIL:-admin@localhost} \
|
||||||
@@ -44,7 +48,7 @@ fi
|
|||||||
|
|
||||||
# Collect static files
|
# Collect static files
|
||||||
echo "Collecting static files..."
|
echo "Collecting static files..."
|
||||||
python manage.py collectstatic --noinput
|
$PYTHON manage.py collectstatic --noinput
|
||||||
|
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
echo "Migrations completed successfully!"
|
echo "Migrations completed successfully!"
|
||||||
|
|||||||
Reference in New Issue
Block a user