diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 2b4f5b8..0000000 --- a/Dockerfile +++ /dev/null @@ -1,178 +0,0 @@ -# Dockerfile - -# Docker image for TYPO3 CMS -FROM php:8.2-apache - -LABEL maintainer="Raphael Martin " - -# set envirement -ENV LANG=de_AT.UTF-8 -ENV APACHE_RUN_USER a2g-www -ENV TYPO3_VERSION 12.4.8 -ENV TYPO3_SHA256CHECKSUM 8293b3441ec133fc8f9174fab5b88f450044ded0e188a0f12de37ad60a8bf8b3 - -# change apache user -RUN adduser --uid 1000 --gecos 'Apache User' --disabled-password $APACHE_RUN_USER \ - && chown -R "$APACHE_RUN_USER:$APACHE_RUN_USER" /var/lock/apache2 /var/run/apache2 - -# update system -RUN apt-get update -y && apt-get upgrade -y - -# Install wget and locales -RUN apt-get install -y --no-install-recommends \ - wget \ - locales - -RUN export LANG=${LANG} && \ - export LC_ALL=${LANG} && \ - export LC_TIME=${LANG} && \ - export LANGUAGE=${LANG} && \ - echo "${LANG} UTF-8" > /etc/locale.gen && \ - /usr/sbin/locale-gen - -# Export env vars -RUN { \ - echo "export LC_ALL=${LANG}"; \ - echo "export LANG=${LANG}"; \ - echo "export LANGUAGE=${LANG}"; \ -} >> ~/.bashrc - -RUN cp ~/.bashrc /home/${APACHE_RUN_USER} && \ - chown -R "$APACHE_RUN_USER:$APACHE_RUN_USER" /home/${APACHE_RUN_USER}/.bashrc - -# Download TYPO3 -RUN cd /tmp && \ - wget -O download.tar.gz https://get.typo3.org/${TYPO3_VERSION} && \ - echo "${TYPO3_SHA256CHECKSUM} /tmp/download.tar.gz" > /tmp/download.tar.gz.sum - -RUN sha256sum -c "/tmp/download.tar.gz.sum" - -# Install -RUN set -ex; \ - \ - apt-get install -y --no-install-recommends \ -# Configure PHP - libxml2-dev \ - libfreetype6-dev \ - libjpeg62-turbo-dev \ - libmcrypt-dev \ - libpng-dev \ - libpq-dev \ - zlib1g-dev \ - sendmail \ - graphicsmagick - -RUN docker-php-ext-configure gd --with-libdir=/usr/include/ --with-jpeg --with-freetype - -RUN docker-php-ext-install -j$(nproc) \ - pdo \ - pdo_mysql \ - soap \ - gd \ - opcache \ - intl - -RUN apt-get -y purge \ - libxml2-dev libfreetype6-dev \ - libjpeg62-turbo-dev \ - libmcrypt-dev \ - libpng-dev \ - zlib1g-dev \ - wget && \ - apt-get autoremove -y - -RUN apt-get install -y --no-install-recommends \ - libzip-dev \ - zip - -RUN docker-php-ext-install -j$(nproc) \ - zip - -# Clean -RUN apt-get -y purge \ - libzip-dev && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /usr/src/* - -# Configure Apache - -RUN set -eux; \ - a2enmod alias authz_core deflate filter rewrite expires setenvif remoteip headers; \ - docker-php-ext-enable opcache; - -RUN set -eux; \ - { \ - echo 'opcache.save_comments=1'; \ - echo 'opcache.use_cwd=1'; \ - echo 'opcache.validate_timestamps=1'; \ - echo 'opcache.max_accelerated_files=10000'; \ - echo 'opcache.revalidate_freq=30'; \ - echo 'opcache.revalidate_path=0'; \ - } > /usr/local/etc/php/conf.d/opcache-recommended.ini - -RUN set -eux; \ - { \ - echo 'memory_limit=256M'; \ - echo 'max_execution_time=240'; \ - echo 'max_input_vars=1500'; \ - } > /usr/local/etc/php/conf.d/typo3-recommended.ini - -RUN set -eux; \ - { \ - echo 'post_max_size=10M'; \ - echo 'upload_max_filesize=10M'; \ - } > /usr/local/etc/php/conf.d/upload-recommended.ini - -RUN set -eux; \ - { \ - echo 'error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR'; \ - echo 'display_errors = Off'; \ - echo 'display_startup_errors = Off'; \ - echo 'log_errors = On'; \ - echo 'error_log = /dev/stderr'; \ - echo 'log_errors_max_len = 1024'; \ - echo 'ignore_repeated_errors = On'; \ - echo 'ignore_repeated_source = Off'; \ - echo 'html_errors = Off'; \ - } > /usr/local/etc/php/conf.d/error-logging.ini - -RUN set -eux; \ - { \ - echo 'RemoteIPHeader X-Forwarded-For'; \ -# these IP ranges are reserved for "private" use and should thus *usually* be safe inside Docker - echo 'RemoteIPInternalProxy 10.0.0.0/8'; \ - echo 'RemoteIPInternalProxy 172.16.0.0/12'; \ - echo 'RemoteIPInternalProxy 192.168.0.0/16'; \ - echo 'RemoteIPInternalProxy 169.254.0.0/16'; \ - echo 'RemoteIPInternalProxy 127.0.0.0/8'; \ - } > /etc/apache2/conf-available/remoteip.conf; \ - a2enconf remoteip; \ - find /etc/apache2 -type f -name '*.conf' -exec sed -ri 's/([[:space:]]*LogFormat[[:space:]]+"[^"]*)%h([^"]*")/\1%a\2/g' '{}' + - -RUN cp ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini - -# install TYPO3 surf -# RUN mkdir /usr/local/surf && \ -# curl -L https://github.com/TYPO3/Surf/releases/download/3.4.6/surf.phar -o /usr/local/surf/surf.phar && \ -# chmod +x /usr/local/surf/surf.phar && \ -# ln -s /usr/local/surf/surf.phar /usr/local/bin/surf - -# install TYPO3 -RUN tar -xzf /tmp/download.tar.gz -C /var/www/ && \ - rm /tmp/download* - -RUN cd /var/www/html && \ - ln -s ../typo3_src-* typo3_src && \ - ln -s typo3_src/index.php && \ - ln -s typo3_src/typo3 - -RUN chown -R $APACHE_RUN_USER:$APACHE_RUN_USER /var/www/html && \ - chown -R $APACHE_RUN_USER:$APACHE_RUN_USER /var/www/typo3_src-* && \ - chown -R root:root /etc/apache2/sites-enabled - -RUN { \ - echo "ServerSignature Off"; \ - echo "ServerTokens Prod"; \ - } >> /etc/apache2/apache2.conf - -VOLUME /var/www \ No newline at end of file diff --git a/README.md b/README.md index d9f373e..3be065b 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,19 @@ for development: 'transport_sendmail_command' => '/usr/sbin/sendmail -bs', -and append: +and append / set: - ['SYS']['features']['security.backend.enforceReferrer'] = true + ['SYS'][ + ... + 'systemLocale' => 'de_AT.UTF-8', + 'reverseProxyHeaderMultiValue' => 'first', + 'reverseProxyIP' => '127.0.0.1', + 'features' => [ + ... + 'security.backend.enforceReferrer] => false, + 'security.backend.enforceContentSecurityPolicy' => false, + ] + ] because we are behind the reverse proxy. diff --git a/apache-conf/.htaccess b/apache-conf/.htaccess new file mode 100644 index 0000000..d39e2af --- /dev/null +++ b/apache-conf/.htaccess @@ -0,0 +1,395 @@ +##### +# +# Example .htaccess file for TYPO3 CMS - for use with Apache Webserver +# +# This file includes settings for the following configuration options: +# +# - Compression +# - Caching +# - MIME types +# - Cross Origin requests +# - Rewriting and Access +# - Miscellaneous +# - PHP optimisation +# +# If you want to use it, you have to copy it to the root folder of your TYPO3 installation (if its +# not there already) and rename it to '.htaccess'. To make .htaccess files work, you might need to +# adjust the 'AllowOverride' directive in your Apache configuration file. +# +# IMPORTANT: You may need to change this file depending on your TYPO3 installation! +# Consider adding this file's content to your webserver's configuration directly for speed improvement +# +# Lots of the options are taken from https://github.com/h5bp/html5-boilerplate/blob/master/dist/.htaccess +# +#### + + +### Begin: Compression ### + +# Compressing resource files will save bandwidth and so improve loading speed especially for users +# with slower internet connections. TYPO3 can compress the .js and .css files for you. +# *) Uncomment the following lines and +# *) Set $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'] = 9 for the Backend +# *) Set $GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] = 9 together with the TypoScript properties +# config.compressJs and config.compressCss for GZIP compression of Frontend JS and CSS files. + +# +# AddType "text/javascript" .gz +# +# +# AddType "text/css" .gz +# +#AddEncoding x-gzip .gz + + + # Force compression for mangled `Accept-Encoding` request headers + + + SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding + RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding + + + + # Compress all output labeled with one of the following media types. + # + # (!) For Apache versions below version 2.3.7 you don't need to + # enable `mod_filter` and can remove the `` + # and `` lines as `AddOutputFilterByType` is still in + # the core directives. + # + # https://httpd.apache.org/docs/current/mod/mod_filter.html#addoutputfilterbytype + + + AddOutputFilterByType DEFLATE application/atom+xml \ + application/javascript \ + application/json \ + application/ld+json \ + application/manifest+json \ + application/rdf+xml \ + application/rss+xml \ + application/schema+json \ + application/vnd.geo+json \ + application/geo+json \ + application/vnd.ms-fontobject \ + application/x-font-ttf \ + application/x-javascript \ + application/x-web-app-manifest+json \ + application/xhtml+xml \ + application/xml \ + font/eot \ + font/opentype \ + font/otf \ + font/ttf \ + image/bmp \ + image/svg+xml \ + image/vnd.microsoft.icon \ + image/x-icon \ + text/cache-manifest \ + text/css \ + text/html \ + text/javascript \ + text/plain \ + text/vcard \ + text/vnd.rim.location.xloc \ + text/vtt \ + text/x-component \ + text/x-cross-domain-policy \ + text/xml + + + + AddEncoding gzip svgz + + + +### End: Compression ### + + + +### Begin: Browser caching of resource files ### + +# This affects Frontend and Backend and increases performance. + + + ExpiresActive On + ExpiresDefault "access plus 1 month" + + ExpiresByType text/css "access plus 1 year" + + ExpiresByType application/json "access plus 0 seconds" + ExpiresByType application/ld+json "access plus 0 seconds" + ExpiresByType application/schema+json "access plus 0 seconds" + ExpiresByType application/vnd.geo+json "access plus 0 seconds" + ExpiresByType application/geo+json "access plus 0 seconds" + ExpiresByType application/xml "access plus 0 seconds" + ExpiresByType text/xml "access plus 0 seconds" + + ExpiresByType image/vnd.microsoft.icon "access plus 1 week" + ExpiresByType image/x-icon "access plus 1 week" + + ExpiresByType text/x-component "access plus 1 month" + + ExpiresByType text/html "access plus 0 seconds" + + ExpiresByType application/javascript "access plus 1 year" + ExpiresByType application/x-javascript "access plus 1 year" + ExpiresByType text/javascript "access plus 1 year" + + ExpiresByType application/manifest+json "access plus 1 week" + ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" + ExpiresByType text/cache-manifest "access plus 0 seconds" + + ExpiresByType audio/ogg "access plus 1 month" + ExpiresByType image/apng "access plus 1 month" + ExpiresByType image/avif "access plus 1 month" + ExpiresByType image/avif-sequence "access plus 1 month" + ExpiresByType image/bmp "access plus 1 month" + ExpiresByType image/gif "access plus 1 month" + ExpiresByType image/jpeg "access plus 1 month" + ExpiresByType image/jxl "access plus 1 month" + ExpiresByType image/png "access plus 1 month" + ExpiresByType image/svg+xml "access plus 1 month" + ExpiresByType image/webp "access plus 1 month" + ExpiresByType video/mp4 "access plus 1 month" + ExpiresByType video/ogg "access plus 1 month" + ExpiresByType video/webm "access plus 1 month" + + ExpiresByType application/atom+xml "access plus 1 hour" + ExpiresByType application/rdf+xml "access plus 1 hour" + ExpiresByType application/rss+xml "access plus 1 hour" + + ExpiresByType font/collection "access plus 1 month" + ExpiresByType application/vnd.ms-fontobject "access plus 1 month" + ExpiresByType font/eot "access plus 1 month" + ExpiresByType font/opentype "access plus 1 month" + ExpiresByType font/otf "access plus 1 month" + ExpiresByType application/x-font-ttf "access plus 1 month" + ExpiresByType font/ttf "access plus 1 month" + ExpiresByType application/font-woff "access plus 1 month" + ExpiresByType application/x-font-woff "access plus 1 month" + ExpiresByType font/woff "access plus 1 month" + ExpiresByType application/font-woff2 "access plus 1 month" + ExpiresByType font/woff2 "access plus 1 month" + + ExpiresByType text/x-cross-domain-policy "access plus 1 week" + + + +### End: Browser caching of resource files ### + + +### Begin: MIME types ### + +# Proper MIME types for all files + + # Security configuration + RemoveType .html .htm + + AddType text/html .html .htm + + + RemoveType .svg .svgz + + AddType image/svg+xml .svg .svgz + + + # Data interchange + AddType application/atom+xml atom + AddType application/json json map topojson + AddType application/ld+json jsonld + AddType application/rss+xml rss + AddType application/vnd.geo+json geojson + AddType application/xml rdf xml + + # JavaScript + AddType application/javascript js + + # Manifest files + AddType application/manifest+json webmanifest + AddType application/x-web-app-manifest+json webapp + AddType text/cache-manifest appcache + + # Media files + + AddType audio/mp4 f4a f4b m4a + AddType audio/ogg oga ogg opus + AddType image/avif avif + AddType image/avif-sequence avifs + AddType image/bmp bmp + AddType image/jxl jxl + AddType image/webp webp + AddType video/mp4 f4v f4p m4v mp4 + AddType video/ogg ogv + AddType video/webm webm + AddType video/x-flv flv + AddType image/x-icon cur ico + + # Web fonts + AddType font/woff woff + AddType font/woff2 woff2 + AddType application/vnd.ms-fontobject eot + AddType font/ttf ttc ttf + AddType font/otf otf + + # Other + AddType application/octet-stream safariextz + AddType application/x-bb-appworld bbaw + AddType application/x-chrome-extension crx + AddType application/x-opera-extension oex + AddType application/x-xpinstall xpi + AddType text/vcard vcard vcf + AddType text/vnd.rim.location.xloc xloc + AddType text/vtt vtt + AddType text/x-component htc + + + +# UTF-8 encoding +AddDefaultCharset utf-8 + + AddCharset utf-8 .atom .css .js .json .manifest .rdf .rss .vtt .webapp .webmanifest .xml + + +### End: MIME types ### + + + +### Begin: Cross Origin ### + +# Send the CORS header for images when browsers request it. + + + + SetEnvIf Origin ":" IS_CORS + Header set Access-Control-Allow-Origin "*" env=IS_CORS + + + + +# Allow cross-origin access to web fonts. + + + Header set Access-Control-Allow-Origin "*" + + + +### End: Cross Origin ### + + + +### Begin: Rewriting and Access ### + + + + # Enable URL rewriting + RewriteEngine On + + # Store the current location in an environment variable CWD to use + # mod_rewrite in .htaccess files without knowing the RewriteBase + RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$ + RewriteRule ^.*$ - [E=CWD:%2] + + # Rules to set ApplicationContext based on hostname + #RewriteCond %{HTTP_HOST} ^dev\.example\.com$ + #RewriteRule .? - [E=TYPO3_CONTEXT:Development] + #RewriteCond %{HTTP_HOST} ^staging\.example\.com$ + #RewriteRule .? - [E=TYPO3_CONTEXT:Production/Staging] + #RewriteCond %{HTTP_HOST} ^www\.example\.com$ + #RewriteRule .? - [E=TYPO3_CONTEXT:Production] + + # Rule for versioned static files, configured through: + # - $GLOBALS['TYPO3_CONF_VARS']['BE']['versionNumberInFilename'] + # - $GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename'] + # IMPORTANT: This rule has to be the very first RewriteCond in order to work! + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gz)$ %{ENV:CWD}$1.$3 [L] + + # Access block for folders + RewriteRule _(?:recycler|temp)_/ - [F] + RewriteRule fileadmin/templates/.*\.(?:txt|ts)$ - [F] + RewriteRule ^(?:vendor|typo3_src|typo3temp/var) - [F] + RewriteRule (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|Documentation|docs?)/ - [F] + + # Block access to all hidden files and directories with the exception of + # the visible content from within the `/.well-known/` hidden directory (RFC 5785). + RewriteCond %{REQUEST_URI} "!(^|/)\.well-known/([^./]+./?)+$" [NC] + RewriteCond %{SCRIPT_FILENAME} -d [OR] + RewriteCond %{SCRIPT_FILENAME} -f + RewriteRule (?:^|/)\. - [F] + + # Stop rewrite processing, if we are in any other known directory + # NOTE: Add your additional local storages here + RewriteRule ^(?:fileadmin/|typo3conf/|typo3temp/|uploads/) - [L] + + # If the file/symlink/directory does not exist but is below /typo3/, redirect to the TYPO3 Backend entry point. + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-l + RewriteRule ^typo3/(.*)$ %{ENV:CWD}typo3/index.php [QSA,L] + + # If the file/symlink/directory does not exist => Redirect to index.php. + # For httpd.conf, you need to prefix each '%{REQUEST_FILENAME}' with '%{DOCUMENT_ROOT}'. + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-l + RewriteRule ^.*$ %{ENV:CWD}index.php [QSA,L] + + + +# Access block for files +# Apache < 2.3 + + + Order allow,deny + Deny from all + Satisfy All + + +# Apache ≥ 2.3 + + + Require all denied + + + +# Block access to vcs directories + + RedirectMatch 404 /\.(?:git|svn|hg)/ + + +### End: Rewriting and Access ### + + + +### Begin: Miscellaneous ### + +# 404 error prevention for non-existing redirected folders +Options -MultiViews + +# Make sure that directory listings are disabled. + + Options -Indexes + + + + # Force IE to render pages in the highest available mode + Header set X-UA-Compatible "IE=edge" + + Header unset X-UA-Compatible + + + # Reducing MIME type security risks + Header set X-Content-Type-Options "nosniff" + + +# ETag removal + + Header unset ETag + +FileETag None + +### End: Miscellaneous ### + + +# Add your own rules here. diff --git a/apache-conf/sites-enabled/typo3.localhost.conf b/apache-conf/sites-enabled/typo3.localhost.conf index e8f8a5d..3dbadc6 100644 --- a/apache-conf/sites-enabled/typo3.localhost.conf +++ b/apache-conf/sites-enabled/typo3.localhost.conf @@ -33,12 +33,25 @@ # RewriteCond %{HTTP_HOST} !^www\. [NC] # RewriteRule ^(.*)$ https://www.%1altogether.at%{REQUEST_URI} [R=301,L] -# SSLEngine on -# SSLOptions +StrictRequire -# SSLCertificateFile /etc/ssl/certs/CF-altogether.at.crt -# SSLCertificateKeyFile /etc/ssl/private/CF-altogether.at.key - # Header always set Content-Security-Policy "default-src 'self'; font-src *;img-src *; script-src 'none'; style-src 'unsafe-inline' *; connect-src 'self'" # Header set Content-Security-Policy "default-src 'self' 'unsafe-inline'; img-src * data:; font-src 'self' data:;" + + + DocumentRoot /var/www/html +# ServerName typo3.localhost +# ServerName localhost + UseCanonicalName On + # ServerAlias altogether.at + + # SSLEngine on + # SSLOptions +StrictRequire + # SSLCertificateFile /etc/ssl/certs/typo3.localhost.crt + # SSLCertificateKeyFile /etc/ssl/typo3.localhost.key + # SSLCertificateChainFile /etc/ssl/typo3.localhost.csr + +# Header always set Content-Security-Policy "default-src 'self'; font-src *;img-src *; script-src 'none'; style-src 'unsafe-inline' *; connect-src 'self'" +# Header set Content-Security-Policy "default-src 'self' 'unsafe-inline'; img-src * data:; font-src 'self' data:;" + + \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 64dd375..290606d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '1' +version: '3.8' networks: default: @@ -12,7 +12,7 @@ services: typo3: container_name: "${PROJECT_NAME}_typo3" hostname: "${PROJECT_URL}" - build: . + image: "altogether/typo3:12.4.8-apache" user: "1000" networks: - "traefik" @@ -23,10 +23,10 @@ services: - "${PROJECT_DATA}/${PROJECT_NAME}-typo3/protected:/var/www/protected" - "${PROJECT_DATA}/${PROJECT_NAME}-typo3/typo3conf:/var/www/html/typo3conf" - "./apache-conf/sites-enabled:/etc/apache2/sites-enabled" - # - "./php-conf/conf.d:/usr/local/etc/php/conf.d" + - "./apache-conf/.htaccess:/var/www/html/.htaccess" - "./php-conf/php.ini:/usr/local/etc/php/php.ini:ro" ## use for the first install - # - "./LICENSE:/var/www/html/FIRST_INSTALL:ro" + #- "./LICENSE:/var/www/html/FIRST_INSTALL:ro" - "/etc/timezone:/etc/timezone:ro" - "/etc/localtime:/etc/localtime:ro" depends_on: @@ -40,7 +40,11 @@ services: - "traefik.http.routers.${PROJECT_NAME}_typo3.rule=Host(`${PROJECT_URL}`)" - "traefik.http.routers.${PROJECT_NAME}_typo3.entrypoints=websecure" - "traefik.http.routers.${PROJECT_NAME}_typo3.tls=true" - - "traefik.http.services.${PROJECT_NAME}_typo3.loadbalancer.server.port=80" + - "traefik.http.services.${PROJECT_NAME}_typo3.loadbalancer.server.port=443" + # Use the special Traefik service api@internal with the web UI/Dashboard + # - traefik.http.routers.${PROJECT_NAME}_typo3.service=api@internal + # Use the "le" (Let's Encrypt) resolver created below + # - traefik.http.routers.${PROJECT_NAME}_typo3.tls.certresolver=le db: image: "mariadb:latest" container_name: "${PROJECT_NAME}_typo3_db"