Skip to content

Refinement

Iva edited this page Aug 23, 2024 · 6 revisions
  • Configuration Refinement (Dependencies)

    • Add the definition of dependency and startup order for each container in the docker-compose.yml file as applied below:
    version: "3.8"
    
    services:
      nginx:
        build: requirements/nginx/.
        container_name: nginx
        restart: on-failure
        depends_on:
          - wordpress
        networks:
          - inception
        ports:
          - "443:443"
        volumes:
          - .web:/var/www/html
      wordpress:
        build: requirements/wordpress/.
        container_name: wordpress
        restart: on-failure
        depends_on:
          - mariadb
        networks:
          - inception
        expose:
          - "9000"
        volumes:
          - .web:/var/www/html
      mariadb:
        build: requirements/mariadb/.
        container_name: mariadb
        restart: on-failure
        networks:
          - inception
        expose:
          - "3306"
    networks:
      inception:
        driver: bridge
    👉🏼 After defining dependencies, the container startup order will change. If no dependencies are declared, the order followed will always be the order written in the docker-compose.yml file. 👉🏼 Dependencies:
    • nginx: Needs PHP-FPM to process .php requests. Since PHP-FPM is in the WordPress container, nginx will depend on WordPress starting first.
    • wordpress: Needs MariaDB to manage the database present in the DB volume. Since MariaDB is in the MariaDB container, WordPress will

