diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..35983cc --- /dev/null +++ b/.env.example @@ -0,0 +1,31 @@ +# ID to uses in docker file. +PUID=1000 +PGID=1000 + +# Timezone of the application. +TIMEZONE=UTC + +# If `SKIP_PERMISSIONS_CHECKS` is set to "yes", the entrypoint script will not check or set the permissions of files and directories on startup. +# SKIP_PERMISSIONS_CHECKS=false + +# Set up the cache driver, use either "redis" or "file" +# CACHE_DRIVER=redis + +# It is safer to use file cache driver for the log viewer. +# That way, if your application is running Redis and crashes, you will still be able to access the logs. +LOG_VIEWER_CACHE_DRIVER=file + +# Default app URL +# APP_URL=http://localhost + +# Redis configuration +# REDIS_PORT=6379 +# REDIS_USERNAME=default +# REDIS_PASSWORD= +# REDIS_HOST=lychee_redis + +# Database configuration +# DB_ROOT_PASSWORD=rootpassword +# DB_DATABASE=lychee +# DB_USERNAME=lychee +# DB_PASSWORD=lychee \ No newline at end of file diff --git a/.github/workflows/build_branch.yml b/.github/workflows/build_branch.yml index 34883c2..70e4663 100644 --- a/.github/workflows/build_branch.yml +++ b/.github/workflows/build_branch.yml @@ -118,7 +118,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set Password run: "sed -i 's/<.*_PASSWORD>/password/g' docker-compose.yml" diff --git a/.github/workflows/pull.yml b/.github/workflows/pull.yml index c0030ab..9fce77c 100644 --- a/.github/workflows/pull.yml +++ b/.github/workflows/pull.yml @@ -25,7 +25,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Test multiarch building - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm/v7,linux/arm64 @@ -35,7 +35,7 @@ jobs: lycheeorg/lychee:testing-${{ github.run_id }} - name: Save amd64 image to pass to testing - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64 @@ -54,7 +54,7 @@ jobs: sha256sum artifact/lychee.tar || echo 0 - name: Store as artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: artifact path: ./artifact diff --git a/.github/workflows/test_pull.yml b/.github/workflows/test_pull.yml index d9eb164..e8d3f44 100644 --- a/.github/workflows/test_pull.yml +++ b/.github/workflows/test_pull.yml @@ -28,7 +28,7 @@ jobs: steps: - name: 'Download artifact' - uses: actions/github-script@v3.1.0 + uses: actions/github-script@v7 with: script: | var artifacts = await github.actions.listWorkflowRunArtifacts({ @@ -59,7 +59,7 @@ jobs: - name: "Create check" id: create_check - uses: actions/github-script@v6 + uses: actions/github-script@v7 env: parameter_url: '${{ github.event.workflow_run.html_url }}' with: @@ -80,7 +80,7 @@ jobs: run: docker image load -i ./lychee.tar - name: Login to DockerHub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -234,7 +234,7 @@ jobs: steps: - name: "Update check" - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | await github.rest.checks.update({ diff --git a/Dockerfile b/Dockerfile index 94be31d..e332660 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim as base +FROM debian:bookworm-slim AS base # Set version label LABEL maintainer="lycheeorg" @@ -93,7 +93,7 @@ RUN \ # Multi-stage build: Build static assets # This allows us to not include Node within the final container -FROM node:20 as static_builder +FROM node:20 AS static_builder RUN mkdir /app diff --git a/README.md b/README.md index a050f33..abd74ae 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,18 @@ ![Supports arm64/aarch64 Architecture][arm64-shield] ![Supports armv7 Architecture][armv7-shield] -## Notice: Dockerhub repository has been migrated to [lycheeorg/lychee](https://hub.docker.com/r/lycheeorg/lychee) -**Make sure you update your docker-compose files accordingly** - ## Table of Contents -- [Image content](#image-content) +- [Table of Contents](#table-of-contents) +- [Image Content](#image-content) - [Setup](#setup) - [Quick Start](#quick-start) - [Prerequisites](#prerequisites) - [Run with Docker](#run-with-docker) - [Run with Docker Compose](#run-with-docker-compose) + - [Create admin account during first run](#create-admin-account-during-first-run) + - [Docker secrets](#docker-secrets) - [Available environment variables and defaults](#available-environment-variables-and-defaults) -- [Advanced configuration](#advanced-configuration) ## Image Content @@ -91,9 +90,19 @@ alter user 'lychee' identified with mysql_native_password by ''; ### Run with Docker Compose -Change the environment variables in the [provided example](./docker-compose.yml) to reflect your database credentials. +You can take the provided docker-compose.yml example as a start and edit it to enable more configuration variables. + +Use the `.env.exanple` to create a `.env` at the root of your folder containing your `docker-compose.yml`. +Populate your database credentials and other environment variables. + +This `.env` file will be loaded by docker compose and populate environment in the docker container. +Those will then be injected in the Lychee configuration file (located in e.g. `lychee/config/.env`). -Note that in order to avoid writing credentials directly into the file, you can create a `db_secrets.env` and use the `env_file` directive (see the [docs](https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option)). +![environment-loading.png](./environment-loading.png) + +:warning: If you later edit your `lychee/config/.env` file, restarting the container will overwrite those variables with the ones provided in your docker-compose `.env` file. +For this reason it is better to make your changes directly in `docker-compose.yml`/`.env` rather than in `lychee/config/.env` when the values are supported. +Please refer to the [inject.sh](https://github.com/LycheeOrg/Lychee/blob/master/inject.sh) script for more details. ### Create admin account during first run @@ -114,7 +123,7 @@ The following _FILE variables are supported: ## Available environment variables and defaults -If you do not provide environment variables or `.env` file, the [example .env file](https://github.com/LycheeOrg/Lychee/blob/master/.env.example) will be used with some values already set by default. +If you do not provide environment variables or `.env` file, Lychee's [example .env file](https://github.com/LycheeOrg/Lychee/blob/master/.env.example) will be used with some values already set by default inside the docker container. Some variables are specific to Docker, and the default values are : @@ -126,22 +135,6 @@ Some variables are specific to Docker, and the default values are : Additionally, if `SKIP_PERMISSIONS_CHECKS` is set to "yes", the entrypoint script will not check or set the permissions of files and directories on startup. Users are strongly advised **against** using this option, and efforts have been made to keep the checks as fast as possible. Nonetheless, it may be suitable for some advanced use cases. -## Advanced configuration - -Note that nginx will accept by default images up to 100MB (`client_max_body_size 100M`) and that PHP parameters are overridden according to the [recommendations of the Lychee FAQ](https://lycheeorg.github.io/docs/faq.html#i-cant-upload-large-photos). - -You may still want to further customize PHP configuration. The first method is to mount a custom `php.ini` to `/etc/php/8.2/fpm/php.ini` when starting the container. However, this method is kind of brutal as it will override all parameters. It will also need to be remapped whenever an image is released with a new version of PHP. - -Instead, we recommend to use the `PHP_VALUE` directive of PHP-FPM to override specific parameters. To do so, you will need to mount a custom `nginx.conf` in your container : - -1. Take the [default.conf](./default.conf) file as a base -2. Find the line starting by `fastcgi_param PHP_VALUE [...]` -3. Add a new line and set your new parameter -4. Add or change any other parameters (e.g. `client_max_body_size`) -5. Mount your new file to `/etc/nginx/nginx.conf` - -If you need to add (not change) nginx directives, files mounted in `/etc/nginx/conf.d/` will be included in the `http` context. - [arm64-shield]: https://img.shields.io/badge/arm64-yes-success.svg?style=flat [amd64-shield]: https://img.shields.io/badge/amd64-yes-success.svg?style=flat [armv7-shield]: https://img.shields.io/badge/armv7-yes-success.svg?style=flat diff --git a/docker-compose.yml b/docker-compose.yml index b19a4da..c651e3c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,14 +5,33 @@ #------------------------------------------- services: + lychee_cache: + image: redis:alpine + container_name: lychee_redis + hostname: lychee_redis + security_opt: + - no-new-privileges:true + healthcheck: + test: ["CMD-SHELL", "redis-cli ping || exit 1"] + ports: + - ${REDIS_PORT:-6379}:${REDIS_PORT:-6379} + user: 1026:100 + environment: + - TZ=${TIMEZONE:-UTC} + networks: + - lychee + volumes: + - cache:/data:rw + restart: on-failure:5 + lychee_db: container_name: lychee_db image: mariadb:10 environment: - - MYSQL_ROOT_PASSWORD= - - MYSQL_DATABASE=lychee - - MYSQL_USER=lychee - - MYSQL_PASSWORD= + - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD:-rootpassword} + - MYSQL_DATABASE=${DB_DATABASE:-lychee} + - MYSQL_USER=${DB_USERNAME:-lychee} + - MYSQL_PASSWORD=${DB_PASSWORD} expose: - 3306 volumes: @@ -22,7 +41,7 @@ services: restart: unless-stopped lychee: - image: lycheeorg/lychee + image: lycheeorg/lychee:nightly container_name: lychee ports: - 90:80 @@ -38,13 +57,13 @@ services: #- PUID=1000 #- PGID=1000 # PHP timezone e.g. PHP_TZ=America/New_York - - PHP_TZ=UTC - - TIMEZONE=UTC + - PHP_TZ=${TIMEZONE:-UTC} + - TIMEZONE=${TIMEZONE:-UTC} #- APP_NAME=Laravel #- APP_ENV=local #- APP_DEBUG=true #- APP_FORCE_HTTPS=false - #- APP_URL=http://localhost + - APP_URL=${APP_URL:-http://localhost} #- APP_DIR= #- DEBUGBAR_ENABLEd=false #- VUEJS_ENABLED=true @@ -53,10 +72,10 @@ services: #- DB_OLD_LYCHEE_PREFIX='' - DB_CONNECTION=mysql - DB_HOST=lychee_db - - DB_PORT=3306 - - DB_DATABASE=lychee - - DB_USERNAME=lychee - - DB_PASSWORD= + - DB_PORT=${DB_PORT:-3306} + - DB_DATABASE=${DB_DATABASE:-lychee} + - DB_USERNAME=${DB_USERNAME:-lychee} + - DB_PASSWORD=${DB_PASSWORD} #- DB_PASSWORD_FILE= #- DB_LOG_SQL=false #- DB_LOG_SQL_EXPLAIN=false @@ -79,16 +98,17 @@ services: #- MAIL_FROM_NAME= #- MAIL_FROM_ADDRESS= #- TRUSTED_PROXIES= - #- SKIP_PERMISSIONS_CHECKS + - SKIP_PERMISSIONS_CHECKS=${SKIP_PERMISSIONS_CHECKS:-false} - STARTUP_DELAY=30 #- ADMIN_USER=admin #- ADMIN_PASSWORD= #- ADMIN_PASSWORD_FILE= - ### Unused in Lychee - #- REDIS_HOST=127.0.0.1 - #- REDIS_PASSWORD=null - #- REDIS_PASSWORD_FILE= - #- REDIS_PORT=6379 + - CACHE_DRIVER=${CACHE_DRIVER:-redis} + - REDIS_URL=redis://${REDIS_USERNAME:-default}:${REDIS_PASSWORD:-}@${REDIS_HOST:-lychee_redis}:${REDIS_PORT:-6379} + - REDIS_HOST=${REDIS_HOST:-lychee_redis} + - REDIS_PORT=${REDIS_PORT:-6379} + - REDIS_PASSWORD=${REDIS_PASSWORD:-} + - LOG_VIEWER_CACHE_DRIVER=${LOG_VIEWER_CACHE_DRIVER:-file} restart: unless-stopped depends_on: - lychee_db @@ -98,3 +118,8 @@ networks: volumes: mysql: + name: lychee_prod_mysql + driver: local + cache: + name: lychee_prod_redis + driver: local diff --git a/environment-loading.png b/environment-loading.png new file mode 100644 index 0000000..8ca4164 Binary files /dev/null and b/environment-loading.png differ diff --git a/inject.sh b/inject.sh index f104e50..4be92dc 100755 --- a/inject.sh +++ b/inject.sh @@ -112,6 +112,9 @@ if [ "$ENABLE_TOKEN_AUTH" != '' ]; then if [ "$CACHE_DRIVER" != '' ]; then replace_or_insert "CACHE_DRIVER" "$CACHE_DRIVER" fi +if [ "$LOG_VIEWER_CACHE_DRIVER" != '' ]; then + replace_or_insert "LOG_VIEWER_CACHE_DRIVER" "$LOG_VIEWER_CACHE_DRIVER" + fi if [ "$SESSION_DRIVER" != '' ]; then replace_or_insert "SESSION_DRIVER" "$SESSION_DRIVER" fi @@ -133,24 +136,27 @@ if [ "$SECURITY_HEADER_SCRIPT_SRC_ALLOW" != '' ]; then if [ "$SESSION_SECURE_COOKIE" != '' ]; then replace_or_insert "SESSION_SECURE_COOKIE" "$SESSION_SECURE_COOKIE" fi -# if [ "$REDIS_SCHEME" != '' ]; then -# sed -i "s|REDIS_SCHEME=.*|REDIS_SCHEME=${REDIS_SCHEME}|i" /conf/.env -# fi -# if [ "$REDIS_PATH" != '' ]; then -# sed -i "s|REDIS_PATH=.*|REDIS_PATH=${REDIS_PATH}|i" /conf/.env -# fi -# if [ "$REDIS_HOST" != '' ]; then -# sed -i "s|REDIS_HOST=.*|REDIS_HOST=${REDIS_HOST}|i" /conf/.env -# fi -# if [ "$REDIS_PORT" != '' ]; then -# sed -i "s|REDIS_PORT=.*|REDIS_PORT=${REDIS_PORT}|i" /conf/.env -# fi -# if [ "$REDIS_PASSWORD" != '' ]; then -# sed -i "s|REDIS_PASSWORD=.*|REDIS_PASSWORD=${REDIS_PASSWORD}|i" /conf/.env -# elif [ "$REDIS_PASSWORD_FILE" != '' ]; then -# value=$(<$REDIS_PASSWORD_FILE) -# sed -i "s|REDIS_PASSWORD=.*|REDIS_PASSWORD=${value}|i" /conf/.env -# fi +if [ "$REDIS_URL" != '' ]; then + replace_or_insert "REDIS_URL" "$REDIS_URL" + fi +if [ "$REDIS_PATH" != '' ]; then + replace_or_insert "REDIS_PATH" "$REDIS_PATH" + fi +if [ "$REDIS_HOST" != '' ]; then + replace_or_insert "REDIS_HOST" "$REDIS_HOST" + fi +if [ "$REDIS_PORT" != '' ]; then + replace_or_insert "REDIS_PORT" "$REDIS_PORT" + fi +if [ "$REDIS_USERNAME" != '' ]; then + replace_or_insert "REDIS_USERNAME" "$REDIS_USERNAME" + fi +if [ "$REDIS_PASSWORD" != '' ]; then + replace_or_insert "REDIS_PASSWORD" "$REDIS_PASSWORD" +elif [ "$REDIS_PASSWORD_FILE" != '' ]; then + value=$(<$REDIS_PASSWORD_FILE) + replace_or_insert "REDIS_PASSWORD" "$value" +fi if [ "$MAIL_DRIVER" != '' ]; then replace_or_insert "MAIL_DRIVER" "$MAIL_DRIVER" fi