diff --git a/.drone.yml b/.drone.yml
new file mode 100644
index 0000000..33118cf
--- /dev/null
+++ b/.drone.yml
@@ -0,0 +1,152 @@
+kind: pipeline
+type: docker
+name: arm32
+
+platform:
+  arch: arm
+
+steps:
+- name: Build arm/v7
+  image: registry.cuzo.dev/plugins/docker
+  privileged: true
+  settings:
+    repo: parrazam/crypto-reporter
+    auto_tag: true
+    auto_tag_suffix: linux-arm
+    mirror: https://registry.cuzo.dev
+    username:
+      from_secret: DOCKER_REGISTRY_USER
+    password:
+      from_secret: DOCKER_REGISTRY_PASSWORD
+
+image_pull_secrets:
+- PRIVATE_DOCKER_REGISTRY
+
+trigger:
+  event:
+  - push
+  - tag
+
+---
+kind: pipeline
+type: docker
+name: amd64
+
+platform:
+  arch: amd64
+
+steps:
+- name: Build amd64
+  image: registry.cuzo.dev/plugins/docker
+  privileged: true
+  volumes:
+    - name: manifest
+      path: docker
+  settings:
+    repo: parrazam/crypto-reporter
+    auto_tag: true
+    auto_tag_suffix: linux-amd64
+    mirror: https://registry.cuzo.dev
+    username:
+      from_secret: DOCKER_REGISTRY_USER
+    password:
+      from_secret: DOCKER_REGISTRY_PASSWORD
+
+image_pull_secrets:
+- PRIVATE_DOCKER_REGISTRY
+
+trigger:
+  event:
+  - push
+  - tag
+
+---
+kind: pipeline
+type: docker
+name: manifest
+
+steps:
+- name: Upload manifest
+  image: registry.cuzo.dev/plugins/manifest
+  privileged: true
+  volumes:
+    - name: manifest
+      path: docker
+  settings:
+    target: parrazam/crypto-reporter
+    template: parrazam/crypto-reporter:OS-ARCH
+    auto_tag: true
+    ignore_missing: true
+    username:
+      from_secret: DOCKER_REGISTRY_USER
+    password:
+      from_secret: DOCKER_REGISTRY_PASSWORD
+    platforms:
+      - linux/amd64
+      - linux/arm
+
+depends_on:
+- amd64
+- arm32
+
+image_pull_secrets:
+- PRIVATE_DOCKER_REGISTRY
+
+trigger:
+  event:
+  - push
+  - tag
+
+---
+kind: pipeline
+type: docker
+name: release
+steps:
+- name: release
+  image: registry.cuzo.dev/plugins/gitea-release
+  settings:
+    api_key:
+      from_secret: DRONE_API_KEY
+    base_url: https://git.cuzo.dev
+    title: 
+      from_secret: DRONE_SEMVER
+  when:
+    ref:
+    - refs/tags/*
+
+depends_on:
+- manifest
+
+image_pull_secrets:
+- PRIVATE_DOCKER_REGISTRY
+
+trigger:
+  event:
+  - tag
+---
+kind: pipeline
+type: docker
+name: Notify result
+
+steps:
+- name: send telegram notification
+  image: registry.cuzo.dev/appleboy/drone-telegram
+  when:
+      status: [success, failure]
+  settings:
+    to:
+      from_secret: TG_USER
+    token:
+      from_secret: TG_TOKEN
+
+depends_on:
+- manifest
+- release
+
+image_pull_secrets:
+- PRIVATE_DOCKER_REGISTRY
+
+trigger:
+  event:
+    - push
+    - tag
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f295d3d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,162 @@
+# ---> Python
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+.idea/
+
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..88ccfca
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,9 @@
+FROM python:3-alpine
+
+# Install dependencies:
+COPY requirements.txt .
+RUN pip install -r requirements.txt
+
+# Run the application:
+COPY main.py .
+CMD ["python", "main.py"]
diff --git a/README.md b/README.md
index cc83cdb..c7aee98 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,45 @@
 # crypto-reporter
+
+[![Build Status](https://drone.cuzo.dev/api/badges/Parra/crypto-reporter/status.svg)](https://drone.cuzo.dev/Parra/crypto-reporter)
+
+Obtiene y publica precios de criptomonedas.
+
+## Instalación y ejecución desde CLI
+
+Descargar el repositorio en una nueva carpeta:
+
+````shell
+git clone https://git.cuzo.dev/Parra/crypto-reporter.git
+````
+
+Copiar el fichero `env_file` a `.env` y abrirlo con un editor de textos y editarlo 
+con la información del servidor MQTT, así como editar los tópicos que se quieran usar 
+y el tiempo de refresco.
+
+Dar permisos de ejecución al fichero principal con `chmod +x main.py` y ejecutar con `./main.py`.
+
+## Instalación y ejecución desde Docker
+
+Crear una carpeta (por ejemplo `crypto-reporter`) y acceder a ella.
+
+Crear un fichero `.env` con el contenido del fichero `env_file` de este repositorio y 
+editarlo con la información del servidor MQTT.
+
+Crear un fichero `docker-compose.yml` como el siguiente:
+````yml
+version: '3'
+
+services:
+  crypto-reporter:
+    image: parrazam/crypto-reporter
+    container_name: crypto-reporter
+    restart: unless-stopped
+    volumes:
+      - ./.env:/.env:ro
+````
+
+Ejecutar con el comando `docker compose up -d`.
+
+## Menciones
+
+La API se extrae de Coingecko y se puede consultar aquí: https://www.coingecko.com/en/api/documentation
\ No newline at end of file
diff --git a/env_file b/env_file
new file mode 100644
index 0000000..78583ec
--- /dev/null
+++ b/env_file
@@ -0,0 +1,21 @@
+# Log configuration
+LOG_LEVEL=INFO
+
+# Crypto configuration
+CRYPTOS_TO_PUBLISH=bitcoin,ethereum
+CURRENCIES=eur,usd
+
+# Broker configuration
+MQTT_SERVER=
+MQTT_PORT=
+MQTT_USER=
+MQTT_PASSWORD=
+MQTT_CLIENT_ID=
+
+# Topic configuration
+MQTT_TOPIC_PREFIX=
+
+MQTT_TOPIC_STATE=${MQTT_TOPIC_PREFIX}/state
+MQTT_TOPIC_DATA=${MQTT_TOPIC_PREFIX}/data
+
+MQTT_PUBLISH_DELAY=60
\ No newline at end of file
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..d3a5c5e
--- /dev/null
+++ b/main.py
@@ -0,0 +1,89 @@
+# !/usr/bin/env python3
+
+"""Crypto reporter"""
+
+import json
+import logging
+import os
+import requests
+import time
+
+from dotenv import load_dotenv
+import paho.mqtt.client as mqtt
+
+
+load_dotenv()  # Cargamos las variables de entorno necesarias
+
+LOG_LEVEL = os.getenv('LOG_LEVEL', logging.INFO)
+
+logging.basicConfig(level=LOG_LEVEL, format='[%(levelname)s] %(asctime)s - %(message)s')
+
+BASE_API = 'https://api.coingecko.com/api/v3'
+
+MQTT_TOPIC_DATA = os.getenv('MQTT_TOPIC_DATA', 'crypto-reporter/data')
+MQTT_TOPIC_STATE = os.getenv('MQTT_TOPIC_STATE', 'crypto-reporter/state')
+
+MQTT_PUBLISH_DELAY = int(os.getenv('MQTT_PUBLISH_DELAY', 60))
+MQTT_CLIENT_ID = os.getenv('MQTT_CLIENT_ID', 'crypto-reporter')
+
+MQTT_SERVER = os.getenv('MQTT_SERVER', 'localhost')
+MQTT_PORT = int(os.getenv('MQTT_PORT', '1883'))
+MQTT_USER = os.getenv('MQTT_USER', '')
+MQTT_PASSWORD = os.getenv('MQTT_PASSWORD', '')
+
+CRYPTOS_TO_PUBLISH = os.getenv('CRYPTOS_TO_PUBLISH', 'bitcoin')
+CURRENCIES = os.getenv('CURRENCIES', 'eur')
+
+
+def on_connect(client, userdata, flags, rc):
+    logging.info("Connected to MQTT server.")
+    client.publish(MQTT_TOPIC_STATE, 'connected', 1, True)
+
+
+def main():
+    logging.info(f'Connecting to MQTT host {MQTT_SERVER}:{MQTT_PORT}...')
+    mqttc = mqtt.Client(MQTT_CLIENT_ID)
+    mqttc.username_pw_set(MQTT_USER, MQTT_PASSWORD)
+    mqttc.will_set(MQTT_TOPIC_STATE, 'disconnected', 1, True)
+    mqttc.on_connect = on_connect
+
+    mqttc.connect(MQTT_SERVER, MQTT_PORT, 60)
+    mqttc.loop_start()
+    last_msg_time = time.time()
+
+    while True:
+        try:
+            x = requests.get(BASE_API + '/simple/price',
+                             params={'ids': CRYPTOS_TO_PUBLISH,
+                                     'vs_currencies': CURRENCIES})
+            logging.debug(f'HTTP response: {x.status_code}')
+            publish_data(mqttc, x.text)
+
+            delay_gap = time.time() - last_msg_time
+            if delay_gap < MQTT_PUBLISH_DELAY:
+                time.sleep(MQTT_PUBLISH_DELAY - delay_gap)
+            last_msg_time = time.time()
+
+        except KeyboardInterrupt:
+            logging.info("exiting...")
+            exit(0)
+        except Exception:
+            logging.exception("something went wrong.")
+            exit(1)
+
+
+def publish_data(mqttc, raw):
+    try:
+        logging.debug(f'RAW message to publish: {raw}')
+        data = json.loads(raw)
+        for crypto in data:
+            currencies = data[crypto]
+            for currency in currencies:
+                mqttc.publish(MQTT_TOPIC_DATA + f'/{crypto}/{currency}', data[crypto][currency], 1, True)
+    except AttributeError:
+        logging.exception("Error decoding JSON")
+
+
+if __name__ == '__main__':
+    logging.info('Starting crypto broker')
+    main()
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..6ba395e
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,3 @@
+paho-mqtt==1.6.1
+python-dotenv==0.21.0
+requests==2.28.1
\ No newline at end of file