depend on MariaDB starting first. - mariadb: …

  • Configuration Refinement (DB Volume)

    • Add a volume to the docker-compose.yml file responsible for gathering the database data to be accessed by the MariaDB container. Link the directory where the volume will be stored with the /var/lib/mysql directory in each container:
    version: "3.8"
    
    services:
      nginx:
        build: requirements/nginx/.
        container_name: nginx
        restart: on-failure
        depends_on:
          - wordpress
        networks:
          - inception
        ports:
          - "443:443"
        volumes:
          - .web:/var/www/html
      wordpress:
        build: requirements/wordpress/.
        container_name: wordpress
        restart: on-failure
        depends_on:
          - mariadb
        networks:
          - inception
        expose:
          - "9000"
        volumes:
          - .web:/var/www/html
      mariadb:
        build: requirements/mariadb/.
        container_name: mariadb
        restart: on-failure
        networks:
          - inception
        expose:
          - "3306"
        volumes:
          - .db:/var/lib/mysql
    networks:
      inception:
        driver: bridge
    👉🏼 The directory structure created by the docker-compose.yml file will be modified, adding the `rootInception/srcs/db/` directory if it does not exist, and considering it if it does exist. This directory will be responsible for storing the volume to be accessed by MariaDB. 👉🏼 The project requirements specify that the volume directory should be located at `/home/login/data/` within the host. For this reason, the `.db` directory will be renamed to the required path later on.
    • Create a script file mariadb-run.sh in the rootInception/srcs/requirements/mariadb/tools/ path that will be executed last in the Dockerfile of the MariaDB container. This file will be responsible for configuring the necessary files and directories to initialize the database, and finally, running MariaDB in the terminal. The file should be filled as described below:
    #!/bin/bash
    mysql_install_db 
    mysqld
    • Add the command to copy the script created above to the local directory and change the permissions so that it can be executed at the end of the Dockerfile in the Dockerfile for MariaDB, as shown below:
    FROM debian:bullseye 
    RUN apt update && apt upgrade -y && apt install -y mariadb-server
    COPY conf/50-server.cnf /etc/mysql/mariadb.conf.d/.
    COPY conf/init.sql /etc/mysql/init.sql
    RUN mkdir /run/mysqld
    COPY tools/mariadb-run.sh .
    RUN chmod +x ./mariadb-run.sh
    ENTRYPOINT ["./mariadb-run.sh"]
  • Configuration Refinement (Volumes)

    • Change the volume directories to the one specified in the project requirements with the home/login/data structure and add the volume configuration in the docker-compose.yml file, as shown below:
    version: "3.8"
    
    services:
      nginx:
        build: requirements/nginx/.
        container_name: nginx
        restart: on-failure
        depends_on:
          - wordpress
        networks:
          - inception
        ports:
          - "443:443"
        volumes:
          - v_web:/var/www/html
      wordpress:
        build: requirements/wordpress/.
        container_name: wordpress
        restart: on-failure
        depends_on:
          - mariadb
        networks:
          - inception
        expose:
          - "9000"
        volumes:
          - v_web:/var/www/html
      mariadb:
        build: requirements/mariadb/.
        container_name: mariadb
        restart: on-failure
        networks:
          - inception
        expose:
          - "3306"
        volumes:
          - v_db:/var/lib/mysql
    volumes:
      v_web:
        driver: local
        driver_opts:
          type: none
          o: bind
          device: ./home/ivbatist/data/wordpress
      v_db:
        driver: local
        driver_opts:
          type: none
          o: bind
          device: ./home/ivbatist/data/mariadb
    networks:
      inception:
        driver: bridge
    👉🏼 The directory structure defined as the device in the volume configuration must already exist to start the volumes correctly.
  • Configuration Refinement (Domain)

    • Change the domain name to be considered by the server in the nginx.conf configuration file of the NGINX container, changing server_name from _ to the domain specified in the project requirements, as shown below:
    server_name _; #Line before
    server_name ivbatist.42.fr; #Line after
    • Change the previously defined URL for localhost in the WordPress creation script wp-install.sh to the domain specified in the project requirements, as shown below:
    ./wp-cli.phar core install --url=localhost --title=inception --admin_user=ivbatist --admin_password=1234567890 [email protected] --allow-root
    ./wp-cli.phar core install --url=ivbatist.42.fr --title=inception --admin_user=ivbatist --admin_password=1234567890 [email protected] --allow-root
    • Add the following to the host/VM in the /etc/hosts file, informing your operating system that all traffic to ivbatist.42.fr should be treated as traffic to localhost (127.0.0.1):
    127.0.0.1       ivbatist.42.fr
    👉🏼 This command should be included in the Makefile to evaluate whether this line is present in the original file and add it if not.
  • Configuration Refinement (Env File and Sensitive Data)

    👉🏼 The YAML file of Docker compose automatically loads the values from the `.env` file if it is in the same directory as the `.yml` file. These values/variables can be passed to the Dockerfiles called by the YAML as arguments or as environment variables. For environment variables, all values from the `.env` file can be passed at once or one by one. 👉🏼 Values in the YAML file:
    • Arguments (build: args:): Responsible for passing key=value from the YAML file to the Dockerfile of the specific service/container, to be used only during the Docker image build time. Example: Dockerfile.
      • It can be accessed by the Dockerfile via the ARG instruction.
    • Environment Variables (environment): Responsible for passing key=value from the YAML file to the Dockerfile of the specific service/container, to be used as environment variables, only during container runtime, after the Docker image is created. Example: Bash Scripts, SQL Scripts…
      • It can be received and redeclared by the Dockerfile via the ENV instruction.
    • Environment Variables (env_file): Responsible for passing all key=value from the file passed as an argument from the YAML to the Dockerfile of the specific service/container, to be used as environment variables, only during container runtime, after the Docker image is created. Example: Bash Scripts, SQL Scripts…
      • It can be received and redeclared by the Dockerfile via the ENV instruction.
    • Add the declaration to consider all content from the .env file as environment variables for runtime in the WordPress service/container to be used in the secondary wp_install.sh file called by the Dockerfile in the docker-compose.yml file:
    [...]
      wordpress:
        build: requirements/wordpress/.
        container_name: wordpress
        restart: on-failure
        depends_on:
          - mariadb
        networks:
          - inception
        expose:
          - "9000"
        volumes:
          - v_web:/var/www/html
        env_file:
          - .env
    [...]
    • Change the sensitive values for the WordPress installation and profile creation to be replaced with environment variables in the wp-install.sh file for WordPress, as shown below:
    #!/bin/bash
    [...]
    ./wp-cli.phar config create --dbname=${DB_NAME} --dbuser=${DB_USER} --dbpass=${DB_PASSWORD} --dbhost=${DB_HOST} --allow-root
    ./wp-cli.phar core install --url=${WP_DOMAIN} --title=${WP_TITLE} --admin_user=${WP_ADMIN_USER} --admin_password=${WP_ADMIN_PASSWORD} --admin_email=${WP_ADMIN_EMAIL} --allow-root
    ./wp-cli.phar user create ${WP_GUEST_USER} ${WP_GUEST_EMAIL} --role=subscriber --user_pass=${WP_GUEST_PASSWORD} --allow-root
    [...]
    • Add the declaration to consider all content from the .env file as environment variables for runtime in the MariaDB service/container to be used in the creation of the secondary init.sql file in the docker-compose.yml file:
    [...]
      mariadb:
        build: requirements/mariadb/.
        container_name: mariadb
        restart: on-failure
        networks:
          - inception
        expose:
          - "3306"
        volumes:
          - v_db:/var/lib/mysql
        env_file:
          - .env
    [...]
    • Change the sensitive values for profile and database creation with MariaDB to be replaced with environment variables in the init.sql file for MariaDB, as shown below:
    CREATE DATABASE IF NOT EXISTS ${DB_NAME};
    CREATE USER IF NOT EXISTS '${DB_USER}'@'%' IDENTIFIED BY '${DB_PASSWORD}';
    GRANT ALL PRIVILEGES ON *.* TO '${DB_USER}'@'%' IDENTIFIED BY '${DB_PASSWORD}' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    • Modify the content of the init.sql file, and add this content as an echo command in the mariadb-run.sh script, so that this script can create the init.sql file in the specified path, using the Docker environment variables, in the mariadb-run.sh file for MariaDB:
    #!/bin/bash
    echo "CREATE DATABASE IF NOT EXISTS $DB_NAME;" > /etc/mysql/init.sql
    echo "CREATE USER IF NOT EXISTS '$DB_USER'@'%' IDENTIFIED BY '$DB_PASSWORD';" >> /etc/mysql/init.sql
    echo "GRANT ALL PRIVILEGES ON *.* TO '$DB_USER'@'%' IDENTIFIED BY '$DB_PASSWORD' WITH GRANT OPTION;" >> /etc/mysql/init.sql
    echo "FLUSH PRIVILEGES;" >> /etc/mysql/init.sql
    sleep 5
    mysql_install_db 
    mysqld
    👉🏼 At this point, the `/conf/init.sql` file that existed earlier can be deleted.
    • Remove the line that copied the init.sql file to the specified path inside the container in the Dockerfile for MariaDB, as shown below:
    FROM debian:bullseye 
    RUN apt update && apt upgrade -y && apt install -y mariadb-server
    COPY conf/50-server.cnf /etc/mysql/mariadb.conf.d/.
                                                #Deleted line -> COPY conf/init.sql /etc/mysql/init.sql
    RUN mkdir /run/mysqld
    COPY tools/mariadb-run.sh .
    RUN chmod +x ./mariadb-run.sh
    ENTRYPOINT ["./mariadb-run.sh"]
    • Add the declaration to consider some contents of the .env file as arguments for build time to be used in the creation of the secondary certificate files ssl and server configurations in nginx.conf in the NGINX service/container, in the docker-compose.yml file:
    [...]
      nginx:
        build: 
          context: requirements/nginx/.
          args:
            - CRED_PATH
            - CRED_CERT
            - CRED_KEY
            - COUNTRY
            - STATE
            - LOCALITY
            - ORGANIZATION
            - ORG_UNIT
            - COMMON_NAME
        container_name: nginx
        restart: on-failure
        depends_on:
          - wordpress
        networks:
          - inception
        ports:
          - "443:443"
        volumes:
          - v_web:/var/www/html
    [...]
    • Add the command to receive the arguments passed by the YAML file so that they can be used internally, in the Dockerfile for NGINX, as shown below:
    FROM debian:bullseye 
    ARG CRED_PATH CRED_CERT CRED_KEY COUNTRY STATE LOCALITY ORGANIZATION ORG_UNIT COMMON_NAME
    RUN apt update && apt upgrade -y && apt install -y nginx openssl
    RUN mkdir -p ${CRED_PATH}
    RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${CRED_PATH}/${CRED_KEY} -out ${CRED_PATH}/${CRED_CERT} -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=${COMMON_NAME}"
    COPY conf/nginx.conf /etc/nginx/sites-available/default
    ENTRYPOINT ["nginx", "-g", "daemon off;"]
    • Modify the sensitive values for the SSL certificate storage directory, as well as all the data necessary for certificate creation and the final certificate files, to be replaced with environment variables in the Dockerfile for NGINX, as shown below:
    FROM debian:bullseye 
    ARG CRED_PATH CRED_CERT CRED_KEY COUNTRY STATE LOCALITY ORGANIZATION ORG_UNIT COMMON_NAME
    RUN apt update && apt upgrade -y && apt install -y nginx openssl
    RUN mkdir -p ${CRED_PATH}
    RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${CRED_PATH}/${CRED_KEY} -out ${CRED_PATH}/${CRED_CERT} -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=${COMMON_NAME}"
    COPY conf/nginx.conf /etc/nginx/sites-available/default
    ENTRYPOINT ["nginx", "-g", "daemon off;"]
    • Modify the sensitive values for the SSL certificate storage files and the server/domain name of the site to be replaced with environment variables in the nginx.conf configuration file for NGINX:
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_certificate ${CRED_PATH}/${CRED_CERT}; #Value before: /etc/nginx/certs/nginx-selfsigned.crt;
    ssl_certificate_key ${CRED_PATH}/${CRED_KEY}; #Value before: /etc/nginx/certs/nginx-selfsigned.key;
    
    root /var/www/html;
    
    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;
    
    server_name ${COMMON_NAME}; #Value before: ivbatist.42.fr;
    • Change the copy command of the conf/nginx.conf file, which previously went directly to the final configuration directory of NGINX, to copying this same file to a temporary /tmp directory, which will be used during the modification of masked values before copying to the final directory in the Dockerfile for NGINX, as shown below:
    FROM debian:bullseye 
    ARG CRED_PATH CRED_CERT CRED_KEY COUNTRY STATE LOCALITY ORGANIZATION ORG_UNIT COMMON_NAME
    RUN apt update && apt upgrade -y && apt install -y nginx openssl
    RUN mkdir -p ${CRED_PATH}
    RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${CRED_PATH}/${CRED_KEY} -out ${CRED_PATH}/${CRED_CERT} -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=${COMMON_NAME}"
    COPY conf/nginx.conf ./tmp/nginx.conf #Line before -> COPY conf/nginx.conf /etc/nginx/sites-available/default
    ENTRYPOINT ["nginx", "-g", "daemon off;"]
    • Add the command to modify the masked data in the nginx.conf file with the values of the variables received from the YAML file in the Dockerfile for NGINX, as shown below:
    FROM debian:bullseye 
    ARG CRED_PATH CRED_CERT CRED_KEY COUNTRY STATE LOCALITY ORGANIZATION ORG_UNIT COMMON_NAME
    RUN apt update && apt upgrade -y && apt install -y nginx openssl
    RUN mkdir -p ${CRED_PATH}
    RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${CRED_PATH}/${CRED_KEY} -out ${CRED_PATH}/${CRED_CERT} -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=${COMMON_NAME}"
    COPY conf/nginx.conf ./tmp/nginx.conf #Line before -> COPY conf/nginx.conf /etc/nginx/sites-available/default
    RUN envsubst '$CRED_PATH $CRED_KEY $CRED_CERT $COMMON_NAME' < /tmp/nginx.conf > /etc/nginx/sites-available/default
    ENTRYPOINT ["nginx", "-g", "daemon off;"]
    • Add the command to install the program responsible for running the envsubst command in the NGINX Docker container, as shown below:
    FROM debian:bullseye 
    ARG CRED_PATH CRED_CERT CRED_KEY COUNTRY STATE LOCALITY ORGANIZATION ORG_UNIT COMMON_NAME
    RUN apt update && apt upgrade -y && apt install -y nginx openssl gettext-base
    RUN mkdir -p ${CRED_PATH}
    RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${CRED_PATH}/${CRED_KEY} -out ${CRED_PATH}/${CRED_CERT} -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCAL
    

ITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=${COMMON_NAME}" COPY conf/nginx.conf ./tmp/nginx.conf RUN envsubst '$CRED_PATH $CRED_KEY $CRED_CERT $COMMON_NAME' < /tmp/nginx.conf > /etc/nginx/sites-available/default ENTRYPOINT ["nginx", "-g", "daemon off;"] ```

- Create an `.env` file in the same `/srcs` directory as the `docker-compose.yml`, and fill it with the variables used and their values:

```
CRED_PATH=/etc/nginx/certs
CRED_CERT=nginx-selfsigned.crt
CRED_KEY=nginx-selfsigned.key

COUNTRY=BR
STATE=Pernambuco
LOCALITY=Recife
ORGANIZATION=42Porto
ORG_UNIT=Cadet
COMMON_NAME=ivbatist.42.fr

DB_NAME=dbsite
DB_USER=dbuser
DB_PASSWORD=123456789
DB_HOST=mariadb

WP_DOMAIN=ivbatist.42.fr
WP_TITLE=inception
WP_ADMIN_USER=ivbatist
WP_ADMIN_PASSWORD=1234567890
[email protected]
WP_GUEST_USER=guest
WP_GUEST_PASSWORD=123456789
[email protected]
```

⏮️ Previous
Next ⏭️

Clone this wiki locally