From a4c01aac2e047769053eb8d8789f10a149eaf3ac Mon Sep 17 00:00:00 2001 From: whaffman Date: Thu, 17 Jul 2025 15:07:07 +0200 Subject: [PATCH] mail hog working ftp working redis working --- Makefile | 11 +++- srcs/.env | 4 ++ srcs/docker-compose.yml | 40 +++++++++++-- srcs/requirements/adminer/Dockerfile | 23 ++++++-- srcs/requirements/adminer/conf/www.conf | 10 ++++ srcs/requirements/ftp/Dockerfile | 15 ++--- srcs/requirements/ftp/conf/vsftpd.conf | 39 +++++-------- .../ftp/tools/docker-entrypoint.sh | 8 +++ srcs/requirements/mailhog/Dockerfile | 29 ++++++++++ srcs/requirements/mariadb/Dockerfile | 24 +------- .../mariadb/tools/docker-entrypoint.sh | 57 +++++-------------- srcs/requirements/nginx/Dockerfile | 4 +- srcs/requirements/nginx/conf/nginx.conf | 31 ++++++++++ srcs/requirements/wordpress/conf/www.conf | 2 +- srcs/requirements/wordpress/tools/install.sh | 18 ++++++ 15 files changed, 201 insertions(+), 114 deletions(-) create mode 100644 srcs/requirements/adminer/conf/www.conf create mode 100644 srcs/requirements/mailhog/Dockerfile diff --git a/Makefile b/Makefile index 86c79c6..14c8792 100644 --- a/Makefile +++ b/Makefile @@ -27,12 +27,17 @@ DC = $(DOCKER_COMPOSE) -f $(DOCKER_COMPOSE_FILE) --env-file $(DOCKER_ENV_FILE) - all: build up -$(WORDPRESS_DATA_DIR): +$(DATA_DIR): + @echo "$(gub)Creating data directory...$(reset)" + @mkdir -p $(DATA_DIR) + @chmod 777 $(DATA_DIR) + +$(WORDPRESS_DATA_DIR): $(DATA_DIR) @echo "$(gub)Creating WordPress data directory...$(reset)" @mkdir -p $(WORDPRESS_DATA_DIR) @chmod 777 $(WORDPRESS_DATA_DIR) -$(MARIADB_DATA_DIR): +$(MARIADB_DATA_DIR): $(DATA_DIR) @echo "$(gub)Creating MariaDB data directory...$(reset)" @mkdir -p $(MARIADB_DATA_DIR) @chmod 777 $(MARIADB_DATA_DIR) @@ -41,7 +46,7 @@ $(MARIADB_DATA_DIR): build: $(WORDPRESS_DATA_DIR) $(MARIADB_DATA_DIR) @echo "$(gub)Building Docker containers...$(reset)" $(DC) build --build-arg HOST_UID=$(UID) -up: +up: $(WORDPRESS_DATA_DIR) $(MARIADB_DATA_DIR) @echo "$(gub)Starting Docker containers...$(reset)" $(DC) up -d diff --git a/srcs/.env b/srcs/.env index c84a9a0..ecfa2fc 100644 --- a/srcs/.env +++ b/srcs/.env @@ -21,6 +21,10 @@ WP_USER=inception WP_USER_PASSWORD=42inception42 WP_USER_EMAIL=inception2@duinvoetje.nl +FTP_USER=ftpuser +FTP_PASS=42ftp42 +FTP_PORT=21 + diff --git a/srcs/docker-compose.yml b/srcs/docker-compose.yml index 44cd49c..b0cd791 100644 --- a/srcs/docker-compose.yml +++ b/srcs/docker-compose.yml @@ -1,15 +1,17 @@ services: mariadb: container_name: mariadb - image: mariadb build: context: ./requirements/mariadb dockerfile: Dockerfile + args: + HOST_UID: ${HOST_UID:-1000} environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - MYSQL_DATABASE=${MYSQL_DATABASE} - MYSQL_USER=${MYSQL_USER} - MYSQL_PASSWORD=${MYSQL_PASSWORD} + - HOST_UID=${HOST_UID:-1000} networks: - docker-network volumes: @@ -18,7 +20,6 @@ services: nginx: container_name: nginx - image: nginx build: context: ./requirements/nginx dockerfile: Dockerfile @@ -30,6 +31,7 @@ services: - DOMAIN_NAME=${DOMAIN_NAME} ports: - '443:443' + - '8443:8443' networks: - docker-network volumes: @@ -38,10 +40,11 @@ services: wordpress: container_name: wordpress - image: wordpress build: context: ./requirements/wordpress dockerfile: Dockerfile + args: + HOST_UID: ${HOST_UID:-1000} depends_on: - mariadb environment: @@ -73,7 +76,6 @@ services: redis: container_name: redis - image: redis build: context: ./requirements/redis dockerfile: Dockerfile @@ -83,16 +85,18 @@ services: ftp: container_name: ftp - image: ftp build: context: ./requirements/ftp dockerfile: Dockerfile + args: + HOST_UID: ${HOST_UID:-1000} depends_on: - wordpress environment: - FTP_USER=${FTP_USER} - FTP_PASS=${FTP_PASS} - FTP_PORT=${FTP_PORT} + - HOST_UID=${HOST_UID:-1000} networks: - docker-network ports: @@ -101,6 +105,32 @@ services: volumes: - data_wordpress:/var/www/html restart: unless-stopped + stop_grace_period: 2s + adminer: + container_name: adminer + build: + context: ./requirements/adminer + dockerfile: Dockerfile + depends_on: + - mariadb + environment: + - ADMINER_DEFAULT_SERVER=mariadb + networks: + - docker-network + restart: unless-stopped + + mailhog: + container_name: mailhog + build: + context: ./requirements/mailhog + dockerfile: Dockerfile + networks: + - docker-network + restart: unless-stopped + environment: + - HOST_UID=${HOST_UID:-1000}=value + + networks: docker-network: diff --git a/srcs/requirements/adminer/Dockerfile b/srcs/requirements/adminer/Dockerfile index 4b6d5f5..a3a15e1 100644 --- a/srcs/requirements/adminer/Dockerfile +++ b/srcs/requirements/adminer/Dockerfile @@ -1,16 +1,31 @@ FROM alpine:3.20 +ARG HOST_UID=1000 + +# Install PHP-FPM and dependencies for Adminer RUN apk add --no-cache \ php83 \ php83-fpm \ php83-mysqli \ php83-mbstring \ php83-session \ + php83-json \ mariadb-client \ - curl &&\ + curl && \ rm -rf /var/cache/apk/* -# Add a new user and group -# Create group with GID = HOST_UID, then user with UID = HOST_UID and GID = HOST_UID -ARG HOST_UID +# Create user with matching UID +RUN addgroup -g ${HOST_UID} adminer && \ + adduser -D -u ${HOST_UID} -G adminer adminer + +# Create web directory and download Adminer +RUN mkdir -p /var/www/html && \ + curl -L https://github.com/vrana/adminer/releases/download/v5.3.0/adminer-5.3.0.php -o /var/www/html/adminer.php && \ + chown -R adminer:adminer /var/www/html + +COPY ./conf/www.conf /etc/php83/php-fpm.d/www.conf + +EXPOSE 9000 + +CMD ["php-fpm83", "-F"] diff --git a/srcs/requirements/adminer/conf/www.conf b/srcs/requirements/adminer/conf/www.conf new file mode 100644 index 0000000..76c68a3 --- /dev/null +++ b/srcs/requirements/adminer/conf/www.conf @@ -0,0 +1,10 @@ +[www] +listen = 0.0.0.0:9000 +user = adminer +group = adminer +pm = dynamic +pm.max_children = 5 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +catch_workers_output = yes \ No newline at end of file diff --git a/srcs/requirements/ftp/Dockerfile b/srcs/requirements/ftp/Dockerfile index be4c1d7..38577ae 100644 --- a/srcs/requirements/ftp/Dockerfile +++ b/srcs/requirements/ftp/Dockerfile @@ -1,17 +1,18 @@ FROM alpine:3.20 +# Accept build argument for host user ID +ARG HOST_UID=1000 + RUN apk add --no-cache \ vsftpd \ && rm -rf /var/cache/apk/* -RUN adduser -D -h /home/ftpuser -s /bin/false ftpuser && \ - echo "ftpuser:password" | chpasswd && \ - mkdir -p /home/ftpuser/ftp && \ - chmod 750 /home/ftpuser/ftp && \ - chown -R ftpuser:ftpuser /home/ftpuser/ftp - COPY ./conf/vsftpd.conf /etc/vsftpd/vsftpd.conf +COPY ./tools/docker-entrypoint.sh /docker-entrypoint.sh +RUN chmod +x /docker-entrypoint.sh EXPOSE 20 21 30000-30009 -CMD ["vsftpd", "/etc/vsftpd/vsftpd.conf"] +CMD ["/docker-entrypoint.sh"] +# HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ +# CMD nc -z localhost 21 || exit 1 \ No newline at end of file diff --git a/srcs/requirements/ftp/conf/vsftpd.conf b/srcs/requirements/ftp/conf/vsftpd.conf index da131b6..909c011 100644 --- a/srcs/requirements/ftp/conf/vsftpd.conf +++ b/srcs/requirements/ftp/conf/vsftpd.conf @@ -1,35 +1,22 @@ -# Allow local users to log in +# Access settings local_enable=YES +anonymous_enable=NO -# Enable write permissions for local users +# Write settings write_enable=YES +allow_writeable_chroot=YES -# Restrict users to their home directories +# Chroot settings chroot_local_user=YES -# Enable passive mode (useful for NAT and firewalls) +# Listen settings +listen=YES +background=NO + +# Security settings +seccomp_sandbox=NO + +# Passive mode settings pasv_enable=YES pasv_min_port=30000 pasv_max_port=30009 - - -# Disable anonymous login -anonymous_enable=NO - -# Set the FTP banner message -ftpd_banner=Welcome to the FTP server. - -# Listen on IPv4 -listen=YES - -# Disable IPv6 (optional, if not needed) -listen_ipv6=NO - -# Set the maximum number of clients -max_clients=10 - -# Set the maximum number of connections per IP -max_per_ip=5 - -# Log all FTP requests -xferlog_enable=YES \ No newline at end of file diff --git a/srcs/requirements/ftp/tools/docker-entrypoint.sh b/srcs/requirements/ftp/tools/docker-entrypoint.sh index 8b13789..a6dcec5 100644 --- a/srcs/requirements/ftp/tools/docker-entrypoint.sh +++ b/srcs/requirements/ftp/tools/docker-entrypoint.sh @@ -1 +1,9 @@ +#!/bin/sh +adduser -D -u "${HOST_UID}" -h /var/www/html -s /bin/false "${FTP_USER}" 2>/dev/null || true +echo "${FTP_USER}:${FTP_PASS}" | chpasswd +mkdir -p /var/www/html +# chown -R "${FTP_USER}:${FTP_USER}" /var/www/html +echo "${FTP_USER}" > /etc/vsftpd.userlist + +exec vsftpd /etc/vsftpd/vsftpd.conf diff --git a/srcs/requirements/mailhog/Dockerfile b/srcs/requirements/mailhog/Dockerfile new file mode 100644 index 0000000..41d03cd --- /dev/null +++ b/srcs/requirements/mailhog/Dockerfile @@ -0,0 +1,29 @@ +FROM alpine:3.21 AS builder + +RUN apk add --no-cache \ + go \ + git \ + && rm -rf /var/cache/apk/* + +ENV GOROOT /usr/lib/go +ENV GOPATH /go +ENV PATH /go/bin:$PATH + +RUN mkdir -p ${GOPATH}/src ${GOPATH}/bin +ENV GOTOOLCHAIN=auto + + +RUN go install github.com/mailhog/MailHog@latest + +FROM alpine:3.20 + +ARG HOST_UID=1000 + +RUN adduser -D -u ${HOST_UID} mailhog + +COPY --from=builder /go/bin/MailHog /usr/local/bin/MailHog + +CMD ["MailHog"] + +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD curl --silent --fail http://localhost:8025/ || exit 1 \ No newline at end of file diff --git a/srcs/requirements/mariadb/Dockerfile b/srcs/requirements/mariadb/Dockerfile index 65bedd5..38678af 100644 --- a/srcs/requirements/mariadb/Dockerfile +++ b/srcs/requirements/mariadb/Dockerfile @@ -1,10 +1,6 @@ FROM alpine:3.20 -# Install MariaDB and MariaDB client -# The --no-cache option is used to prevent the package manager from caching the downloaded packages -# rm -rf /var/cache/apk/* is used to remove any cached files after installation -# This helps to keep the image size small RUN apk add --no-cache \ mariadb \ mariadb-client && \ @@ -12,42 +8,24 @@ RUN apk add --no-cache \ ARG HOST_UID -# Create a new user and group RUN addgroup -S -g $HOST_UID mariadb && \ adduser -S -u $HOST_UID mariadb -G mariadb -# Create the necessary directories RUN mkdir -p /var/run/mysqld && \ chown -R mariadb:mariadb /var/run/mysqld && \ chown -R mariadb:mariadb /var/lib/mysql && \ chmod -R 750 /var/lib/mysql -# Copy the entrypoint script and configuration files -# and set the necessary permissions -# The entrypoint script will be responsible for initializing the database -# and starting the MariaDB server -# The configuration file will be used to set the server settings -# The init.sql file will be executed when the container is started for the first time COPY ./tools/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh COPY ./conf/my.cnf /etc/my.cnf -# COPY ./init.sql /usr/local/bin/init.sql - -# Expose the MySQL port -#EXPOSE 3306 - -# Set the user and group to run the container - RUN chmod +x /usr/local/bin/docker-entrypoint.sh -# Set the working directory + WORKDIR /var/lib/mysql -# Set the entrypoint script to be executed when the container starts -# The entrypoint script will initialize the database and start the server USER mariadb ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] -# Start the MariaDB server CMD ["mysqld", "--datadir=/var/lib/mysql", "--user=mariadb"] HEALTHCHECK --interval=5s --timeout=3s --start-period=5s --retries=1 CMD mysqladmin ping -h localhost || exit 1 diff --git a/srcs/requirements/mariadb/tools/docker-entrypoint.sh b/srcs/requirements/mariadb/tools/docker-entrypoint.sh index cf60d3b..aeb2df4 100644 --- a/srcs/requirements/mariadb/tools/docker-entrypoint.sh +++ b/srcs/requirements/mariadb/tools/docker-entrypoint.sh @@ -1,48 +1,19 @@ #!/bin/sh set -e -# If the first argument is 'mysqld', then start MariaDB -if [ "$1" = 'mysqld' ]; then - # Initialize the database if it doesn't exist - if [ ! -d "/var/lib/mysql/mysql" ]; then - echo "Initializing database..." - mysql_install_db --user=mariadb --datadir=/var/lib/mysql --rpm - echo "Database initialized." - - # Start MariaDB temporarily to set up initial configuration - mysqld --user=mariadb --skip-networking & - pid="$!" - - # Wait for MariaDB to start - while ! mysqladmin ping --silent; do - sleep 1 - done - - # Set up root user and any initial database - echo "Setting up initial database..." - mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';" - if [ -n "$MYSQL_DATABASE" ]; then - mysql -e "CREATE DATABASE IF NOT EXISTS \`${MYSQL_DATABASE}\`;" - fi - if [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ]; then - mysql -e "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';" - mysql -e "GRANT ALL PRIVILEGES ON \`${MYSQL_DATABASE}\`.* TO '${MYSQL_USER}'@'%';" - fi - mysql -e "FLUSH PRIVILEGES;" - - # Load initial SQL dump if init.sql exists - if [ -f "/usr/bin/local/init.sql" ]; then - echo "Loading initial SQL dump..." - mysql "${MYSQL_DATABASE}" < /usr/bin/local/init.sql - echo "Initial SQL dump loaded." - fi - - # Stop temporary MariaDB instance - kill "$pid" - wait "$pid" - fi - - echo "Starting MariaDB..." +if [ "$1" = 'mysqld' ] && [ ! -d "/var/lib/mysql/mysql" ]; then + mysql_install_db --user=mariadb --datadir=/var/lib/mysql --rpm + mysqld --user=mariadb --skip-networking & + pid=$! + while ! mysqladmin ping --silent; do sleep 1; done + mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';" + [ "$MYSQL_DATABASE" ] && mysql -e "CREATE DATABASE IF NOT EXISTS \`${MYSQL_DATABASE}\`;" + [ "$MYSQL_USER" ] && [ "$MYSQL_PASSWORD" ] && \ + mysql -e "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';" && \ + mysql -e "GRANT ALL PRIVILEGES ON \`${MYSQL_DATABASE}\`.* TO '${MYSQL_USER}'@'%';" + mysql -e "FLUSH PRIVILEGES;" + [ -f "/usr/bin/local/init.sql" ] && mysql "${MYSQL_DATABASE}" < /usr/bin/local/init.sql + kill "$pid" && wait "$pid" fi -exec "$@" \ No newline at end of file +exec "$@" diff --git a/srcs/requirements/nginx/Dockerfile b/srcs/requirements/nginx/Dockerfile index de7e73d..038a552 100644 --- a/srcs/requirements/nginx/Dockerfile +++ b/srcs/requirements/nginx/Dockerfile @@ -14,6 +14,6 @@ RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -subj "/CN=${DOMAIN_NAME}" COPY ./conf/nginx.conf /etc/nginx/nginx.conf -EXPOSE 443 +EXPOSE 443 8443 CMD ["nginx", "-g", "daemon off;"] -HEALTHCHECK --interval=5s --timeout=3s --start-period=5s --retries=1 CMD curl --insecure -f https://127.0.0.1:443/ || exit 1 +# HEALTHCHECK --interval=5s --timeout=3s --start-period=5s --retries=1 CMD curl --insecure -f https://127.0.0.1:443/ || exit 1 diff --git a/srcs/requirements/nginx/conf/nginx.conf b/srcs/requirements/nginx/conf/nginx.conf index 1ae22db..efe999e 100644 --- a/srcs/requirements/nginx/conf/nginx.conf +++ b/srcs/requirements/nginx/conf/nginx.conf @@ -26,12 +26,43 @@ http { try_files $uri $uri/ /index.php$is_args$args; } + location ~ /adminer\.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass adminer:9000; + fastcgi_index adminer.php; + include fastcgi.conf; + } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass wordpress:9000; fastcgi_index index.php; include fastcgi.conf; } + } + server { + listen 8443 ssl; + server_name ${DOMAIN_NAME}; + + ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; + ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; + + location / { + proxy_pass http://mailhog:8025; + chunked_transfer_encoding on; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + } + } + + } \ No newline at end of file diff --git a/srcs/requirements/wordpress/conf/www.conf b/srcs/requirements/wordpress/conf/www.conf index 085cb60..35fac02 100644 --- a/srcs/requirements/wordpress/conf/www.conf +++ b/srcs/requirements/wordpress/conf/www.conf @@ -7,4 +7,4 @@ pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 -catch_workers_output = yes \ No newline at end of file +catch_workers_output = yes diff --git a/srcs/requirements/wordpress/tools/install.sh b/srcs/requirements/wordpress/tools/install.sh index 7abcf4d..443b026 100644 --- a/srcs/requirements/wordpress/tools/install.sh +++ b/srcs/requirements/wordpress/tools/install.sh @@ -1,5 +1,12 @@ #!/bin/sh +# Set sendmail_path in php.ini for PHP 8.3 FPM +PHP_INI="/etc/php83/php.ini" +if [ -f "$PHP_INI" ]; then + sed -i '/^sendmail_path/d' "$PHP_INI" + echo 'sendmail_path = "/usr/sbin/sendmail -S mailhog:1025"' >> "$PHP_INI" +fi + # This script is used to install WordPress and configure it with a MariaDB database. # It checks for the presence of a database and user, creates them if they don't exist, # and sets up the WordPress configuration file with the database connection details. @@ -61,6 +68,17 @@ wp config set --allow-root \ wp redis enable --allow-root \ --path=/var/www/html +# wp config set --allow-root \ +# SMTP_SERVER \ +# "mailhog" \ +# --type=constant \ +# --path=/var/www/html +# wp config set --allow-root \ +# SMTP_PORT \ +# 1025 \ +# --type=constant \ +# --path=/var/www/html + echo "WordPress installation completed." chown -R wordpress:wordpress /var/www/html