From 7029069aaf79396e874fe19532cd03ee50402fba Mon Sep 17 00:00:00 2001 From: Florian Trayon <26360935+FlorianLeChat@users.noreply.github.com> Date: Tue, 2 Apr 2024 18:58:50 +0200 Subject: [PATCH] Added new Docker images to split dev and production environments --- .dockerignore | 3 +- .env | 14 +++-- .gitignore | 2 + docker-compose.yml | 65 +++++++++++----------- docker/Dockerfile.development | 41 ++++++++++++++ Dockerfile => docker/Dockerfile.production | 17 ++---- 6 files changed, 91 insertions(+), 51 deletions(-) create mode 100644 docker/Dockerfile.development rename Dockerfile => docker/Dockerfile.production (62%) diff --git a/.dockerignore b/.dockerignore index 9d4541d..b3322a9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,4 +8,5 @@ **/Dockerfile **/docker-* **/CODEOWNERS -**/LICENSE \ No newline at end of file +**/LICENSE +**/next-env.d.ts \ No newline at end of file diff --git a/.env b/.env index dfdf62a..9eff7d1 100644 --- a/.env +++ b/.env @@ -11,7 +11,7 @@ SENTRY_ENABLED=false SENTRY_DSN=https://url.to.sentry.io/1234567890 SENTRY_ORG=org SENTRY_PROJECT=project -SENTRY_AUTH_TOKEN=token +SENTRY_AUTH_TOKEN=sntrys_token # S3 Object Storage parameters S3_ENABLED=false @@ -23,14 +23,20 @@ S3_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Google Analytics and reCAPTCHA keys NEXT_PUBLIC_RECAPTCHA_ENABLED=false -NEXT_PUBLIC_RECAPTCHA_PUBLIC_KEY=6Lxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -RECAPTCHA_SECRET_KEY=6Lxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +NEXT_PUBLIC_RECAPTCHA_PUBLIC_KEY=6Ldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +RECAPTCHA_SECRET_KEY=6Ldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx NEXT_PUBLIC_ANALYTICS_ENABLED=false NEXT_PUBLIC_ANALYTICS_TAG=G-XXXXXXXXXX # Database credentials -DATABASE_URL="mysql://username:password@127.0.0.1:3306/simple_file_storage" +DATABASE_TYPE=mysql +DATABASE_HOST=mariadb +DATABASE_PORT=3306 +DATABASE_NAME=simple_file_storage +DATABASE_USERNAME=username +DATABASE_PASSWORD=password +DATABASE_URL="${DATABASE_TYPE}://${DATABASE_USERNAME}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}" # SMTP and DKIM credentials SMTP_HOST=smtp.example.com diff --git a/.gitignore b/.gitignore index c0aa72c..22a70f5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,8 @@ # misc .DS_Store *.pem +/docker/database/ +/docker-compose.override.yml # debug npm-debug.log* diff --git a/docker-compose.yml b/docker-compose.yml index c683816..ee803e2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,27 +13,40 @@ services: restart: always volumes: - ./docker/database:/var/lib/mysql - secrets: - - db_password - - db_root_password environment: - MARIADB_DATABASE: simple_file_storage - MARIADB_PORT: 3306 - MARIADB_USER: simple_file_storage - # > Default credentials (for test image) - MARIADB_PASSWORD: password - MARIADB_ROOT_PASSWORD: password - # > Custom credentials with secrets (for production image) - # MARIADB_PASSWORD_FILE: /run/secrets/db_password - # MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db_root_password + MARIADB_DATABASE: ${DATABASE_NAME} + MARIADB_PORT: ${DATABASE_PORT} + MARIADB_USER: ${DATABASE_USERNAME} + MARIADB_PASSWORD: ${DATABASE_PASSWORD} + MARIADB_RANDOM_ROOT_PASSWORD: 1 networks: - simple_file_storage healthcheck: - test: ["CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized"] + test: healthcheck.sh --su-mysql --connect --innodb_initialized retries: 3 timeout: 5s ports: - - 3306:3306 + - "3306:${DATABASE_PORT}" + + # https://hub.docker.com/_/phpmyadmin + phpmyadmin: + image: phpmyadmin:latest + restart: always + depends_on: + - mariadb + environment: + PMA_HOST: ${DATABASE_HOST} + PMA_PORT: ${DATABASE_PORT} + PMA_USER: ${DATABASE_USERNAME} + PMA_PASSWORD: ${DATABASE_PASSWORD} + networks: + - simple_file_storage + healthcheck: + test: curl -f http://localhost + retries: 3 + timeout: 5s + ports: + - "8080:80" # https://github.com/FlorianLeChat/Simple-File-Storage node: @@ -46,32 +59,16 @@ services: target: /usr/src/app depends_on: - mariadb - secrets: - - db_password environment: - - WAIT_HOSTS=mariadb:3306 + - WAIT_HOSTS=mariadb:${DATABASE_PORT} networks: - simple_file_storage healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000"] + test: curl -f http://localhost:3000 retries: 3 timeout: 5s - deploy: - resources: - limits: - cpus: "1" - memory: 512M - reservations: - cpus: "0.25" - memory: 128M build: context: . - dockerfile: ./Dockerfile + dockerfile: ./docker/Dockerfile.${NEXT_PUBLIC_ENV} ports: - - 3000:3000 - -secrets: - db_password: - file: ./docker/config/db_password.txt - db_root_password: - file: ./docker/config/db_root_password.txt \ No newline at end of file + - "3000:3000" \ No newline at end of file diff --git a/docker/Dockerfile.development b/docker/Dockerfile.development new file mode 100644 index 0000000..558e2d9 --- /dev/null +++ b/docker/Dockerfile.development @@ -0,0 +1,41 @@ +# syntax=docker/dockerfile:1 + +# Use an customized image of Node.js +# https://hub.docker.com/_/node +FROM node:lts-alpine + +# Add cURL for health check and OpenSSL for generating random secret +RUN apk update && apk add --no-cache curl openssl + +# Set the working directory to the website files +WORKDIR /usr/src/app + +# Change permissions of the working directory +RUN chown node:node . + +# Copy all files required to build the project +COPY --chown=node:node . . + +# Create a directory for the Next.js build cache +RUN mkdir -p .next && chown -R node:node .next + +# Install all dependencies +# Use cache mount to speed up installation of existing dependencies +RUN --mount=type=cache,target=.npm \ + npm set cache .npm && \ + npm install && chown -R node:node ./node_modules + +# Add wait script to wait for other services to be ready +ADD https://github.com/ufoscout/docker-compose-wait/releases/latest/download/wait /wait +RUN chmod +x /wait + +# Use non-root user +USER node + +# Find and replace some default environment variables +RUN sed -i "s#AUTH_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#AUTH_SECRET=$(openssl rand -base64 32)#g" .env + +# Create a custom entrypoint script +RUN echo "/wait && npm run migrate && npm run dev" > docker/entrypoint.sh && chmod +x docker/entrypoint.sh + +CMD ["docker/entrypoint.sh"] \ No newline at end of file diff --git a/Dockerfile b/docker/Dockerfile.production similarity index 62% rename from Dockerfile rename to docker/Dockerfile.production index 0a48074..6bd6993 100644 --- a/Dockerfile +++ b/docker/Dockerfile.production @@ -5,7 +5,7 @@ FROM node:lts-alpine # Add cURL for health check and OpenSSL for generating random secret -RUN apk --no-cache add curl openssl +RUN apk update && apk add --no-cache curl openssl # Set the working directory to the website files WORKDIR /usr/src/app @@ -16,6 +16,9 @@ RUN chown node:node . # Copy all files required to build the project COPY --chown=node:node . . +# Create a directory for the Next.js build cache +RUN mkdir -p .next && chown -R node:node .next + # Install all dependencies # Use cache mount to speed up installation of existing dependencies RUN --mount=type=cache,target=.npm \ @@ -29,14 +32,6 @@ RUN chmod +x /wait # Use non-root user USER node -# Find and replace some default environment variables -RUN sed -i "s/NEXT_PUBLIC_ENV=development/NEXT_PUBLIC_ENV=production/g" .env -RUN sed -i "s#AUTH_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#AUTH_SECRET=$(openssl rand -base64 32)#g" .env -RUN sed -i "s/username:password@127.0.0.1:3306/simple_file_storage:password@mariadb:3306/g" .env -RUN if [ -f "docker/config/db_root_password.txt" ]; then \ - sed -i "s/simple_file_storage:password/simple_file_storage:$(cat \/usr\/src\/app\/docker\/config\/db_root_password.txt)/" .env; \ -fi - # Build the entire project RUN npm run build @@ -44,8 +39,6 @@ RUN npm run build RUN npm prune --production # Create a custom entrypoint script -RUN mkdir -p docker -RUN echo "/wait && npm run migrate && npm run start" > docker/entrypoint.sh -RUN chmod +x docker/entrypoint.sh +RUN echo "/wait && npm run migrate && npm run start" > docker/entrypoint.sh && chmod +x docker/entrypoint.sh CMD ["docker/entrypoint.sh"] \ No newline at end of file