diff --git a/.dockerignore b/.dockerignore index 7bc63e0..a1cf263 100644 --- a/.dockerignore +++ b/.dockerignore @@ -34,4 +34,7 @@ tests/medias/ # Dump for installation dump-with-anonymous-user.sql -dump-without-anonymous-user.sql \ No newline at end of file +dump-without-anonymous-user.sql + +# Examples +docker-examples/ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..1884213 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,65 @@ +name: build + +on: + push: + branches: + - main + tags: + - 'v*' + pull_request: + branches: + - main + +env: + DOCKERHUB_SLUG: blueprintue/blueprintue-self-hosted-edition + GHCR_SLUG: ghcr.io/blueprintue/blueprintue-self-hosted-edition + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.DOCKERHUB_SLUG }} + ${{ env.GHCR_SLUG }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Build Image + uses: docker/bake-action@v4 + with: + files: | + ./docker-bake.hcl + ${{ steps.meta.outputs.bake-file }} + targets: image-all + push: ${{ github.event_name != 'pull_request' }} diff --git a/.gitignore b/.gitignore index ec50b3f..c277fb1 100644 --- a/.gitignore +++ b/.gitignore @@ -23,8 +23,13 @@ tests/tests.env.cache.php # Storage storage/ tests/storage_test/ +docker-examples/storage/ # Medias www/medias/avatars/ www/medias/blueprints/ -tests/medias/ \ No newline at end of file +tests/medias/ +docker-examples/medias/ + +# Examples +docker-examples/db/ diff --git a/Dockerfile b/Dockerfile index 2dbf2a8..ed30e60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM crazymax/alpine-s6:3.13 AS base +FROM crazymax/alpine-s6:latest AS base ENV S6_BEHAVIOR_IF_STAGE2_FAILS="2" \ TZ="UTC" \ @@ -6,29 +6,30 @@ ENV S6_BEHAVIOR_IF_STAGE2_FAILS="2" \ PGID="1500" RUN apk --update --no-cache add \ + curl \ nginx \ - php7 \ - php7-cli \ - php7-ctype \ - php7-curl \ - php7-dom \ - php7-exif \ - php7-fileinfo \ - php7-fpm \ - php7-gd \ - php7-iconv \ - php7-intl \ - php7-json \ - php7-mbstring \ - php7-opcache \ - php7-openssl \ - php7-pdo \ - php7-pdo_mysql \ - php7-phar \ - php7-session \ - php7-sodium \ - php7-xml \ - php7-zlib \ + php \ + php-cli \ + php-ctype \ + php-curl \ + php-dom \ + php-exif \ + php-fileinfo \ + php-fpm \ + php-gd \ + php-iconv \ + php-intl \ + php-json \ + php-mbstring \ + php-opcache \ + php-openssl \ + php-pdo \ + php-pdo_mysql \ + php-phar \ + php-session \ + php-sodium \ + php-xml \ + php-zlib \ mariadb-client \ shadow \ tzdata \ @@ -46,7 +47,7 @@ RUN apk --update --no-cache add curl \ && chown -R blueprintue-self-hosted-edition. /opt/blueprintue-self-hosted-edition COPY app ./app COPY www ./www -COPY .env.template ./.env +RUN touch .env FROM base @@ -58,4 +59,7 @@ EXPOSE 8000 WORKDIR /opt/blueprintue-self-hosted-edition VOLUME [ "/opt/blueprintue-self-hosted-edition/storage" ] +COPY cronscript.sh /etc/periodic/15min/crons +CMD [ "crond", "-l", "2", "-f" ] + ENTRYPOINT ["/init"] diff --git a/README.md b/README.md index 4908705..19ff40e 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,22 @@ * \>= MySQL 8 or >= MariaDB 10.6 ## How to install? +### Docker Image +| Registry | Image | +|------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------| +| [Docker Hub](https://hub.docker.com/r/blueprintue/blueprintue-self-hosted-edition/) | `blueprintue/blueprintue-self-hosted-edition` | +| [GitHub Container Registry](https://github.com/users/blueprintue/packages/container/package/blueprintue-self-hosted-edition) | `ghcr.io/blueprintue/blueprintue-self-hosted-edition` | + +Read [docker-examples](https://github.com/blueprintue/blueprintue-self-hosted-edition/blob/main/docker-examples) about documentation and docker-compose file example. + +### FTP / localhost Download zip file from last [release](https://github.com/blueprintue/blueprintue-self-hosted-edition/releases) or run a `composer install` to have `vendor` folder. 1. copy folders `app`, `storage`, `vendor` and paste **outside** of the public folder of your server 2. copy folder content `www` and paste **inside** the public folder of your server 3. copy `dump-with-anonymous-user.sql` or `dump-without-anonymous-user.sql` and paste file in your database 4. copy `.env.template` and paste file **outside** of the public folder of your server 5. fill values in `.env.template` file with what you need (database and email) -6. rename `.env.template` to `.env` +6. rename `.env.template` to `.env` (see [Configuration explanations](#configuration-explanations)) 7. done The `public folder` means what your http server can show you, usually it is called is `www` or `public_html` @@ -41,9 +50,9 @@ blueprintUE self-hosted edition is like blueprintUE but without ## GDPR Because GDPR you will need to: -* fill contact email -* fill page privacy policy -* fill page terms of service +* fill contact email [(in .env file)](https://github.com/blueprintue/blueprintue-self-hosted-edition/blob/main/.env.template#L46) +* fill page privacy policy [(in /app/views/www/pages/privacy_policy.php)](https://github.com/blueprintue/blueprintue-self-hosted-edition/blob/main/app/views/www/pages/privacy_policy.php#L25) +* fill page terms of service [(in /app/views/www/pages/terms_of_service.php)](https://github.com/blueprintue/blueprintue-self-hosted-edition/blob/main/app/views/www/pages/terms_of_service.php#L25) ## Configuration explanations ### .env file @@ -74,10 +83,10 @@ Because GDPR you will need to: | SESSION_REMEMBER_SAMESITE | NO | string | Strict | None \| Lax \| Strict | security policies on how cookies are shared, Lax is mandatory for Twitter OAuth | #### Host -| Parameter | Mandatory | Type | Default value | Specific values | Description | -| --------- | --------- | ------ | -------------- | --------------- |-----------------------------------------------------| -| HOST | YES | string | | | hostname (e.g. blueprintue-self-hosted-edition.com) | -| HTTPS | YES | bool | | | use for detect scheme (http or https) | +| Parameter | Mandatory | Type | Default value | Specific values | Description | +| --------- | --------- | ------ | -------------- | --------------- |------------------------------------------------------| +| HOST | YES | string | | | hostname (e.g. blueprintue-self-hosted-edition.test) | +| HTTPS | YES | bool | | | use for detect scheme (http or https) | #### Site | Parameter | Mandatory | Type | Default value | Specific values | Description | @@ -225,7 +234,7 @@ After you can launch dev environment ```shell cd .dev touch .env -docker-compose up --build +docker-compose up -d --build --force-recreate ``` ### Neard / Wamp / Old school @@ -236,46 +245,3 @@ You have to update your `hosts` file those values ``` Follow [How to install](#how-to-install). - -## How to test -`docker buildx bake test` create image -`docker run --rm -v $(pwd)/coverage:/src/coverage -e XDEBUG_MODE=coverage --network host blueprintue-self-hosted-edition:test test` launch tests - -## Docker -### Buildx -* `docker buildx bake` create image-local -* `docker buildx bake validate` launch 2 subtasks vendor-update && vendor-validate -* `docker buildx bake vendor-validate` check if there is a drift with composer.lock -* `docker buildx bake lint` check if code is matching with lint rules -* `docker buildx bake test` end 2 end testing -* `docker buildx bake image` create a docker image for registry -* `docker buildx bake image-local` create a local docker image - -### Docker-compose -`docker-compose build && docker-compose run lib composer ci` for launching tests - -### Run image-local -`docker buildx bake && docker run --rm -it -p 8000:8000 blueprintue-self-hosted-edition:local` - -### Env variables -#### Rootfs -##### User rights -* `PUID` user id -* `PGID` group id - -##### Timezone -* `TZ` timezone (by default: UTC) - -##### PHP-FPM -* `MEMORY_LIMIT` memory limit (by default: 256M) -* `POST_MAX_SIZE` post max size (by default: 16M) -* `UPLOAD_MAX_SIZE` upload max size (by default: 16M) - -##### OPCache -* `OPCACHE_ENABLE` opcache enable (by default: 1) -* `OPCACHE_MEM_SIZE` opcache memory consumption (by default: 128) - -##### Nginx -* `REAL_IP_FROM` real ip from (by default: 0.0.0.0/32) -* `REAL_IP_HEADER` real ip header (by default: X-Forwarded-For) -* `LOG_IP_VAR` log ip var (by default: remote_addr) diff --git a/cronscript.sh b/cronscript.sh new file mode 100755 index 0000000..a1c70fd --- /dev/null +++ b/cronscript.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env sh +# purge sessions +echo "Job started (purge sessions): $(date)" +curl --silent http://localhost:8000/cron/purge_sessions/ &>/dev/null +echo "Job started: $(date)" +# purge users not confirmed +echo "Job started (purge users not confirmed): $(date)" +curl --silent http://localhost:8000/cron/purge_users_not_confirmed/ &>/dev/null +echo "Job started: $(date)" +# set soft delete anonymous private blueprints +echo "Job started (set soft delete anonymous private blueprints): $(date)" +curl --silent http://localhost:8000/cron/set_soft_delete_anonymous_private_blueprints/ &>/dev/null +echo "Job started: $(date)" +# purge deleted blueprints +echo "Job started (purge deleted blueprints): $(date)" +curl --silent http://localhost:8000/cron/purge_deleted_blueprints/ &>/dev/null +echo "Job started: $(date)" diff --git a/docker-bake.hcl b/docker-bake.hcl index f5b5a85..be11b4a 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -1,5 +1,5 @@ variable "PHP_VERSION" { - default = "7.4" + default = "8.2" } target "php-version" { @@ -8,6 +8,10 @@ target "php-version" { } } +target "docker-meta-action" { + tags = ["blueprintue-self-hosted-edition:local"] +} + group "default" { targets = ["image-local"] } @@ -44,11 +48,20 @@ target "test" { } target "image" { - inherits = ["ghaction-docker-meta"] + inherits = ["docker-meta-action"] dockerfile = "./Dockerfile" } target "image-local" { inherits = ["image"] output = ["type=docker"] -} \ No newline at end of file +} + +target "image-all" { + inherits = ["image"] + platforms = [ + "linux/amd64", + "linux/arm/v7", + "linux/arm64", + ] +} diff --git a/docker-examples/README.md b/docker-examples/README.md new file mode 100644 index 0000000..ad0cd1f --- /dev/null +++ b/docker-examples/README.md @@ -0,0 +1,78 @@ +# Examples of docker-compose + +## Pull Docker Image from GitHub Registry +```shell +docker login ghcr.io +docker pull ghcr.io/blueprintue/blueprintue-self-hosted-edition:edge +docker-compose pull +``` + +## Docker Compose variations +For each files you will need to find and replace values `_____REPLACE_ME_____` with what you need. + +### Basic +You will have in that file [docker-compose-localhost.yml]: +- traefik + - open on port 80 + - use `traefik-http.yml` +- mariadb + - on init use `dump-with-anonymous-user.sql` + - use `database.env` +- maildev + - all emails sent are visible on `localhost:1080` + +### HTTPS +You will have in that file [docker-compose-https.yml]: +- traefik + - open on port 80 and 443 + - use `traefik-https.yml` with let's encrypt challenge for OVH + - use `traefik-https.env` with OVH +- mariadb + - on init use `dump-with-anonymous-user.sql` + - use `database.env` +- maildev + - all emails sent are visible on `localhost:1080` + +### SMTP +You will have in that file [docker-compose-smtp.yml]: +- traefik + - open on port 80 + - use `traefik-http.yml` +- mariadb + - on init use `dump-with-anonymous-user.sql` + - use `database.env` +- msmtpd + - emails will be sent using smtp relay + - use `msmtpd.env` + +## Env variables +### Rootfs +#### User rights +* `PUID` user id +* `PGID` group id + +#### Timezone +* `TZ` timezone (by default: UTC) + +#### PHP-FPM +* `MEMORY_LIMIT` memory limit (by default: 256M) +* `POST_MAX_SIZE` post max size (by default: 16M) +* `UPLOAD_MAX_SIZE` upload max size (by default: 16M) + +#### OPCache +* `OPCACHE_ENABLE` opcache enable (by default: 1) +* `OPCACHE_MEM_SIZE` opcache memory consumption (by default: 128) + +#### Nginx +* `REAL_IP_FROM` real ip from (by default: 0.0.0.0/32) +* `REAL_IP_HEADER` real ip header (by default: X-Forwarded-For) +* `LOG_IP_VAR` log ip var (by default: remote_addr) + +## Docker Buildx Commands +* `docker buildx bake` create image-local +* `docker buildx bake validate` launch 2 subtasks vendor-update && vendor-validate +* `docker buildx bake vendor-validate` check if there is a drift with composer.lock +* `docker buildx bake lint` check if code is matching with lint rules +* `docker buildx bake test` end 2 end testing +* `docker buildx bake image` create a docker image for registry +* `docker buildx bake image-local` create a local docker image diff --git a/docker-examples/database.env b/docker-examples/database.env new file mode 100644 index 0000000..d984c06 --- /dev/null +++ b/docker-examples/database.env @@ -0,0 +1,4 @@ +MYSQL_ALLOW_EMPTY_PASSWORD=yes +MYSQL_DATABASE=database_name +MYSQL_USER=database_user +MYSQL_PASSWORD=database_password diff --git a/docker-examples/docker-compose-https.yml b/docker-examples/docker-compose-https.yml new file mode 100644 index 0000000..0c3a0a3 --- /dev/null +++ b/docker-examples/docker-compose-https.yml @@ -0,0 +1,106 @@ +version: "3.8" + +services: + traefik: + image: traefik + container_name: traefik + ports: + - target: 80 + published: 80 + protocol: tcp + - target: 443 + published: 443 + protocol: tcp + volumes: + - "./traefik-https.yml:/etc/traefik/traefik.yml:ro" + - "./acme.json:/acme.json" + - "/var/run/docker.sock:/var/run/docker.sock" + env_file: + - traefik.env + restart: always + + mariadb: + image: mariadb + container_name: database + volumes: + - "./db:/var/lib/mysql" + - "./dump-with-anonymous-user.sql:/docker-entrypoint-initdb.d/init.sql" + env_file: + - "./database.env" + restart: "always" + ports: + - "3306:3306" + + maildev: + container_name: maildev + image: maildev/maildev + restart: always + ports: + - "1080:1080" + + blueprintue-self-hosted-edition: + image: blueprintue/blueprintue-self-hosted-edition + container_name: blueprintue-self-hosted-edition + depends_on: + - mariadb + - msmtpd + ports: + - "8000:8000" + volumes: + - "./storage:/opt/blueprintue-self-hosted-edition/storage" + - "./medias:/opt/blueprintue-self-hosted-edition/www/medias" + labels: + - "traefik.enable=true" + - "traefik.http.routers.blueprintue-self-hosted-edition.entrypoints=https" + - "traefik.http.routers.blueprintue-self-hosted-edition.rule=Host(`_____REPLACE_ME_____`)" + - "traefik.http.routers.blueprintue-self-hosted-edition.tls=true" + - "traefik.http.routers.blueprintue-self-hosted-edition.tls.certresolver=ovh" + - "traefik.http.routers.blueprintue-self-hosted-edition.tls.domains[0].main=_____REPLACE_ME_____" + - "traefik.http.services.blueprintue-self-hosted-edition.loadbalancer.server.port=8000" + - "traefik.http.services.blueprintue-self-hosted-edition.loadbalancer.passhostheader=true" + environment: + - "OPCACHE_ENABLE=0" + - "REAL_IP_FROM=0.0.0.0/32" + - "REAL_IP_HEADER=X-Forwarded-For" + - "LOG_IP_VAR=http_x_forwarded_for" + - "TIMEZONE=UTC" + - "DATABASE_DRIVER=mysql" + - "DATABASE_HOST=database" + - "DATABASE_USER=database_user" + - "DATABASE_PASSWORD=database_password" + - "DATABASE_NAME=database_name" + - "DATABASE_PERSISTENT_CONNECTION=false" + - "SESSION_DRIVER=default" + - "SESSION_ENCRYPT_KEY=" + - "SESSION_GC_MAXLIFETIME=86400" + - "SESSION_LIFETIME=0" + - "SESSION_PATH=/" + - "SESSION_HTTPS=true" + - "SESSION_SAMESITE=Strict" + - "SESSION_REMEMBER_NAME=remember_token" + - "SESSION_REMEMBER_LIFETIME=2592000" + - "SESSION_REMEMBER_PATH=/" + - "SESSION_REMEMBER_HTTPS=true" + - "SESSION_REMEMBER_SAMESITE=Strict" + - "HOST=_____REPLACE_ME_____" + - "HTTPS=true" + - "SITE_NAME=blueprintUE self-hosted edition" + - "SITE_BASE_TITLE=" + - "SITE_DESCRIPTION=" + - "ANONYMOUS_ID=1" + - "MAIL_USE_SMTP=true" + - "MAIL_SMTP_HOST=maildev" + - "MAIL_SMTP_PORT=1025" + - "MAIL_USE_SMTP_AUTH=false" + - "MAIL_SMTP_USER=" + - "MAIL_SMTP_PASSWORD=" + - "MAIL_FROM_ADDRESS=_____REPLACE_ME_____" + - "MAIL_FROM_NAME=blueprintue-self-hosted-edition" + - "MAIL_CONTACT_TO=_____REPLACE_ME_____" + - "MAIL_HEADER_LOGO_PATH=blueprintue-self-hosted-edition_logo-full.png" + restart: "always" + +volumes: + database: + blueprintue-self-hosted-edition_storage: + blueprintue-self-hosted-edition_medias: diff --git a/docker-examples/docker-compose-localhost.yml b/docker-examples/docker-compose-localhost.yml new file mode 100644 index 0000000..1bb8d6d --- /dev/null +++ b/docker-examples/docker-compose-localhost.yml @@ -0,0 +1,97 @@ +version: "3.8" + +services: + traefik: + image: traefik + container_name: traefik + ports: + - target: 80 + published: 80 + protocol: tcp + volumes: + - "./traefik-http.yml:/etc/traefik/traefik.yml:ro" + - "/var/run/docker.sock:/var/run/docker.sock" + restart: always + + mariadb: + image: mariadb + container_name: database + volumes: + - "./db:/var/lib/mysql" + - "./dump-with-anonymous-user.sql:/docker-entrypoint-initdb.d/init.sql" + env_file: + - "./database.env" + restart: "always" + ports: + - "3306:3306" + + maildev: + container_name: maildev + image: maildev/maildev + restart: always + ports: + - "1080:1080" + + blueprintue-self-hosted-edition: + image: blueprintue/blueprintue-self-hosted-edition + container_name: blueprintue-self-hosted-edition + depends_on: + - mariadb + - maildev + ports: + - "8000:8000" + volumes: + - "./storage:/opt/blueprintue-self-hosted-edition/storage" + - "./medias:/opt/blueprintue-self-hosted-edition/www/medias" + labels: + - "traefik.enable=true" + - "traefik.http.routers.blueprintue-self-hosted-edition.entrypoints=http" + - "traefik.http.routers.blueprintue-self-hosted-edition.rule=Host(`_____REPLACE_ME_____`)" + - "traefik.http.services.blueprintue-self-hosted-edition.loadbalancer.server.port=8000" + - "traefik.http.services.blueprintue-self-hosted-edition.loadbalancer.passhostheader=true" + environment: + - "OPCACHE_ENABLE=0" + - "REAL_IP_FROM=0.0.0.0/32" + - "REAL_IP_HEADER=X-Forwarded-For" + - "LOG_IP_VAR=http_x_forwarded_for" + - "TIMEZONE=UTC" + - "DATABASE_DRIVER=mysql" + - "DATABASE_HOST=database" + - "DATABASE_USER=database_user" + - "DATABASE_PASSWORD=database_password" + - "DATABASE_NAME=database_name" + - "DATABASE_PERSISTENT_CONNECTION=false" + - "SESSION_DRIVER=default" + - "SESSION_ENCRYPT_KEY=" + - "SESSION_GC_MAXLIFETIME=86400" + - "SESSION_LIFETIME=0" + - "SESSION_PATH=/" + - "SESSION_HTTPS=false" + - "SESSION_SAMESITE=Strict" + - "SESSION_REMEMBER_NAME=remember_token" + - "SESSION_REMEMBER_LIFETIME=2592000" + - "SESSION_REMEMBER_PATH=/" + - "SESSION_REMEMBER_HTTPS=false" + - "SESSION_REMEMBER_SAMESITE=Strict" + - "HOST=_____REPLACE_ME_____" + - "HTTPS=false" + - "SITE_NAME=blueprintUE self-hosted edition" + - "SITE_BASE_TITLE=" + - "SITE_DESCRIPTION=" + - "ANONYMOUS_ID=1" + - "MAIL_USE_SMTP=true" + - "MAIL_SMTP_HOST=maildev" + - "MAIL_SMTP_PORT=1025" + - "MAIL_USE_SMTP_AUTH=false" + - "MAIL_SMTP_USER=" + - "MAIL_SMTP_PASSWORD=" + - "MAIL_FROM_ADDRESS=_____REPLACE_ME_____" + - "MAIL_FROM_NAME=blueprintue-self-hosted-edition" + - "MAIL_CONTACT_TO=_____REPLACE_ME_____" + - "MAIL_HEADER_LOGO_PATH=blueprintue-self-hosted-edition_logo-full.png" + restart: "always" + +volumes: + database: + blueprintue-self-hosted-edition_storage: + blueprintue-self-hosted-edition_medias: diff --git a/docker-examples/docker-compose-smtp.yml b/docker-examples/docker-compose-smtp.yml new file mode 100644 index 0000000..c441fe1 --- /dev/null +++ b/docker-examples/docker-compose-smtp.yml @@ -0,0 +1,97 @@ +version: "3.8" + +services: + traefik: + image: traefik + container_name: traefik + ports: + - target: 80 + published: 80 + protocol: tcp + volumes: + - "./traefik-http.yml:/etc/traefik/traefik.yml:ro" + - "/var/run/docker.sock:/var/run/docker.sock" + restart: always + + mariadb: + image: mariadb + container_name: database + volumes: + - "./db:/var/lib/mysql" + - "./dump-with-anonymous-user.sql:/docker-entrypoint-initdb.d/init.sql" + env_file: + - "./database.env" + restart: "always" + ports: + - "3306:3306" + + msmtpd: + image: crazymax/msmtpd + container_name: msmtpd + env_file: + - "./msmtpd.env" + restart: always + + blueprintue-self-hosted-edition: + image: blueprintue/blueprintue-self-hosted-edition + container_name: blueprintue-self-hosted-edition + depends_on: + - mariadb + - msmtpd + ports: + - "8000:8000" + volumes: + - "./storage:/opt/blueprintue-self-hosted-edition/storage" + - "./medias:/opt/blueprintue-self-hosted-edition/www/medias" + labels: + - "traefik.enable=true" + - "traefik.http.routers.blueprintue-self-hosted-edition.entrypoints=http" + - "traefik.http.routers.blueprintue-self-hosted-edition.rule=Host(`_____REPLACE_ME_____`)" + - "traefik.http.services.blueprintue-self-hosted-edition.loadbalancer.server.port=8000" + - "traefik.http.services.blueprintue-self-hosted-edition.loadbalancer.passhostheader=true" + environment: + - "OPCACHE_ENABLE=0" + - "REAL_IP_FROM=0.0.0.0/32" + - "REAL_IP_HEADER=X-Forwarded-For" + - "LOG_IP_VAR=http_x_forwarded_for" + - "TIMEZONE=UTC" + - "DATABASE_DRIVER=mysql" + - "DATABASE_HOST=database" + - "DATABASE_USER=database_user" + - "DATABASE_PASSWORD=database_password" + - "DATABASE_NAME=database_name" + - "DATABASE_PERSISTENT_CONNECTION=false" + - "SESSION_DRIVER=default" + - "SESSION_ENCRYPT_KEY=" + - "SESSION_GC_MAXLIFETIME=86400" + - "SESSION_LIFETIME=0" + - "SESSION_PATH=/" + - "SESSION_HTTPS=false" + - "SESSION_SAMESITE=Strict" + - "SESSION_REMEMBER_NAME=remember_token" + - "SESSION_REMEMBER_LIFETIME=2592000" + - "SESSION_REMEMBER_PATH=/" + - "SESSION_REMEMBER_HTTPS=false" + - "SESSION_REMEMBER_SAMESITE=Strict" + - "HOST=_____REPLACE_ME_____" + - "HTTPS=false" + - "SITE_NAME=blueprintUE self-hosted edition" + - "SITE_BASE_TITLE=" + - "SITE_DESCRIPTION=" + - "ANONYMOUS_ID=1" + - "MAIL_USE_SMTP=false" + - "MAIL_SMTP_HOST=msmtpd" + - "MAIL_SMTP_PORT=2500" + - "MAIL_USE_SMTP_AUTH=false" + - "MAIL_SMTP_USER=" + - "MAIL_SMTP_PASSWORD=" + - "MAIL_FROM_ADDRESS=_____REPLACE_ME_____" + - "MAIL_FROM_NAME=blueprintue-self-hosted-edition" + - "MAIL_CONTACT_TO=_____REPLACE_ME_____" + - "MAIL_HEADER_LOGO_PATH=blueprintue-self-hosted-edition_logo-full.png" + restart: "always" + +volumes: + database: + blueprintue-self-hosted-edition_storage: + blueprintue-self-hosted-edition_medias: diff --git a/docker-examples/dump-with-anonymous-user.sql b/docker-examples/dump-with-anonymous-user.sql new file mode 100644 index 0000000..2820dc7 --- /dev/null +++ b/docker-examples/dump-with-anonymous-user.sql @@ -0,0 +1,140 @@ +create table if not exists blueprints +( + id int unsigned auto_increment + primary key, + id_author int unsigned null, + slug varchar(100) not null, + file_id varchar(100) not null, + title varchar(255) not null, + type enum('animation', 'behavior_tree', 'blueprint', 'material', 'metasound', 'niagara', 'pcg') default 'blueprint' not null, + ue_version char(5) default '4.0' not null, + current_version int unsigned not null, + thumbnail varchar(255) null, + description longtext null, + exposure enum('public', 'unlisted', 'private') default 'public' not null, + expiration datetime null, + tags varchar(255) null, + video varchar(255) null, + video_provider varchar(255) null, + comments_hidden tinyint(1) default '0', + comments_closed tinyint(1) default '0', + comments_count int unsigned default '0', + created_at datetime not null, + updated_at datetime null, + published_at datetime null, + deleted_at datetime null, + constraint file_id_UNIQUE + unique (file_id), + constraint slug_UNIQUE + unique (slug) + ) + charset=utf8mb4; + +create table if not exists blueprints_version +( + id int unsigned auto_increment + primary key, + id_blueprint int unsigned not null, + version int unsigned not null, + reason text not null, + created_at datetime not null, + updated_at datetime null, + published_at datetime null +) + charset=utf8mb4; + +create table if not exists comments +( + id int unsigned auto_increment + primary key, + id_author int unsigned null, + id_blueprint int unsigned not null, + name_fallback varchar(255) null, + content text not null, + created_at datetime not null + ) + charset=utf8mb4; + +create table if not exists sessions +( + id varchar(128) not null + primary key, + id_user int unsigned null, + last_access datetime not null, + content text not null + ) + charset=utf8mb4; + +create table if not exists tags +( + id int unsigned auto_increment + primary key, + name varchar(100) not null, + slug varchar(100) not null, + constraint slug_UNIQUE + unique (slug) + ) + charset=utf8mb4; + +create table if not exists users +( + id int unsigned auto_increment + primary key, + username varchar(100) not null, + password text null, + slug varchar(100) not null, + email varchar(100) null, + password_reset varchar(255) null, + password_reset_at datetime null, + grade enum('member', 'admin') default 'member' not null, + avatar varchar(255) null, + remember_token char(255) null, + created_at datetime not null, + confirmed_token char(255) null, + confirmed_sent_at datetime null, + confirmed_at datetime null, + last_login_at datetime null, + constraint email_UNIQUE + unique (email), + constraint username_UNIQUE + unique (username), + constraint slug_UNIQUE + unique (slug), + constraint remember_token_UNIQUE + unique (remember_token), + constraint confirmed_token_UNIQUE + unique (confirmed_token) + ) + charset=utf8mb4; + +create table if not exists users_api +( + id_user int unsigned not null + primary key, + api_key varchar(100) not null, + constraint api_key_UNIQUE + unique (api_key) + ) + charset=utf8mb4; + +create table if not exists users_infos +( + id_user int unsigned not null + primary key, + count_public_blueprint int unsigned default 0 not null, + count_public_comment int unsigned default 0 not null, + count_private_blueprint int unsigned default 0 not null, + count_private_comment int unsigned default 0 not null, + bio text null, + link_website varchar(255) null, + link_facebook varchar(255) null, + link_twitter varchar(255) null, + link_github varchar(255) null, + link_twitch varchar(255) null, + link_unreal varchar(255) null, + link_youtube varchar(255) null + ) + charset=utf8mb4; + +INSERT INTO `users` (`id`, `username`, `password`, `slug`, `email`, `password_reset`, `password_reset_at`, `grade`, `avatar`, `remember_token`, `created_at`, `confirmed_token`, `confirmed_sent_at`, `confirmed_at`) VALUES ('1', 'anonymous', NULL, 'anonymous', NULL, NULL, NOW(), 'member', NULL, NULL, NOW(), NULL, NOW(), NOW()); +INSERT INTO `users_infos` (`id_user`, `count_public_blueprint`, `count_public_comment`, `count_private_blueprint`, `count_private_comment`, `bio`, `link_website`, `link_facebook`, `link_twitter`, `link_github`, `link_twitch`, `link_unreal`, `link_youtube`) VALUES ('1', '0', '0', '0', '0', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/docker-examples/msmtpd.env b/docker-examples/msmtpd.env new file mode 100644 index 0000000..ddba0ae --- /dev/null +++ b/docker-examples/msmtpd.env @@ -0,0 +1,12 @@ +TZ=UTC +PUID=1500 +PGID=1500 +SMTP_HOST=_____REPLACE_ME_____ +SMTP_PORT=587 +SMTP_TLS=on +SMTP_STARTTLS=on +SMTP_TLS_CHECKCERT=on +SMTP_AUTH=on +SMTP_USER=_____REPLACE_ME_____ +SMTP_PASSWORD=_____REPLACE_ME_____ +SMTP_DOMAIN=localhost diff --git a/docker-examples/traefik-http.yml b/docker-examples/traefik-http.yml new file mode 100644 index 0000000..18f465a --- /dev/null +++ b/docker-examples/traefik-http.yml @@ -0,0 +1,18 @@ +global: + checkNewVersion: false + sendAnonymousUsage: false + +log: + level: "INFO" + +entryPoints: + http: + address: ":80" + +providers: + file: + filename: "/etc/traefik/traefik.yml" + watch: true + docker: + watch: true + exposedByDefault: false diff --git a/docker-examples/traefik-https.env b/docker-examples/traefik-https.env new file mode 100644 index 0000000..36406ce --- /dev/null +++ b/docker-examples/traefik-https.env @@ -0,0 +1,4 @@ +OVH_ENDPOINT=_____REPLACE_ME_____ +OVH_APPLICATION_KEY=_____REPLACE_ME_____ +OVH_APPLICATION_SECRET=_____REPLACE_ME_____ +OVH_CONSUMER_KEY=_____REPLACE_ME_____ diff --git a/docker-examples/traefik-https.yml b/docker-examples/traefik-https.yml new file mode 100644 index 0000000..437825e --- /dev/null +++ b/docker-examples/traefik-https.yml @@ -0,0 +1,34 @@ +global: + checkNewVersion: false + sendAnonymousUsage: false + +log: + level: "INFO" + +entryPoints: + http: + address: ":80" + http: + redirections: + entryPoint: + to: https + https: + address: ":443" + +providers: + file: + filename: "/etc/traefik/traefik.yml" + watch: true + docker: + watch: true + exposedByDefault: false + +certificatesResolvers: + ovh: + acme: + caServer: https://acme-staging-v02.api.letsencrypt.org/directory + storage: "acme.json" + email: "_____REPLACE_ME_____" + dnsChallenge: + provider: "ovh" + delayBeforeCheck: 10 diff --git a/rootfs/etc/cont-init.d/fix-perms.sh b/rootfs/etc/cont-init.d/fix-perms.sh index 0b9e659..38c87dc 100644 --- a/rootfs/etc/cont-init.d/fix-perms.sh +++ b/rootfs/etc/cont-init.d/fix-perms.sh @@ -19,6 +19,6 @@ chown -R blueprintue-self-hosted-edition. \ /tpls \ /var/lib/nginx \ /var/log/nginx \ - /var/log/php7 \ + /var/log/php82 \ /var/run/nginx \ /var/run/php-fpm diff --git a/rootfs/etc/cont-init.d/svc-main.sh b/rootfs/etc/cont-init.d/svc-main.sh index 8af0c9c..1259327 100644 --- a/rootfs/etc/cont-init.d/svc-main.sh +++ b/rootfs/etc/cont-init.d/svc-main.sh @@ -20,17 +20,17 @@ echo "Setting PHP-FPM configuration..." sed -e "s/@MEMORY_LIMIT@/$MEMORY_LIMIT/g" \ -e "s/@POST_MAX_SIZE@/$POST_MAX_SIZE/g" \ -e "s/@UPLOAD_MAX_FILESIZE@/$UPLOAD_MAX_FILESIZE/g" \ - /tpls/etc/php7/php-fpm.d/www.conf > /etc/php7/php-fpm.d/www.conf + /tpls/etc/php82/php-fpm.d/www.conf > /etc/php82/php-fpm.d/www.conf echo "Setting php.ini configuration..." -sed -i "s|memory_limit.*|memory_limit = ${MEMORY_LIMIT}|g" /etc/php7/php.ini -sed -i "s|;date\.timezone.*|date\.timezone = ${TZ}|g" /etc/php7/php.ini +sed -i "s|memory_limit.*|memory_limit = ${MEMORY_LIMIT}|g" /etc/php82/php.ini +sed -i "s|;date\.timezone.*|date\.timezone = ${TZ}|g" /etc/php82/php.ini # OpCache echo "Setting OpCache configuration..." sed -e "s/@OPCACHE_MEM_SIZE@/$OPCACHE_MEM_SIZE/g" \ -e "s/@OPCACHE_ENABLE@/$OPCACHE_ENABLE/g" \ - /tpls/etc/php7/conf.d/opcache.ini > /etc/php7/conf.d/opcache.ini + /tpls/etc/php82/conf.d/opcache.ini > /etc/php82/conf.d/opcache.ini # Nginx echo "Setting Nginx configuration..." @@ -54,6 +54,6 @@ cat > /etc/services.d/php-fpm/run <