more docker updates
This commit is contained in:
@@ -4,11 +4,11 @@ SECRET_KEY=w(s0&(_eb058wvmg@44_repv8)r9@5p8fx*g_@c)1dm&d*ew^u
|
||||
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
|
||||
|
||||
# External DB (you mentioned production uses an external DB)
|
||||
DATABASE_HOST=db-postgresql-lon1-05515-jan-22-backup-do-user-8165014-0.c.db.ondigitalocean.com
|
||||
DATABASE_PORT=25060
|
||||
DATABASE_NAME=testing
|
||||
DATABASE_USER=testing
|
||||
DATABASE_PASSWORD=AVNS_ykXO4RxAq0zeJTI-1Nl
|
||||
DB_HOST=db-postgresql-lon1-05515-jan-22-backup-do-user-8165014-0.c.db.ondigitalocean.com
|
||||
DB_PORT=25060
|
||||
DB_NAME=testing
|
||||
DB_USER=django
|
||||
DB_PASSWORD=AVNS_NG_s4i7SMMobWLO
|
||||
|
||||
# Redis
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
@@ -16,3 +16,7 @@ REDIS_URL=redis://redis:6379/0
|
||||
# Gunicorn tuning
|
||||
GUNICORN_WORKERS=3
|
||||
GUNICORN_LOGLEVEL=info
|
||||
|
||||
# Nginx host ports for local development (override prod defaults)
|
||||
NGINX_HTTP_PORT=8000
|
||||
NGINX_HTTPS_PORT=8443
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
upstream app_server {
|
||||
server web:8000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
location /static/ {
|
||||
alias /usr/src/app/static/;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
location /media {
|
||||
alias /usr/src/app/media;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $host;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
proxy_pass http://app_server;
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,6 @@ server {
|
||||
}
|
||||
|
||||
# Default dev / health server block; keep 443 managed outside of docker unless you mount certs
|
||||
listen 80;
|
||||
}
|
||||
|
||||
# A minimal HTTPS server block that expects certs to be mounted at /etc/letsencrypt
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
"""
|
||||
Example `settings_local.py` derived from the production server file.
|
||||
This file is a template only — DO NOT commit real secrets. Copy it to
|
||||
`rad/deploy/settings_local.py` on your server (or provide your own) and
|
||||
ensure the real file is excluded from git.
|
||||
"""
|
||||
import os
|
||||
|
||||
DEBUG = True
|
||||
|
||||
INTERNAL_IPS = ["82.69.88.125", "217.155.198.96", "localhost"]
|
||||
|
||||
# Paths inside the nginx container / host-mounted deploy directories.
|
||||
# On the server, these paths are mounted into nginx as described in the
|
||||
# deployment README. Adjust as needed.
|
||||
STATIC_ROOT = '/usr/src/app/static/'
|
||||
|
||||
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
|
||||
|
||||
if not DEBUG:
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'verbose': {
|
||||
'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
|
||||
'datefmt': "%d/%b/%Y %H:%M:%S",
|
||||
},
|
||||
'simple': {
|
||||
'format': '%(levelname)s %(message)s',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'file': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.FileHandler',
|
||||
'filename': 'log.txt',
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'django': {
|
||||
'handlers': ['file'],
|
||||
'propagate': True,
|
||||
'level': 'DEBUG',
|
||||
},
|
||||
'atlas': {
|
||||
'handlers': ['file'],
|
||||
'level': 'DEBUG',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
# External service credentials (placeholders)
|
||||
CIMAR_USERNAME = "your.username@example.com"
|
||||
CIMAR_PASSWORD = "<REPLACE-WITH-SECRET>"
|
||||
|
||||
# Celery settings — when running in docker the redis service is
|
||||
# reachable at the `redis` hostname provided by docker compose.
|
||||
CELERY_BROKER_URL = "redis://redis:6379"
|
||||
CELERY_RESULT_BACKEND = "redis://redis:6379"
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql_psycopg2",
|
||||
"NAME": os.environ.get("DB_NAME", "django"),
|
||||
"USER": os.environ.get("DB_USER", "django"),
|
||||
"PASSWORD": os.environ.get("DB_PASSWORD", "AVNS_NG_s4i7SMMobWLO"),
|
||||
#"HOST": os.environ.get("DB_HOST", "db-postgresql-lon1-05515-do-user-8165014-0.b.db.ondigitalocean.com"),
|
||||
"HOST": os.environ.get("DB_HOST", "db-postgresql-lon1-05515-jan-22-backup-do-user-8165014-0.c.db.ondigitalocean.com"),
|
||||
"PORT": os.environ.get("DB_PORT", "25060"),
|
||||
#"NAME": os.environ.get("DB_NAME", "django"),
|
||||
#"USER": os.environ.get("DB_USER", "django"),
|
||||
#"PASSWORD": os.environ.get("DB_PASSWORD", "f7bf31dc9bda1256ea827953480d1917"),
|
||||
#"HOST": os.environ.get("DB_HOST", "161.35.163.87"),
|
||||
#"PORT": os.environ.get("DB_PORT", "5432"),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
DEBUG=1
|
||||
SECRET_KEY=w(s0&(_eb058wvmg@44_repv8)r9@5p8fx*g_@c)1dm&d*ew^u
|
||||
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
|
||||
|
||||
DB_NAME=rad
|
||||
DB_HOST=db
|
||||
DB_USER=django
|
||||
DB_PASSWORD=postgres
|
||||
DB_PORT=5432
|
||||
|
||||
MEMCACHE_HOST=cache
|
||||
|
||||
# DEV-specific vars used by rad/settings_local.py
|
||||
DEV_USE_POSTGRES=1
|
||||
DEV_DB_NAME=${DB_NAME}
|
||||
DEV_DB_USER=${DB_USER}
|
||||
DEV_DB_PASSWORD=${DB_PASSWORD}
|
||||
DEV_DB_HOST=${DB_HOST}
|
||||
DEV_DB_PORT=${DB_PORT}
|
||||
|
||||
# pgAdmin creds
|
||||
PGADMIN_DEFAULT_EMAIL=admin@example.com
|
||||
PGADMIN_DEFAULT_PASSWORD=admin
|
||||
@@ -5,8 +5,10 @@ services:
|
||||
web:
|
||||
env_file:
|
||||
- ../.env.dev
|
||||
|
||||
nginx:
|
||||
ports:
|
||||
- "8080:80"
|
||||
- "8443:443"
|
||||
# Development nginx override: mount a simplified config that does not
|
||||
# reference LetsEncrypt certs so the container can start without real
|
||||
# certificates present on the host.
|
||||
volumes:
|
||||
- ../deploy/nginx/dev.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ services:
|
||||
env_file:
|
||||
- ../.env.${COMPOSE_ENV:-prod}
|
||||
environment:
|
||||
- DJANGO_SETTINGS_MODULE=rad.settings.production
|
||||
- DJANGO_SETTINGS_MODULE=rad.settings
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
@@ -39,8 +39,8 @@ services:
|
||||
image: nginx:stable-alpine
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "${NGINX_HTTP_PORT:-80}:80"
|
||||
- "${NGINX_HTTPS_PORT:-443}:443"
|
||||
depends_on:
|
||||
- web
|
||||
volumes:
|
||||
|
||||
@@ -29,7 +29,7 @@ services:
|
||||
- 8000:8000
|
||||
- 3459:3459
|
||||
env_file:
|
||||
- ./.env.dev
|
||||
- ./.env.dev.local
|
||||
db:
|
||||
image: postgres:14.2-alpine
|
||||
volumes:
|
||||
|
||||
Executable → Regular
+33
-5
@@ -29,17 +29,45 @@ WORKDIR /usr/src/app
|
||||
|
||||
# Install python deps into a uv-managed venv for reproducible builds
|
||||
COPY requirements.txt /usr/src/app/
|
||||
# Prebuild wheels into /wheels so compiled artifacts are cached in a layer.
|
||||
# This speeds rebuilds when `requirements.txt` hasn't changed. The first build
|
||||
# still needs to compile any packages without prebuilt wheels.
|
||||
RUN mkdir -p /wheels \
|
||||
&& python -m venv /tmp/venvbuild \
|
||||
&& /tmp/venvbuild/bin/pip install --upgrade pip setuptools wheel \
|
||||
&& /tmp/venvbuild/bin/pip wheel --wheel-dir=/wheels -r requirements.txt \
|
||||
&& rm -rf /tmp/venvbuild
|
||||
|
||||
# Create the final uv-managed venv and install from the cached wheels where
|
||||
# possible. Using `--no-index --find-links=/wheels` makes pip prefer the
|
||||
# prebuilt wheels, avoiding recompilation.
|
||||
RUN uv venv /opt/venv \
|
||||
&& export VIRTUAL_ENV=/opt/venv \
|
||||
&& export PATH="/opt/venv/bin:$PATH" \
|
||||
&& uv pip install --upgrade pip setuptools wheel \
|
||||
&& uv pip install --no-cache-dir -r requirements.txt
|
||||
&& uv pip install --no-index --find-links=/wheels -r requirements.txt
|
||||
|
||||
# Copy project files into image
|
||||
COPY . /usr/src/app
|
||||
# Ensure the runtime environment uses the uv-managed venv by default.
|
||||
# This persists the venv into image ENV so `python` and `gunicorn` point
|
||||
# to the venv-installed binaries at container start.
|
||||
ENV VIRTUAL_ENV=/opt/venv
|
||||
ENV PATH="/opt/venv/bin:$PATH"
|
||||
|
||||
# Create non-root user
|
||||
RUN useradd -m appuser && chown -R appuser /usr/src/app /opt/venv
|
||||
# Create non-root user before copying files so we can use Docker's
|
||||
# `--chown` flag during COPY and avoid an expensive recursive `chown -R`.
|
||||
RUN useradd -m appuser
|
||||
|
||||
# Copy project files into image and set ownership during copy (faster than
|
||||
# a separate `chown -R` step). This keeps layer reuse efficient.
|
||||
COPY --chown=appuser:appuser . /usr/src/app
|
||||
|
||||
# Ensure the venv is usable by the non-root user; chown only the venv path
|
||||
# (much smaller than the whole project tree) to avoid a long recursive chown.
|
||||
RUN chown -R appuser:appuser /opt/venv
|
||||
|
||||
# Make the entrypoint executable (some files in the repo may not have the
|
||||
# executable bit set). Do this as root before switching to the app user.
|
||||
RUN [ -f /usr/src/app/entrypoint.sh ] && chmod +x /usr/src/app/entrypoint.sh || true
|
||||
USER appuser
|
||||
|
||||
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
|
||||
|
||||
+23
-1
@@ -19,4 +19,26 @@ fi
|
||||
COMPOSE_ENV=${COMPOSE_ENV:-dev}
|
||||
|
||||
echo "Starting compose with COMPOSE_ENV=$COMPOSE_ENV (using .env.$COMPOSE_ENV)"
|
||||
COMPOSE_ENV=$COMPOSE_ENV docker compose -f docker/docker-compose.prod.yml -f docker/docker-compose.dev.yml up -d --build
|
||||
# Load variables from .env.<env> into the environment so Compose variable
|
||||
# substitution (e.g. ${NGINX_HTTP_PORT}) works. We export all variables from
|
||||
# the file for the duration of the command.
|
||||
ENV_FILE="$REPO_ROOT/.env.$COMPOSE_ENV"
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
# Export variables from the .env file safely without sourcing it. Some
|
||||
# values include characters (parentheses, ampersands) that break POSIX
|
||||
# shell parsing if the file is sourced directly. Read line-by-line,
|
||||
# ignore comments/empty lines and export KEY=VALUE pairs.
|
||||
while IFS= read -r _line || [ -n "$_line" ]; do
|
||||
line="$_line"
|
||||
case "$line" in
|
||||
''|\#*) continue ;;
|
||||
esac
|
||||
# Split on first '=' into key and value
|
||||
key=${line%%=*}
|
||||
val=${line#*=}
|
||||
# Export directly (preserves special characters in the value)
|
||||
export "$key=$val"
|
||||
done < "$ENV_FILE"
|
||||
fi
|
||||
|
||||
COMPOSE_ENV=$COMPOSE_ENV docker compose -f docker/docker-compose.prod.yml -f docker/docker-compose.dev.yml up --build
|
||||
|
||||
Reference in New Issue
Block a user