From 18dd1f4175b73eeb0f95458fea548cf8685c5585 Mon Sep 17 00:00:00 2001 From: Antoni Kiszka Date: Sun, 23 Jul 2023 21:06:07 +0200 Subject: [PATCH] Add prod and dev modes --- .env | 2 ++ README.md | 49 +++++++++++++++++++++++++- caddy/Caddyfile | 12 +++++++ docker-compose.dev.yaml | 16 +++++++++ docker-compose.yaml | 54 ++++++++++++++++++++--------- nginx/Dockerfile | 12 +++++++ nginx/docker.conf | 1 + php/Dockerfile | 76 +++++++++++++++++------------------------ php/docker-config.ini | 1 - php/fpm.conf | 10 ++++++ 10 files changed, 170 insertions(+), 63 deletions(-) create mode 100644 caddy/Caddyfile create mode 100644 docker-compose.dev.yaml create mode 100644 nginx/Dockerfile create mode 100644 php/fpm.conf diff --git a/.env b/.env index 1a50c08..3efc638 100644 --- a/.env +++ b/.env @@ -2,3 +2,5 @@ MARIADB_ROOT_PASSWORD=example MARIADB_DATABASE=yetiforce MARIADB_USER=yeti MARIADB_PASSWORD=yeti +HOSTNAME=yeti +TLS_EMAIL=internal \ No newline at end of file diff --git a/README.md b/README.md index a804221..371ec1a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,49 @@ -# docker +# YetiForceCRM Docker + Official YetiForce Docker image + +## Instructions + +### Production + +To start YetiForce in a production configuration: +1. In the `.env` file set the `HOSTNAME` to the where you will be running YetiForce and set `TLS_EMAIL` to your email address. Those settings will make sure that your website has a proper TLS certificate. +2. Download the YetiForce code: `git submodule update --init`. +3. Run `docker compose up -d`. +4. Go to `https://HOSTNAME` and go through the installation process. For your database settings, enter: + - Address: db + - Port: 3306 + - Username: yeti + - Password: yeti + - Database name: yetiforce + +### Development + +This image can also work in development mode. This mode is designed for actively making changes in YF itself. As such, it includes the following changes: +- YetiForce is run from the `./YetiForceCRM` directory +- MariaDB is available on `localhost:3306` +- PHP has a development configuration + +This means that you will be able to make changes in `./YetiForceCRM`, see them reflected in your browser, and commit them normally. + +To run in this mode: +1. Add a line with `127.0.0.1 yeti` to `/etc/hosts` on Unix or `C:\Windows\System32\drivers\etc\hosts` on Windows. +2. Download the YetiForce code: `git submodule update --init`. +3. Install YetiForce dependencies: + ```shell + cd ./YetiForceCRM + install -m755 -d YetiForceCRM/config/Modules + yarn install --modules-folder "./public_html/libraries" --ignore-optional --production=true + cd public_html/src + yarn install --ignore-optional --production=true + cd ../.. + composer --no-interaction install --no-dev + cd .. + ``` +4. Start the server with `docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up -d` +4. Go to `https://HOSTNAME` and go through the installation process. For your database settings, enter: + - Address: db + - Port: 3306 + - Username: yeti + - Password: yeti + - Database name: yetiforce diff --git a/caddy/Caddyfile b/caddy/Caddyfile new file mode 100644 index 0000000..98dbb41 --- /dev/null +++ b/caddy/Caddyfile @@ -0,0 +1,12 @@ +{ + auto_https disable_redirects +} + +{$HOSTNAME}:443 { + tls {$TLS_EMAIL} + reverse_proxy nginx:80 +} + +{$HOSTNAME}:80 { + reverse_proxy nginx:80 +} \ No newline at end of file diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml new file mode 100644 index 0000000..5bf984b --- /dev/null +++ b/docker-compose.dev.yaml @@ -0,0 +1,16 @@ +name: yetiforce-dev +version: '3' +services: + db: + ports: + - 3306:3306 + php: + build: + target: php-dev + volumes: + - type: bind + source: ./YetiForceCRM + target: /var/www/html + +volumes: + crm_data: null \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 92f3ad0..3c7476d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,29 +1,53 @@ +name: yetiforce version: '3' services: + caddy: + hostname: ${HOSTNAME} + image: caddy:2.6 + depends_on: + - nginx + env_file: + - .env + restart: on-failure + ports: + - "80:80" + - "443:443" + - "443:443/udp" + volumes: + - ./caddy/Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + - caddy_config:/config db: build: context: . dockerfile: ./mariadb/Dockerfile env_file: - .env + restart: on-failure volumes: - type: volume source: db_data target: /var/lib/mysql - ports: - - 3306:3306 - nginx: - hostname: yeti + php: build: context: . dockerfile: ./php/Dockerfile - target: nginx + target: php-prod + restart: on-failure volumes: - type: volume source: crm_data target: /var/www/html - ports: - - 80:80 + nginx: + build: + context: . + dockerfile: ./nginx/Dockerfile + target: nginx + depends_on: + - php + restart: on-failure + volumes_from: + - php:rw cron: build: context: ./cron @@ -32,14 +56,12 @@ services: condition: on-failure delay: 60s volumes_from: - - nginx:ro - php: - build: - context: . - dockerfile: ./php/Dockerfile - target: php-prod - volumes_from: - - nginx:rw + - php:ro + depends_on: + - nginx + volumes: crm_data: - db_data: \ No newline at end of file + db_data: + caddy_data: + caddy_config: diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000..c85bea1 --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,12 @@ +FROM nginx:stable AS nginx + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update && \ + apt-get install --no-install-recommends -y \ + nginx-extras \ + && apt-get clean \ + && rm -rf /etc/nginx/conf.d/* /etc/nginx/sites-enabled/* /var/lib/apt/lists/* + +COPY ./YetiForceCRM/tests/setup/nginx/yetiforce.conf /etc/nginx/yetiforce.conf +COPY ./nginx/docker.conf /etc/nginx/conf.d/default.conf diff --git a/nginx/docker.conf b/nginx/docker.conf index f4cb77c..8fb86a1 100644 --- a/nginx/docker.conf +++ b/nginx/docker.conf @@ -1,6 +1,7 @@ ############################################## # Best configuration for YetiForceCRM # # Created by m.krzaczkowski@yetiforce.com # +# Modified to work with Docker # ############################################## # HTTP server { diff --git a/php/Dockerfile b/php/Dockerfile index 39e3265..42db60f 100644 --- a/php/Dockerfile +++ b/php/Dockerfile @@ -12,30 +12,30 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ libpng-dev \ libxml2-dev \ libzip-dev \ + unixodbc-dev \ zlib1g-dev \ && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ && docker-php-ext-install -j8 imap pdo_mysql curl gd xml zip soap iconv intl bcmath sockets exif ldap opcache \ - && apt-get clean + && apt-get clean \ + && printf "\n" | pecl install imagick \ + && docker-php-ext-enable imagick \ + && printf "\n" | pecl install apcu \ + && docker-php-ext-enable apcu \ + && pecl install pdo_sqlsrv \ + && docker-php-ext-enable pdo_sqlsrv \ + && pecl cache-clear \ + && rm -rf /tmp/pear -WORKDIR /opt +FROM node:18-alpine AS build-yarn -# docker-php-ext-* does not work with the imagick extension; it must be compiled manually -RUN curl -sL https://github.com/Imagick/imagick/archive/refs/tags/3.7.0.tar.gz -o imagick.tar.gz \ - && tar -xzf imagick.tar.gz \ - && cd imagick-3.7.0 \ - && phpize \ - && ./configure \ - && make \ - && make install \ - && docker-php-ext-enable imagick \ - && cd .. \ - && rm -rf imagick.tar.gz imagick-3.7.0 +RUN apk add --no-cache git -FROM php-base AS php-prod +COPY ./YetiForceCRM /opt/YetiForceCRM +WORKDIR /opt/YetiForceCRM +RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn rm .git && yarn install --modules-folder "./public_html/libraries" --ignore-optional --production=true +WORKDIR /opt/YetiForceCRM/public_html/src +RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --ignore-optional --production=true -RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" -COPY ./YetiForceCRM/tests/setup/php/prod.ini /usr/local/etc/php/conf.d -COPY ./php/docker-config.ini /usr/local/etc/php/conf.d FROM php-base AS build-composer @@ -45,38 +45,24 @@ RUN php -r "copy('https://raw.githubusercontent.com/composer/getcomposer.org/705 && php -r "unlink('composer-setup.php');" \ && mv composer.phar /usr/local/bin/composer -COPY ./YetiForceCRM /opt/YetiForceCRM +COPY --from=build-yarn /opt/YetiForceCRM /opt/YetiForceCRM WORKDIR /opt/YetiForceCRM RUN --mount=type=cache,target=/root/.composer/cache composer --no-interaction install --no-dev -FROM node:18-alpine AS build-yarn - -RUN apk add --no-cache git - -COPY --from=build-composer /opt/YetiForceCRM /opt/YetiForceCRM -WORKDIR /opt/YetiForceCRM -RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn rm .git && yarn install --modules-folder "./public_html/libraries" --ignore-optional --production=true -WORKDIR /opt/YetiForceCRM/public_html/src -RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --ignore-optional --production=true - -FROM scratch AS app-data - -COPY --from=build-yarn /opt/YetiForceCRM /var/www/html - -FROM nginx:stable AS nginx +FROM php-base AS php-prod -SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" +COPY ./YetiForceCRM/tests/setup/php/prod.ini /usr/local/etc/php/conf.d +COPY ./php/docker-config.ini /usr/local/etc/php/conf.d +COPY ./php/fpm.conf /usr/local/etc/php-fpm.d/zzz-docker.conf -RUN apt-get update && \ - apt-get install --no-install-recommends -y \ - nginx-extras \ - && apt-get clean \ - && rm -rf /etc/nginx/conf.d/* /etc/nginx/sites-enabled/* /var/lib/apt/lists/* +WORKDIR /var/www/html +COPY --from=build-composer --chown=www-data:www-data --chmod=644 /opt/YetiForceCRM/ /var/www/html +RUN install -owww-data -gwww-data -m755 -d config/Modules && find . -type d -exec chown www-data:www-data -- {} \+ && find . -type d -exec chmod 755 -- {} \+ -COPY ./YetiForceCRM/tests/setup/nginx/yetiforce.conf /etc/nginx/yetiforce.conf -COPY ./nginx/docker.conf /etc/nginx/conf.d/default.conf +FROM php-base AS php-dev -WORKDIR /var/www/html -# fixme - 666 and 777 are not secure -COPY --from=build-yarn --chown=www-data:www-data --chmod=666 /opt/YetiForceCRM/ /var/www/html -RUN install -owww-data -gwww-data -m777 -d config/Modules && find . -type d -exec chown www-data:www-data -- {} \+ && find . -type d -exec chmod 755 -- {} \+ +RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" +COPY ./YetiForceCRM/tests/setup/php/dev.ini /usr/local/etc/php/conf.d +COPY ./php/docker-config.ini /usr/local/etc/php/conf.d +COPY ./php/fpm.conf /usr/local/etc/php-fpm.d/zzz-docker.conf \ No newline at end of file diff --git a/php/docker-config.ini b/php/docker-config.ini index 845e4ec..6416f4d 100644 --- a/php/docker-config.ini +++ b/php/docker-config.ini @@ -1,2 +1 @@ -open_basedir="/var/www/html" session.cookie_samesite="Strict" diff --git a/php/fpm.conf b/php/fpm.conf new file mode 100644 index 0000000..743aaea --- /dev/null +++ b/php/fpm.conf @@ -0,0 +1,10 @@ +[www] + +env[PROVIDER] = docker +php_admin_value[error_log] = /var/log/php/fpm_yfprod_error.log +php_admin_value[open_basedir] = /var/www/html/:/tmp/:/var/tmp/:/etc/nginx/ssl/:/etc/ssl/:/usr/bin/gpg:/usr/bin/gpg-agent:/usr/bin/gpgconf +clear_env = no +request_terminate_timeout = 600 +pm.process_idle_timeout = 600s; +pm.max_requests = 5000 +catch_workers_output = yes