Make container more robust
This commit is contained in:
@@ -9,7 +9,6 @@ static
|
||||
.drone.yml
|
||||
.editorconfig
|
||||
.gitignore
|
||||
Caddyfile
|
||||
CHANGELOG.md
|
||||
db.sqlite3
|
||||
docker-compose*
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
{
|
||||
auto_https off
|
||||
admin off
|
||||
}
|
||||
|
||||
:8000 {
|
||||
handle_path /static/* {
|
||||
root * /usr/share/caddy
|
||||
root * /home/timetracker/app/static
|
||||
file_server
|
||||
}
|
||||
handle {
|
||||
reverse_proxy backend:8001
|
||||
handle /robots.txt {
|
||||
root * /home/timetracker/app/games/static
|
||||
file_server
|
||||
}
|
||||
reverse_proxy localhost:8001
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
auto_https off
|
||||
}
|
||||
|
||||
:8000 {
|
||||
handle_path /static/* {
|
||||
root * static
|
||||
file_server browse
|
||||
}
|
||||
handle /robots.txt {
|
||||
root * games/static
|
||||
file_server browse
|
||||
}
|
||||
reverse_proxy :8001
|
||||
}
|
||||
+15
-6
@@ -22,20 +22,29 @@ ENV PROD=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PATH="/home/timetracker/app/.venv/bin:$PATH"
|
||||
|
||||
RUN useradd -m --uid 1000 timetracker \
|
||||
&& mkdir -p /var/www/django/static \
|
||||
&& chown timetracker:timetracker /var/www/django/static
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl \
|
||||
ca-certificates \
|
||||
libcap2-bin \
|
||||
supervisor \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& useradd -m --uid 1000 timetracker \
|
||||
&& mkdir -p /var/log/supervisor /etc/supervisor/conf.d /home/timetracker/data \
|
||||
&& chown timetracker:timetracker /var/log/supervisor /home/timetracker/data
|
||||
|
||||
RUN curl -sL "https://caddyserver.com/api/download?os=linux&arch=amd64" \
|
||||
-o /usr/local/bin/caddy && chmod +x /usr/local/bin/caddy
|
||||
|
||||
WORKDIR /home/timetracker/app
|
||||
|
||||
COPY --from=builder --chown=timetracker:timetracker /home/timetracker/app /home/timetracker/app
|
||||
|
||||
COPY --chown=timetracker:timetracker Caddyfile /etc/caddy/Caddyfile
|
||||
COPY --chown=timetracker:timetracker supervisor.conf /etc/supervisor/conf.d/supervisor.conf
|
||||
COPY --chown=timetracker:timetracker entrypoint.sh /
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
USER timetracker
|
||||
|
||||
ENV VERSION_NUMBER=1.6.1
|
||||
|
||||
EXPOSE 8000
|
||||
CMD [ "/entrypoint.sh" ]
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
||||
@@ -41,9 +41,10 @@ caddy:
|
||||
|
||||
dev-prod: migrate collectstatic
|
||||
@npx concurrently \
|
||||
--names "Django,Django-Q" \
|
||||
"PROD=1 uv run python -m gunicorn --bind 0.0.0.0:8001 timetracker.asgi:application -k uvicorn.workers.UvicornWorker"
|
||||
"uv run manage.py qcluster"
|
||||
--names "Caddy,Django,Django-Q" \
|
||||
"caddy run --config Caddyfile.dev" \
|
||||
"PROD=1 uv run python -m gunicorn --bind 0.0.0.0:8001 timetracker.asgi:application -k uvicorn.workers.UvicornWorker" \
|
||||
"PROD=1 uv run manage.py qcluster"
|
||||
|
||||
dumpgames:
|
||||
uv run python manage.py dumpdata --format yaml games --output tracker_fixture.yaml
|
||||
|
||||
+11
-21
@@ -1,30 +1,20 @@
|
||||
---
|
||||
services:
|
||||
backend:
|
||||
image: registry.kucharczyk.xyz/timetracker
|
||||
timetracker:
|
||||
image: ${REGISTRY_URL:-registry.kucharczyk.xyz}/timetracker:1.7.0
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: timetracker
|
||||
environment:
|
||||
- TZ=Europe/Prague
|
||||
- CSRF_TRUSTED_ORIGINS="https://tracker.kucharczyk.xyz"
|
||||
user: "1000"
|
||||
- TZ=${TZ:-Europe/Prague}
|
||||
- CSRF_TRUSTED_ORIGINS=https://tracker.kucharczyk.xyz
|
||||
- PUID=${PUID:-1000}
|
||||
- PGID=${PGID:-100}
|
||||
ports:
|
||||
- "${TIMETRACKER_EXTERNAL_PORT:-8000}:8000"
|
||||
volumes:
|
||||
- "static-files:/var/www/django/static"
|
||||
- "$PWD/db.sqlite3:/home/timetracker/app/db.sqlite3"
|
||||
- "${DOCKER_STORAGE_PATH:-/tmp}/timetracker/data:/home/timetracker/data"
|
||||
- "${DOCKER_STORAGE_PATH:-/tmp}/timetracker/backups:/home/timetracker/app/games/fixtures/backups"
|
||||
restart: unless-stopped
|
||||
|
||||
frontend:
|
||||
image: caddy
|
||||
volumes:
|
||||
- "static-files:/usr/share/caddy:ro"
|
||||
- "$PWD/Caddyfile:/etc/caddy/Caddyfile"
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
volumes:
|
||||
static-files:
|
||||
|
||||
|
||||
+18
-18
@@ -1,23 +1,23 @@
|
||||
#!/bin/bash
|
||||
# Apply database migrations
|
||||
set -euo pipefail
|
||||
echo "Apply database migrations"
|
||||
python manage.py migrate
|
||||
|
||||
echo "Collect static files"
|
||||
PUID=${PUID:-1000}
|
||||
PGID=${PGID:-100}
|
||||
|
||||
USERHOME=$(grep timetracker /etc/passwd | cut -d ":" -f6)
|
||||
usermod -d "/root" timetracker
|
||||
groupmod -o -g "$PGID" timetracker
|
||||
usermod -o -u "$PUID" timetracker
|
||||
usermod -d "${USERHOME}" timetracker
|
||||
|
||||
mkdir -p /home/timetracker/data /var/log/supervisor
|
||||
chmod 755 /home/timetracker/app
|
||||
chmod 755 /home/timetracker/app/.venv
|
||||
|
||||
chown "$PUID:$PGID" /home/timetracker/data
|
||||
chown "$PUID:$PGID" /var/log/supervisor
|
||||
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --clear --no-input
|
||||
|
||||
_term() {
|
||||
echo "Caught SIGTERM signal!"
|
||||
kill -SIGTERM "$gunicorn_pid"
|
||||
kill -SIGTERM "$django_q_pid"
|
||||
}
|
||||
trap _term SIGTERM
|
||||
|
||||
echo "Starting Django-Q cluster"
|
||||
python manage.py qcluster & django_q_pid=$!
|
||||
|
||||
echo "Starting app"
|
||||
python -m gunicorn --bind 0.0.0.0:8001 timetracker.asgi:application -k uvicorn.workers.UvicornWorker --access-logfile - --error-logfile - & gunicorn_pid=$!
|
||||
|
||||
wait "$gunicorn_pid" "$django_q_pid"
|
||||
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisor.conf
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
user=root
|
||||
logfile=/dev/stdout
|
||||
logfile_maxbytes=0
|
||||
|
||||
[program:caddy]
|
||||
command=/usr/local/bin/caddy run --config /etc/caddy/Caddyfile
|
||||
directory=/home/timetracker/app
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/dev/stderr
|
||||
stdout_logfile=/dev/stdout
|
||||
stderr_logfile_maxbytes=0
|
||||
stdout_logfile_maxbytes=0
|
||||
user=timetracker
|
||||
|
||||
[program:gunicorn]
|
||||
command=python -m gunicorn --bind 0.0.0.0:8001 timetracker.asgi:application -k uvicorn.workers.UvicornWorker --access-logfile - --error-logfile -
|
||||
directory=/home/timetracker/app
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/dev/stderr
|
||||
stdout_logfile=/dev/stdout
|
||||
stderr_logfile_maxbytes=0
|
||||
stdout_logfile_maxbytes=0
|
||||
process_name=%(program_name)s
|
||||
user=timetracker
|
||||
|
||||
[program:qcluster]
|
||||
command=python manage.py qcluster
|
||||
directory=/home/timetracker/app
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/dev/stderr
|
||||
stdout_logfile=/dev/stdout
|
||||
stderr_logfile_maxbytes=0
|
||||
stdout_logfile_maxbytes=0
|
||||
process_name=%(program_name)s
|
||||
user=timetracker
|
||||
@@ -4,7 +4,7 @@ Django settings for timetracker project.
|
||||
Generated by 'django-admin startproject' using Django 4.1.4.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.1/topics/settings/
|
||||
https://docs.djangoproject.com/en/4.1/topics/deployment/checklist/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/4.1/ref/settings/
|
||||
@@ -110,7 +110,7 @@ WSGI_APPLICATION = "timetracker.wsgi.application"
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": BASE_DIR / "db.sqlite3",
|
||||
"NAME": Path(os.environ.get("DATA_DIR", "/home/timetracker/data")) / "db.sqlite3",
|
||||
"OPTIONS": {
|
||||
"timeout": 20,
|
||||
"init_command": "PRAGMA synchronous=FULL; PRAGMA journal_mode=WAL;",
|
||||
@@ -154,7 +154,7 @@ USE_TZ = True
|
||||
# https://docs.djangoproject.com/en/4.1/howto/static-files/
|
||||
|
||||
STATIC_URL = "static/"
|
||||
STATIC_ROOT = BASE_DIR / "static" if DEBUG else "/var/www/django/static"
|
||||
STATIC_ROOT = BASE_DIR / "static"
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
|
||||
|
||||
Reference in New Issue
Block a user