Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update to recent template changes #291

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 85 additions & 61 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,99 +1,123 @@
# syntax=docker/dockerfile:1
ARG PYTHON_VERSION=3.12
ARG NODE_VERSION=20.9.0
ARG NVM_VERSION=0.39.5
ARG TAILWINDCSS_VERSION=3.4.0
ARG NODE_VERSION=20
ARG UID=1000
ARG GID=1000


FROM python:${PYTHON_VERSION}-slim as base
ARG UID
ARG GID
ENV DEBUG False
ENV DEBIAN_FRONTEND noninteractive
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
ENV PYTHONPATH /app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /app /app/mediafiles
RUN echo 'deb http://deb.debian.org/debian/ bookworm main contrib' >> /etc/apt/sources.list \
&& DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y --no-install-recommends \
build-essential \
curl \
# litefs
fuse3 \
gosu \
sqlite3 \
# cleanup
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
RUN addgroup -gid "${GID}" --system django \
&& adduser -uid "${UID}" -gid "${GID}" --home /home/django --system django
ENV UV_SYSTEM_PYTHON true
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/var/lib/apt,sharing=locked \
echo 'deb http://deb.debian.org/debian/ bookworm main contrib' >> /etc/apt/sources.list \
&& apt-get update --fix-missing \
&& apt-get install -y --no-install-recommends \
build-essential \
curl \
git \
jq \
# litefs
fuse3 \
gosu \
sqlite3 \
# cleanup
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /app \
&& addgroup -gid "${GID}" --system django \
&& adduser -uid "${UID}" -gid "${GID}" --home /home/django --system django
WORKDIR /app


FROM base as node-base
ARG NODE_VERSION
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/var/lib/apt,sharing=locked \
curl -sL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - \
&& apt-get update --fix-missing \
&& apt-get install -y --no-install-recommends nodejs \
&& npm install -g npm@latest \
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*


FROM base as py
COPY requirements*.txt ./
RUN python -m pip install --upgrade pip \
&& python -m pip install -r requirements.txt
COPY --link requirements*.txt ./
RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/root/.cache/uv \
python -m pip install --upgrade pip uv \
&& uv pip install -r requirements.txt


FROM base as node
ARG NODE_VERSION
ARG NVM_VERSION
ENV NVM_DIR=/usr/local/share/nvm
ENV PATH="$NVM_DIR/versions/node/v${NODE_VERSION}/bin:${PATH}"
COPY --from=py /usr/local /usr/local
COPY package*.json /app/
RUN mkdir -p ${NVM_DIR} \
&& curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash \
&& . "$NVM_DIR/nvm.sh" \
&& nvm use v${NODE_VERSION} \
&& nvm alias default v${NODE_VERSION} \
&& chmod -R 755 "$NVM_DIR" \
&& npm install -g npm@latest \
&& npm install
FROM node-base as node
COPY --from=py --link /usr/local /usr/local
COPY --link package*.json /app
RUN --mount=type=cache,target=/root/.npm npm install


FROM node as tailwind
ARG TAILWINDCSS_VERSION
ADD https://github.com/tailwindlabs/tailwindcss/releases/download/v${TAILWINDCSS_VERSION}/tailwindcss-linux-x64 /usr/local/bin/tailwindcss-linux-x64-${TAILWINDCSS_VERSION}
RUN chmod 755 /usr/local/bin/tailwindcss-linux-x64-${TAILWINDCSS_VERSION} \
&& chown ${UID}:${GID} /usr/local/bin/tailwindcss-linux-x64-${TAILWINDCSS_VERSION}
ARG UID
ARG GID
ARG BUILDARCH
ARG BUILDVARIANT
RUN case ${BUILDARCH} in \
arm64) \
case ${BUILDVARIANT} in \
v7) TAILWINDCSS_ARCH=armv7 ;; \
*) TAILWINDCSS_ARCH=arm64 ;; \
esac ;; \
*) TAILWINDCSS_ARCH=x64 ;; \
esac \
&& TAILWINDCSS_VERSION=$(jq -r '.dependencies.tailwindcss // .devDependencies.tailwindcss' package.json | sed 's/^[^0-9]*//') \
&& curl -L https://github.com/tailwindlabs/tailwindcss/releases/download/v${TAILWINDCSS_VERSION}/tailwindcss-linux-${TAILWINDCSS_ARCH} -o /usr/local/bin/tailwindcss-linux-${TAILWINDCSS_ARCH}-${TAILWINDCSS_VERSION} \
&& chmod 755 /usr/local/bin/tailwindcss-linux-${TAILWINDCSS_ARCH}-${TAILWINDCSS_VERSION} \
&& chown ${UID}:${GID} /usr/local/bin/tailwindcss-linux-${TAILWINDCSS_ARCH}-${TAILWINDCSS_VERSION}


