feat: upgrade python version and install frontend in container
This commit is contained in:
parent
3be3a45606
commit
a482d5bba8
6 changed files with 77 additions and 30 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,6 +1,16 @@
|
||||||
# Secrets
|
# Secrets
|
||||||
config.yaml
|
config.yaml
|
||||||
|
|
||||||
|
# External frontend repo and build
|
||||||
|
/frontend/
|
||||||
|
/app/static/ui/
|
||||||
|
|
||||||
|
# build-harness
|
||||||
|
/build-harness/
|
||||||
|
/build-harness-extensions/
|
||||||
|
.build-harness
|
||||||
|
.build-harness-ext
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
image: python:3.8-bullseye
|
image: python:3.11-bookworm
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
|
|
61
Dockerfile
61
Dockerfile
|
@ -1,55 +1,64 @@
|
||||||
#FROM python:3.9.13-slim-bullseye
|
FROM debian:bookworm AS portal
|
||||||
FROM debian:bullseye AS portal
|
|
||||||
MAINTAINER Ana Custura <ana@sr2.uk>
|
|
||||||
|
|
||||||
ENV APP="bc"
|
ENV APP="bc"
|
||||||
ENV APP_BASE="/srv/"
|
ENV APP_BASE="/srv"
|
||||||
ENV SHELL="/bin/bash"
|
ENV SHELL="/bin/bash"
|
||||||
ENV FLASK_APP="${FLASK_APP:-app}"
|
ENV FLASK_APP="${FLASK_APP:-app}"
|
||||||
ENV FLASK_RUN_HOST="${FLASK_RUN_HOST:-0.0.0.0}"
|
ENV FLASK_RUN_HOST="${FLASK_RUN_HOST:-0.0.0.0}"
|
||||||
ENV FLASK_RUN_PORT="${FLASK_RUN_PORT:-5000}"
|
ENV FLASK_RUN_PORT="${FLASK_RUN_PORT:-5000}"
|
||||||
|
ENV PYTHONPATH="${APP_BASE}/env/lib/python3.11/site-packages"
|
||||||
|
ENV PATH="${APP_BASE}/env/bin:/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin:/home/${APP}/.local/bin"
|
||||||
|
|
||||||
# Set PATH and PYTHONPATH in the container
|
|
||||||
ENV PYTHONPATH="/usr/lib/python3/dist-packages:/home/${APP}/.local/lib/python3.9/site-packages"
|
|
||||||
ENV PATH="/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin:/home/${APP}/.local/bin"
|
|
||||||
|
|
||||||
# UID and GID might be read-only values, so use non-conflicting ones
|
|
||||||
ARG CONTAINER_UID="${CONTAINER_UID:-1000}"
|
ARG CONTAINER_UID="${CONTAINER_UID:-1000}"
|
||||||
ARG CONTAINER_GID="${CONTAINER_GID:-1000}"
|
ARG CONTAINER_GID="${CONTAINER_GID:-1000}"
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install --no-install-recommends -y \
|
apt-get install --no-install-recommends -y \
|
||||||
curl \
|
curl \
|
||||||
software-properties-common \
|
|
||||||
python3-pip \
|
python3-pip \
|
||||||
|
python3-venv \
|
||||||
cron \
|
cron \
|
||||||
git \
|
git \
|
||||||
gnupg2
|
gnupg && \
|
||||||
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
|
ARG OPENTOFU_VERSION="1.8.5"
|
||||||
|
RUN curl -fsSL https://get.opentofu.org/opentofu.gpg -o opentofu.gpg && \
|
||||||
|
gpg --import opentofu.gpg && \
|
||||||
|
curl -fsSL https://github.com/opentofu/opentofu/releases/download/v${OPENTOFU_VERSION}/tofu_${OPENTOFU_VERSION}_linux_amd64.tar.gz -o opentofu.tar.gz && \
|
||||||
|
curl -fsSL https://github.com/opentofu/opentofu/releases/download/v${OPENTOFU_VERSION}/tofu_${OPENTOFU_VERSION}_linux_amd64.tar.gz.gpgsig -o opentofu.tar.gz.gpgsig && \
|
||||||
|
gpg --verify opentofu.tar.gz.gpgsig opentofu.tar.gz && \
|
||||||
|
tar -xzf opentofu.tar.gz -C /usr/local/bin tofu && \
|
||||||
|
chmod +x /usr/local/bin/tofu && \
|
||||||
|
ln -s /usr/local/bin/tofu /usr/local/bin/terraform && \
|
||||||
|
rm -rf opentofu.tar.gz opentofu.tar.gz.gpgsig opentofu.gpg /tmp/* /var/tmp/*
|
||||||
|
|
||||||
# Install Terraform
|
|
||||||
# See https://www.terraform.io/downloads
|
|
||||||
RUN /usr/bin/curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add -
|
|
||||||
RUN apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com bullseye main"
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y terraform \
|
apt-get install --no-install-recommends -y curl sudo && \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
||||||
|
apt-get install -y nodejs && \
|
||||||
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
# Switch to a regular user
|
|
||||||
RUN groupadd -r -g ${CONTAINER_GID} ${APP} && \
|
RUN groupadd -r -g ${CONTAINER_GID} ${APP} && \
|
||||||
useradd --no-log-init -r -u ${CONTAINER_UID} -g ${APP} ${APP} && \
|
useradd --no-log-init -r -u ${CONTAINER_UID} -g ${APP} ${APP} && \
|
||||||
mkdir -p /home/${APP} && chown -R ${APP}. /home/${APP}
|
mkdir -p /home/${APP} && chown -R ${APP}:${APP} /home/${APP} && \
|
||||||
RUN mkdir -p ${APP_BASE}/${APP} && chown ${APP}. ${APP_BASE}/${APP}
|
mkdir -p ${APP_BASE}/${APP} ${APP_BASE}/env && chown ${APP}:${APP} ${APP_BASE}/${APP} ${APP_BASE}/env
|
||||||
|
|
||||||
USER ${APP}
|
USER ${APP}
|
||||||
|
|
||||||
# Copy the project into the workdir
|
|
||||||
WORKDIR ${APP_BASE}/${APP}
|
WORKDIR ${APP_BASE}/${APP}
|
||||||
COPY --chown=${APP}:${APP} . ${APP_BASE}/${APP}
|
COPY --chown=${APP}:${APP} . ${APP_BASE}/${APP}
|
||||||
|
|
||||||
# Install Python requirements
|
RUN python3 -m venv ${APP_BASE}/env && \
|
||||||
RUN pip3 install -r requirements.txt
|
${APP_BASE}/env/bin/pip install --no-cache-dir -r requirements.txt && \
|
||||||
RUN pip3 install psycopg2-binary
|
${APP_BASE}/env/bin/pip install --no-cache-dir psycopg2-binary
|
||||||
|
|
||||||
|
RUN rm -rf frontend && \
|
||||||
|
git clone https://gitlab.com/guardianproject-ops/bypass-censorship/portal-frontend.git frontend && \
|
||||||
|
cd frontend && npm install && npm run build && \
|
||||||
|
mkdir -p ${APP_BASE}/${APP}/app/static/ui && \
|
||||||
|
cp -r dist/* ${APP_BASE}/${APP}/app/static/ui && \
|
||||||
|
rm -rf frontend /tmp/* /var/tmp/*
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
RUN crontab -u ${APP} docker-crontab
|
RUN crontab -u ${APP} docker-crontab
|
||||||
# Set the entrypoint to the web app
|
|
||||||
|
|
14
Makefile
Normal file
14
Makefile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
export README_TEMPLATE_FILE ?= $(BUILD_HARNESS_EXTENSIONS_PATH)/templates/README.md.gotmpl
|
||||||
|
export README_DEPS ?= docs/targets.md
|
||||||
|
|
||||||
|
-include $(shell curl -sSL -o .build-harness-ext "https://go.sr2.uk/build-harness"; echo .build-harness-ext)
|
||||||
|
|
||||||
|
.PHONY: install-frontend
|
||||||
|
# Clone the frontend repo, install dependencies, and build the React app for serving with Flask
|
||||||
|
install-frontend:
|
||||||
|
if [ ! -d "frontend" ]; then git clone https://gitlab.com/guardianproject-ops/bypass-censorship/portal-frontend.git frontend; fi
|
||||||
|
cd frontend && npm install && npm run build
|
||||||
|
mkdir -p app/static/ui
|
||||||
|
cp -r frontend/dist/* app/static/ui/
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
from typing import Iterator
|
from typing import Iterator
|
||||||
|
|
||||||
from flask import Flask, redirect, url_for
|
from flask import Flask, redirect, url_for, send_from_directory
|
||||||
from flask.typing import ResponseReturnValue
|
from flask.typing import ResponseReturnValue
|
||||||
from prometheus_client.metrics_core import GaugeMetricFamily, CounterMetricFamily
|
from prometheus_client.metrics_core import GaugeMetricFamily, CounterMetricFamily
|
||||||
from prometheus_client.registry import Collector
|
from prometheus_client.registry import Collector
|
||||||
|
@ -109,8 +109,21 @@ if not_migrating() and 'DISABLE_METRICS' not in os.environ:
|
||||||
REGISTRY.register(AutomationCollector())
|
REGISTRY.register(AutomationCollector())
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/ui')
|
||||||
|
def redirect_ui():
|
||||||
|
return redirect("/ui/")
|
||||||
|
|
||||||
|
@app.route('/ui/', defaults={'path': ''})
|
||||||
|
@app.route('/ui/<path:path>')
|
||||||
|
def serve_ui(path):
|
||||||
|
if path != "" and os.path.exists("app/static/ui/" + path):
|
||||||
|
return send_from_directory('static/ui', path)
|
||||||
|
else:
|
||||||
|
return send_from_directory('static/ui', 'index.html')
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index() -> ResponseReturnValue:
|
def index() -> ResponseReturnValue:
|
||||||
|
# TODO: update to point at new UI when ready
|
||||||
return redirect(url_for("portal.portal_home"))
|
return redirect(url_for("portal.portal_home"))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -195,11 +195,13 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% if config['ADDITIONAL_SIDEBAR_LINKS'] %}
|
|
||||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||||
<span>Extras</span>
|
<span>Extras</span>
|
||||||
</h6>
|
</h6>
|
||||||
<ul class="nav flex-column">
|
<ul class="nav flex-column">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/ui/">{{ icon("globe") }} New UI</a>
|
||||||
|
</li>
|
||||||
{% for link in config['ADDITIONAL_SIDEBAR_LINKS'] %}
|
{% for link in config['ADDITIONAL_SIDEBAR_LINKS'] %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{ link['url'] }}">
|
<a class="nav-link" href="{{ link['url'] }}">
|
||||||
|
@ -208,7 +210,6 @@
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
|
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue