mirror of
https://github.com/donlon/cloudflare-error-page.git
synced 2026-01-06 15:41:45 +00:00
editor: build docker image for editor server
This commit is contained in:
11
.dockerignore
Normal file
11
.dockerignore
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
.vscode/
|
||||||
|
.DS_Store
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
node_modules/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
__pycache__/
|
||||||
|
.ruff_cache/
|
||||||
|
instance/
|
||||||
78
editor/editor.dockerfile
Normal file
78
editor/editor.dockerfile
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# To build docker image:
|
||||||
|
# cd ..
|
||||||
|
# docker build -t cferr-editor:latest -f editor/editor.dockerfile .
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Stage 1 — Build frontend
|
||||||
|
# =========================
|
||||||
|
FROM node:24-alpine AS frontend-builder
|
||||||
|
|
||||||
|
WORKDIR /work
|
||||||
|
|
||||||
|
# Install dependencies first (better caching)
|
||||||
|
COPY ["editor/web/package.json", "editor/web/yarn.lock", "editor/web/"]
|
||||||
|
COPY ["javascript/package.json", "javascript/package-lock.json", "javascript/"]
|
||||||
|
RUN cd /work/javascript && npm ci && \
|
||||||
|
cd /work/editor/web && yarn install
|
||||||
|
|
||||||
|
# Copy source and build
|
||||||
|
COPY ["editor/web/", "./editor/web"]
|
||||||
|
COPY ["resources/", "./resources"]
|
||||||
|
COPY ["javascript/", "./javascript"]
|
||||||
|
RUN cd /work/javascript && npm run build && \
|
||||||
|
cd /work/editor/web && yarn add ../../javascript && yarn build
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Stage 2 — Build backend
|
||||||
|
# =========================
|
||||||
|
FROM python:3.14-alpine AS backend-builder
|
||||||
|
|
||||||
|
WORKDIR /work
|
||||||
|
|
||||||
|
# Install dependencies first (better caching)
|
||||||
|
RUN pip install hatch
|
||||||
|
|
||||||
|
# Copy source and build
|
||||||
|
COPY ["cloudflare_error_page/", "./cloudflare_error_page"]
|
||||||
|
COPY ["editor/server/", "./editor/server"]
|
||||||
|
COPY ["resources/", "./resources"]
|
||||||
|
COPY ["scripts/", "./scripts"]
|
||||||
|
COPY ["pyproject.toml", "README.md", "LICENSE.txt", "./"]
|
||||||
|
COPY --from=frontend-builder /work/editor/web/dist ./web/dist
|
||||||
|
|
||||||
|
RUN hatch build -t wheel && \
|
||||||
|
cd editor/server && hatch build -t wheel
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Stage 3 — Runtime image
|
||||||
|
# =========================
|
||||||
|
FROM python:3.14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install some dependencies first (better caching)
|
||||||
|
RUN pip install gunicorn Flask Flask-Limiter Flask-SqlAlchemy
|
||||||
|
|
||||||
|
# Copy only the built artifacts from the previous stages
|
||||||
|
COPY --from=frontend-builder /work/editor/web/dist ./web/dist
|
||||||
|
COPY --from=backend-builder /work/dist/*.whl ./packages/
|
||||||
|
COPY --from=backend-builder /work/editor/server/dist/*.whl ./packages/
|
||||||
|
|
||||||
|
# Install packages
|
||||||
|
RUN sh -c 'pip install ./packages/*.whl'
|
||||||
|
|
||||||
|
# Optional but recommended: non-root user
|
||||||
|
RUN adduser -D appuser \
|
||||||
|
&& chown -R appuser:appuser /app
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Instance path of the application
|
||||||
|
VOLUME [ "/data" ]
|
||||||
|
ENV INSTANCE_PATH=/data
|
||||||
|
ENV STATIC_DIR=/app/web/dist
|
||||||
|
|
||||||
|
# Expose the port you will serve on
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Start web server
|
||||||
|
CMD ["gunicorn", "-b", "0.0.0.0:8000", "-w", "1", "app:create_app()"]
|
||||||
@@ -56,7 +56,9 @@ def _initialize_app_config(app: Flask):
|
|||||||
'isolation_level': 'SERIALIZABLE',
|
'isolation_level': 'SERIALIZABLE',
|
||||||
# "execution_options": {"autobegin": False}
|
# "execution_options": {"autobegin": False}
|
||||||
}
|
}
|
||||||
static_dir = os.path.join(app.instance_path, app.config.get('STATIC_DIR', '../../web/dist'))
|
static_dir = os.getenv('STATIC_DIR')
|
||||||
|
if not static_dir:
|
||||||
|
static_dir = os.path.join(app.instance_path, app.config.get('STATIC_DIR', '../../web/dist'))
|
||||||
app.logger.info(f'Static directory: {static_dir}')
|
app.logger.info(f'Static directory: {static_dir}')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# Directory of static files for editor (.html, .js, ...), relative to instance dir
|
# Directory of static files for editor (.html, .js, ...), relative to instance dir.
|
||||||
|
# Overridden by environment varable 'STATIC_DIR'
|
||||||
STATIC_DIR = '../../web/dist'
|
STATIC_DIR = '../../web/dist'
|
||||||
|
|
||||||
# Url prefix for app urls
|
# Url prefix for app urls
|
||||||
|
|||||||
@@ -12,10 +12,15 @@ dependencies = [
|
|||||||
"Flask",
|
"Flask",
|
||||||
"Flask-Limiter",
|
"Flask-Limiter",
|
||||||
"Flask-SqlAlchemy",
|
"Flask-SqlAlchemy",
|
||||||
"cloudflare-error-page @ {root:uri}/../../",
|
"cloudflare-error-page",
|
||||||
]
|
]
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[tool.hatch.envs.default]
|
||||||
|
dependencies = [
|
||||||
|
"cloudflare-error-page @ {root:uri}/../../",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.hatch.metadata]
|
[tool.hatch.metadata]
|
||||||
allow-direct-references = true
|
allow-direct-references = true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user