diff --git a/.gitignore b/.gitignore index 1c2d52b..8ff3812 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .idea/* +.DS_Store +Docker/ diff --git a/Docker/.env.template b/Docker/.env.template new file mode 100644 index 0000000..b02237a --- /dev/null +++ b/Docker/.env.template @@ -0,0 +1,30 @@ +COMPOSE_PROJECT_NAME=zip-magento2 + +ZIPMONEY_SANDBOX_PUBLIC_KEY= +ZIPMONEY_SANDBOX_PRIVATE_KEY= +MAGE_REPO_PUBLIC_KEY= +MAGE_REPO_PRIVATE_KEY= + +MAGENTO_VERSION=2.4.5-p1 +PHP_VERSION=8.1.1 +ELASTICSEARCH_VERSION=7.17.8 +MARIADB_VERSION=10.4 + +MAGENTO_ADMIN_EMAIL=admin@zip.local +MAGENTO_ADMIN_FIRSTNAME=Shitiz +MAGENTO_ADMIN_LASTNAME=Garg +MAGENTO_ADMIN_USERNAME=admin +MAGENTO_ADMIN_PASSWORD=Testing1234; +MAGENTO_ENCRYPTION_KEY=d25657075d00b940ff37edd2f8ecd4df + +MAGENTO_HOST=localhost +MAGENTO_EXTERNAL_HTTP_PORT=8080 +MAGENTO_EXTERNAL_HTTPS_PORT=8443 +MAGENTO_DATABASE_HOST=mariadb +MAGENTO_DATABASE_PORT=3306 +MAGENTO_DATABASE_USER=bn_magento +MAGENTO_DATABASE_NAME=bitnami_magento +MAGENTO_DATABASE_PASSWORD=test1234 +ELASTICSEARCH_HOST=elasticsearch +ELASTICSEARCH_PORT=9200 +SENDMAIL_PATH='/usr/local/bin/mhsendmail --smtp-addr="mailhog:1025"' \ No newline at end of file diff --git a/Docker/docker-compose.yml b/Docker/docker-compose.yml new file mode 100644 index 0000000..3428ff5 --- /dev/null +++ b/Docker/docker-compose.yml @@ -0,0 +1,96 @@ +version: '3' +services: + mariadb: + image: mariadb:$MARIADB_VERSION + environment: + - MARIADB_USER=$MAGENTO_DATABASE_USER + - MARIADB_DATABASE=$MAGENTO_DATABASE_NAME + - MARIADB_PASSWORD=$MAGENTO_DATABASE_PASSWORD + - MARIADB_ROOT_PASSWORD=$MAGENTO_DATABASE_PASSWORD + volumes: + - 'mariadb:/var/lib/mysql' + + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:$ELASTICSEARCH_VERSION + volumes: + - 'elasticsearch:/usr/share/elasticsearch/data' + environment: + - discovery.type=single-node + - xpack.security.enabled=false + - "ES_JAVA_OPTS=-Xms2G -Xmx2G" + ulimits: + memlock: + soft: -1 + hard: -1 + + # Note: This image purely exists to install and build Magento. The primary reason we separated out CLI and FPM + # are because: + # 1) Cannot mount Zip plugin properly before composer has installed because then /app/app/code directory wouldn't be empty + # and composer would refuse installation. PS: Mounting to a separate directory and symlinking doesn't work either, + # since Magento keeps throwing an error that templates are outside Magento's root. The solution was to have a separate image + # which copies the plugin files into module directory after composer has setup Magento, installs the module, deletes the module + # then transfer the files into the Web VM where the plugin is directly mounted from the source files. + # 2) It is way faster on macOS to build within a Docker VM then move the files to outside FS for persistance then it is + # to install the files on a mounted folder. + php-cli-magento: + build: + context: ./php-cli-magento + args: + PHP_VERSION: ${PHP_VERSION} + env_file: + - './.env' + volumes: + - 'magento:/app-dest' + - '..:/magento-zip' + - '/magento-zip/Docker' + - '/magento-zip/.git' + - 'composer:/composer' + depends_on: + - mariadb + - elasticsearch + + # Serves Magento using PHP-FPM + php-fpm-magento: + build: + context: ./php-fpm-magento + args: + PHP_VERSION: ${PHP_VERSION:-8.1.1} + ports: + - 9000:9000 + env_file: + - './.env' + volumes: + - 'magento:/app' + - '..:/app/app/code/Zip/ZipPayment' + - '/app/app/code/Zip/ZipPayment/.git' + - '/app/app/code/Zip/ZipPayment/Docker' + depends_on: + - mariadb + - elasticsearch + - php-cli-magento + + nginx: + build: ./nginx + depends_on: + - php-fpm-magento + ports: + - 8000:80 + - 8080:8080 + environment: + - FPM_HOST=php-fpm-magento + restart: unless-stopped + volumes: + - 'magento:/app' + + mailhog: + hostname: $MAGENTO_HOST + image: 'mailhog/mailhog:latest' + ports: + - '1025:1025' + - '8025:8025' + +volumes: + mariadb: + elasticsearch: + magento: + composer: \ No newline at end of file diff --git a/Docker/nginx/Dockerfile b/Docker/nginx/Dockerfile new file mode 100644 index 0000000..1f4b3c2 --- /dev/null +++ b/Docker/nginx/Dockerfile @@ -0,0 +1,40 @@ +FROM nginx:1.19 + +ENV UPLOAD_MAX_FILESIZE 64M +ENV XDEBUG_HOST fpm_xdebug +ENV FPM_HOST fpm +ENV FPM_PORT 9000 +ENV UPSTREAM_HOST 127.0.0.1 +ENV UPSTREAM_PORT 8080 +ENV MAGENTO_ROOT /app +ENV MAGENTO_RUN_MODE developer +ENV MFTF_UTILS 0 +ENV DEBUG false +ENV NGINX_WORKER_PROCESSES 1 +ENV NGINX_WORKER_CONNECTIONS 1024 + +COPY etc/nginx.conf /etc/nginx/ +COPY etc/vhost.conf /etc/nginx/conf.d/default.conf +COPY etc/xdebug-upstream.conf /etc/nginx/conf.d/xdebug/upstream.conf + +RUN mkdir /etc/nginx/ssl + +RUN apt-get update && \ + apt-get install -y openssl + +RUN openssl req -x509 -newkey rsa:2048 -sha256 -days 730 -nodes \ + -keyout /etc/nginx/ssl/magento.key -out /etc/nginx/ssl/magento.crt \ + -subj "/C=US/ST=TX/L=Austin/O=Adobe Commerce/OU=Cloud Docker/CN=magento2.docker" \ + -addext "subjectAltName=DNS:magento2.docker,DNS:www.magento2.docker" + +VOLUME ${MAGENTO_ROOT} + +COPY docker-entrypoint.sh /docker-entrypoint.sh +RUN ["chmod", "+x", "/docker-entrypoint.sh"] +ENTRYPOINT ["/docker-entrypoint.sh"] + +EXPOSE 443 + +WORKDIR ${MAGENTO_ROOT} + +CMD ["nginx", "-g", "daemon off;"] diff --git a/Docker/nginx/docker-entrypoint.sh b/Docker/nginx/docker-entrypoint.sh new file mode 100755 index 0000000..c8bd038 --- /dev/null +++ b/Docker/nginx/docker-entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +[ "$DEBUG" = "true" ] && set -x + +VHOST_FILE="/etc/nginx/conf.d/default.conf" +NGINX_FILE="/etc/nginx/nginx.conf" +XDEBUG_UPSTREAM_FILE="/etc/nginx/conf.d/xdebug/upstream.conf" + +[ ! -z "${FPM_HOST}" ] && sed -i "s/!FPM_HOST!/${FPM_HOST}/" $VHOST_FILE +[ ! -z "${XDEBUG_HOST}" ] && sed -i "s/!XDEBUG_HOST!/${XDEBUG_HOST}/" $XDEBUG_UPSTREAM_FILE +[ ! -z "${FPM_PORT}" ] && sed -i "s/!FPM_PORT!/${FPM_PORT}/" $VHOST_FILE +[ ! -z "${FPM_PORT}" ] && sed -i "s/!FPM_PORT!/${FPM_PORT}/" $XDEBUG_UPSTREAM_FILE +[ ! -z "${UPSTREAM_HOST}" ] && sed -i "s/!UPSTREAM_HOST!/${UPSTREAM_HOST}/" $VHOST_FILE +[ ! -z "${UPSTREAM_PORT}" ] && sed -i "s/!UPSTREAM_PORT!/${UPSTREAM_PORT}/" $VHOST_FILE +[ ! -z "${MAGENTO_ROOT}" ] && sed -i "s#!MAGENTO_ROOT!#${MAGENTO_ROOT}#" $VHOST_FILE +[ ! -z "${MAGENTO_RUN_MODE}" ] && sed -i "s/!MAGENTO_RUN_MODE!/${MAGENTO_RUN_MODE}/" $VHOST_FILE +[ ! -z "${MFTF_UTILS}" ] && sed -i "s/!MFTF_UTILS!/${MFTF_UTILS}/" $VHOST_FILE +[ ! -z "${UPLOAD_MAX_FILESIZE}" ] && sed -i "s/!UPLOAD_MAX_FILESIZE!/${UPLOAD_MAX_FILESIZE}/" $VHOST_FILE +[ ! -z "${WITH_XDEBUG}" ] && sed -i "s/!WITH_XDEBUG!/${WITH_XDEBUG}/" $VHOST_FILE +[ "${WITH_XDEBUG}" == "1" ] && sed -i "s/#include_xdebug_upstream/include/" $NGINX_FILE +[ ! -z "${NGINX_WORKER_PROCESSES}" ] && sed -i "s/!NGINX_WORKER_PROCESSES!/${NGINX_WORKER_PROCESSES}/" $NGINX_FILE +[ ! -z "${NGINX_WORKER_CONNECTIONS}" ] && sed -i "s/!NGINX_WORKER_CONNECTIONS!/${NGINX_WORKER_CONNECTIONS}/" $NGINX_FILE + +# Check if the nginx syntax is fine, then launch. +nginx -t + +exec "$@" diff --git a/Docker/nginx/etc/nginx.conf b/Docker/nginx/etc/nginx.conf new file mode 100644 index 0000000..530fb8b --- /dev/null +++ b/Docker/nginx/etc/nginx.conf @@ -0,0 +1,34 @@ +worker_processes !NGINX_WORKER_PROCESSES!; + +error_log /var/log/nginx/error.log debug; +pid /var/run/nginx.pid; + +events { + # this should be equal to value of "ulimit -n" + # reference: https://www.digitalocean.com/community/tutorials/how-to-optimize-nginx-configuration + worker_connections !NGINX_WORKER_CONNECTIONS!; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main + '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + client_max_body_size 20M; + + #include_xdebug_upstream /etc/nginx/conf.d/xdebug/upstream.conf; + include /etc/nginx/conf.d/*.conf; +} diff --git a/Docker/nginx/etc/vhost.conf b/Docker/nginx/etc/vhost.conf new file mode 100755 index 0000000..690bbcd --- /dev/null +++ b/Docker/nginx/etc/vhost.conf @@ -0,0 +1,228 @@ +upstream fastcgi_backend { + server !FPM_HOST!:!FPM_PORT!; # Variables: FPM_HOST FPM_PORT +} + +server { + listen 80; + listen 443 ssl; + + server_name _; + + ssl_certificate /etc/nginx/ssl/magento.crt; + ssl_certificate_key /etc/nginx/ssl/magento.key; + + location / { + proxy_pass http://!UPSTREAM_HOST!:!UPSTREAM_PORT!; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffer_size 128k; + proxy_buffers 4 256k; + proxy_busy_buffers_size 256k; + } +} + +server { + listen 8080; + + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + + server_name _; + + set $MAGE_ROOT !MAGENTO_ROOT!; # Variable: MAGENTO_ROOT + set $MAGE_MODE !MAGENTO_RUN_MODE!; # Variable: MAGENTO_RUN_MODE + set $MFTF_UTILS !MFTF_UTILS!; # Variable: MFTF_UTILS + set $WITH_XDEBUG !WITH_XDEBUG!; # Variable: WITH_XDEBUG + + set $my_fastcgi_pass "fastcgi_backend"; + if ($cookie_XDEBUG_SESSION) { + set $my_fastcgi_pass "fastcgi_backend_xdebug"; + } + + # Support for SSL termination. + set $my_http "http"; + set $my_ssl "off"; + set $my_port "80"; + if ($http_x_forwarded_proto = "https") { + set $my_http "https"; + set $my_ssl "on"; + set $my_port "443"; + } + + ssl_certificate /etc/nginx/ssl/magento.crt; + ssl_certificate_key /etc/nginx/ssl/magento.key; + + root $MAGE_ROOT/pub; + + index index.php; + autoindex off; + charset UTF-8; + client_max_body_size !UPLOAD_MAX_FILESIZE!; # Variable: UPLOAD_MAX_FILESIZE + error_page 404 403 = /errors/404.php; + #add_header "X-UA-Compatible" "IE=Edge"; + + # Deny access to sensitive files + location /.user.ini { + deny all; + } + + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + + location /pub/ { + location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) { + deny all; + } + alias $MAGE_ROOT/pub/; + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /static/ { + if ($MAGE_MODE = "production") { + expires max; + } + + # Remove signature of the static files that is used to overcome the browser cache + location ~ ^/static/version { + rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/ { + try_files $uri $uri/ /get.php$is_args$args; + + location ~ ^/media/theme_customization/.*\.xml { + deny all; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + try_files $uri $uri/ /get.php$is_args$args; + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + try_files $uri $uri/ /get.php$is_args$args; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/customer/ { + deny all; + } + + location /media/downloadable/ { + deny all; + } + + location /media/import/ { + deny all; + } + + location /errors/ { + location ~* \.xml$ { + deny all; + } + } + + # PHP entry point for main application + location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ { + try_files $uri =404; + fastcgi_pass $my_fastcgi_pass; + fastcgi_buffers 1024 4k; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "max_execution_time=18000"; + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + fastcgi_param MAGE_MODE $MAGE_MODE; + + # Magento uses the HTTPS env var to detrimine if it is using SSL or not. + fastcgi_param HTTPS $my_ssl; + + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~* ^/dev/tests/acceptance/utils($|/) { + root $MAGE_ROOT; + location ~ ^/dev/tests/acceptance/utils/command.php { + if ($MFTF_UTILS = 0) { + return 405; + } + + fastcgi_pass $my_fastcgi_pass; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + } + + gzip on; + gzip_disable "msie6"; + + gzip_comp_level 6; + gzip_min_length 1100; + gzip_buffers 16 8k; + gzip_proxied any; + gzip_types + text/plain + text/css + text/js + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + image/svg+xml; + gzip_vary on; + + # Banned locations (only reached if the earlier PHP entry point regexes don't match) + location ~* (\.php$|\.htaccess$|\.git) { + deny all; + } + + location /nginx_status { + stub_status on; + access_log off; + } + + location ~ ^/(status|ping)$ { + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + fastcgi_pass $my_fastcgi_pass; + } +} diff --git a/Docker/nginx/etc/xdebug-upstream.conf b/Docker/nginx/etc/xdebug-upstream.conf new file mode 100644 index 0000000..ba31b04 --- /dev/null +++ b/Docker/nginx/etc/xdebug-upstream.conf @@ -0,0 +1,3 @@ +upstream fastcgi_backend_xdebug { + server !XDEBUG_HOST!:!FPM_PORT!; # Variables: XDEBUG_HOST FPM_PORT +} diff --git a/Docker/php-cli-magento/Dockerfile b/Docker/php-cli-magento/Dockerfile new file mode 100644 index 0000000..b218276 --- /dev/null +++ b/Docker/php-cli-magento/Dockerfile @@ -0,0 +1,133 @@ +ARG PHP_VERSION=8.1.1 +FROM php:${PHP_VERSION}-cli + +ARG MAGENTO_ROOT=/app + +ENV PHP_MEMORY_LIMIT 2G +ENV PHP_VALIDATE_TIMESTAMPS 1 +ENV DEBUG false +ENV MAGENTO_RUN_MODE developer +ENV UPLOAD_MAX_FILESIZE 64M +ENV SENDMAIL_PATH /dev/null +ENV PHPRC ${MAGENTO_ROOT}/php.ini +ENV COMPOSER_HOME=/composer + +ENV PHP_EXTENSIONS bcmath bz2 calendar exif gd gettext intl mysqli opcache pdo_mysql redis soap sockets sodium sysvmsg sysvsem sysvshm xsl zip pcntl + +# Install dependencies +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + sendmail-bin \ + sendmail \ + sudo \ + iproute2 \ + git \ + gnupg2 \ + ca-certificates \ + lsb-release \ + software-properties-common \ + libbz2-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libfreetype6-dev \ + libgmp-dev \ + libgpgme11-dev \ + libicu-dev \ + libldap2-dev \ + libpcre3-dev \ + libpspell-dev \ + libtidy-dev \ + libxslt1-dev \ + libyaml-dev \ + libzip-dev \ + zip \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# Configure the gd library +RUN docker-php-ext-configure \ + gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ +RUN docker-php-ext-configure \ + opcache --enable-opcache + +# Install required PHP extensions +RUN docker-php-ext-install -j$(nproc) \ + bcmath \ + bz2 \ + calendar \ + exif \ + gd \ + gettext \ + gmp \ + intl \ + mysqli \ + opcache \ + pdo_mysql \ + pspell \ + shmop \ + soap \ + sockets \ + sysvmsg \ + sysvsem \ + sysvshm \ + tidy \ + xsl \ + zip \ + pcntl + +RUN pecl install -o -f \ + gnupg \ + mailparse \ + msgpack \ + oauth \ + pcov \ + raphf \ + redis \ + xdebug-3.1.2 \ + yaml + +RUN curl -L https://packages.blackfire.io/gpg.key | gpg --dearmor > blackfire.io-archive-keyring.gpg \ + && install -o root -g root -m 644 blackfire.io-archive-keyring.gpg /etc/apt/trusted.gpg.d/ \ + && echo "deb http://packages.blackfire.io/debian any main" | tee /etc/apt/sources.list.d/blackfire.list \ + && apt-get update \ + && apt-get install blackfire-php \ + && rm -rf /var/lib/apt/lists/* +RUN if [ $(uname -m) = "x86_64" ]; then ldap_arch="x86_64-linux-gnu"; else ldap_arch="aarch64-linux-gnu"; fi \ + && docker-php-ext-configure ldap --with-libdir=lib/${ldap_arch} +RUN rm -f /usr/local/etc/php/conf.d/*sodium.ini \ + && rm -f /usr/local/lib/php/extensions/*/*sodium.so \ + && apt-get remove libsodium* -y \ + && mkdir -p /tmp/libsodium \ + && curl -sL https://github.com/jedisct1/libsodium/archive/1.0.18-RELEASE.tar.gz | tar xzf - -C /tmp/libsodium \ + && cd /tmp/libsodium/libsodium-1.0.18-RELEASE/ \ + && ./configure \ + && make && make check \ + && make install \ + && cd / \ + && rm -rf /tmp/libsodium \ + && pecl install -o -f libsodium + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +COPY etc/php-fpm.ini /usr/local/etc/php/conf.d/zz-magento.ini + +RUN groupadd -g 1000 www && useradd -g 1000 -u 1000 -d ${MAGENTO_ROOT} -s /bin/bash www + +COPY docker-entrypoint.sh /docker-entrypoint.sh +RUN ["chmod", "+x", "/docker-entrypoint.sh"] + +RUN mkdir -p ${MAGENTO_ROOT} + +RUN mkdir -p ${COMPOSER_HOME} + +RUN chown -R www:www /usr/local /var/www /var/log /usr/local/etc/php/conf.d ${MAGENTO_ROOT} ${COMPOSER_HOME} + +ENTRYPOINT ["/docker-entrypoint.sh"] + +WORKDIR ${MAGENTO_ROOT} + +USER root + +CMD ["bash"] \ No newline at end of file diff --git a/Docker/php-cli-magento/docker-entrypoint.sh b/Docker/php-cli-magento/docker-entrypoint.sh new file mode 100644 index 0000000..adbbeb1 --- /dev/null +++ b/Docker/php-cli-magento/docker-entrypoint.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +[ "$DEBUG" = "true" ] && set -x + +if [ ! -z "${CRONTAB}" ]; then + echo "${CRONTAB}" > /etc/cron.d/magento && touch /var/log/cron.log +fi + +PHP_EXT_DIR=/usr/local/etc/php/conf.d + +# Enable PHP extensions +PHP_EXT_COM_ON=docker-php-ext-enable + +[ -d ${PHP_EXT_DIR} ] && rm -f ${PHP_EXT_DIR}/docker-php-ext-*.ini + +if [ -x "$(command -v ${PHP_EXT_COM_ON})" ] && [ ! -z "${PHP_EXTENSIONS}" ]; then + ${PHP_EXT_COM_ON} ${PHP_EXTENSIONS} +fi + +composer config --global http-basic.repo.magento.com ${MAGE_REPO_PUBLIC_KEY} ${MAGE_REPO_PRIVATE_KEY} +chown -R www:www ${COMPOSER_HOME} + +# Run first time setup only if composer.json doesn't already exist +if [ ! -f "/app-dest/composer.json" ]; then + rm -rf /app/* + + echo "Running composer install" + + composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition . ${MAGENTO_VERSION} + + echo "Running setup for Magento" + + install_flags=( + "--no-interaction" + "--base-url" "http://${MAGENTO_HOST}:${MAGENTO_EXTERNAL_HTTP_PORT}" + "--db-host" "${MAGENTO_DATABASE_HOST}:${MAGENTO_DATABASE_PORT}" + "--db-name" "${MAGENTO_DATABASE_NAME}" + "--db-user" "${MAGENTO_DATABASE_USER}" + "--db-password" "${MAGENTO_DATABASE_PASSWORD}" + "--admin-firstname" "${MAGENTO_ADMIN_FIRSTNAME}" + "--admin-lastname" "${MAGENTO_ADMIN_LASTNAME}" + "--admin-email" "${MAGENTO_ADMIN_EMAIL}" + "--admin-user" "${MAGENTO_ADMIN_USERNAME}" + "--admin-password" "${MAGENTO_ADMIN_PASSWORD}" + "--use-rewrites" "1" + "--backend-frontname" "admin" + "--search-engine" "elasticsearch7" + "--elasticsearch-host" "${ELASTICSEARCH_HOST}" + "--elasticsearch-port" "${ELASTICSEARCH_PORT}" + "--key" "${MAGENTO_ENCRYPTION_KEY}" + "--language" "en_AU" + "--currency" "AUD" + "--timezone" "Australia/Sydney" + ) + + php bin/magento setup:install "${install_flags[@]}" + php bin/magento sampledata:deploy + php bin/magento setup:upgrade + + mkdir -p app/code/Zip/ZipPayment + cp -R /magento-zip/* app/code/Zip/ZipPayment/ + chown -R www:www app/code + + php bin/magento module:disable Magento_TwoFactorAuth + php bin/magento module:enable Zip_ZipPayment + php bin/magento setup:upgrade + php bin/magento config:set payment/zippayment/active 1 + php bin/magento config:set payment/zippayment/title "Zip now, pay later" + php bin/magento config:set payment/zippayment/environment sandbox + php bin/magento config:set payment/zippayment/merchant_public_key $ZIPMONEY_SANDBOX_PUBLIC_KEY + php bin/magento config:set payment/zippayment/merchant_private_key $ZIPMONEY_SANDBOX_PRIVATE_KEY + php bin/magento config:set payment/zippayment/widget_region au + php bin/magento config:set payment/zippayment/payment_action capture + php bin/magento config:set payment/zippayment/display_widget_mode iframe + php bin/magento indexer:reindex + php bin/magento cache:clean + php bin/magento cache:flush + + rm -rf app/code/Zip + + echo "Installation complete, moving Magento persistance" + tar c . | (cd /app-dest && tar -xf -) +fi + +exec "$@" \ No newline at end of file diff --git a/Docker/php-cli-magento/etc/php-fpm.ini b/Docker/php-cli-magento/etc/php-fpm.ini new file mode 100644 index 0000000..387c8ae --- /dev/null +++ b/Docker/php-cli-magento/etc/php-fpm.ini @@ -0,0 +1,4 @@ +memory_limit = ${PHP_MEMORY_LIMIT} +opcache.enable = 1 +opcache.validate_timestamps = ${PHP_VALIDATE_TIMESTAMPS} +user_ini.filename = diff --git a/Docker/php-fpm-magento/Dockerfile b/Docker/php-fpm-magento/Dockerfile new file mode 100644 index 0000000..6fcfa1a --- /dev/null +++ b/Docker/php-fpm-magento/Dockerfile @@ -0,0 +1,176 @@ +ARG PHP_VERSION=8.1.1 +FROM golang:1.15 AS builder + +RUN if [ $(uname -m) = "x86_64" ]; then mailhog_arch="amd64"; else mailhog_arch="arm64"; fi \ + && wget -O mhsendmail.tar.gz https://github.com/mailhog/mhsendmail/archive/refs/tags/v0.2.0.tar.gz \ + && tar -xf mhsendmail.tar.gz \ + && mkdir -p ./src/github.com/mailhog/ \ + && mv ./mhsendmail-0.2.0 ./src/github.com/mailhog/mhsendmail \ + && cd ./src/github.com/mailhog/mhsendmail/ \ + && go get . \ + && GOOS=linux GOARCH=${mailhog_arch} go build -o mhsendmail . + +FROM php:${PHP_VERSION}-fpm + +ARG MAGENTO_ROOT=/app + +ENV PHP_MEMORY_LIMIT 2G +ENV PHP_VALIDATE_TIMESTAMPS 1 +ENV DEBUG false +ENV MAGENTO_RUN_MODE developer +ENV UPLOAD_MAX_FILESIZE 64M +ENV SENDMAIL_PATH /dev/null +ENV PHPRC ${MAGENTO_ROOT}/php.ini + +ENV PHP_EXTENSIONS bcmath bz2 calendar exif gd gettext intl mysqli opcache pdo_mysql redis soap sockets sodium sysvmsg sysvsem sysvshm xsl zip pcntl xdebug + +# Install dependencies +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + sendmail-bin \ + sendmail \ + sudo \ + iproute2 \ + git \ + gnupg2 \ + ca-certificates \ + lsb-release \ + software-properties-common \ + libbz2-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libfreetype6-dev \ + libgmp-dev \ + libgpgme11-dev \ + libicu-dev \ + libldap2-dev \ + libpcre3-dev \ + libpspell-dev \ + libtidy-dev \ + libxslt1-dev \ + libyaml-dev \ + libzip-dev \ + zip \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# Install MailHog +COPY --from=builder /go/src/github.com/mailhog/mhsendmail/mhsendmail /usr/local/bin/ +RUN sudo chmod +x /usr/local/bin/mhsendmail + +# Configure the gd library +RUN docker-php-ext-configure \ + gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ +RUN docker-php-ext-configure \ + opcache --enable-opcache + +# Install required PHP extensions +RUN docker-php-ext-install -j$(nproc) \ + bcmath \ + bz2 \ + calendar \ + exif \ + gd \ + gettext \ + gmp \ + intl \ + mysqli \ + opcache \ + pdo_mysql \ + pspell \ + shmop \ + soap \ + sockets \ + sysvmsg \ + sysvsem \ + sysvshm \ + tidy \ + xsl \ + zip \ + pcntl + +RUN pecl install -o -f \ + gnupg \ + mailparse \ + msgpack \ + oauth \ + pcov \ + raphf \ + redis \ + xdebug-3.1.2 \ + yaml + +RUN curl -L https://packages.blackfire.io/gpg.key | gpg --dearmor > blackfire.io-archive-keyring.gpg \ + && install -o root -g root -m 644 blackfire.io-archive-keyring.gpg /etc/apt/trusted.gpg.d/ \ + && echo "deb http://packages.blackfire.io/debian any main" | tee /etc/apt/sources.list.d/blackfire.list \ + && apt-get update \ + && apt-get install blackfire-php \ + && rm -rf /var/lib/apt/lists/* +RUN if [ $(uname -m) = "x86_64" ]; then ldap_arch="x86_64-linux-gnu"; else ldap_arch="aarch64-linux-gnu"; fi \ + && docker-php-ext-configure ldap --with-libdir=lib/${ldap_arch} +RUN mkdir -p /tmp/zoo \ + && cd /tmp/zoo \ + && git clone https://github.com/php-zookeeper/php-zookeeper.git \ + && curl -LO https://archive.apache.org/dist/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz \ + && tar -xf zookeeper-3.4.14.tar.gz \ + && cp zookeeper-3.4.14/zookeeper-client/zookeeper-client-c/generated/zookeeper.jute.h zookeeper-3.4.14/zookeeper-client/zookeeper-client-c/include \ + && cd zookeeper-3.4.14/zookeeper-client/zookeeper-client-c \ + && ./configure \ + && sed -i 's/CFLAGS = -g -O2 -D_GNU_SOURCE/CFLAGS = -g -O2 -D_GNU_SOURCE -Wno-error=format-overflow -Wno-error=stringop-truncation/g' Makefile \ + && make \ + && make install \ + && ldconfig \ + && cd /tmp/zoo/php-zookeeper \ + && phpize \ + && ./configure --with-libzookeeper-dir=../zookeeper-3.4.14/zookeeper-client/zookeeper-client-c \ + && make \ + && make install +RUN rm -f /usr/local/etc/php/conf.d/*sodium.ini \ + && rm -f /usr/local/lib/php/extensions/*/*sodium.so \ + && apt-get remove libsodium* -y \ + && mkdir -p /tmp/libsodium \ + && curl -sL https://github.com/jedisct1/libsodium/archive/1.0.18-RELEASE.tar.gz | tar xzf - -C /tmp/libsodium \ + && cd /tmp/libsodium/libsodium-1.0.18-RELEASE/ \ + && ./configure \ + && make && make check \ + && make install \ + && cd / \ + && rm -rf /tmp/libsodium \ + && pecl install -o -f libsodium +RUN cd /tmp \ + && if [ $(uname -m) = "x86_64" ]; then ioncube_arch="x86-64"; else ioncube_arch="aarch64"; fi \ + && curl -O https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_${ioncube_arch}.tar.gz \ + && tar zxvf ioncube_loaders_lin_${ioncube_arch}.tar.gz \ + && export PHP_VERSION=$(php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;") \ + && export PHP_EXT_DIR=$(php-config --extension-dir) \ + && cp "./ioncube/ioncube_loader_lin_${PHP_VERSION}.so" "${PHP_EXT_DIR}/ioncube.so" \ + && rm -rf ./ioncube \ + && rm ioncube_loaders_lin_${ioncube_arch}.tar.gz + +COPY etc/php-fpm.ini /usr/local/etc/php/conf.d/zz-magento.ini +COPY etc/php-xdebug.ini /usr/local/etc/php/conf.d/zz-xdebug-settings.ini +COPY etc/php-pcov.ini /usr/local/etc/php/conf.d/zz-pcov-settings.ini +COPY etc/mail.ini /usr/local/etc/php/conf.d/zz-mail.ini +COPY etc/php-fpm.conf /usr/local/etc/ +COPY etc/php-gnupg.ini /usr/local/etc/php/conf.d/gnupg.ini + +RUN groupadd -g 1000 www && useradd -g 1000 -u 1000 -d ${MAGENTO_ROOT} -s /bin/bash www + +COPY docker-entrypoint.sh /docker-entrypoint.sh +RUN ["chmod", "+x", "/docker-entrypoint.sh"] + +RUN mkdir -p ${MAGENTO_ROOT} + +VOLUME ${MAGENTO_ROOT} + +RUN chown -R www:www /usr/local /var/www /var/log /usr/local/etc/php/conf.d ${MAGENTO_ROOT} + +ENTRYPOINT ["/docker-entrypoint.sh"] + +WORKDIR ${MAGENTO_ROOT} + +USER root + +CMD ["php-fpm", "-R"] diff --git a/Docker/php-fpm-magento/docker-entrypoint.sh b/Docker/php-fpm-magento/docker-entrypoint.sh new file mode 100644 index 0000000..c33bccd --- /dev/null +++ b/Docker/php-fpm-magento/docker-entrypoint.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +[ "$DEBUG" = "true" ] && set -x + +PHP_EXT_DIR=/usr/local/etc/php/conf.d + +# Enable PHP extensions +PHP_EXT_COM_ON=docker-php-ext-enable + +[ -d ${PHP_EXT_DIR} ] && rm -f ${PHP_EXT_DIR}/docker-php-ext-*.ini + +if [ -x "$(command -v ${PHP_EXT_COM_ON})" ] && [ ! -z "${PHP_EXTENSIONS}" ]; then + ${PHP_EXT_COM_ON} ${PHP_EXTENSIONS} +fi + +# Set host.docker.internal if not available +HOST_NAME="host.docker.internal" +HOST_IP=$(php -r "putenv('RES_OPTIONS=retrans:1 retry:1 timeout:1 attempts:1'); echo gethostbyname('$HOST_NAME');") +if [[ "$HOST_IP" == "$HOST_NAME" ]]; then + HOST_IP=$(/sbin/ip route|awk '/default/ { print $3 }') + printf "\n%s %s\n" "$HOST_IP" "$HOST_NAME" >> /etc/hosts +fi + +chown -R www:www /app + +exec "$@" \ No newline at end of file diff --git a/Docker/php-fpm-magento/etc/mail.ini b/Docker/php-fpm-magento/etc/mail.ini new file mode 100644 index 0000000..c162028 --- /dev/null +++ b/Docker/php-fpm-magento/etc/mail.ini @@ -0,0 +1,2 @@ +; Sendmail +sendmail_path = ${SENDMAIL_PATH} diff --git a/Docker/php-fpm-magento/etc/php-fpm.conf b/Docker/php-fpm-magento/etc/php-fpm.conf new file mode 100644 index 0000000..d988b31 --- /dev/null +++ b/Docker/php-fpm-magento/etc/php-fpm.conf @@ -0,0 +1,25 @@ +[global] + +error_log = /proc/self/fd/2 +daemonize = no + +[www] + +; if we send this to /proc/self/fd/1, it never appears +access.log = /proc/self/fd/2 + +listen = [::]:9000 + +pm = dynamic +pm.max_children = 10 +pm.start_servers = 4 +pm.min_spare_servers = 2 +pm.max_spare_servers = 6 +pm.status_path = /status + +clear_env = no + +env[MAGE_MODE] = $MAGENTO_RUN_MODE + +; Ensure worker stdout and stderr are sent to the main error log. +catch_workers_output = yes diff --git a/Docker/php-fpm-magento/etc/php-fpm.ini b/Docker/php-fpm-magento/etc/php-fpm.ini new file mode 100644 index 0000000..387c8ae --- /dev/null +++ b/Docker/php-fpm-magento/etc/php-fpm.ini @@ -0,0 +1,4 @@ +memory_limit = ${PHP_MEMORY_LIMIT} +opcache.enable = 1 +opcache.validate_timestamps = ${PHP_VALIDATE_TIMESTAMPS} +user_ini.filename = diff --git a/Docker/php-fpm-magento/etc/php-gnupg.ini b/Docker/php-fpm-magento/etc/php-gnupg.ini new file mode 100644 index 0000000..f0f7e9a --- /dev/null +++ b/Docker/php-fpm-magento/etc/php-gnupg.ini @@ -0,0 +1 @@ +extension = gnupg.so diff --git a/Docker/php-fpm-magento/etc/php-pcov.ini b/Docker/php-fpm-magento/etc/php-pcov.ini new file mode 100644 index 0000000..a9f0145 --- /dev/null +++ b/Docker/php-fpm-magento/etc/php-pcov.ini @@ -0,0 +1,2 @@ +pcov.enabled = 1 +pcov.directory = ${MAGENTO_ROOT} diff --git a/Docker/php-fpm-magento/etc/php-xdebug.ini b/Docker/php-fpm-magento/etc/php-xdebug.ini new file mode 100644 index 0000000..4479cb4 --- /dev/null +++ b/Docker/php-fpm-magento/etc/php-xdebug.ini @@ -0,0 +1,12 @@ +; Xdebug settings will only kick in if the Xdebug module is loaded +zend_extension=xdebug + +[xdebug] +xdebug.mode = develop,debug,coverage,profile +xdebug.client_port = 9003 +xdebug.start_with_request = yes +xdebug.discover_client_host = true +xdebug.client_host = 'host.docker.internal' +xdebug.scream = false +xdebug.show_local_vars = 1 +xdebug.idekey = docker