FROM base as app
COPY --from=py /usr/local /usr/local
COPY litefs.yml manage.py redirects.json /app/
COPY blog /app/blog
COPY config /app/config
COPY core /app/core
COPY flyio /app/flyio
COPY templates /app/templates
COPY users /app/users
COPY --from=py --link /usr/local /usr/local
COPY --link litefs.yml manage.py redirects.json /app/
COPY --link blog /app/blog
COPY --link config /app/config
COPY --link core /app/core
COPY --link flyio /app/flyio
COPY --link templates /app/templates
COPY --link users /app/users


FROM node as node-final
COPY --from=tailwind /usr/local /usr/local
COPY --from=app /app /app
COPY static /app/static
COPY postcss.config.cjs tailwind.config.cjs /app/
COPY --from=tailwind --link /usr/local /usr/local
COPY --from=app --link /app /app
COPY --link static /app/static
COPY --link postcss.config.mjs tailwind.config.mjs /app/
RUN python manage.py tailwind --skip-checks build


FROM app as static
ENV DATABASE_URL sqlite://:memory:
COPY --from=py /usr/local /usr/local
COPY --from=node-final /app/static/dist /app/static/dist
COPY static/public /app/static/public
COPY --from=py --link /usr/local /usr/local
COPY --from=node-final --link /app/static/dist /app/static/dist
COPY --link static/public /app/static/public
RUN python manage.py collectstatic --noinput --clear --skip-checks --no-default-ignore


FROM base as final
COPY --from=py /usr/local /usr/local
COPY --from=app /app /app
COPY --from=static /app/staticfiles /app/staticfiles
ARG UID
ARG GID
COPY --from=py --link /usr/local /usr/local
COPY --from=app --chown=${UID}:${GID} --link /app /app
COPY --from=static --chown=${UID}:${GID} --link /app/staticfiles /app/staticfiles
COPY --from=flyio/litefs:0.5 /usr/local/bin/litefs /usr/local/bin/litefs
RUN chown -R django:django /app \
&& DEBIAN_FRONTEND=noninteractive apt-get remove -y --purge \
build-essential \
curl \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
RUN apt-get remove -y --purge \
build-essential \
curl \
git \
jq \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
EXPOSE 8000
ENTRYPOINT litefs mount
140 changes: 65 additions & 75 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,79 +10,73 @@ set dotenv-load := true
# DEPENDENCIES
# ----------------------------------------------------------------------

_pip-compile *ARGS:
python -m piptools compile --resolver=backtracking --strip-extras {{ ARGS }}

@pip-compile *ARGS:
just _pip-compile {{ ARGS }} --generate-hashes requirements.in

_install *ARGS:
python -m pip install --upgrade {{ ARGS }}

@install:
just _install -r requirements.txt

@upgrade:
just pip-compile --upgrade

# Generate requirements file
lock *ARGS:
python -m uv pip compile {{ ARGS }} --generate-hashes requirements.in --output-file requirements.txt

# Install dependencies
install *ARGS:
python -m uv pip install --upgrade -r requirements.txt

# Generate and upgrade dependencies
upgrade:
@just lock --upgrade
# Install and update dependency tools
pup:
python -m pip install --upgrade pip pip-tools
python -m pip install --upgrade pip uv

# Update local development environment
update:
@just pup
@just upgrade
@just install

# ----------------------------------------------------------------------
# TESTING/TYPES
# ----------------------------------------------------------------------

coverage:
rm -rf htmlcov
@just command "python -m coverage run -m pytest && python -m coverage html --skip-covered --skip-empty"

# Run tests using pytest within the 'app' container, with optional arguments
test *ARGS:
@just command pytest {{ ARGS }}

# Run mypy on project
types:
@just command python -m mypy .

# ----------------------------------------------------------------------
# DJANGO
# ----------------------------------------------------------------------

@manage *COMMAND:
just command python -m manage {{ COMMAND }}
# Run a Django management command
manage *COMMAND:
@just command python -m manage {{ COMMAND }}

# Alias for makemigrations
alias mm := makemigrations

