diff --git a/.dockerignore b/.dockerignore index e91689fa..95fb3c5d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,5 @@ README.md LICENCE .git docker-compose.yml +Dockerfile +.github diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..2c7d1708 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..f58ecd39 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,18 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 30 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security + - keep-alive +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + any activity for the last 30 days. It will be closed if no further activity + occurs during the next 7 days. Thank you for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml new file mode 100644 index 00000000..aa4dcbcf --- /dev/null +++ b/.github/workflows/master.yml @@ -0,0 +1,125 @@ +name: "master" + +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Set up CI Image Metadata + id: docker_meta_ci + uses: docker/metadata-action@v5 + with: + images: solidnerd/bookstack-dev + tags: | + type=sha + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + push: false + tags: | + ${{ steps.docker_meta_ci.outputs.tags }} + labels: ${{ steps.docker_meta_ci.outputs.labels }} + cache-from: type=registry,ref=solidnerd/bookstack-dev:master + outputs: type=docker,dest=/tmp/image-bookstack.tar + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: image-bookstack-master + path: /tmp/image-bookstack.tar + if-no-files-found: warn + + e2e: + runs-on: ubuntu-latest + needs: build + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: image-bookstack-master + path: /tmp + + - name: Load Docker image + run: | + docker load --input /tmp/image-bookstack.tar + docker image ls -a + + push: + runs-on: ubuntu-24.04 + needs: e2e + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Set up Docker Hub Image Metadata + id: docker_meta + uses: docker/metadata-action@v5 + with: + images: solidnerd/bookstack,ghcr.io/solidnerd/docker-bookstack + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}}.{{minor}}.{{patch}} + # Get "master" for master-branch changes + type=ref,event=branch + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: image-bookstack-master + path: /tmp + if-no-files-found: warn + - name: Load Docker image + run: | + docker load --input /tmp/image-bookstack.tar + docker image ls -a + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.CR_PAT }} + + - name: Build and Push + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + push: ${{ github.event_name != 'pull_request' }} + tags: | + ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + cache-from: type=registry,ref=solidnerd/bookstack-dev:${{ github.sha }} + cache-to: type=registry,ref=solidnerd/bookstack-dev:${{ github.sha }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 00000000..d1bf1e42 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,67 @@ +name: "PR" + +on: + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Docker meta ci + id: docker_meta_ci + uses: docker/metadata-action@v5 + with: + images: solidnerd/bookstack-dev + tags: | + type=sha + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Dev + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + push: ${{ github.event_name != 'pull_request' }} + tags: | + ${{ steps.docker_meta_ci.outputs.tags }} + labels: ${{ steps.docker_meta_ci.outputs.labels }} + cache-from: type=registry,ref=solidnerd/bookstack-dev:master + cache-to: type=inline + outputs: type=docker,dest=/tmp/image-bookstack.tar + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: image-bookstack + path: /tmp/image-bookstack.tar + if-no-files-found: warn + + e2e: + runs-on: ubuntu-latest + needs: build + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: image-bookstack + path: /tmp + if-no-files-found: warn + + - name: Load Docker image + run: | + docker load --input /tmp/image-bookstack.tar + docker image ls -a + + - name: Execute End-to-End Test + run: make e2e diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..c0f69e6b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,155 @@ +name: release +on: + push: + # Sequence of patterns matched against refs/tags + tags: + - '*' # Push on all tag events + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Set up CI Image Metadata + id: docker_meta_ci + uses: docker/metadata-action@v5 + with: + images: solidnerd/bookstack-dev + tags: | + type=sha + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Dev + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + push: false + tags: | + ${{ steps.docker_meta_ci.outputs.tags }} + labels: ${{ steps.docker_meta_ci.outputs.labels }} + cache-from: type=registry,ref=solidnerd/bookstack-dev:master + outputs: type=docker,dest=/tmp/image-bookstack.tar + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: image-bookstack-master + path: /tmp/image-bookstack.tar + + e2e: + runs-on: ubuntu-latest + needs: build + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: image-bookstack-master + path: /tmp + + - name: Load Docker image + run: | + docker load --input /tmp/image-bookstack.tar + docker image ls -a + + push: + runs-on: ubuntu-24.04 + needs: e2e + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Set up Docker Hub Image Metadata + id: docker_meta + uses: docker/metadata-action@v5 + with: + images: | + solidnerd/bookstack + ghcr.io/solidnerd/docker-bookstack + # Blanket-enable "latest" tagging for all of the releases that make it + # this far, as SemVer's pre-release tag is used as a build indicator + # for this project. Note that _actual_ semver build info is not used, + # as it is discarded by almost everything that consumes SemVer (as it + # should be). + flavor: | + latest=true + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}}.{{minor}}.{{patch}} + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: image-bookstack-master + path: /tmp + + - name: Load Docker image + run: | + docker load --input /tmp/image-bookstack.tar + docker image ls -a + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.CR_PAT }} + + - name: Build and Push master + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + push: ${{ github.event_name != 'pull_request' }} + tags: | + ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + cache-from: type=registry,ref=solidnerd/bookstack-dev:${{ github.sha }} + cache-to: type=registry,ref=solidnerd/bookstack-dev:${{ github.sha }} + + create-release: + runs-on: ubuntu-24.04 + needs: push + steps: + # To use this repository's private action, you must check out the repository + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Generate changelog + id: changelog + uses: metcalfc/changelog-generator@v4.6.2 + with: + myToken: ${{ secrets.GITHUB_TOKEN }} + + - name: Create Release + id: create_release + uses: softprops/action-gh-release@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + body: ${{ steps.changelog.outputs.changelog }} + draft: false + prerelease: false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 65037c47..00000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -sudo: required - -services: - - docker - -before_install: - - docker build -t solidnerd/bookstack:$(cat VERSION) . - -install: - - docker-compose up -d - - sleep 30 - -script: - - curl -sSf http://localhost:8080/login > /dev/null - -after_failure: - - timeout 3s docker-compose logs bookstack mysql diff --git a/Dockerfile b/Dockerfile index 0950bf22..3dad8686 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,79 @@ -FROM php:7.1-apache-stretch - -ENV BOOKSTACK=BookStack \ - BOOKSTACK_VERSION=0.22.0 \ - BOOKSTACK_HOME="/var/www/bookstack" - -RUN apt-get update && apt-get install -y git zlib1g-dev libfreetype6-dev libjpeg62-turbo-dev libmcrypt-dev libpng-dev wget libldap2-dev libtidy-dev \ - && docker-php-ext-install pdo pdo_mysql mbstring zip tidy \ - && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \ - && docker-php-ext-install ldap \ - && docker-php-ext-configure gd --with-freetype-dir=usr/include/ --with-jpeg-dir=/usr/include/ \ - && docker-php-ext-install gd \ - && cd /var/www && curl -sS https://getcomposer.org/installer | php \ - && mv /var/www/composer.phar /usr/local/bin/composer \ - && wget https://github.com/ssddanbrown/BookStack/archive/v${BOOKSTACK_VERSION}.tar.gz -O ${BOOKSTACK}.tar.gz \ - && tar -xf ${BOOKSTACK}.tar.gz && mv BookStack-${BOOKSTACK_VERSION} ${BOOKSTACK_HOME} && rm ${BOOKSTACK}.tar.gz \ - && cd $BOOKSTACK_HOME && composer install \ - && chown -R www-data:www-data $BOOKSTACK_HOME \ - && apt-get -y autoremove \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* /var/tmp/* /etc/apache2/sites-enabled/000-*.conf +FROM alpine:3 AS bookstack +ENV BOOKSTACK_VERSION=v25.05.1 +RUN apk add --no-cache curl tar +RUN set -x; \ + curl -SL -o bookstack.tar.gz https://github.com/BookStackApp/BookStack/archive/${BOOKSTACK_VERSION}.tar.gz \ + && mkdir -p /bookstack \ + && tar xvf bookstack.tar.gz -C /bookstack --strip-components=1 \ + && rm bookstack.tar.gz + +FROM php:8.4-apache-bookworm AS final +RUN set -x; \ + apt-get update \ + && apt-get install -y --no-install-recommends \ + git \ + zlib1g-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libmcrypt-dev \ + libpng-dev \ + libldap2-dev \ + libtidy-dev \ + libxml2-dev \ + fontconfig \ + fonts-freefont-ttf \ + wget \ + tar \ + curl \ + libzip-dev \ + unzip \ + && docker-php-ext-install -j$(nproc) dom pdo pdo_mysql zip tidy \ + && docker-php-ext-configure ldap \ + && docker-php-ext-install -j$(nproc) ldap \ + && docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \ + && docker-php-ext-install -j$(nproc) gd + +RUN a2enmod rewrite remoteip; \ + { \ + echo RemoteIPHeader X-Real-IP ; \ + echo RemoteIPTrustedProxy 10.0.0.0/8 ; \ + echo RemoteIPTrustedProxy 172.16.0.0/12 ; \ + echo RemoteIPTrustedProxy 192.168.0.0/16 ; \ + } > /etc/apache2/conf-available/remoteip.conf; \ + a2enconf remoteip + +RUN set -ex; \ + sed -i "s/Listen 80/Listen 8080/" /etc/apache2/ports.conf; \ + sed -i "s/VirtualHost *:80/VirtualHost *:8080/" /etc/apache2/sites-available/*.conf + +COPY bookstack.conf /etc/apache2/sites-available/000-default.conf + +COPY --from=bookstack --chown=33:33 /bookstack/ /var/www/bookstack/ + +ARG COMPOSER_VERSION=2.7.6 +RUN set -x; \ + cd /var/www/bookstack \ + && curl -sS https://getcomposer.org/installer | php -- --version=$COMPOSER_VERSION \ + && /var/www/bookstack/composer.phar install -v -d /var/www/bookstack/ \ + && rm -rf /var/www/bookstack/composer.phar /root/.composer \ + && chown -R www-data:www-data /var/www/bookstack COPY php.ini /usr/local/etc/php/php.ini -COPY bookstack.conf /etc/apache2/sites-enabled/bookstack.conf -RUN a2enmod rewrite +COPY docker-entrypoint.sh /bin/docker-entrypoint.sh + +WORKDIR /var/www/bookstack -COPY docker-entrypoint.sh / +# www-data +USER 33 -WORKDIR $BOOKSTACK_HOME +VOLUME ["/var/www/bookstack/public/uploads","/var/www/bookstack/storage/uploads"] -EXPOSE 80 +ENV RUN_APACHE_USER=www-data \ + RUN_APACHE_GROUP=www-data -VOLUME ["$BOOKSTACK_HOME/public/uploads","$BOOKSTACK_HOME/public/storage"] +EXPOSE 8080 -ENTRYPOINT ["/docker-entrypoint.sh"] +ENTRYPOINT ["/bin/docker-entrypoint.sh"] ARG BUILD_DATE ARG VCS_REF diff --git a/LICENSE b/LICENSE index 734bbebc..c2de2d01 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017 Niclas Mietz +Copyright (c) 2020 Niclas Mietz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..ded68cbf --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +DOCKER_RELEASE_REG=solidnerd +DOCKER_IMAGE=bookstack +DOCKER_IMAGE_DEV=${DOCKER_IMAGE}-dev +DOCKER_INTERNAL_TAG := "sha-$(shell git rev-parse --short HEAD)" +DOCKER_RELEASE_TAG := $(shell git describe) +BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") +VCS_URL := https://github.com/solidnerd/docker-bookstack + +.PHONY: build push pull release + +build: + docker image build . \ + -t $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE_DEV):$(DOCKER_INTERNAL_TAG) \ + --build-arg VCS_REF=$(DOCKER_INTERNAL_TAG) \ + --build-arg BUILD_DATE=$(BUILD_DATE) \ + --build-arg VCS_URL=$(VCS_URL) + +push-dev: + docker push $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE_DEV):$(DOCKER_INTERNAL_TAG) + +pull: + docker pull $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE_DEV):$(DOCKER_INTERNAL_TAG) + +release: + docker tag $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE_DEV):$(DOCKER_INTERNAL_TAG) $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE):$(DOCKER_RELEASE_TAG) + docker tag $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE_DEV):$(DOCKER_INTERNAL_TAG) $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE):latest + +push-release: + docker push $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE):$(DOCKER_RELEASE_TAG) + docker push $(DOCKER_RELEASE_REG)/$(DOCKER_IMAGE):latest + + +e2e: + @BOOKSTACK_IMAGE="$(DOCKER_RELEASE_REG)/${DOCKER_IMAGE_DEV}:${DOCKER_INTERNAL_TAG}" docker compose -f docker-compose.test.yml up -d + @BOOKSTACK_IMAGE="$(DOCKER_RELEASE_REG)/${DOCKER_IMAGE_DEV}:${DOCKER_INTERNAL_TAG}" docker compose -f docker-compose.test.yml run --rm sut + @BOOKSTACK_IMAGE="$(DOCKER_RELEASE_REG)/${DOCKER_IMAGE_DEV}:${DOCKER_INTERNAL_TAG}" docker compose -f docker-compose.test.yml down -v + diff --git a/README.md b/README.md index 908b21c4..1e47cf6b 100644 --- a/README.md +++ b/README.md @@ -1,74 +1,117 @@ -## Docker Image For [BookStack](https://github.com/ssddanbrown/BookStack) +# Docker Image For [BookStack](https://github.com/ssddanbrown/BookStack) -[![Build Status](https://travis-ci.org/solidnerd/docker-bookstack.svg?branch=master)](https://travis-ci.org/solidnerd/docker-bookstack) [![](https://images.microbadger.com/badges/image/solidnerd/bookstack.svg)](https://microbadger.com/images/solidnerd/bookstack "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/commit/solidnerd/bookstack.svg)](https://microbadger.com/images/solidnerd/bookstack "Get your own commit badge on microbadger.com") [![](https://images.microbadger.com/badges/version/solidnerd/bookstack.svg)](https://microbadger.com/images/solidnerd/bookstack "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/license/solidnerd/bookstack.svg)](https://microbadger.com/images/solidnerd/bookstack "Get your own license badge on microbadger.com") +![Build Status](https://img.shields.io/github/actions/workflow/status/solidnerd/docker-bookstack/master.yml) +![Latest release](https://img.shields.io/github/v/tag/solidnerd/docker-bookstack?label=Latest%20release) +![GitHub contributors](https://img.shields.io/github/contributors/solidnerd/docker-bookstack) -## Current Version: [0.22.0](https://github.com/SolidNerd/docker-bookstack/blob/master/Dockerfile) +## Changes -### Changes -In 0.12.2 we removed `DB_PORT` . You can now specify the port via `DB_HOST` like `DB_HOST=mysql:3306` +Users of version 24.2.3 should switch to 24.2.3-1 (or higher); a maintainer +erroneously set image tag 24.2.3 to use 23.2.3 as the release. + +Versions higher than 23.6.2 no longer use an in-container `.env` file for +environment variable management. Instead, the preferred approach is to manage +them directly with the container runtime (e.g. Docker's `-e`). This is to +simplify troubleshooting if and when errors occur. The most important change is +that `${APP_KEY}` is no longer provided for you, instead it is up to the +operator to ensure this value is present. Versions prior to this supplied +`${APP_KEY}` (with a default of `SomeRandomStringWith32Characters`. A full +reference of available environment variables is available in the [Bookstack +repository](https://github.com/BookStackApp/BookStack/blob/development/.env.example.complete) + +The version 23.6.0 is broken due to a bad `.env` configuration created by the +entrypoint script. This is fixed in version 23.6.0-1. + +In 0.28.0 we changed the container http port from 80 to 8080 to allow root +privileges to be dropped + +In 0.12.2 we removed `DB_PORT` . You can now specify the port via `DB_HOST` like +`DB_HOST=mysql:3306` + +## Quickstart -### Quickstart With Docker Compose is a Quickstart very easy. Run the following command: -``` -docker-compose up +```bash +docker compose up ``` -and after that open your Browser and go to [http://localhost:8080](http://localhost:8080) . +and after that open your Browser and go to +[http://localhost:8080](http://localhost:8080) . You can login with username +`admin@admin.com` and password `password`. -### Issues +## Issues If you have any issues feel free to create an [issue on GitHub](https://github.com/solidnerd/docker-bookstack/issues). +## How to use the Image without Docker compose -### How to use the Image without Docker compose -Networking changed in Docker v1.9, so you need to do one of the following steps. +Note that if you want to use LDAP, `$` has to be escape like `\$`, i.e. `-e "LDAP_USER_FILTER"="(&(uid=\${user}))"` -#### Docker < v1.9 -1. MySQL Container: -```bash -docker run -d --name bookstack-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=bookstack -e MYSQL_USER=bookstack -e MYSQL_PASSWORD=secret mysql:5.7.21 -``` -2. BookStack Container: -```bash -docker run --name my-bookstack -d --link bookstack-mysql:mysql -p 8080:80 solidnerd/bookstack:0.22.0 -``` +### Docker 1.9+ -#### Docker 1.9+ +1. Create a shared network: -1.Create a shared network: + ```bash + docker network create bookstack_nw + ``` -```bash -docker network create bookstack_nw` -``` +2. Run MySQL container : -2.MySQL container : -```bash -docker run -d --net bookstack_nw \ --e MYSQL_ROOT_PASSWORD=secret \ --e MYSQL_DATABASE=bookstack \ --e MYSQL_USER=bookstack \ --e MYSQL_PASSWORD=secret \ - --name="bookstack_db" \ - mysql:5.7.21 -``` + ```bash + docker run -d --net bookstack_nw \ + -e MYSQL_ROOT_PASSWORD=secret \ + -e MYSQL_DATABASE=bookstack \ + -e MYSQL_USER=bookstack \ + -e MYSQL_PASSWORD=secret \ + --name="bookstack_db" \ + mysql:9.2.0 + ``` + +3. Run BookStack Container + ```bash + docker run -d --net bookstack_nw \ + -e DB_HOST=bookstack_db:3306 \ + -e DB_DATABASE=bookstack \ + -e DB_USERNAME=bookstack \ + -e DB_PASSWORD=secret \ + -e APP_URL=http://localhost:8080 \ + -e APP_KEY=SomeRandomStringWith32Characters \ + -p 8080:8080 \ + --name="bookstack_25.5.1" \ + solidnerd/bookstack:25.5.1 + ``` -3.Create BookStack Container + The APP_URL parameter should be the base URL for your BookStack instance without + a trailing slash, but including any port numbers. For example: + + `APP_URL=http://example.com` or `APP_URL=http://localhost:8080`. + + The following environment variables are required for Bookstack to start: + - `APP_KEY` + - `APP_URL` + - `DB_HOST` (in the form `${hostname_or_ip_address}:${port}`) + - `DB_DATABASE` + - `DB_USERNAME` + - `DB_PASSWORD` + +### Volumes + +To access your important bookstack folders on your host system change `` +in the following line to your host directory and add it then to your run +command: ```bash -docker run -d --net bookstack_nw \ --e DB_HOST=bookstack_db:3306 \ --e DB_DATABASE=bookstack \ --e DB_USERNAME=bookstack \ --e DB_PASSWORD=secret \ --p 8080:80 \ - solidnerd/bookstack:0.22.0 +-v :/var/www/bookstack/public/uploads \ +-v :/var/www/bookstack/storage/uploads ``` -After the steps you can visit [http://localhost:8080](http://localhost:8080) . You can login with username 'admin@admin.com' and password 'password'. - +After these steps you can visit [http://localhost:8080](http://localhost:8080). +You can login with username `admin@admin.com` and password `password`. -### Inspiration +## Inspiration -This is a fork of [Kilhog/docker-bookstack](https://github.com/Kilhog/docker-bookstack). Kilhog did the intial work, but I want to go in a different direction. +This is a fork of +[Kilhog/docker-bookstack](https://github.com/Kilhog/docker-bookstack). Kilhog +did the intial work, but I want to go in a different direction. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..0db7ced4 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,38 @@ +# Making a release + +When the version changes, a new release should be cut. To do this, push a tag +with the [valid SemVer][semver-checker] version number as the tag. +It may also be useful to update documentation references at the same time. + +## Scripts + +Update the Dockerfile with: + +```shell +$ scripts/update_dockerfile.sh +Fetching latest Bookstack release from GitHub API + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed +100 3467 100 3467 0 0 18743 0 --:--:-- --:--:-- --:--:-- 18842 +Found latest version: v24.10.1 +Updating Dockerfile.. +``` + +## Example + +For Bookstack version 23.01: + +```shell +sed -i '' -e 's/22.11.1/23.1.0/g' Dockerfile # 22.11.1 was the previous version +git commit -am "feat: Update Bookstack to version 23.1.0" [-S] +# Build and test this +git tag [-s] -a 23.1.0 -m "Release version 23.01" +git push --tags +sed -i '' -e 's/22.11.1/23.1.0/g' * # Update documentation to point to the +newer release +git commit -am "doc: update references to version 23.1" +``` + +The workflow will then build, test, push, and release this image. + +[semver-checker]: https://jubianchi.github.io/semver-check/ diff --git a/VERSION b/VERSION index 21574090..bf383d9b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.22.0 +25.5.1 diff --git a/bookstack.conf b/bookstack.conf index a079aff8..8f2b1fbf 100644 --- a/bookstack.conf +++ b/bookstack.conf @@ -1,10 +1,23 @@ - - ServerName bookstack.dev - DocumentRoot "/var/www/bookstack/public/" + + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + ServerName bookstack - - Options FollowSymLinks MultiViews - AllowOverride All - Require all granted - + DocumentRoot /var/www/bookstack/public + + + Options FollowSymLinks MultiViews + AllowOverride All + Require all granted + + # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, + # error, crit, alert, emerg. + # It is also possible to configure the loglevel for particular + # modules, e.g. + LogLevel info diff --git a/docker-compose.test.yml b/docker-compose.test.yml new file mode 100644 index 00000000..7caf048f --- /dev/null +++ b/docker-compose.test.yml @@ -0,0 +1,38 @@ +version: '2.4' +services: + sut: + image: appropriate/curl + command: ["--ipv4","--retry", "15","--retry-delay","5","--retry-connrefused","http://bookstack:8080/login"] + depends_on: + - bookstack + mysql: + image: mysql:9.2 + environment: + - MYSQL_ROOT_PASSWORD=secret + - MYSQL_DATABASE=bookstack + - MYSQL_USER=bookstack + - MYSQL_PASSWORD=secret + volumes: + - mysql-data:/var/lib/mysql + + bookstack: + image: ${BOOKSTACK_IMAGE:-solidnerd/bookstack} + depends_on: + - mysql + environment: + - APP_URL=http://localhost:${DEV_PORT:-8080} + - APP_KEY=SomeRandomStringWith32Characters + - DB_HOST=mysql:3306 + - DB_DATABASE=bookstack + - DB_USERNAME=bookstack + - DB_PASSWORD=secret + volumes: + - uploads:/var/www/bookstack/public/uploads + - storage-uploads:/var/www/bookstack/storage/uploads + ports: + - "8080:80" + +volumes: + mysql-data: + uploads: + storage-uploads: diff --git a/docker-compose.yml b/docker-compose.yml index 2ae24e74..d4d3cf1a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '2' services: mysql: - image: mysql:5.7.21 + image: mysql:9.2 environment: - MYSQL_ROOT_PASSWORD=secret - MYSQL_DATABASE=bookstack @@ -11,7 +11,7 @@ services: - mysql-data:/var/lib/mysql bookstack: - image: solidnerd/bookstack:0.22.0 + image: solidnerd/bookstack:25.5.1 depends_on: - mysql environment: @@ -19,11 +19,21 @@ services: - DB_DATABASE=bookstack - DB_USERNAME=bookstack - DB_PASSWORD=secret + # Set the APP_ to the URL of bookstack without without a trailing slash, + # but including any port numbers. For example, one of: + # APP_URL=https://example.com + # APP_URL=http://localhost:8080 + # APP_URL=https://wiki.example.com:8443 + - APP_URL=http://localhost:8080 + # APP_KEY is used for encryption where needed, so needs to be persisted to + # preserve decryption abilities. + # Can run `php artisan key:generate` to generate a key + - APP_KEY=SomeRandomStringWith32Characters volumes: - uploads:/var/www/bookstack/public/uploads - - storage-uploads:/var/www/bookstack/public/storage + - storage-uploads:/var/www/bookstack/storage/uploads ports: - - "8080:80" + - "8080:8080" volumes: mysql-data: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 34a7a17f..7d5dea20 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -3,90 +3,46 @@ set -e echoerr() { echo "$@" 1>&2; } +check_vars_exist() { + var_names=("$@") + + for var_name in "${var_names[@]}"; do + if [ -z "${!var_name}" ]; then + echoerr "error: missing ${var_name} environment variable" + exit 1 + fi + done +} + # Split out host and port from DB_HOST env variable IFS=":" read -r DB_HOST_NAME DB_PORT <<< "$DB_HOST" DB_PORT=${DB_PORT:-3306} -if [ ! -f "$BOOKSTACK_HOME/.env" ]; then - if [[ "${DB_HOST}" ]]; then - cat > "$BOOKSTACK_HOME/.env" <&2 'error: missing DB_HOST environment variable' - exit 1 - fi +# Check a number of essential variables are set +check_vars_exist \ + APP_KEY \ + APP_URL \ + DB_DATABASE \ + DB_HOST \ + DB_PASSWORD \ + DB_PORT \ + DB_USERNAME + +if [ -n "${FILE_UPLOAD_SIZE_LIMITS}" ]; then + echo "Note: If you're setting FILE_UPLOAD_SIZE_LIMITS to more than 10M, you" + echo "may also need to modify the php.ini file." + echo "See:" + echo "https://github.com/solidnerd/docker-bookstack/issues/423" fi -echoerr wait-for-db: waiting for ${DB_HOST_NAME}:${DB_PORT} +echoerr "wait-for-db: waiting for ${DB_HOST_NAME}:${DB_PORT}" timeout 15 bash < /dev/tcp/${DB_HOST_NAME}/${DB_PORT}) >/dev/null 2>&1; @@ -98,24 +54,17 @@ RESULT=$? if [ $RESULT -eq 0 ]; then # sleep another second for so that we don't get a "the database system is starting up" error sleep 1 - echoerr wait-for-db: done + echoerr "wait-for-db: done" else - echoerr wait-for-db: timeout out after 15 seconds waiting for ${DB_HOST_NAME}:${DB_PORT} + echoerr "wait-for-db: timeout out after 15 seconds waiting for ${DB_HOST_NAME}:${DB_PORT}" fi -composer install - -php artisan key:generate - +echo "Starting Migration..." php artisan migrate --force - -echo "Setting folder permissions for uploads" -chown -R www-data:www-data public/uploads && chmod -R 775 public/uploads -chown -R www-data:www-data storage/uploads && chmod -R 775 storage/uploads - +echo "Clearing caches..." php artisan cache:clear - php artisan view:clear +trap "echo Catching SIGWINCH apache error and perventing it." SIGWINCH exec apache2-foreground diff --git a/hooks/build b/hooks/build deleted file mode 100644 index f426e0a3..00000000 --- a/hooks/build +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -docker build \ - --build-arg BUILD_DATE="$(date --rfc-3339=s)" \ - --build-arg VCS_REF=`git rev-parse --short HEAD` \ - -t $IMAGE_NAME . \ No newline at end of file diff --git a/hooks/post_push b/hooks/post_push deleted file mode 100644 index 6ac70c0a..00000000 --- a/hooks/post_push +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -set -e - -docker tag $IMAGE_NAME $DOCKER_REPO:latest -docker push $DOCKER_REPO:latest \ No newline at end of file diff --git a/php.ini b/php.ini index 8c04c367..3b9c045a 100644 --- a/php.ini +++ b/php.ini @@ -1,4 +1,4 @@ [PHP] - +memory_limit = 256M post_max_size = 10M upload_max_filesize = 10M diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..f45d8f11 --- /dev/null +++ b/renovate.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "config:base" + ] +} diff --git a/scripts/update_dockerfile.sh b/scripts/update_dockerfile.sh new file mode 100755 index 00000000..e203e0ff --- /dev/null +++ b/scripts/update_dockerfile.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +echo "Fetching latest Bookstack release from GitHub API" + +BOOKSTACK_VERSION=$(curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/BookstackApp/Bookstack/releases/latest | \ + jq -r .tag_name +) + +echo "Found latest version: ${BOOKSTACK_VERSION}" + +# Get the root of the Git repository in order to correctly path e.g. Dockerfile +GIT_ROOT=$(git rev-parse --show-toplevel) + +echo "Updating Dockerfile.." +sed \ + -i '' \ + -e "s/^ENV BOOKSTACK_VERSION=.*/ENV BOOKSTACK_VERSION=${BOOKSTACK_VERSION}/" \ + "${GIT_ROOT}/Dockerfile" + +git add "${GIT_ROOT}/Dockerfile" +git commit -S -m "feat: update Dockerfile to use Bookstack ${BOOKSTACK_VERSION}" diff --git a/scripts/update_tags_and_docs.sh b/scripts/update_tags_and_docs.sh new file mode 100755 index 00000000..51c8edec --- /dev/null +++ b/scripts/update_tags_and_docs.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# Get the root of the Git repository in order to correctly path e.g. Dockerfile +GIT_ROOT=$(git rev-parse --show-toplevel) + +# Extract the version from the Dockerfile, as there could have been a new +# release since the last run. + +BOOKSTACK_VERSION=$(awk \ + '/ENV BOOKSTACK_VERSION/{split($2,b,"="); print b[2]}' \ + "${GIT_ROOT}/Dockerfile" +) + +echo "Extracted version: ${BOOKSTACK_VERSION}" + +# Remove the 'v' for our tags +BOOKSTACK_VERSION="${BOOKSTACK_VERSION/#v/}" +# Remove leading zeros to make the version fit a SemVer-shaped hole +BOOKSTACK_VERSION="${BOOKSTACK_VERSION/.0/.}" + +# If the version only has one decimal dot in it, it doesn't have a patch +# version and one should be added to ensure semver-shape. +BS_DECIMALS="${BOOKSTACK_VERSION//[^.]}" +if [[ "${#BS_DECIMALS}" -eq "1" ]]; then + BOOKSTACK_VERSION="${BOOKSTACK_VERSION}.0" +fi + +echo "Tag name: ${BOOKSTACK_VERSION}" + +read -p "Is the tag name correct? (y/n)" -n 1 -r +echo +if ! [[ "${REPLY}" =~ ^[Yy]$ ]]; then + echo "Aborting.." + exit 1 +fi + +git tag -s -a "${BOOKSTACK_VERSION}" -m "Release version ${BOOKSTACK_VERSION}" +git push --tags + +echo "Extracting old version info.." +OLD_BS_VERSION="$(cat VERSION)" + +echo "Updating README and reference docker-compose.yml.." +sed \ + -i '' \ + -e "s/${OLD_BS_VERSION}/${BOOKSTACK_VERSION}/g" \ + "${GIT_ROOT}/README.md" \ + "${GIT_ROOT}/docker-compose.yml" + +echo "Updating VERSION file.." +echo "${BOOKSTACK_VERSION}" > "${GIT_ROOT}/VERSION" + +git add \ + "${GIT_ROOT}/README.md" \ + "${GIT_ROOT}/docker-compose.yml" \ + "${GIT_ROOT}/VERSION" + +git commit -S -m "doc: update documentation to reference ${BOOKSTACK_VERSION}" +git push