Merge branch 'dev' of github.com:bunkerity/bunkerweb into dev

This commit is contained in:
fl0ppy-d1sk 2024-03-15 18:45:08 +01:00
commit 52cfe645b2
No known key found for this signature in database
GPG key ID: 93EE47CC3D061500
52 changed files with 405 additions and 298 deletions

View file

@ -63,22 +63,22 @@ jobs:
SSH_IP: ${{ secrets.ARM_SSH_IP }}
SSH_CONFIG: ${{ secrets.ARM_SSH_CONFIG }}
- name: Setup Buildx
uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
if: inputs.CACHE_SUFFIX != 'arm'
- name: Setup Buildx (ARM)
uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
if: inputs.CACHE_SUFFIX == 'arm'
with:
endpoint: ssh://root@arm
platforms: linux/arm64,linux/arm/v7,linux/arm/v6
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
if: inputs.PUSH == true
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@ -92,7 +92,7 @@ jobs:
# Build cached image
- name: Build image
if: inputs.CACHE == true
uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e # v5.2.0
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
context: .
file: ${{ inputs.DOCKERFILE }}
@ -105,7 +105,7 @@ jobs:
# Build non-cached image
- name: Build image
if: inputs.CACHE != true
uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e # v5.2.0
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
context: .
file: ${{ inputs.DOCKERFILE }}

View file

@ -149,12 +149,12 @@ jobs:
packages: write
steps:
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -72,21 +72,21 @@ jobs:
SSH_IP: ${{ secrets.ARM_SSH_IP }}
SSH_CONFIG: ${{ secrets.ARM_SSH_CONFIG }}
- name: Setup Buildx
uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
if: startsWith(env.ARCH, 'arm') == false
- name: Setup Buildx (ARM)
uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
if: startsWith(env.ARCH, 'arm') == true
with:
endpoint: ssh://root@arm
platforms: linux/arm64,linux/arm/v7,linux/arm/v6
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@ -94,7 +94,7 @@ jobs:
# Build testing package image
- name: Build package image
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui'
uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e # v5.2.0
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
context: .
load: true
@ -106,7 +106,7 @@ jobs:
# Build non-testing package image
- name: Build package image
if: inputs.RELEASE != 'testing' && inputs.RELEASE != 'dev'
uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e # v5.2.0
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
context: .
load: true
@ -142,7 +142,7 @@ jobs:
images: ghcr.io/bunkerity/${{ inputs.LINUX }}-tests:${{ inputs.RELEASE }}
- name: Build test image
if: inputs.TEST == true
uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e # v5.2.0
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
context: .
file: tests/linux/Dockerfile-${{ inputs.LINUX }}

View file

@ -35,12 +35,12 @@ jobs:
- name: Check out repository code
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@ -58,7 +58,7 @@ jobs:
SSH_IP: ${{ secrets.ARM_SSH_IP }}
SSH_CONFIG: ${{ secrets.ARM_SSH_CONFIG }}
- name: Setup Buildx (ARM)
uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
with:
endpoint: ssh://root@arm
platforms: linux/arm64,linux/arm/v7,linux/arm/v6
@ -70,7 +70,7 @@ jobs:
images: bunkerity/${{ inputs.IMAGE }}
# Build and push
- name: Build and push
uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e # v5.2.0
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
context: .
file: ${{ inputs.DOCKERFILE }}

View file

@ -27,7 +27,7 @@ jobs:
- name: Checkout source code
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -197,12 +197,12 @@ jobs:
packages: write
steps:
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -47,7 +47,7 @@ jobs:
sudo chmod +x /usr/local/bin/geckodriver
rm -f geckodriver.tar.gz
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -18,7 +18,7 @@ jobs:
- name: Checkout source code
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -47,7 +47,7 @@ jobs:
sudo chmod +x /usr/local/bin/geckodriver
rm -f geckodriver.tar.gz
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -17,7 +17,7 @@ jobs:
- name: Checkout source code
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Login to ghcr
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -45,6 +45,8 @@
- [MISC] Use ed5519 key instead of RSA for default/fallback certificates
- [MISC] Refactor certbot-new job to optimize the certbot requests
- [MISC] Refactor jobs utils to make it more consistent
- [MISC] Review jobs and utils to make it more consistent and better in general
- [MISC] Change BunkerWeb base Docker image to nginx:1.24.0-alpine-slim
- [DOCUMENTATION] Update web UI's setup wizard instructions in the documentation
- [DOCUMENTATION] Update plugins documentation to reflect the new plugin system
- [DOCUMENTATION] Update ModSecurity documentation to reflect the new changes in the Security Tuning section