# Generate Django migrations
makemigrations *APPS:
@just manage makemigrations {{ APPS }}

# Run Django migrations
migrate *ARGS:
@just manage migrate {{ ARGS }}

# Open a Django shell using django-extensions shell_plus command
shell-plus:
@just manage shell_plus

# Quickly create a superuser with the provided credentials
createsuperuser USERNAME="admin" EMAIL="" PASSWORD="admin":
docker compose run --rm --no-deps app /bin/bash -c 'echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('"'"'{{ USERNAME }}'"'"', '"'"'{{ EMAIL }}'"'"', '"'"'{{ PASSWORD }}'"'"') if not User.objects.filter(username='"'"'{{ USERNAME }}'"'"').exists() else None" | python manage.py shell'

# ----------------------------------------------------------------------
# DOCS
# ----------------------------------------------------------------------

@docs-pip-compile *ARGS:
just _pip-compile {{ ARGS }} --output-file --generate-hashes docs/requirements.txt docs/requirements.in

@docs-upgrade:
just docs-pip-compile --upgrade

@docs-install:
python -m pip install -r docs/requirements.txt

@docs-serve:
#!/usr/bin/env sh
# just _cog
if [ -f "/.dockerenv" ]; then
sphinx-autobuild docs docs/_build/html --host "0.0.0.0"
else
sphinx-autobuild docs docs/_build/html --host "localhost"
fi

@docs-build LOCATION="docs/_build/html":
# just _cog
sphinx-build docs {{ LOCATION }}

# DOCS UTILS
# @_cog:
# cog -r docs/misc/utilities/just.md
# Reset a user's password
resetuserpassword USERNAME="admin" PASSWORD="admin":
docker compose run --rm --no-deps app /bin/bash -c 'echo "from django.contrib.auth import get_user_model; User = get_user_model(); user = User.objects.get(username='"'"'{{ USERNAME }}'"'"'); user.set_password('"'"'{{ PASSWORD }}'"'"'); user.save()" | python manage.py shell'

# ----------------------------------------------------------------------
# UTILS
Expand Down Expand Up @@ -112,62 +106,58 @@ lint:
# DOCKER
# ----------------------------------------------------------------------

# Build services using docker-compose
@build:
docker compose build
# Build services using docker compose
build *ARGS:
docker compose build {{ ARGS }}

# Stop and remove all containers, networks, images, and volumes
@clean:
just down --volumes --rmi local
clean:
@just down --volumes --rmi local

# Run a command within the 'app' container
@command *ARGS:
command *ARGS:
docker compose run --rm --no-deps app /bin/bash -c "{{ ARGS }}"

# Open an interactive shell within the 'app' container opens a console
@console:
console:
docker compose run --rm --no-deps app /bin/bash

# Stop and remove all containers defined in docker-compose
@down *ARGS:
# Stop and remove all containers defined in docker compose
down *ARGS:
docker compose down {{ ARGS }}

# Display the logs for containers, optionally using provided arguments (e.g., --follow)
@logs *ARGS:
logs *ARGS:
docker compose logs {{ ARGS }}

# Display the running containers and their statuses
@ps:
ps:
docker compose ps

# Pull the latest versions of all images defined in docker-compose
@pull:
# Pull the latest versions of all images defined in docker compose
pull:
docker compose pull

# Restart services, optionally targeting specific ones
@restart *ARGS:
restart *ARGS:
docker compose restart {{ ARGS }}

# Open an interactive shell within a specified container (default: 'app')
@shell *ARGS="app":
shell *ARGS="app":
docker compose run --rm --no-deps {{ ARGS }} /bin/bash

# Start services using docker-compose, defaulting to detached mode
@start *ARGS="--detach":
just up {{ ARGS }}
# Start services using docker compose, defaulting to detached mode
start *ARGS="--detach":
@just up {{ ARGS }}

# Stop services by calling the 'down' command
@stop:
just down
stop:
@just down

# Continuously display the latest logs by using the --follow option, optionally targeting specific containers
@tail *ARGS:
just logs '--follow {{ ARGS }}'

# Run tests using pytest within the 'app' container, with optional arguments
@test *ARGS:
docker compose run --rm --no-deps app pytest {{ ARGS }}
tail *ARGS:
@just logs --follow {{ ARGS }}

# Start services using docker-compose, with optional arguments
@up *ARGS:
# Start services using docker compose, with optional arguments
up *ARGS:
docker compose up {{ ARGS }}
Loading
Loading