Merge branch 'source' into issue-51

This commit is contained in:
Mark van Holsteijn 2021-07-17 20:06:08 +02:00
commit 92b1e57289
8 changed files with 144 additions and 57 deletions

View file

@ -11,9 +11,6 @@ name: Snyk Container
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '23 7 * * 5'

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
Dockerfile.edge

View file

@ -1,19 +1,32 @@
FROM alpine:3.14
ARG RELEASE=1.3.5
MAINTAINER PrivateBin <support@privatebin.org>
ARG ALPINE_PACKAGES="php8-pdo_mysql php8-pdo_pgsql php8-openssl"
ARG COMPOSER_PACKAGES=google/cloud-storage
ARG PBURL=https://github.com/PrivateBin/PrivateBin/
ARG RELEASE=1.3.5
ENV RELEASE ${RELEASE}
ENV PBURL https://github.com/PrivateBin/PrivateBin/
ENV S6_READ_ONLY_ROOT 1
ENV CONFIG_PATH /srv/cfg
ENV CONFIG_PATH=/srv/cfg S6_READ_ONLY_ROOT=1
LABEL org.opencontainers.image.authors=support@privatebin.org \
org.opencontainers.image.vendor=PrivateBin \
org.opencontainers.image.documentation=https://github.com/PrivateBin/docker-nginx-fpm-alpine/blob/master/README.md \
org.opencontainers.image.source=https://github.com/PrivateBin/docker-nginx-fpm-alpine \
org.opencontainers.image.licenses=zlib-acknowledgement \
org.opencontainers.image.version=${RELEASE}
RUN \
# Prepare composer dependencies
ALPINE_PACKAGES="$(echo ${ALPINE_PACKAGES} | sed 's/,/ /g')" ;\
ALPINE_COMPOSER_PACKAGES="" ;\
if [ -n "${COMPOSER_PACKAGES}" ] ; then \
ALPINE_COMPOSER_PACKAGES="php8 php8-curl php8-mbstring php8-phar" ;\
RAWURL="$(echo ${PBURL} | sed s/github.com/raw.githubusercontent.com/)" ;\
fi \
# Install dependencies
apk add --no-cache gnupg nginx php8 php8-curl php8-fpm php8-json php8-gd \
php8-mbstring php8-opcache php8-pdo_mysql php8-pdo_pgsql php8-phar \
s6-overlay tzdata git \
&& apk upgrade --no-cache \
&& apk add --no-cache gnupg nginx php8-fpm php8-json php8-gd php8-opcache \
s6-overlay tzdata ${ALPINE_PACKAGES} ${ALPINE_COMPOSER_PACKAGES} \
# Remove (some of the) default nginx config
&& rm -f /etc/nginx.conf /etc/nginx/http.d/default.conf /etc/php8/php-fpm.d/www.conf \
&& rm -rf /etc/nginx/sites-* \
@ -25,27 +38,25 @@ RUN \
&& wget -qO - https://privatebin.info/key/release.asc | gpg2 --import - \
&& rm -rf /var/www/* \
&& cd /tmp \
&& if expr "${RELEASE}" : '[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}$' >/dev/null ; then \
echo "getting release ${RELEASE}"; \
wget -qO ${RELEASE}.tar.gz.asc ${PBURL}releases/download/${RELEASE}/PrivateBin-${RELEASE}.tar.gz.asc \
&& wget -q ${PBURL}archive/${RELEASE}.tar.gz \
&& gpg2 --verify ${RELEASE}.tar.gz.asc ; \
else \
echo "getting tarball for ${RELEASE}"; \
git clone ${PBURL%%/}.git -b ${RELEASE}; \
(cd $(basename ${PBURL}) && git archive --prefix ${RELEASE}/ --format tgz ${RELEASE} > /tmp/${RELEASE}.tar.gz); \
fi \
&& wget -qO composer-setup.php https://getcomposer.org/installer \
&& ln -s $(which php8) /usr/local/bin/php \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& wget -qO $RELEASE.tar.gz.asc ${PBURL}releases/download/${RELEASE}/PrivateBin-${RELEASE}.tar.gz.asc \
&& wget -q ${PBURL}archive/${RELEASE}.tar.gz \
&& gpg2 --verify ${RELEASE}.tar.gz.asc \
&& if [ -n "${COMPOSER_PACKAGES}" ] ; then \
wget -qO composer-installer.php https://getcomposer.org/installer \
&& ln -s $(which php8) /usr/local/bin/php \
&& php composer-installer.php --install-dir=/usr/local/bin --filename=composer ;\
fi \
&& cd /var/www \
&& tar -xzf /tmp/${RELEASE}.tar.gz --strip 1 \
&& wget -q $(echo ${PBURL} | sed s/github.com/raw.githubusercontent.com/)${RELEASE}/composer.json \
&& wget -q $(echo ${PBURL} | sed s/github.com/raw.githubusercontent.com/)${RELEASE}/composer.lock \
&& composer remove --dev --no-update phpunit/phpunit \
&& composer require --no-update google/cloud-storage \
&& composer update --no-dev --optimize-autoloader \
&& rm *.md cfg/conf.sample.php composer.* /usr/local/bin/* \
&& if [ -n "${COMPOSER_PACKAGES}" ] ; then \
wget -q ${RAWURL}${RELEASE}/composer.json \
&& wget -q ${RAWURL}${RELEASE}/composer.lock \
&& composer remove --dev --no-update phpunit/phpunit \
&& composer require --no-update ${COMPOSER_PACKAGES} \
&& composer update --no-dev --optimize-autoloader \
rm composer.* /usr/local/bin/* ;\
fi \
&& rm *.md cfg/conf.sample.php \
&& mv cfg lib tpl vendor /srv \
&& mkdir -p /srv/data \
&& sed -i "s#define('PATH', '');#define('PATH', '/srv/');#" index.php \
@ -58,7 +69,7 @@ RUN \
&& chmod o+rwx /run /var/lib/nginx /var/lib/nginx/tmp \
# Clean up
&& rm -rf "${GNUPGHOME}" /tmp/* \
&& apk del gnupg php8 php8-curl php8-mbstring php8-phar git
&& apk del gnupg ${ALPINE_COMPOSER_PACKAGES}
COPY etc/ /etc/

7
README.fs.md Normal file
View file

@ -0,0 +1,7 @@
# PrivateBin on Nginx, php-fpm & Alpine with file based storage backend
**PrivateBin** is a minimalist, open source online [pastebin](https://en.wikipedia.org/wiki/Pastebin) where the server has zero knowledge of pasted data. Data is encrypted and decrypted in the browser using 256bit AES in [Galois Counter mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode).
## Image variants
This is an image optimized for the file based storage backend. Please see the [generic image](https://hub.docker.com/r/privatebin/nginx-fpm-alpine) for details on how to use this image, other images variants and the different tags.

7
README.gcs.md Normal file
View file

@ -0,0 +1,7 @@
# PrivateBin on Nginx, php-fpm & Alpine with Google Cloud Storage backend
**PrivateBin** is a minimalist, open source online [pastebin](https://en.wikipedia.org/wiki/Pastebin) where the server has zero knowledge of pasted data. Data is encrypted and decrypted in the browser using 256bit AES in [Galois Counter mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode).
## Image variants
This is an image optimized for the Google Cloud Storage backend. Please see the [generic image](https://hub.docker.com/r/privatebin/nginx-fpm-alpine) for details on how to use this image, other images variants and the different tags.

View file

@ -1,8 +1,26 @@
# PrivateBin on nginx, php-fpm & alpine
# PrivateBin on Nginx, php-fpm & Alpine
**PrivateBin** is a minimalist, open source online [pastebin](https://en.wikipedia.org/wiki/Pastebin) where the server has zero knowledge of pasted data. Data is encrypted and decrypted in the browser using 256bit AES in [Galois Counter mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode).
This repository contains the Dockerfile and resources needed to create a docker image with a pre-installed PrivateBin instance in a secure default configuration. The images are based on the docker hub alpine image, extended with the GD module required to generate discussion avatars and the Nginx webserver to serve static JavaScript libraries, CSS & the logos. All logs of php-fpm and Nginx (access & errors) are forwarded to docker logs.
This repository contains the Dockerfile and resources needed to create a docker image with a pre-installed PrivateBin instance in a secure default configuration. The images are based on the docker hub Alpine image, extended with the GD module required to generate discussion avatars and the Nginx webserver to serve static JavaScript libraries, CSS & the logos. All logs of php-fpm and Nginx (access & errors) are forwarded to docker logs.
## Image variants
This is the all-in-one image that can be used with any storage backend supported by PrivateBin: File based storage, database or Google Cloud Storage. We also offer dedicated images for each backend:
- [Image for file based storage](https://hub.docker.com/r/privatebin/fs)
- [Image for PostgreSQL, MariaDB & MySQL](https://hub.docker.com/r/privatebin/pdo)
- [Image for Google Cloud Storage](https://hub.docker.com/r/privatebin/gcs)
## Image tags
All images contain a release version of PrivateBin and are offered with the following tags:
- `latest` is an alias of the latest pushed image, usually the same as `nightly`, but excluding `edge`
- `nightly` is the latest released PrivateBin version on an upgraded Alpine release image, including the latest changes from the docker image repository
- `edge` is the latest released PrivateBin version on an upgraded Alpine edge image
- `1.3.5` contains PrivateBin version 1.3.5 on the latest tagged release of the docker image repository - gets updated when important security fixes are released for Alpine or upon new Alpine releases
- `1.3.5-...` are provided for selecting specific, immutable images
If you update your images automatically via pulls, the `nightly` or `latest` are recommended. If you prefer to have control and reproducability or use a form of orchestration, the numeric tags are probably preferable. The `edge` tag offers a preview of software in future Alpine releases and as an early warning system to detect image build issues in these.
## Running the image
@ -14,14 +32,14 @@ docker run -d --restart="always" --read-only -p 8080:8080 -v $PWD/privatebin-dat
The parameters in detail:
- `-v $PWD/privatebin-data:/srv/data` - replace `$PWD/privatebin-data` with the path to the folder on your system, where the pastes and other service data should be persisted. This guarantees that your pastes aren't lost after you stop and restart the image or when you replace it. May be skipped if you just want to test the image.
- `-v $PWD/privatebin-data:/srv/data` - replace `$PWD/privatebin-data` with the path to the folder on your system, where the pastes and other service data should be persisted. This guarantees that your pastes aren't lost after you stop and restart the image or when you replace it. May be skipped if you just want to test the image or use database or Google Cloud Storage backend.
- `-p 8080:8080` - The Nginx webserver inside the container listens on port 8080, this parameter exposes it on your system on port 8080. Be sure to use a reverse proxy for HTTPS termination in front of it in production environments.
- `--read-only` - This image supports running in read-only mode. Using this reduces the attack surface slightly, since an exploit in one of the images services can't overwrite arbitrary files in the container. Only /tmp, /var/tmp, /var/run & /srv/data may be written into.
- `-d` - launches the container in the background. You can use `docker ps` and `docker logs` to check if the container is alive and well.
- `--restart="always"` - restart the container if it crashes, mainly useful for production setups
> Note that the volume mounted must be owned by UID 65534 / GID 82. If you run the container in a docker instance with "userns-remap" you need to add your subuid/subgid range to these numbers.
>
>
> Note, too, that this image exposes the same service on port 80, for backwards compatibility with older versions of the image. To use port 80 with the current image, you either need to have a filesystem with extended attribute support so the nginx binary can be granted the capability to bind to ports below 1024 as non-root user or you need to start the image with user id 0 (root) using the parameter `-u 0`.
### Custom configuration
@ -129,4 +147,3 @@ Nginx is required to serve static files and caches them, too. Requests to the in
The Nginx setup supports only HTTP, so make sure that you run a reverse proxy in front of this for HTTPS offloading and reducing the attack surface on your TLS stack. The Nginx in this image is set up to deflate/gzip text content.
During the build of the image the PrivateBin release archive and the s6 overlay binaries are downloaded from Github. All the downloaded Alpine packages, s6 overlay binaries and the PrivateBin archive are validated using cryptographic signatures to ensure they have not been tempered with, before deploying them in the image.

7
README.pdo.md Normal file
View file

@ -0,0 +1,7 @@
# PrivateBin on Nginx, php-fpm & Alpine with PostgreSQL, MariaDB & MySQL backend
**PrivateBin** is a minimalist, open source online [pastebin](https://en.wikipedia.org/wiki/Pastebin) where the server has zero knowledge of pasted data. Data is encrypted and decrypted in the browser using 256bit AES in [Galois Counter mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode).
## Image variants
This is an image optimized for PostgreSQL, MariaDB & MySQL storage backends. Please see the [generic image](https://hub.docker.com/r/privatebin/nginx-fpm-alpine) for details on how to use this image, other images variants and the different tags.

View file

@ -4,29 +4,69 @@
# accessing an uninitialized variable and print commands before executing them
set -euxo pipefail
IMAGE=privatebin/nginx-fpm-alpine
QEMU_PLATFORMS=linux/amd64,linux/386,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le
VERSION=${GITHUB_REF##*/}
EVENT=$1
[ "${EVENT}" = "schedule" ] && VERSION=nightly
BUILDX_ARGS="--tag ${IMAGE}:latest \
--tag ${IMAGE}:${VERSION} --tag ${IMAGE}:${VERSION%%-*} \
--platform ${QEMU_PLATFORMS} ."
BUILDX_EDGE_ARGS="--tag ${IMAGE}:edge \
--platform ${QEMU_PLATFORMS} -f Dockerfile-edge ."
build_image() {
local PUSH
PUSH=$1
shift 1
# build images
docker build --no-cache --pull --output "type=image,push=false" ${BUILDX_ARGS}
sed 's/^FROM alpine:.*$/FROM alpine:edge/' Dockerfile > Dockerfile-edge
docker build --no-cache --pull --output "type=image,push=false" ${BUILDX_EDGE_ARGS}
docker buildx build \
--platform linux/amd64,linux/386,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le \
--output type=image,push="$PUSH" \
--pull \
--no-cache \
--progress plain \
$@ \
.
}
# push cached images
if [ "${EVENT}" != "pull_request" ] && ([ "${GITHUB_REF}" != "refs/heads/master" ] || [ "${EVENT}" = "schedule" ])
then
printenv DOCKER_PASSWORD | docker login --username "${DOCKER_USERNAME}" --password-stdin
docker build --output "type=image,push=true" ${BUILDX_ARGS}
docker build --output "type=image,push=true" ${BUILDX_EDGE_ARGS}
rm -f ${HOME}/.docker/config.json
fi
docker_login() {
printenv DOCKER_PASSWORD | docker login \
--username "$DOCKER_USERNAME" \
--password-stdin
}
image_build_arguments() {
cat<<!
privatebin/fs --build-arg ALPINE_PACKAGES= --build-arg COMPOSER_PACKAGES=
privatebin/pdo --build-arg ALPINE_PACKAGES=php8-pdo_mysql,php8-pdo_pgsql --build-arg COMPOSER_PACKAGES=
privatebin/gcs --build-arg ALPINE_PACKAGES=php8-openssl
privatebin/nginx-fpm-alpine
!
}
is_image_push_required() {
[ "$EVENT" != pull_request ] && { \
[ "$GITHUB_REF" != refs/heads/master ] || \
[ "$EVENT" = schedule ]
}
}
main() {
local PUSH TAG IMAGE BUILD_ARGS
if [ "$EVENT" = schedule ] ; then
TAG=nightly
else
TAG=${GITHUB_REF##*/}
fi
if is_image_push_required ; then
PUSH=true
docker_login
else
PUSH=false
fi
sed -e 's/^FROM alpine:.*$/FROM alpine:edge/' Dockerfile > Dockerfile.edge
image_build_arguments | while read -r IMAGE BUILD_ARGS ; do
build_image $PUSH --tag "$IMAGE:latest" --tag "$IMAGE:$TAG" --tag "${IMAGE}:${TAG%%-*}" "$BUILD_ARGS"
build_image $PUSH -f Dockerfile.edge --tag "$IMAGE:edge" "$BUILD_ARGS"
done
rm -f Dockerfile.edge "$HOME/.docker/config.json"
}
[ "$(basename "$0")" = 'buildx.sh' ] && main