Posts

Showing posts from 2024

[Solved] Apache 2.4.62 - AH00534: httpd: Configuration error: More than one MPM loaded.

 If you are building Apache/httpd from source (in my case it is httpd 2.4.62) and you encounter this error: AH00534: httpd: Configuration error: More than one MPM loaded. But you are absolutely sure that in your config file you just enable 1 module, here is what you need to check: In my case, my command of building Apache from source is this: ./configure --prefix=/usr/local/httpd-2.4.62 \ --enable-proxy \ --enable-proxy-http \ --enable-proxy-ajp \ --enable-forward \ --enable-module=most \ --enable-mods-shared=all \ --enable-so \ --enable-include \ --enable-headers \ --enable-deflate \ --enable-cache \ --enable-disk-cache \ --enable-mem-cache \ --enable-rewrite \ --enable-static-support \ --enable-expires \ --with-apr-util=/usr/local/apr \ --with-apr=/usr/local/apr Important: If you run httpd -M, you will see that mpm-event is "static", which means it is compiled as "static" module, i.e. pre-build and loaded by default. But if you add: --enable-mpms-shared \ --with-m...

[Working] Docker-compose + Nginx + PHP with Wordpress Multisites in subdirectory config

I'm sorry but I cannot add my config file here without a lot of editing.  Blogger.com is not good for developers who write technical blog easily.  Here is the blog on my medium.com site: https://medium.com/@alucard001/working-docker-compose-nginx-php-with-wordpress-multisites-in-subdirectory-config-cd51c0445d6a Hope it helps someone.

Recommended Security Headers for Nginx

This summary is not available. Please click here to view the post.

AWS cloudfront + S3 result in 503 error - S3 to serve HTML

Image
 Quick note: If you are serving HTML/CSS/JS/Any image files via AWS S3 with Cloudfront, but got 503 error, here is one way to solve: Simply put: In Viewer request, set cloudfront function to "serve-html-by-s3" Set Viewer repsonse to "No association" Setting Viewer response to value other than "No association" will result in 503 error. Hope it helps someone.

PHP 5.6 way to send AWS SNS topic message

