From 85668d7bb87b0b42b2169deaaf50c535e3ec57fb Mon Sep 17 00:00:00 2001 From: Matteo Gheza Date: Fri, 23 Feb 2024 22:19:17 +0100 Subject: [PATCH] Add Docker configuration files to the project. Add a Dockerfile to the project. Add a docker-compose.yml --- .gitignore | 4 +- backend/.dockerignore | 35 ++++++++++++++++ backend/Dockerfile | 54 ++++++++++++++++++++++++ backend/docker-entrypoint.sh | 27 ++++++++++++ deployment.php | 79 ----------------------------------- deployment_remotes.sample.php | 12 ------ docker-compose.yaml | 61 +++++++++++++++++++++++++++ docker_nginx/Dockerfile | 16 +++++++ docker_nginx/default.conf | 16 +++++++ frontend/.dockerignore | 2 + frontend/Dockerfile | 25 +++++++++++ 11 files changed, 239 insertions(+), 92 deletions(-) create mode 100644 backend/.dockerignore create mode 100644 backend/Dockerfile create mode 100644 backend/docker-entrypoint.sh delete mode 100644 deployment.php delete mode 100644 deployment_remotes.sample.php create mode 100644 docker-compose.yaml create mode 100644 docker_nginx/Dockerfile create mode 100644 docker_nginx/default.conf create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile diff --git a/.gitignore b/.gitignore index 8dc7740..5acd051 100644 --- a/.gitignore +++ b/.gitignore @@ -527,4 +527,6 @@ adminer.php /server/resources/images/logo.png /server/resources/images/owner.png -/server/resources/images/map_cache \ No newline at end of file +/server/resources/images/map_cache + +.env.docker diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..b3c0dd2 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,35 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.next +**/.cache +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/charts +**/docker-compose* +**/compose* +!**/composer.json +!**/composer.lock +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +**/vendor +LICENSE +README.md diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..9f2987c --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,54 @@ +# Stage 1: Build PHP app and install dependencies +FROM php:8.2 AS builder + +WORKDIR /app + +# Copy the application code +COPY . . + +# Install git +RUN apt-get update && apt-get install -y git unzip + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Install dependencies +RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader + +# Stage 2: Serve the application using Apache PHP +FROM php:8.1.10-apache + +# Copy the built PHP app from the builder stage +COPY --from=builder /app /var/www/html + +RUN apt-get update && apt-get install -y \ + libfreetype-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + && rm -rf /var/lib/apt/lists/* \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) gd + +RUN pecl install redis-5.3.7 \ + && docker-php-ext-enable redis + +# Use the default production configuration for PHP runtime arguments, see +# https://github.com/docker-library/docs/tree/master/php#configuration +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +ENV APACHE_DOCUMENT_ROOT=/var/www/html/public +RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf +RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf + +RUN a2enmod rewrite headers && chown -R www-data:www-data /var/www/html + +ADD ./docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +# Switch to a non-privileged user (defined in the base image) that the app will run under. +# See https://docs.docker.com/go/dockerfile-user-best-practices/ +USER www-data + +EXPOSE 80 + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/backend/docker-entrypoint.sh b/backend/docker-entrypoint.sh new file mode 100644 index 0000000..a8777ed --- /dev/null +++ b/backend/docker-entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Check if .env file exists and is empty +if grep -q "DB_HOST=" .env; then + echo ".env file already exists and is not empty." +else + # Copy .env.example to .env + echo "Copying .env.example to .env..." + cat .env.example > .env + + # Set database credentials + cp .env .env.tmp + echo "Setting database credentials..." + sed -i "s/DB_HOST=127.0.0.1/DB_HOST=${DB_HOST}/g" .env.tmp + sed -i "s/DB_DATABASE=laravel/DB_DATABASE=${DB_DATABASE}/g" .env.tmp + sed -i "s/DB_USERNAME=root/DB_USERNAME=${DB_USER}/g" .env.tmp + sed -i "s/DB_PASSWORD=/DB_PASSWORD=${DB_PASSWORD}/g" .env.tmp + cat .env.tmp > .env + rm .env.tmp + + # Generate encryption key + echo "Generating encryption key..." + php artisan key:generate +fi + +# Run Apache +apache2-foreground diff --git a/deployment.php b/deployment.php deleted file mode 100644 index 5aa4c9a..0000000 --- a/deployment.php +++ /dev/null @@ -1,79 +0,0 @@ - 'backend', - 'ignore' => ' - .git* - .github - .vscode - *.json - config.old.php - config.php - keys - *tests* - *tests - *examples* - *examples - *Makefile* - *LICENSE* - *CREDITS* - *VERSION* - *CHANGELOG* - *.md - *.rst - *.txt - !robots.txt - *.sh - *editorconfig - *doc* - *.yml - *.travis* - *.eslintrc* - *.phpstorm* - *.php_cs* - *.xml - *phpcs* - *phpstan* - *phpunit* - vendor/nikic/fast-route/test - *.lock - *.zip - ', - 'allowDelete' => false, - 'before' => [ - 'local: cd backend && composer update --no-dev -o' - ], - 'after' => [ - 'local: cd backend && composer install' - ], - 'filePermissions' => "0644", - 'dirPermissions' => "0755" -]; - -try { - require("deployment_remotes.php"); -} catch (\Throwable $th) { - print("ERROR: no 'deployment_remotes.php' file.".PHP_EOL); - print("Rename 'deployment_remotes.sample.php' in 'deployment_remotes.php' and edit remotes config.".PHP_EOL); - exit(); -} - -$config = []; -foreach ($remotes as $key => $value) { - $config[$key] = array_merge($value, $baseConfig); - if(isset($value["before"]) && $value["before"] === false){ - $config[$key]["before"] = []; - } else { - $env = isset($config[$key]["sentry_env"]) ? $config[$key]["sentry_env"] : "prod"; - $config[$key]["before"][] = "local: cd frontend && npm ci && npm run build"; - } - if(isset($value["after"]) && $value["after"] === false){ - $config[$key]["after"] = []; - } - if(isset($config[$key]["skip_composer_upload"]) && $config[$key]["skip_composer_upload"]){ - $config[$key]["ignore"] .= " - vendor"; - } -} - -return $config; \ No newline at end of file diff --git a/deployment_remotes.sample.php b/deployment_remotes.sample.php deleted file mode 100644 index 387c017..0000000 --- a/deployment_remotes.sample.php +++ /dev/null @@ -1,12 +0,0 @@ - [ - 'remote' => 'sftp://user:secretpassword@ftp.example.com/directory_testing', - ], - 'production' => [ - 'remote' => 'ftp://ftp.example.com/directory', - 'user' => 'user', - 'password' => 'secretpassword' - ] -]; \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..39552de --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,61 @@ +services: + server: + build: + context: ./docker_nginx + dockerfile: Dockerfile + args: + - UID=${UID:-1000} + - GID=${GID:-1000} + ports: + - "80:80" + depends_on: + - backend + - frontend + + backend: + build: + context: ./backend + dockerfile: Dockerfile + args: + - UID=${UID:-1000} + - GID=${GID:-1000} + depends_on: + - db + environment: + - DB_HOST=db + - DB_USER=user + - DB_PASSWORD=password + - DB_DATABASE=mydb + volumes: + - laravel-storage:/var/www/html/storage + - ./.env.docker:/var/www/html/.env + + db: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: mydb + MYSQL_USER: user + MYSQL_PASSWORD: password + volumes: + - db-data:/var/lib/mysql + + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + args: + - UID=${UID:-1000} + - GID=${GID:-1000} + + phpmyadmin: + image: phpmyadmin/phpmyadmin + environment: + PMA_HOST: db + MYSQL_ROOT_PASSWORD: root + ports: + - "8080:80" + +volumes: + db-data: + laravel-storage: diff --git a/docker_nginx/Dockerfile b/docker_nginx/Dockerfile new file mode 100644 index 0000000..9cddff6 --- /dev/null +++ b/docker_nginx/Dockerfile @@ -0,0 +1,16 @@ +FROM nginx:stable-alpine + +ARG UID +ARG GID + +ENV UID=${UID} +ENV GID=${GID} + +# MacOS staff group's gid is 20, so is the dialout group in alpine linux. We're not using it, let's just remove it. +RUN delgroup dialout + +RUN addgroup -g ${GID} --system laravel +RUN adduser -G laravel --system -D -s /bin/sh -u ${UID} laravel +RUN sed -i "s/user nginx/user laravel/g" /etc/nginx/nginx.conf + +ADD ./default.conf /etc/nginx/conf.d/ diff --git a/docker_nginx/default.conf b/docker_nginx/default.conf new file mode 100644 index 0000000..fa56732 --- /dev/null +++ b/docker_nginx/default.conf @@ -0,0 +1,16 @@ +server { + listen 80; + server_name localhost; + + location / { + proxy_pass http://frontend:80; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + + location /api { + proxy_pass http://backend:80; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..f344dc7 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,2 @@ +.angular +node_modules diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..5b59ddc --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,25 @@ +# Step 1: Build Angular in production mode +FROM node:18 AS builder + +WORKDIR /app + +# Copy package.json and package-lock.json +COPY package*.json ./ + +# Install dependencies +RUN npm install --force + +# Copy the rest of the application code +COPY . . + +# Build the Angular application in production mode +RUN npm run build --ignore-scripts -- --output-path=./dist/frontend + +# Step 2: Serve the built application using Nginx +FROM nginx:latest + +# Copy the built Angular application from the previous step +COPY --from=builder /app/dist/frontend /usr/share/nginx/html + +# Expose port 80 for Nginx +EXPOSE 80