From f0fef9814b7bde8366b5bb68c6823f4989215382 Mon Sep 17 00:00:00 2001 From: Luciano Righetti Date: Tue, 4 Apr 2023 17:09:21 +0200 Subject: [PATCH] new: [wip] docker env for misp3 --- docker-compose.dev.yml | 24 +++++++ docker-compose.yml | 82 ++++++++++++++++++++++++ docker/.env.dist | 1 + docker/.gitignore | 4 ++ docker/README.md | 49 +++++++++++++++ docker/misp/Dockerfile | 81 ++++++++++++++++++++++++ docker/misp/config/app_local.php | 104 +++++++++++++++++++++++++++++++ docker/misp/config/php-fpm.conf | 19 ++++++ docker/misp/config/php.dev.ini | 16 +++++ docker/misp/config/php.ini | 24 +++++++ docker/nginx/Dockerfile | 21 +++++++ docker/nginx/certs/.keepdir | 0 docker/nginx/entrypoint.sh | 19 ++++++ docker/nginx/nginx.conf | 38 +++++++++++ 14 files changed, 482 insertions(+) create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.yml create mode 100644 docker/.env.dist create mode 100644 docker/.gitignore create mode 100644 docker/README.md create mode 100644 docker/misp/Dockerfile create mode 100644 docker/misp/config/app_local.php create mode 100644 docker/misp/config/php-fpm.conf create mode 100644 docker/misp/config/php.dev.ini create mode 100644 docker/misp/config/php.ini create mode 100644 docker/nginx/Dockerfile create mode 100644 docker/nginx/certs/.keepdir create mode 100644 docker/nginx/entrypoint.sh create mode 100644 docker/nginx/nginx.conf diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 000000000..f1aef0653 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,24 @@ +version: "3.9" + +services: + php-fpm: + build: + context: . + dockerfile: docker/misp/Dockerfile + target: dev + volumes: + - ./bin:/var/www/html/bin + - ./config:/var/www/html/config + - ./libraries:/var/www/html/libraries + - ./plugins:/var/www/html/plugins + - ./src:/var/www/html/src + - ./templates:/var/www/html/templates + - ./tests:/var/www/html/tests + - ./tools:/var/www/html/tools + - ./webroot:/var/www/html/webroot + extra_hosts: + - "host.docker.internal:host-gateway" + + nginx: + volumes: + - ./webroot:/var/www/html/webroot diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..014651b52 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,82 @@ +version: "3.9" + +services: + php-fpm: + image: misp3/php:8.2-fpm + build: + context: . + dockerfile: docker/misp/Dockerfile + target: prod + restart: unless-stopped + tty: true + environment: + MISP_DB: misp + MISP_DB_USER: misp + MISP_DB_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - ./docker/misp/config/app_local.php:/var/www/html/config/app_local.php + - ./docker/misp/logs:/var/www/html/logs + networks: + - backend-network + - frontend-network + depends_on: + - db + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9000" ] + interval: 30s + timeout: 10s + retries: 5 + + nginx: + image: misp3/nginx + build: + context: . + dockerfile: docker/nginx/Dockerfile + ports: + - "80:80" + - "443:443" + volumes: + - ./docker/nginx/certs:/etc/nginx/certs + entrypoint: /usr/local/bin/entrypoint.sh + depends_on: + - php-fpm + networks: + - frontend-network + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost" ] + interval: 30s + timeout: 10s + retries: 5 + + db: + image: postgres:13 + restart: always + environment: + POSTGRES_DB: misp + POSTGRES_USER: misp + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - db_data:/var/lib/postgresql/data + networks: + - backend-network + healthcheck: + test: "pg_isready --username=$$POSTGRES_USER --dbname=$$POSTGRES_DB" + interval: 30s + timeout: 10s + retries: 5 + + redis: + image: redis:7 + ports: + - "6379:6379" + networks: + - backend-network + +networks: + frontend-network: + driver: bridge + backend-network: + driver: bridge + +volumes: + db_data: diff --git a/docker/.env.dist b/docker/.env.dist new file mode 100644 index 000000000..795f3af53 --- /dev/null +++ b/docker/.env.dist @@ -0,0 +1 @@ +POSTGRES_PASSWORD= \ No newline at end of file diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 000000000..1d65d5bbb --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1,4 @@ +*.key +*.crt +.env +.env.dev \ No newline at end of file diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..598b0e134 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,49 @@ +# Docker + +## Development +Create a copy of `./docker/.env.dist` + +```bash +cp ./docker/.env.dist ./docker.env.dev # <-- update your dev environment +docker-compose -f docker-compose.yml -f docker-compose.dev.yml --env-file=".env.dev" build +docker-compose -f docker-compose.yml -f docker-compose.dev.yml --env-file=".env.dev" up +``` + +```bash +docker-compose -f docker-compose.yml -f docker-compose.dev.yml --env-file=".env.dev" exec --user www-data php-fpm bash +``` + +### Debugging +For debugging the PHP code with XDebug and VSCODE use the following configuration file: +`launch.json`: +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9003, + "pathMappings": { + "/var/www/html": "${workspaceRoot}", + }, + }, + ] +} +``` +> **NOTE**: Add `XDEBUG_SESSION_START` query parameter or `XDEBUG_SESION=VSCODE` cookie to debug your requests. + +## Testing +```bash +docker-compose -f docker-compose.yml -f docker-compose.test.yml --env-file=".env.test" build +docker-compose -f docker-compose.yml -f docker-compose.test.yml --env-file=".env.test" up -d +docker-compose --env-file=".env.test" exec --user www-data php-fpm /var/www/html/bin/cake test +``` + +## Production +```bash +cp ./docker/.env.dist ./docker.env # <-- update your prod environment +docker-compose --env-file="docker/.env" build +docker-compose --env-file="docker/.env" up -d +``` \ No newline at end of file diff --git a/docker/misp/Dockerfile b/docker/misp/Dockerfile new file mode 100644 index 000000000..056443535 --- /dev/null +++ b/docker/misp/Dockerfile @@ -0,0 +1,81 @@ +# Base image with necessary extensions and configurations +FROM php:8.2-fpm AS base + +USER root + +# Install additional PHP extensions +RUN apt-get -y update \ + && apt-get install -y libicu-dev libpq-dev sqlite3 libsqlite3-dev \ + && docker-php-ext-configure intl \ + && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ + && docker-php-ext-install intl pdo pdo_pgsql pgsql pdo_sqlite + +# Copy custom php-fpm config file +COPY docker/misp/config/php-fpm.conf /usr/local/etc/php-fpm.conf + +# Set working directory +WORKDIR /var/www/html + +# Install Composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Set permissions for log file +RUN touch /var/run/php-fpm.pid /var/log/php-fpm.error.log /var/log/php-fpm.slow.log \ + && chown www-data:www-data /var/run/php-fpm.pid /var/log/php-fpm.error.log /var/log/php-fpm.slow.log + +EXPOSE 9000 + +# Development image with additional packages and dependencies +FROM base AS dev +USER root + +RUN usermod -u 1000 www-data + +# Copy application code +COPY . /var/www/html/ + +# Create tmp directory (for DebugKit) +RUN mkdir /var/www/html/tmp\ + && chown -R www-data:www-data /var/www/html/tmp + +# Install development dependencies +RUN pecl install -f xdebug \ + && docker-php-ext-enable xdebug + +# Install additional packages +RUN apt-get update \ + && apt-get install -y \ + git \ + sudo + +# Write Xdebug configuration +RUN echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ + && echo "xdebug.start_with_request=debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ + && echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ + && echo "xdebug.client_port=9003" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ + && echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini + +# Copy dev php.ini file +COPY docker/misp/config/php.dev.ini /usr/local/etc/php/php.ini + +# Install dependencies +RUN composer install --dev --no-cache + +RUN chown -R www-data:www-data /var/www/html + +CMD ["php-fpm", "-F"] + +# Production image with only necessary packages and dependencies +FROM base AS prod +USER www-data + +# Copy application code +COPY . /var/www/html/ + +# Copy prod php.ini file +COPY docker/misp/config/php.ini /usr/local/etc/php/php.ini + +# Install only production dependencies +RUN composer install --no-dev --optimize-autoloader --no-cache --no-interaction --no-progress --no-suggest --no-scripts + +CMD ["php-fpm", "-F"] diff --git a/docker/misp/config/app_local.php b/docker/misp/config/app_local.php new file mode 100644 index 000000000..57e234e30 --- /dev/null +++ b/docker/misp/config/app_local.php @@ -0,0 +1,104 @@ + filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN), + + /* + * Security and encryption configuration + * + * - salt - A random string used in security hashing methods. + * The salt value is also used as the encryption key. + * You should treat it as extremely sensitive data. + */ + 'Security' => [ + 'salt' => env('SECURITY_SALT', '__SALT__'), + ], + + /* + * Connection information used by the ORM to connect + * to your application's datastores. + * + * See app.php for more configuration options. + */ + 'Datasources' => [ + 'default' => [ + 'driver' => 'Postgres', + 'host' => 'db', + /* + * CakePHP will use the default DB port based on the driver selected + * MySQL on MAMP uses port 8889, MAMP users will want to uncomment + * the following line and set the port accordingly + */ + //'port' => 'non_standard_port_number', + + 'username' => env('MISP_DB_USER', 'misp'), + 'password' => env('MISP_DB_USER'), + 'database' => env('MISP_DB', 'misp'), + /** + * If not using the default 'public' schema with the PostgreSQL driver + * set it here. + */ + //'schema' => 'myapp', + + /** + * You can use a DSN string to set the entire configuration + */ + // 'url' => env('DATABASE_URL', null), + ], + /* + * The test connection is used during the test suite. + */ + 'test' => [ + 'driver' => 'Postgres', + 'host' => 'db', + 'username' => 'misp', + 'password' => 'misp', + 'database' => 'misp_test', + ], + ], + + /* + * Email configuration. + * + * Host and credential configuration in case you are using SmtpTransport + * + * See app.php for more configuration options. + */ + 'EmailTransport' => [ + 'default' => [ + 'host' => 'localhost', + 'port' => 25, + 'username' => null, + 'password' => null, + 'client' => null, + 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), + ], + ], + 'MISP' => [ + 'dark' => 0 + ] +]; diff --git a/docker/misp/config/php-fpm.conf b/docker/misp/config/php-fpm.conf new file mode 100644 index 000000000..2565cae8e --- /dev/null +++ b/docker/misp/config/php-fpm.conf @@ -0,0 +1,19 @@ +[global] +pid = /var/run/php-fpm.pid +error_log = /var/log/php-fpm.error.log + +[www] +user = www-data +group = www-data +listen = 0.0.0.0:9000 +listen.owner = www-data +listen.group = www-data +pm = dynamic +pm.max_children = 5 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +catch_workers_output = yes +request_terminate_timeout = 60s +request_slowlog_timeout = 10s +slowlog = /var/log/php-fpm.slow.log diff --git a/docker/misp/config/php.dev.ini b/docker/misp/config/php.dev.ini new file mode 100644 index 000000000..4c6020b16 --- /dev/null +++ b/docker/misp/config/php.dev.ini @@ -0,0 +1,16 @@ +; PHP settings +error_reporting = E_ALL +display_errors = On +log_errors = On +max_execution_time = 300 +memory_limit = 128M + +; File uploads +upload_max_filesize = 64M +post_max_size = 64M + +; Date and time +date.timezone = UTC + +; Session settings +session.save_handler = files \ No newline at end of file diff --git a/docker/misp/config/php.ini b/docker/misp/config/php.ini new file mode 100644 index 000000000..88779e003 --- /dev/null +++ b/docker/misp/config/php.ini @@ -0,0 +1,24 @@ +; PHP settings +error_reporting = E_ALL +display_errors = Off +log_errors = On +max_execution_time = 300 +memory_limit = 128M + +; File uploads +upload_max_filesize = 64M +post_max_size = 64M + +; Date and time +date.timezone = UTC + +; Session settings +session.save_handler = files + +; OPcache settings +opcache.enable = 1 +opcache.memory_consumption = 128 +opcache.interned_strings_buffer = 16 +opcache.max_accelerated_files = 10000 +opcache.revalidate_freq = 60 +opcache.fast_shutdown = 1 diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 000000000..a9dd044bb --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +1,21 @@ +FROM nginx:1.23.4 + +# Copy nginx.conf to container +COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf + +# Set entrypoint script and make it executable +COPY docker/nginx/entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/entrypoint.sh + +# Copy application code +COPY . /var/www/html/ + +# Set working directory +WORKDIR /var/www/html + +# Expose ports +EXPOSE 80 +EXPOSE 443 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker/nginx/certs/.keepdir b/docker/nginx/certs/.keepdir new file mode 100644 index 000000000..e69de29bb diff --git a/docker/nginx/entrypoint.sh b/docker/nginx/entrypoint.sh new file mode 100644 index 000000000..d19b351f2 --- /dev/null +++ b/docker/nginx/entrypoint.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e + +# Generate SSL certificate and key +SSL_KEY_FILE=/etc/nginx/certs/server.key +CERT_FILE=/etc/nginx/certs/server.crt + +if [ ! -f "$SSL_KEY_FILE" ]; then + echo "Generating self-signed certificate..." + openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \ + -subj "/C=US/ST=California/L=San Francisco/O=My Company/CN=localhost" \ + -keyout $SSL_KEY_FILE \ + -out $CERT_FILE +fi + + +# Start nginx +nginx -g "daemon off;" diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf new file mode 100644 index 000000000..c9b9ce661 --- /dev/null +++ b/docker/nginx/nginx.conf @@ -0,0 +1,38 @@ +events { + worker_connections 1024; +} +http { + server { + server_name misp.local; + + listen 80 default_server; + listen [::]:80 default_server; + listen 443 ssl http2 default_server; + listen [::]:443 ssl http2 default_server; + + ssl_certificate /etc/nginx/certs/server.crt; + ssl_certificate_key /etc/nginx/certs/server.key; + + root /var/www/html/webroot; + + index index.php; + + error_log /var/log/nginx/error.log debug; + access_log /var/log/nginx/access.log; + + include /etc/nginx/mime.types; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + try_files $uri =404; + include /etc/nginx/fastcgi_params; + fastcgi_pass php-fpm:9000; + fastcgi_index index.php; + fastcgi_intercept_errors on; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } +} \ No newline at end of file