View file

@ -602,10 +602,6 @@ For example, you can get the request arguments in your template like this :
#### Actions.py
!!! info "Python libraries"
You can use Python libraries that are already available like :
`Flask`, `Flask-Login`, `Flask-WTF`, `beautifulsoup4`, `docker`, `Jinja2`, `python-magic` and `requests`. To see the full list, you can have a look at the Web UI [requirements.txt](https://github.com/bunkerity/bunkerweb/blobsrc/ui/requirements.txt). If you need external libraries, you can install them inside the **ui** folder of your plugin and then use the classical **import** directive.
!!! warning "CSRF Token"
Please note that every form submission is protected via a CSRF token, you will need to include the following snippet into your forms :
@ -613,16 +609,55 @@ For example, you can get the request arguments in your template like this :
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
```
You can power-up your plugin page with additional scripting with the **actions.py** file when sending a **POST /plugins/<*plugin_id*>**.
Here is what is send to the function :
You have two functions by default in **actions.py** :
**pre_render function**
This allows you to retrieve data when you **GET** the template, and to use the data with the pre_render variable available in Jinja to display content more dynamically.
```python
def pre_render(**kwargs)
return <pre_render_data>
```
BunkerWeb will send you this type of response :
```python
return jsonify({"status": "ok|ko", "code" : XXX, "data": <pre_render_data>}), 200
```
**<*plugin_id*> function**
This allows you to retrieve data when you make a **POST** from the template endpoint, which must be used in AJAX.
```python
def myplugin(**kwargs)
return <plugin_id_data>
```
BunkerWeb will send you this type of response :
```python
return jsonify({"message": "ok", "data": <plugin_id_data>}), 200
```
**What you can access from action.py**
Here are the arguments that are passed and access on action.py functions:
```python
function(app=app, args=request.args.to_dict() or request.json or None)
```
Some examples of what you can do :
!!! info "Python libraries"
In addition, you can use Python libraries that are already available like :
`Flask`, `Flask-Login`, `Flask-WTF`, `beautifulsoup4`, `docker`, `Jinja2`, `python-magic` and `requests`. To see the full list, you can have a look at the Web UI [requirements.txt](https://github.com/bunkerity/bunkerweb/blobsrc/ui/requirements.txt). If you need external libraries, you can install them inside the **ui** folder of your plugin and then use the classical **import** directive.
**Some examples**
- Retrieve form submitted data
@ -631,73 +666,22 @@ from flask import request
def myplugin(**kwargs) :
my_form_value = request.form["my_form_input"]
return my_form_value
```
- Access app methods
- Access app config
**action.py**
```python
from flask import request
def myplugin(**kwargs) :
def pre_render(**kwargs) :
config = kwargs['app'].config["CONFIG"].get_config(methods=False)
return config
```
**You need to retrieve JSON compatible data from this function**, app will return this as response :
```python
return jsonify({"message": "ok", "data": <function_output>}), 200
```
#### Updating template
To easily update the content of a template inside the UI with JSON, a **SetupPlugin class** is available in `src/ui/static/js/plugins/setup.js`.
!!! info "Check core plugins"
Core plugins are using this class. Feel free to look at them in order to see in details how it works.
For example, in case **actions.py** return this :
```python
def myplugin(**kwargs):
return {"name": "My awesome plugin"}
```
I can add this on my **template.html** :
**template**
```html
<p data-name></p>
<script>
new SetupPlugin({
name: {
el: document.querySelector('[data-name]'),
value: '',
type: 'text',
},
});
</script>
<!-- metadata + config -->
<div>{{ pre_render }}</div>
```
**This class will send a POST request, and will try to match the dict key to a JSON key and update your template**.
Here it will look for a `name` key in the JSON response, and will set the `data` on the defined `el`.
In case there is no `data` matching, this will keep or set the `value` key data.
This class has two arguments `SetupPlugin(setup, url)` :
- `url`(optional) : current endpoint by default. You can define another url or add arguments.
- `setup` : a dict of dict with needed data to update properly the template with the incoming data.
**setup details**
| key | Type | Description |
| :--------: | :--------: | :------------------------------------------------------------------------------------------- |
| `dict name` | string | Replace `dict name` by the JSON key to extract the related value. |
| `el` | DOM element| Select element you want the value to be updated. |
| `value` | any | Default value on template load or in case retrieving JSON failed. |
| `type` | string | Define the script behavior with the incoming value. Available : `text`, `list` and `status`. |
| `textEl` | DOM element| Optional additional text content when type is `status`. |
| `listNames`| string | List of data keys when type is `list`. |

View file

@ -207,9 +207,9 @@ importlib-metadata==7.0.2 \
# markdown
# mike
# mkdocs
importlib-resources==6.1.3 \
--hash=sha256:4c0269e3580fe2634d364b39b38b961540a7738c02cb984e98add8b4221d793d \
--hash=sha256:56fb4525197b78544a3354ea27793952ab93f935bb4bf746b846bb1015020f2b
importlib-resources==6.3.0 \
--hash=sha256:166072a97e86917a9025876f34286f549b9caf1d10b35a1b372bffa1600c6569 \
--hash=sha256:783407aa1cd05550e3aa123e8f7cfaebee35ffa9cb0242919e2d1e4172222705
# via mike
jinja2==3.1.3 \
--hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
@ -218,9 +218,9 @@ jinja2==3.1.3 \
# mike
# mkdocs
# mkdocs-material
markdown==3.5.2 \
--hash=sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd \
--hash=sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8
markdown==3.6 \
--hash=sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f \
--hash=sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224
# via
# mkdocs
# mkdocs-material
@ -612,9 +612,9 @@ requests==2.31.0 \
# importlib-resources
# The following packages are considered to be unsafe in a requirements file:
setuptools==69.1.1 \
--hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \
--hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8
setuptools==69.2.0 \
--hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
--hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
# via mkdocs-material
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
@ -686,7 +686,7 @@ webencodings==0.5.1 \
# via
# cssselect2
# tinycss2
zipp==3.17.0 \
--hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
--hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
zipp==3.18.1 \
--hash=sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b \
--hash=sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715
# via pytablewriter

View file

@ -1738,11 +1738,9 @@ In case you have buy a (pro version)[https://panel.bunkerweb.io/?utm_campaign=se
- fill the **setting Pro License Key**
- **save** your changes
!!! warning "Download"
<figure markdown>
![Overview](assets/img/pro-from-ui.webp){ align=center, width="1000" }
<figcaption>Upgrade to PRO from UI</figcaption>
</figure>
The pro version is downloaded in the background by the scheduler. It may take some time before you see the changes to the UI.
If your license key is valid, the upgrade to the pro version will take place automatically in the background.

View file

@ -1,27 +1,19 @@
FROM python:3.12.2-alpine3.19@sha256:1a0501213b470de000d8432b3caab9d8de5489e9443c2cc7ccaa6b0aa5c3148e as builder
# Install python dependencies
RUN apk add --no-cache build-base postgresql-dev
# Copy python requirements
COPY src/deps/requirements.txt /tmp/requirements-deps.txt
COPY src/common/gen/requirements.txt /tmp/req/requirements.txt
COPY src/common/db/requirements.txt /tmp/req/requirements.txt.1
COPY src/common/gen/requirements.txt /tmp/req/requirements-gen.txt
COPY src/common/db/requirements.txt /tmp/req/requirements-db.txt
WORKDIR /usr/share/bunkerweb
RUN mkdir -p deps/python && \
cat /tmp/req/requirements.txt* > deps/requirements.txt && \
rm -rf /tmp/req
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev
# Install python requirements
RUN export MAKEFLAGS="-j$(nproc)" && \
pip install --no-cache-dir --ignore-installed --require-hashes -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python -r deps/requirements.txt
# Remove build dependencies
RUN apk del .build-deps && \
rm -rf /var/cache/apk/*
pip install --no-cache-dir --require-hashes --break-system-packages -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python $(for file in $(ls /tmp/req/requirements*.txt) ; do echo "-r ${file}" ; done | xargs)
# Copy files
# can't exclude specific files/dir from . so we are copying everything by hand
@ -49,9 +41,8 @@ RUN apk add --no-cache bash && \
addgroup -g 101 autoconf && \
adduser -h /var/cache/autoconf -g autoconf -s /bin/sh -G autoconf -D -H -u 101 autoconf && \
cp helpers/bwcli /usr/bin/ && \
mkdir -p /var/tmp/bunkerweb && \
mkdir -p /var/www && \
mkdir -p /etc/bunkerweb && \
echo "Docker" > INTEGRATION && \
mkdir -p /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb /var/www && \
mkdir -p /data/cache && ln -s /data/cache /var/cache/bunkerweb && \
mkdir -p /data/lib && ln -s /data/lib /var/lib/bunkerweb && \
mkdir -p /data/www && ln -s /data/www /var/www/html && \
@ -59,14 +50,15 @@ RUN apk add --no-cache bash && \
for dir in $(echo "configs/http configs/stream configs/server-http configs/server-stream configs/default-server-http configs/default-server-stream configs/modsec configs/modsec-crs") ; do mkdir "/data/${dir}" ; done && \
chown -R root:autoconf /data && \
chmod -R 770 /data && \
chown -R root:autoconf /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /usr/bin/bwcli && \
chown -R root:autoconf INTEGRATION /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /usr/bin/bwcli && \
chmod -R 770 /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb && \
chmod 750 cli/main.py helpers/*.sh /usr/bin/bwcli autoconf/main.py deps/python/bin/*
chmod 750 cli/main.py helpers/*.sh /usr/bin/bwcli autoconf/main.py deps/python/bin/* && \
chmod 660 INTEGRATION
# Fix CVEs
RUN apk add --no-cache "libexpat>=2.6.0-r0"
VOLUME /data /etc/nginx
VOLUME /data
WORKDIR /usr/share/bunkerweb/autoconf

View file

@ -1,7 +1,7 @@
FROM nginx:1.24.0-alpine@sha256:6845649eadc1f0a5dacaf5bb3f01b480ce200ae1249114be11fef9d389196eaf AS builder
FROM nginx:1.24.0-alpine-slim@sha256:9cec4fd40a4e5156b4f4f555ee44a597491b6e8b91380c32b63ed45a4053a763 AS builder
# Install temporary requirements for the dependencies
RUN apk add --no-cache --virtual .build-deps bash autoconf libtool automake geoip-dev g++ gcc curl-dev libxml2-dev pcre-dev make linux-headers musl-dev gd-dev gnupg brotli-dev openssl-dev patch readline-dev yajl yajl-dev yajl-tools py3-pip
RUN apk add --no-cache bash autoconf libtool automake geoip-dev g++ gcc curl-dev libxml2-dev pcre-dev make linux-headers musl-dev gd-dev gnupg brotli-dev openssl-dev patch readline-dev yajl yajl-dev yajl-tools py3-pip
WORKDIR /tmp/bunkerweb/deps
@ -9,27 +9,21 @@ WORKDIR /tmp/bunkerweb/deps
COPY src/deps/misc misc
COPY src/deps/src src
COPY src/deps/deps.json deps.json
COPY src/deps/install.sh install.sh
COPY --chmod=644 src/deps/install.sh install.sh
# Compile and install dependencies
RUN mkdir -p /usr/share/bunkerweb/deps/python && \
chmod +x install.sh && \
bash install.sh
RUN bash install.sh
WORKDIR /usr/share/bunkerweb
# Copy python requirements
COPY src/deps/requirements.txt /tmp/requirements-deps.txt
COPY src/common/gen/requirements.txt deps/requirements.txt
COPY src/common/gen/requirements.txt deps/requirements-gen.txt
# Install python requirements
RUN export MAKEFLAGS="-j$(nproc)" && \
pip install --no-cache-dir --ignore-installed --require-hashes -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python -r deps/requirements.txt
# Clean up temporary dependencies
RUN apk del .build-deps && \
rm -rf /var/cache/apk/*
pip install --no-cache-dir --require-hashes --ignore-installed -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python -r deps/requirements-gen.txt
# Copy files
# can't exclude deps from . so we are copying everything by hand
@ -48,7 +42,7 @@ COPY src/common/utils utils
COPY src/VERSION VERSION
COPY misc/*.ascii misc/
FROM nginx:1.24.0-alpine@sha256:76ca7f6bfe01c3e22e3af85fd37c30149ece3ac2a444973687cab1765abca115
FROM nginx:1.24.0-alpine-slim@sha256:9cec4fd40a4e5156b4f4f555ee44a597491b6e8b91380c32b63ed45a4053a763
# Set default umask to prevent huge recursive chmod increasing the final image size
RUN umask 027
@ -59,13 +53,9 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb
WORKDIR /usr/share/bunkerweb
# Install runtime dependencies, pypi packages, move bwcli, create data folders and set permissions
RUN apk add --no-cache pcre bash python3 yajl && \
RUN apk add --no-cache openssl pcre bash python3 yajl geoip libxml2 libgd && \
cp helpers/bwcli /usr/bin/ && \
mkdir -p /var/tmp/bunkerweb && \
mkdir -p /var/run/bunkerweb && \
mkdir -p /var/log/bunkerweb && \
mkdir -p /var/www/html && \
mkdir -p /etc/bunkerweb && \
mkdir -p /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb /var/www/html && \
mkdir -p /data/cache && ln -s /data/cache /var/cache/bunkerweb && \
for dir in $(echo "pro configs plugins") ; do mkdir -p "/data/${dir}" && ln -s "/data/${dir}" "/etc/bunkerweb/${dir}" ; done && \
for dir in $(echo "pro/plugins configs/http configs/stream configs/server-http configs/server-stream configs/default-server-http configs/default-server-stream configs/modsec configs/modsec-crs") ; do mkdir "/data/${dir}" ; done && \
@ -80,6 +70,8 @@ RUN apk add --no-cache pcre bash python3 yajl && \
# Fix CVEs
RUN apk add --no-cache "curl>=8.5.0-r0" "libcurl>=8.5.0-r0" "libcrypto3>=3.0.12-r4" "libexpat>=2.6.0-r0" "libssl3>=3.0.12-r4" "libwebp>=1.2.4-r3" "libx11>=1.8.7-r0" "nghttp2-libs>=1.51.0-r2"
VOLUME /data /etc/nginx
EXPOSE 8080/tcp 8443/tcp
USER nginx:nginx

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -14,7 +14,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -15,7 +15,19 @@
</div>
<!-- end info --> <div class="core-layout-separator"></div>
{% if pre_render["status"] and pre_render["status"] == "ok" %}
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
<div class="flex justify-center col-span-12">
<p class="text-white">Error during pre rendering</p>
<div class="ml-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
</div>
{% endif %}
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
{% for key, value in pre_render["data"].items() %}

View file

@ -2,6 +2,6 @@ pip==24.0
pip-compile-multi==2.6.3
pip-tools==7.4.1
pip-upgrader==1.4.15
setuptools==69.1.1
setuptools==69.2.0
tomli==2.0.1
wheel==0.42.0
wheel==0.43.0

View file

@ -163,9 +163,9 @@ requests==2.31.0 \
# via
# -r requirements-deps.in
# pip-tools
setuptools==69.1.1 \
--hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \
--hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8
setuptools==69.2.0 \
--hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
--hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
# via pip-upgrader
terminaltables==3.1.10 \
--hash=sha256:ba6eca5cb5ba02bba4c9f4f985af80c54ec3dccf94cfcd190154386255e47543 \
@ -187,15 +187,15 @@ urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
# via requests
wheel==0.42.0 \
--hash=sha256:177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d \
--hash=sha256:c45be39f7882c9d34243236f2d63cbd58039e360f85d0913425fbd7ceea617a8
wheel==0.43.0 \
--hash=sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85 \
--hash=sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81
# via
# -r requirements-deps.in
# pip-tools
zipp==3.17.0 \
--hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
--hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
zipp==3.18.1 \
--hash=sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b \
--hash=sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715
# via
# -r requirements-deps.in
# pip-tools

View file

@ -1,4 +1,4 @@
pip==24.0
pip-tools==7.4.1
setuptools==69.1.1
wheel==0.42.0
setuptools==69.2.0
wheel==0.43.0

View file

@ -36,9 +36,9 @@ pyproject-hooks==1.0.0 \
# via
# -r requirements.in
# pip-tools
setuptools==69.1.1 \
--hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \
--hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8
setuptools==69.2.0 \
--hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
--hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
# via
# build
# pip-tools
@ -49,15 +49,15 @@ tomli==2.0.1 \
# build
# pip-tools
# pyproject-hooks
wheel==0.42.0 \
--hash=sha256:177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d \
--hash=sha256:c45be39f7882c9d34243236f2d63cbd58039e360f85d0913425fbd7ceea617a8
wheel==0.43.0 \
--hash=sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85 \
--hash=sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81
# via
# -r requirements.in
# pip-tools
zipp==3.17.0 \
--hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
--hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
zipp==3.18.1 \
--hash=sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b \
--hash=sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715
# via
# -r requirements.in
# pip-tools

View file

@ -1,28 +1,20 @@
FROM python:3.12.2-alpine3.19@sha256:1a0501213b470de000d8432b3caab9d8de5489e9443c2cc7ccaa6b0aa5c3148e as builder
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev
RUN apk add --no-cache build-base postgresql-dev
# Copy python requirements
COPY src/deps/requirements.txt /tmp/requirements-deps.txt
COPY src/scheduler/requirements.txt /tmp/req/requirements.txt
COPY src/common/gen/requirements.txt /tmp/req/requirements.txt.1
COPY src/common/db/requirements.txt /tmp/req/requirements.txt.2
COPY src/scheduler/requirements.txt /tmp/req/requirements-scheduler.txt
COPY src/common/gen/requirements.txt /tmp/req/requirements-gen.txt
COPY src/common/db/requirements.txt /tmp/req/requirements-db.txt
WORKDIR /usr/share/bunkerweb
RUN mkdir -p deps/python && \
cat /tmp/req/requirements.txt* > deps/requirements.txt && \
rm -rf /tmp/req
# Install python requirements
RUN export MAKEFLAGS="-j$(nproc)" && \
pip install --no-cache-dir --ignore-installed --require-hashes -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python -r deps/requirements.txt
# Remove build dependencies
RUN apk del .build-deps && \
rm -rf /var/cache/apk/*
pip install --no-cache-dir --require-hashes --break-system-packages -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python $(for file in $(ls /tmp/req/requirements*.txt) ; do echo "-r ${file}" ; done | xargs)
# Copy files
# can't exclude specific files/dir from . so we are copying everything by hand
@ -54,22 +46,19 @@ RUN apk add --no-cache bash libgcc libstdc++ libpq openssl libmagic && \
adduser -h /var/cache/nginx -g scheduler -s /bin/sh -G scheduler -D -H -u 101 scheduler && \
cp helpers/bwcli /usr/bin/ && \
echo "Docker" > INTEGRATION && \
mkdir -p /etc/nginx && \
mkdir -p /var/tmp/bunkerweb && \
mkdir -p /var/run/bunkerweb && \
mkdir -p /var/log/bunkerweb && \
mkdir -p /var/www && \
mkdir -p /etc/bunkerweb && \
mkdir -p /etc/nginx /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb /var/www && \
mkdir -p /data/cache && ln -s /data/cache /var/cache/bunkerweb && \
mkdir -p /data/lib && ln -s /data/lib /var/lib/bunkerweb && \
for dir in $(echo "pro configs plugins") ; do mkdir -p "/data/${dir}" && ln -s "/data/${dir}" "/etc/bunkerweb/${dir}" ; done && \
for dir in $(echo "pro/plugins configs/http configs/stream configs/server-http configs/server-stream configs/default-server-http configs/default-server-stream configs/modsec configs/modsec-crs") ; do mkdir "/data/${dir}" ; done && \
chown -R root:scheduler /data /etc/nginx /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb /usr/bin/bwcli && \
chown -R root:scheduler INTEGRATION /data /etc/nginx /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb /usr/bin/bwcli && \
chmod -R 770 /data /etc/nginx /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb && \
find core/*/jobs/* -type f -exec chmod 750 {} \; && \
chmod 750 cli/main.py gen/*.py scheduler/main.py scheduler/entrypoint.sh helpers/*.sh deps/python/bin/* /usr/bin/bwcli && \
chmod 660 INTEGRATION && \
chown root:scheduler INTEGRATION
chmod 660 INTEGRATION
# Cleanup
RUN rm -rf /var/cache/apk/*
COPY --chown=root:scheduler src/bw/misc/asn.mmdb /var/tmp/bunkerweb/asn.mmdb
COPY --chown=root:scheduler src/bw/misc/country.mmdb /var/tmp/bunkerweb/country.mmdb
@ -79,7 +68,7 @@ RUN chmod 770 /var/tmp/bunkerweb/asn.mmdb /var/tmp/bunkerweb/country.mmdb
# Fix CVEs
RUN apk add --no-cache "libexpat>=2.6.0-r0"
VOLUME /data /etc/nginx
VOLUME /data
WORKDIR /usr/share/bunkerweb/scheduler

View file

@ -320,9 +320,9 @@ schedule==1.2.1 \
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
setuptools==69.1.1 \
--hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \
--hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8
setuptools==69.2.0 \
--hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
--hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
# via -r requirements.in
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
@ -332,9 +332,9 @@ urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
# via requests
zipp==3.17.0 \
--hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
--hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
zipp==3.18.1 \
--hash=sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b \
--hash=sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715
# via
# acme
# certbot

View file

@ -1,28 +1,20 @@
FROM python:3.12.2-alpine3.19@sha256:1a0501213b470de000d8432b3caab9d8de5489e9443c2cc7ccaa6b0aa5c3148e as builder
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev file make
RUN apk add --no-cache build-base postgresql-dev
# Copy python requirements
COPY src/deps/requirements.txt /tmp/requirements-deps.txt
COPY src/ui/requirements.txt /tmp/req/requirements.txt
COPY src/common/gen/requirements.txt /tmp/req/requirements.txt.1
COPY src/common/db/requirements.txt /tmp/req/requirements.txt.2
COPY src/ui/requirements.txt /tmp/req/requirements-ui.txt
COPY src/common/gen/requirements.txt /tmp/req/requirements-gen.txt
COPY src/common/db/requirements.txt /tmp/req/requirements-db.txt
WORKDIR /usr/share/bunkerweb
RUN mkdir -p deps/python && \
cat /tmp/req/requirements.txt* > deps/requirements.txt && \
rm -rf /tmp/req
# Install python requirements
RUN export MAKEFLAGS="-j$(nproc)" && \
pip install --no-cache-dir --ignore-installed --require-hashes -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python -r deps/requirements.txt
# Remove build dependencies
RUN apk del .build-deps && \
rm -rf /var/cache/apk/*
pip install --no-cache-dir --require-hashes --break-system-packages -r /tmp/requirements-deps.txt && \
pip install --no-cache-dir --require-hashes --target deps/python $(for file in $(ls /tmp/req/requirements*.txt) ; do echo "-r ${file}" ; done | xargs)
# Copy files
# can't exclude specific files/dir from . so we are copying everything by hand
@ -51,28 +43,22 @@ RUN apk add --no-cache bash && \
addgroup -g 101 ui && \
adduser -h /var/cache/nginx -g ui -s /bin/sh -G ui -D -H -u 101 ui && \
echo "Docker" > INTEGRATION && \
mkdir -p /var/tmp/bunkerweb && \
mkdir -p /var/run/bunkerweb && \
mkdir -p /etc/bunkerweb && \
mkdir -p /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb /var/www && \
mkdir -p /data/cache && ln -s /data/cache /var/cache/bunkerweb && \
mkdir -p /data/lib && ln -s /data/lib /var/lib/bunkerweb && \
mkdir -p /var/log/bunkerweb/ && \
for dir in $(echo "pro configs plugins") ; do mkdir -p "/data/${dir}" && ln -s "/data/${dir}" "/etc/bunkerweb/${dir}" ; done && \
for dir in $(echo "pro/plugins configs/http configs/stream configs/server-http configs/server-stream configs/default-server-http configs/default-server-stream configs/modsec configs/modsec-crs") ; do mkdir "/data/${dir}" ; done && \
chown -R root:ui /data && \
chmod -R 770 /data && \
chown -R root:ui INTEGRATION /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb && \
chmod 770 /var/cache/bunkerweb /var/lib/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb && \
chown -R root:ui INTEGRATION /data /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb && \
chmod 770 /data /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb && \
chmod 750 gen/*.py ui/*.py ui/src/*.py deps/python/bin/* helpers/*.sh && \
chmod 660 INTEGRATION && \
chown root:ui INTEGRATION && \
ln -s /proc/1/fd/1 /var/log/bunkerweb/ui-access.log && \
ln -s /proc/1/fd/2 /var/log/bunkerweb/ui.log
# Fix CVEs
RUN apk add --no-cache "libexpat>=2.6.0-r0"
VOLUME /data /etc/nginx
VOLUME /data
EXPOSE 7000

View file

@ -283,7 +283,7 @@ wtforms==3.1.2 \
--hash=sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07 \
--hash=sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9
# via flask-wtf
zipp==3.17.0 \
--hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
--hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
zipp==3.18.1 \
--hash=sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b \
--hash=sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715
# via importlib-metadata

File diff suppressed because one or more lines are too long

View file

@ -1,12 +1,11 @@
class Ping {
constructor(
url = location.href,
url = `${location.origin}${location.pathname}`,
statusTextEl = null,
statusColorEl = null,
key_to_check = "ping",
) {
this.url = url;
this.data = data;
this.statusColorEl = statusColorEl;
this.statusTextEl = statusTextEl;
this.key_to_check = key_to_check;
@ -14,30 +13,27 @@ class Ping {
}
init() {
window.addEventListener("DOMContentLoaded", () => {
this.createAlertEl();
this.updateAlert("fetch");
this.createAlertEl();
this.updateAlert("fetch");
// Case no status element
if (!this.statusColorEl || !this.statusTextEl)
return this.updateAlert("error");
// Case no status element
if (!this.statusColorEl || !this.statusTextEl)
return this.updateAlert("error");
fetch(this.url, {
method: "POST",
headers: {
"X-CSRFToken": document.querySelector('input[name="csrf_token"]')
.value,
},
fetch(this.url, {
method: "POST",
headers: {
"X-CSRFToken": document.querySelector('input[name="csrf_token"]').value,
},
})
.then((res) => res.json())
.then((res) => {
// Update data
this.updateEl(res.data);
})
.then((res) => res.json())
.then((res) => {
// Update data
this.updateEl(res);
})
.catch((error) => {
this.updateAlert("error");
});
});
.catch((error) => {
this.updateAlert("error");
});
}
createAlertEl() {

View file

@ -243,7 +243,7 @@
}
.core-card-wrap-logo {
@apply flex justify-start center;
@apply flex justify-start items-center;
}
.core-card-text {

View file

@ -12,7 +12,7 @@
<!-- stats card -->
<a href="{{ card['link'] }}"
class="home-card"
target="_blank"
{% if card['link'].startswith('http') %} target="_blank" {% endif %}
rel="noopener">
<!-- text -->
<div>

View file

@ -72,9 +72,9 @@ idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via anyio
pydantic==2.6.3 \
--hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \
--hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f
pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via fastapi
pydantic-core==2.16.3 \
--hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \

View file

@ -160,9 +160,9 @@ requests==2.31.0 \
# via requests
# The following packages are considered to be unsafe in a requirements file:
setuptools==69.1.1 \
--hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \
--hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8
setuptools==69.2.0 \
--hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
--hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
# via -r requirements.in
urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \

View file

@ -72,9 +72,9 @@ idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via anyio
pydantic==2.6.3 \
--hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \
--hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f
pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via fastapi
pydantic-core==2.16.3 \
--hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \

View file

@ -72,9 +72,9 @@ idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via anyio
pydantic==2.6.3 \
--hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \
--hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f
pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via fastapi
pydantic-core==2.16.3 \
--hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \

View file

@ -160,9 +160,9 @@ requests==2.31.0 \
# via requests
# The following packages are considered to be unsafe in a requirements file:
setuptools==69.1.1 \
--hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \
--hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8
setuptools==69.2.0 \
--hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
--hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
# via -r requirements.in
urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \

View file

@ -192,9 +192,9 @@ outcome==1.3.0.post0 \
--hash=sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8 \
--hash=sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b
# via trio
pydantic==2.6.3 \
--hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \
--hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f
pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via fastapi
pydantic-core==2.16.3 \
--hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \

View file

@ -72,9 +72,9 @@ idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via anyio
pydantic==2.6.3 \
--hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \
--hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f
pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via fastapi
pydantic-core==2.16.3 \
--hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \

View file

@ -170,9 +170,9 @@ idna==3.6 \
# via
# anyio
# requests
pydantic==2.6.3 \
--hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \
--hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f
pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via fastapi
pydantic-core==2.16.3 \
--hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \

View file

@ -72,9 +72,9 @@ idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via anyio
pydantic==2.6.3 \
--hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \
--hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f
pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via fastapi
pydantic-core==2.16.3 \
--hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \

View file

@ -160,9 +160,9 @@ requests==2.31.0 \
# via requests
# The following packages are considered to be unsafe in a requirements file:
setuptools==69.1.1 \
--hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \
--hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8
setuptools==69.2.0 \
--hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
--hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
# via -r requirements.in
urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \