====== RabbitMQ ======
Пароль указан в переменных Гитлаба и хэшируется при сборке. В definitions.json указаны слова-маркеры, которые будут заменены ''sed''-ом в зависимости от окружения, куда будет деплой Реббита.
stages:
- build
- deploy
variables:
IMAGE_DEV: $CI_REGISTRY_IMAGE/rabbitmq_dev
IMAGE_STAGE: $CI_REGISTRY_IMAGE/rabbitmq_stage
IMAGE_PROD: $CI_REGISTRY_IMAGE/rabbitmq_prod
VERSION: 1.0.$CI_PIPELINE_ID
DOCKER_HOST: ssh://cicd@${DEPLOY_HOST} # Set default docker context in docker:cli container
before_script:
- eval $(ssh-agent -s)
- cat $SSH_PRIVATE_KEY | tr -d '\r' | ssh-add -
- sed -i '/StrictHostKeyChecking /c StrictHostKeyChecking no' /etc/ssh/ssh_config || true
- echo "$CI_REGISTRY_PASSWORD" |docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
# Task templates
.build:
stage: build
tags:
- shell
variables:
IMAGE_NAME: ""
DEPLOY_HOST: ""
RABBITMQ_USER: ""
RABBITMQ_PASS: ""
script:
- RABBITMQ_PASS_HASH=`docker run --rm --name rabbit-hash-gen rabbitmq:management-alpine rabbitmqctl hash_password $RABBITMQ_PASS |grep -v $RABBITMQ_PASS`
- sed -i "s|RABBITMQ_USER|$RABBITMQ_USER|g" definitions.json
- sed -i "s|RABBITMQ_PASS_HASH|$RABBITMQ_PASS_HASH|" definitions.json
- docker build -t $IMAGE_NAME:$VERSION .
- docker push $IMAGE_NAME:$VERSION
- docker tag $IMAGE_NAME:$VERSION $IMAGE_NAME:latest
- docker push $IMAGE_NAME:latest
.deploy:
stage: deploy
tags:
- docker
image: docker:cli
variables:
STACK: ""
IMAGE_NAME: ""
NETWORK: ""
DEPLOY_HOST: ""
RABBITMQ_STORAGE: ""
RABBITMQ_PORT: ""
RABBITMQ_ADMIN_PORT: ""
script:
- docker pull $IMAGE_NAME:$VERSION
- docker stack rm $STACK
- docker network create --driver=overlay --scope=swarm $NETWORK || true
- docker stack deploy -c ./docker-compose.yml $STACK
# Build
build_dev:
extends: .build
rules:
- if: $CI_COMMIT_BRANCH == "dev"
- if: $BUILD == "yes"
variables:
IMAGE_NAME: $IMAGE_DEV
DEPLOY_HOST: 10.1.0.138
RABBITMQ_USER: $RABBITMQ_USER_DEV
RABBITMQ_PASS: $RABBITMQ_PASS_DEV
# build_stage:
# build_prod:
# Deploy
deploy_dev:
extends: .deploy
rules:
- if: $CI_COMMIT_BRANCH == "dev"
- if: $BUILD == "yes"
- if: $DEPLOY == "dev"
variables:
VERSION: latest
variables:
STACK: rabbitmq_dev
IMAGE_NAME: $IMAGE_DEV
NETWORK: ${STACK}
DEPLOY_HOST: 10.1.0.138
RABBITMQ_STORAGE: /docker/rabbitmq/dev/rabbitmq_storage
RABBITMQ_PORT: 8088
RABBITMQ_ADMIN_PORT: 8089
environment:
name: dev
url: https://${DEPLOY_HOST}:${RABBITMQ_ADMIN_PORT}
# deploy_stage:
# deploy_prod:
# Админка через TLS (порт 15671)
version: "3.9"
services:
rabbitmq:
image: ${IMAGE_NAME}:${VERSION}
hostname: rabbitmq
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
ports:
- ${RABBITMQ_PORT}:5672
- ${RABBITMQ_ADMIN_PORT}:15671
volumes:
- ${RABBITMQ_STORAGE}:/var/lib/rabbitmq
networks:
- rabbitmq
networks:
rabbitmq:
external: true
name: ${NETWORK}
В Докерфайле генерится сертификат для шифрования канала к админке
FROM rabbitmq:management-alpine
COPY --chown=rabbitmq:rabbitmq rabbitmq.conf /etc/rabbitmq/
COPY --chown=rabbitmq:rabbitmq definitions.json /etc/rabbitmq/
RUN \
mkdir -p -m 700 /etc/ssl/rabbitmq && \
cd /etc/ssl/rabbitmq && \
openssl genrsa -out ca.key 2048 && \
openssl req -new -x509 -days 36500 -key ca.key -subj "/C=CN/ST=GD/L=SZ/O=rabbitmq/CN=rabbitmq Root CA" -out ca.crt && \
openssl req -newkey rsa:2048 -nodes -keyout rabbitmq.key -subj "/C=CN/ST=GD/L=SZ/O=rabbitmq/CN=rabbitmq" -out rabbitmq.csr && \
openssl x509 -req -extfile <(printf "subjectAltName=DNS:rabbitmq") -days 36500 -in rabbitmq.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out rabbitmq.crt && \
chown -R rabbitmq:rabbitmq /etc/ssl/rabbitmq
load_definitions = /etc/rabbitmq/definitions.json
# https://www.rabbitmq.com/management.html#single-listener-https
management.ssl.port = 15671
management.ssl.cacertfile = /etc/ssl/rabbitmq/ca.crt
management.ssl.certfile = /etc/ssl/rabbitmq/rabbitmq.crt
management.ssl.keyfile = /etc/ssl/rabbitmq/rabbitmq.key
definitions.json (часть)
{
"users": [
{
"name": "RABBITMQ_USER",
"password_hash": "RABBITMQ_PASS_HASH",
"hashing_algorithm": "rabbit_password_hashing_sha256",
"tags": "administrator",
"limits": {}
}
],
"vhosts": [
{
"name": "/"
}
],
"permissions": [
{
"user": "RABBITMQ_USER",
"vhost": "/",
"configure": ".*",
"write": ".*",
"read": ".*"
}
],
"topic_permissions": [],
"parameters": [],
"global_parameters": [],
"policies": [],
"queues": [
{
"name": "queue1",
"vhost": "/",
"durable": true,
"auto_delete": false,
"arguments": {
"x-ha-policy": "all"
}
},
===== Очередь пустая после перезапуска RabbitMQ =====
In the class of your producer **you should set delivery mode to “2” which is “persistent”.**\\
You can do that using ''php-amqplib/rabbitmq-bundle'' by extending your producer class with ''OldSound\RabbitMqBundle\RabbitMq\Producer'' which, itself extends ''BaseAmqp''.\\
Once you’ve extended your producer class with ''OldSound\RabbitMqBundle\RabbitMq\Producer'' it’s already by default setting the “persistent” delivery mode and you will see it stored both in “Persistent” and “In memory”.\\
Now even after a restart the messages are still int the queue, ready to be consumed.
https://devmeetsbiz.business.blog/2020/01/12/rabbitmq-queue-empty-after-a-restart-why-even-though-its-durable/