This is an example PHP 5.6 script to send AWS SNS topic message. The architecture and assumption are as follow: Architecture: SNS (FIFO) -> SQS(FIFO) -> Lambda Only FIFO SNS can connect to FIFO SQS. Standard SNS cannot publish to FIFO SQS. Assumption: This script is executed in an EC2 instance. Assigned an AWS role to send SNS message. Because of above, supposed that there is no need to use Credential when creating SnsClient object. As the OS and PHP in this EC2 is old, the curl is already outdated. So it set http to false to bypass SSL verification.  Reference here . The $message part is designed for sending email for different vendor. In other words, it would vary in different case. Since SNS and SQS are FIFO, MessageGroupId must be set. It can be any random string, which is used to group message together for sending purpose. Here is the code <?php  require_once 'vendor/autoload.php'; use Aws\Sns\SnsClient; try{     $snsClient = new SnsClient([ ...

NodeJS dotenv .env: Which comes first? .env or environment var defined in Cloudformation?

As of this writing, in short: Cloud formation comes first. If you are using dotenv (.env), and you define the same variable as in your cloud formation template, cloud formation template will override the value in your .env

Laravel 11 cannot connect to Redis (serverless) - Checking points

Image
 If you are having trouble connecting to Redis server (usually AWS, other cloud platform applied as well), here are some of my tested ideas to check. All points are valid as of this writing, under Laravel 11 (Using Nginx + php-fpm, all dockerize), and build/executed in AWS ECS As of this writing(5 Jul 2024), please use REDIS_CLIENT = phpredis.  predis did not work.  It will not able to connect to your AWS redis (serverless) server.  Yet it works if you setup in your local development In my setting, REDIS_CLUSTER = rediss (double s), before that default value is `redis` There are 3 array sections: default, cache and session default: according to this git comment , this is for "normal" server.  I guess it means standalone server.  Which means the settings under default is for normal server. cache: These settings are for cluster.  I found that serverless = cluster. session: These settings are for sessions, if you are saving session data in redis...

How to clone MySQL database using SQL within same server?

Here is how to clone MySQL/MariaDB within same server. Core principle: use `Create TABLE <new_db>.<table_name> as select * from <old_db>.<table_name>`, and do it for all tables. If you have too many tables, you use the following SQL to generate a list of SQL. Steps: Use `CONCAT` to create SQL by selecting all tables from DB Get a list of `Create Table` and then run it all. SELECT CONCAT('CREATE TABLE my_database.20240510.', table_name, ' AS SELECT * FROM my_database.', table_name, ';') FROM information_schema.tables WHERE table_schema = 'my_database'; CREATE TABLE `my_database.20240510`.change_password_history AS SELECT * FROM my_database.change_password_history; CREATE TABLE `my_database.20240510`.children AS SELECT * FROM my_database.children; CREATE TABLE `my_database.20240510`.failed_jobs AS SELECT * FROM my_database.failed_jobs; CREATE TABLE `my_database.20240510`.interests AS SELECT * FROM my_database.interests; CR...

Laravel 11: Encrypted string length for database (MySQL)

In Laravel, as of this writing, the encryption string length different for different length of source string. Here is the list Encrypted string length: 200 for 1 - 15 chars Encrypted string length: 228 for 16 - 31 chars Encrypted string length: 256 for 32 - 47 chars ... In other words, for every 15 chars increases in source string length, the encrypted string length increased 28 chars accordingly. Which also means: if your table column with set to 200, it stores maximum 15 chars of source string length. Hope it helps.

Plain Javascript to get current datetime with Timezone

That's why I hate javascript, it is too complicated. const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); const dateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; console.log(dateTime); 

Why can't I build AWS OpenSearch/ElasticSearch index, which I could do that before?

One of the reason when you used to build AWS OS/ES index, and you can't do that now, is that there is a maximum shard default setting in AWS, which is 1000 shards. If you continuously build index, yet you did not remove old indices, there will be an increasing number of shards that occupied OS/ES. Until when a new index is built, and new shard is created that exceed the number of maximum shard, you got an error. Solution: Remove old/existing OS/ES indices. While it works for AWS, if you are using on-premise, it should be applied as well. Hope it helps someone.

[Easy to understand] What are Service, Service Container and Service Provider in PHP Laravel?

Imagine you are running a restaurant. Let's break down the concepts of Service, Service Container, and Service Provider using this restaurant analogy: Service: In our restaurant analogy, a service is like a specific task or job that needs to be done. For example, a "Waiter Service" would involve taking orders, serving food, and delivering the bill to the customers. Each service has a specific responsibility. Service Container: The service container is like the restaurant itself. It holds all the services (tasks) that need to be performed. Just like how a restaurant has different sections (kitchen, dining area, bar), the service container in Laravel holds different services that can be accessed when needed. When a customer (controller) needs a specific service (task), they ask the restaurant (service container) to provide it. Service Provider: The service provider is like the manager of the restaurant. They are responsible for setting up the restaurant, organizing the serv...

[Easy to understand] What is Kafka Consumer, Consumer Group, Topic & Partition?

Kafka: Kafka is a distributed streaming platform that allows you to publish and subscribe to streams of records, similar to a message queue or enterprise messaging system. Consume: Consuming in Kafka means reading data from a topic. Consumers read messages from topics and process them. Consumer Group: A consumer group is a set of consumers that cooperate to consume data from Kafka brokers. Each message within a topic is delivered to one consumer instance within each subscribing consumer group. This allows you to scale processing by adding more consumers to a group. Topic: A topic is a category/feed name to which records are sent by producers. Topics in Kafka are always multi-subscriber; that is, a topic can have zero, one, or many consumers that subscribe to the data written to it. Partition: Topics in Kafka are divided into partitions. Each partition is an ordered, immutable sequence of records that are continually appended to. Each message within a partition is assigned a unique offs...

[Easy to understand] Apache Kafka Listener and Advertised Listener

A plain, simple, even novice can understand explanation on what is Apache Kafka LISTENER and ADVERTISED_LISTENER. Imagine you are hosting a big party where people need to communicate with each other. In the world of Apache Kafka, the "Listener" is like the door or entrance to your party. It's where your guests (data producers and consumers) come in to interact with Kafka. Now, let's talk about the "Advertised Listener." This is like the address you give to your guests so they know how to find your party. Just like you might share your home address with friends to visit you, in Kafka, the Advertised Listener is the address that other services or clients use to connect to Kafka. In simpler terms, the Listener is where the communication happens within the Kafka system, while the Advertised Listener is the address that is shared with external services to connect to Kafka. For example, let's say your Kafka server has an internal IP address of 192.168.1.100 b...

How to use aws-lambda-python docker image with example in VSCode for local development

Image
Docker image: https://hub.docker.com/r/amazon/aws-lambda-python This docker image lacks working example on how to use. If you just want to test your lambda with this image locally, please read on. Let's assume the following: Your script is called `my_python.py` The function in this file that you want to execute is called `lambda_handler` Here is the docker command (I'm using windows): docker run --rm \ -p 9000:8080 \ --mount type=bind,src=/c/projects/my_lovely_proj,target=/var/task \ amazon/aws-lambda-python \ my_python.lambda_handler Brief explanation on above: --rm : Remove the container after terminating the script (i.e. Ctrl + C in command line).  So you don't need to run `docker stop <container_id>` and `docker rm <container_id>` -p 9000:8080: map the port of local machine 9000 to container port 8080.  This is super important and will be explained later. --mount: Mount the dir to /var/task in container.  All lambda script will be executed in this /var/tas...

Add WordPress Admin User via Database 2024 (and onwards)

If you are trying to add a user (probably admin), not using UI but via database directly.  Here is what you did. Refer to the following article to add a user to DB https://hk.godaddy.com/en/help/create-an-admin-user-in-the-wordpress-database-27023 (Recommended) https://help.one.com/hc/en-us/articles/17467509114385-How-to-add-an-Admin-User-to-the-WordPress-database https://wpengine.com/support/add-admin-user-phpmyadmin/ They are all talking about same steps, so just pick one and follow.  In case if you don't understand first article, read the next one and so on. Remember, if you are updating existing DB to use new prefix, you need to manually (or via SQL) update all table name to use your prefix. For example, if original prefix is 'wp_', and you want to change it to "my_lovely_", you need to update all table names, like "wp_posts" > "my_lovely_posts". Here is the missing steps:  Thanks to my colleagues, you also need to update {prefix}_optio...