diff --git a/.env.prod.example b/.env.prod.example index 6901cb63d7f1011463b08a393889079d1c4d41c8..0d64db4a07f44a409ac65d8f0c4b18d9f00623bd 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -10,6 +10,7 @@ HASURA_LISTEN_PORT=8888 HASURA_GRAPHQL_ADMIN_SECRET=hasura_admin_secret # kubo configuration +KUBO_PORT=4001 # should be open to incoming connections KUBO_DOMAIN=datapod.coinduf.eu # domain (used in p2p peering) KUBO_GATEWAY_PORT=8080 # listen port of ipfs http gateway KUBO_GATEWAY_DOMAIN=gateway.datapod.coinduf.eu # domain for kubo reverse proxy ipfs http gateway reverse proxy diff --git a/Dockerfile.Kubo b/Dockerfile.Kubo deleted file mode 100644 index dab30d6e5a088e11f686cb77559c546246d91928..0000000000000000000000000000000000000000 --- a/Dockerfile.Kubo +++ /dev/null @@ -1,5 +0,0 @@ -FROM ipfs/kubo:v0.30.0 -COPY ./scripts/configure.sh /container-init.d/001-configure.sh -CMD ["daemon", "--enable-pubsub-experiment"] -# docker buildx build -f Dockerfile.Kubo . -t h30x/datapod-kubo -# docker image push h30x/datapod-kubo \ No newline at end of file diff --git a/README.md b/README.md index 913a2b44d86cd394ca7ff7b698b5efc986e67aea..8142d3c657c9bd8d1638161e745a2e41e0e7e015 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Duniter Datapod is designed for offchain storage of Ğ1 data but does not depend ## Use -To start a full indexer in production mode with docker, use the [`docker-compose.prod.yml`](./docker-compose.prod.yml) and [`.env.prod.example`](./.env.prod.example) files: +To start a full indexer in production mode with docker, use the [`docker-compose.prod.yml`](./docker/docker-compose.prod.yml) and [`.env.prod.example`](./.env.prod.example) files: ```sh # edit env file @@ -43,9 +43,9 @@ pnpm install Start a kubo node with pubsub and postgres/hasura ```sh -# start kubo node TODO put this in the docker +# start kubo node (easier to have it on system instead of docker) ipfs daemon --enable-pubsub-experiment -# start postgres / hasura +# start postgres / hasura from dev docker compose file docker compose up -d ``` diff --git a/doc/nginx/ipfs-rpc.nginx.conf b/doc/nginx/ipfs-rpc.nginx.conf index 88b93a5ee93205b476d5b4199342cf3a6d0abc2f..1b01d00ec763d94e98b53c528e9bc59ee6785bf5 100644 --- a/doc/nginx/ipfs-rpc.nginx.conf +++ b/doc/nginx/ipfs-rpc.nginx.conf @@ -1,6 +1,6 @@ # replace the following: # RPC_KUBO_DOMAIN = the name under which expose your RPC API -# RPC_KUBO_PORT = the rpc api port (ususally 5001) +# RPC_KUBO_PORT = the rpc api port (ususally 5001 or 6001) server { listen 80 ; @@ -26,6 +26,10 @@ server { location / { return 400; } + location /api/v0/file/ { + proxy_pass http://localhost:RPC_KUBO_PORT; + proxy_set_header Host $host; + } location /api/v0/dag/ { proxy_pass http://localhost:RPC_KUBO_PORT; proxy_set_header Host $host; diff --git a/Dockerfile b/docker/Dockerfile similarity index 100% rename from Dockerfile rename to docker/Dockerfile diff --git a/Dockerfile.Hasura b/docker/Dockerfile.Hasura similarity index 100% rename from Dockerfile.Hasura rename to docker/Dockerfile.Hasura diff --git a/docker/Dockerfile.Kubo b/docker/Dockerfile.Kubo new file mode 100644 index 0000000000000000000000000000000000000000..a7efab50e4a4d931a995616fa6cea5723f070485 --- /dev/null +++ b/docker/Dockerfile.Kubo @@ -0,0 +1,11 @@ +# kubo config suited for datapod use +# TODO split gateway in another instance for performance and safeness and separation of concerns +FROM ipfs/kubo:v0.30.0 +COPY ./scripts/configure-keys.sh /container-init.d/001-configure.sh +COPY ./scripts/configure-addresses.sh /container-init.d/002-configure.sh +COPY ./scripts/configure-bootstrap.sh /container-init.d/003-configure.sh +COPY ./scripts/configure-peering.sh /container-init.d/004-configure.sh +COPY ./scripts/configure-rpc.sh /container-init.d/005-configure.sh +COPY ./scripts/configure-gateway.sh /container-init.d/006-configure.sh +COPY ./scripts/configure-extra.sh /container-init.d/007-configure.sh +CMD ["daemon", "--enable-pubsub-experiment"] \ No newline at end of file diff --git a/docker/Dockerfile.KuboRpc b/docker/Dockerfile.KuboRpc new file mode 100644 index 0000000000000000000000000000000000000000..c68cf95307d34a0f5f8ba3a7c6613c3927f8ee5c --- /dev/null +++ b/docker/Dockerfile.KuboRpc @@ -0,0 +1,7 @@ +# kubo config suited for unsafe remote RPC instance +FROM ipfs/kubo:v0.30.0 +COPY ./scripts/configure-addresses.sh /container-init.d/001-configure.sh +COPY ./scripts/configure-bootstrap.sh /container-init.d/002-configure.sh +COPY ./scripts/configure-peering.sh /container-init.d/003-configure.sh +COPY ./scripts/configure-rpc-public.sh /container-init.d/004-configure.sh +CMD ["daemon"] \ No newline at end of file diff --git a/docker/docker-build.sh b/docker/docker-build.sh new file mode 100755 index 0000000000000000000000000000000000000000..a072e5089300397166fcd678e68fb0e8bf0e7db8 --- /dev/null +++ b/docker/docker-build.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -e + +# Get the version number from package.json +version_tag=$(grep -oP '"version": "\K[^"]+' ./package.json) + +# # --- datapod +# docker buildx build -f ./docker/Dockerfile -t duniter-datapod . + +# # Tag with version and 'latest' +# docker image tag duniter-datapod h30x/duniter-datapod:$version_tag +# docker image tag duniter-datapod h30x/duniter-datapod:latest + +# # Push both +# docker image push h30x/duniter-datapod:$version_tag +# docker image push h30x/duniter-datapod:latest + +# # --- kubo +# docker buildx build -f ./docker/Dockerfile.Kubo -t datapod-kubo . + +# # Tag with version and 'latest' +# docker image tag datapod-kubo h30x/datapod-kubo:$version_tag +# docker image tag datapod-kubo h30x/datapod-kubo:latest + +# # Push both +# docker image push h30x/datapod-kubo:$version_tag +# docker image push h30x/datapod-kubo:latest + +# --- kubo-rpc +docker buildx build -f ./docker/Dockerfile.KuboRpc -t datapod-kubo-rpc . + +# Tag with version and 'latest' +docker image tag datapod-kubo-rpc h30x/datapod-kubo-rpc:$version_tag +docker image tag datapod-kubo-rpc h30x/datapod-kubo-rpc:latest + +# Push both +docker image push h30x/datapod-kubo-rpc:$version_tag +docker image push h30x/datapod-kubo-rpc:latest + +# # --- hasura +# docker buildx build -f ./docker/Dockerfile.Hasura -t datapod-hasura . + +# # Tag with version and 'latest' +# docker image tag datapod-hasura h30x/datapod-hasura:$version_tag +# docker image tag datapod-hasura h30x/datapod-hasura:latest + +# # Push both +# docker image push h30x/datapod-hasura:$version_tag +# docker image push h30x/datapod-hasura:latest \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker/docker-compose.prod.yml similarity index 83% rename from docker-compose.prod.yml rename to docker/docker-compose.prod.yml index 4adf11484c40883e6fa30818bb66967d488e45d3..6a37a5aa1ae4badcd013857c8d0db935abcbc209 100644 --- a/docker-compose.prod.yml +++ b/docker/docker-compose.prod.yml @@ -37,8 +37,8 @@ services: image: h30x/datapod-kubo ports: # p2p port public (tcp, udp, webtransport, webrtc) - - 4001:4001/tcp - - 4001:4001/udp + - ${KUBO_PORT}:4001/tcp + - ${KUBO_PORT}:4001/udp # public gateway - 127.0.0.1:${KUBO_GATEWAY_PORT}:8080 - '[::1]:${KUBO_GATEWAY_PORT}:8080' @@ -50,10 +50,27 @@ services: # - kubo_init:/container-init.d environment: KUBO_DOMAIN: ${KUBO_DOMAIN} + KUBO_PORT: ${KUBO_PORT} KUBO_GATEWAY_DOMAIN: ${KUBO_GATEWAY_DOMAIN} KUBO_GATEWAY_SUBDOMAIN: ${KUBO_GATEWAY_SUBDOMAIN} restart: always + # ------ + kubo-rpc: + image: h30x/datapod-kubo-rpc + ports: + # p2p port public (tcp, udp, webtransport, webrtc) + - 4002:4001/tcp + - 4002:4001/udp + # expose RPC to partial reverse proxy + - 127.0.0.1:6001:5001 + volumes: + - kubo-rpc_data:/data/ipfs + environment: + KUBO_DOMAIN: ${KUBO_DOMAIN} + KUBO_PORT: 4002 + restart: always + # ------ # optional kubo pubsub to see what the node receives on pubsub pubsub: @@ -86,4 +103,5 @@ services: volumes: db_data: kubo_data: + kubo-rpc_data: kubo_init: diff --git a/note.txt b/note.txt deleted file mode 100644 index 0b9521d539dd7372d1b4bcd00751aac4fa37aea0..0000000000000000000000000000000000000000 --- a/note.txt +++ /dev/null @@ -1,10 +0,0 @@ -J'arrive plus à réflechir alors j'écris : - -- c'est facile pour un noeud ipfs de récupérer la liste des ses clés (paires nom/clé) -- quand on bootstrap un datapod, il doit récupérer plusieurs objets -- quand on synchronise un datapod, il doit pouvoir récupérer plusieurs objets manquants -- on aimerait avoir à transmettre le minimum d'info pour la configuration du noeud -- avoir un seul lien à ajouter dans l'interface d'admin en plus des hardcodés serait l'idéal -- on dispose déjà d'une liste hardcodée qu'est la liste de pair -- dedans il y a les clés publiques des pairs (12D3KooWF44SaSomGuUSNycgpkRwQcxcsMYeNbtn6XCHPR2ojodv par ex) -- ces clés peuvent être résolues par IPNS \ No newline at end of file diff --git a/scripts/configure-addresses.sh b/scripts/configure-addresses.sh new file mode 100644 index 0000000000000000000000000000000000000000..2475e46e8a37ff08691b04e9c7fec1a031758797 --- /dev/null +++ b/scripts/configure-addresses.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -ex + +# --- addresses --- +# enable p2p, quic, webtransport, webrtc +# ipfs config Swarm.Transports.Network.Websocket --json true +# internal port is always 4001 +ipfs config Addresses.Swarm --json '[ + "/ip4/0.0.0.0/tcp/4001", + "/ip6/::/tcp/4001", + "/ip4/0.0.0.0/udp/4001/quic-v1", + "/ip6/::/udp/4001/quic-v1", + "/ip4/0.0.0.0/udp/4001/quic-v1/webtransport", + "/ip6/::/udp/4001/quic-v1/webtransport", + "/ip4/0.0.0.0/udp/4001/webrtc-direct", + "/ip6/::/udp/4001/webrtc-direct" +]' +# configure the addresses to announce +# KUBO_PORT is external port mapped in docker compose to 4001 +ipfs config Addresses.Announce --json "[ + \"/dns/$KUBO_DOMAIN/tcp/$KUBO_PORT\", + \"/dns/$KUBO_DOMAIN/udp/$KUBO_PORT/quic-v1\", + \"/dns/$KUBO_DOMAIN/udp/$KUBO_PORT/quic-v1/webtransport\", + \"/dns/$KUBO_DOMAIN/udp/$KUBO_PORT/webrtc-direct\" +]" diff --git a/scripts/configure-bootstrap.sh b/scripts/configure-bootstrap.sh new file mode 100644 index 0000000000000000000000000000000000000000..f0960244622e9ac92e3b7708eacf7d6d50082aee --- /dev/null +++ b/scripts/configure-bootstrap.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -ex + +# --- bootstrap --- +# remove default bootstrap nodes +ipfs bootstrap rm all +# add custom bootstrap (hugo, poka, aya) +ipfs config Bootstrap --json '[ + "/dns/datapod.coinduf.eu/tcp/4001/p2p/12D3KooWFp4JsoDo5FX8CFLtyJjaWWRZ8q3gr8uT2s9To2GYzRNA", + "/dns/gateway.datapod.ipfs.p2p.legal/tcp/4001/p2p/12D3KooWEaBZ3JfeXJayneVdpc71iUYWzeykGxzEq4BFWpPTv5wn", + "/dns/ipfs.asycn.io/tcp/4001/p2p/12D3KooWJnzYzJBtruXZwUQJriF1ePtDQCUQp4aNBV5FjpYVdfhc", + "/dns/datapod.gyroi.de/tcp/4001/p2p/12D3KooWAHf2cyDysXXP1xaAt75dNviRhF2T9QfnQGGZ6kSXvMwK" +]' \ No newline at end of file diff --git a/scripts/configure-extra.sh b/scripts/configure-extra.sh new file mode 100644 index 0000000000000000000000000000000000000000..a4fd453c6b4041a7336cdf17e5cf90b0d88c94b8 --- /dev/null +++ b/scripts/configure-extra.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -ex + +# --- IPNS --- +# use pubsub for IPNS records +# ipfs config --json Ipns.UsePubsub true +# republish records frequently +ipfs config --json Ipns.RepublishPeriod '"5m"' \ No newline at end of file diff --git a/scripts/configure-gateway.sh b/scripts/configure-gateway.sh new file mode 100644 index 0000000000000000000000000000000000000000..a45648eefa98617c667c8690744d58cd532ce13e --- /dev/null +++ b/scripts/configure-gateway.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -ex + +# --- gateway --- +# prevent gateway from fetching foreign data +# ipfs config Gateway.NoFetch --json true +# ipfs config Gateway.NoFetch --json false +# public gateway without subdomain (no wildcard) +# enables /ipfs and /routing (delegated routing) +# public gateway with subdomain (needs wildcard) +ipfs config Gateway.PublicGateways --json "{ + \"$KUBO_GATEWAY_DOMAIN\": { \"UseSubdomains\": false, \"Paths\": [\"/ipfs\", \"/routing\"] }, + \"$KUBO_GATEWAY_SUBDOMAIN\": { \"UseSubdomains\": true, \"Paths\": [\"/ipfs\", \"/ipns\"] } +}" +ipfs config Gateway.ExposeRoutingAPI --json true + +# only reprovide pinned data +# ipfs config Reprovider.Strategy "pinned" +# ipfs config Reprovider.Strategy --json null diff --git a/scripts/configure-keys.sh b/scripts/configure-keys.sh new file mode 100644 index 0000000000000000000000000000000000000000..224cc936139eff3acf993c6da3a3a82d022e6ede --- /dev/null +++ b/scripts/configure-keys.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -ex + +# --- keys --- +# generate key for index history if not defined +ipfs key gen dd_root || true +ipfs key gen dd_tamt || true +ipfs key gen dd_tamt_hist || true +ipfs key gen dd_profiles || true diff --git a/scripts/configure-peering.sh b/scripts/configure-peering.sh new file mode 100644 index 0000000000000000000000000000000000000000..8bb5b7bde928a03e818c21baa161f467be3eb70d --- /dev/null +++ b/scripts/configure-peering.sh @@ -0,0 +1,26 @@ +#!/bin/sh +set -ex + +# --- peering --- +# add known peers (poka, hugo, aya) +ipfs config Peering.Peers --json '[ + { + "ID": "12D3KooWEaBZ3JfeXJayneVdpc71iUYWzeykGxzEq4BFWpPTv5wn", + "Addrs": ["/dns/gateway.datapod.ipfs.p2p.legal/tcp/4001"] + }, + { + "ID": "12D3KooWFp4JsoDo5FX8CFLtyJjaWWRZ8q3gr8uT2s9To2GYzRNA", + "Addrs": ["/dns/datapod.coinduf.eu/tcp/4001"] + }, + { + "ID": "12D3KooWJnzYzJBtruXZwUQJriF1ePtDQCUQp4aNBV5FjpYVdfhc", + "Addrs": ["/dns/ipfs.asycn.io/tcp/4001"] + }, + { + "ID": "12D3KooWAHf2cyDysXXP1xaAt75dNviRhF2T9QfnQGGZ6kSXvMwK", + "Addrs": ["/dns/datapod.gyroi.de/tcp/4001"] + } +] +' +# configure as a dht to avoid unnecessary http routing +ipfs config Routing.Type dht diff --git a/scripts/configure-rpc-public.sh b/scripts/configure-rpc-public.sh new file mode 100644 index 0000000000000000000000000000000000000000..1b06c5e59f1d85e3278c9f94b0710fe055f00190 --- /dev/null +++ b/scripts/configure-rpc-public.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -ex + +# --- rpc --- +ipfs config API.HTTPHeaders.Access-Control-Allow-Origin --json '["http://127.0.0.1:5001","http://127.0.0.1:6001","http://127.0.0.1:6002"]' +ipfs config API.HTTPHeaders.Access-Control-Allow-Methods --json '["PUT", "POST"]' diff --git a/scripts/configure-rpc.sh b/scripts/configure-rpc.sh new file mode 100644 index 0000000000000000000000000000000000000000..48798f75a38cb6bce0d3cb1ce5a17792d859277e --- /dev/null +++ b/scripts/configure-rpc.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -ex + +# --- rpc --- +# allow easy access through ssh tunnel on port 500x +# ssh -NL 5002:localhost:500x datapod +# ipfs --api=/ip4/127.0.0.1/tcp/500x +ipfs config API.HTTPHeaders.Access-Control-Allow-Origin --json '["http://127.0.0.1:5001","http://127.0.0.1:5002","http://127.0.0.1:5003","http://127.0.0.1:5004","http://127.0.0.1:5005"]' +ipfs config API.HTTPHeaders.Access-Control-Allow-Methods --json '["PUT", "POST"]' diff --git a/scripts/configure.sh b/scripts/configure.sh deleted file mode 100644 index a6a9f4ada513d3528a621b80f0c3bb16defa9521..0000000000000000000000000000000000000000 --- a/scripts/configure.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/sh -set -ex - -# --- keys --- -# generate key for index history if not defined -ipfs key gen dd_root || true -ipfs key gen dd_tamt || true -ipfs key gen dd_tamt_hist || true -ipfs key gen dd_profiles || true - -# --- addresses --- -# enable p2p, quic, webtransport, webrtc -# ipfs config Swarm.Transports.Network.Websocket --json true -ipfs config Addresses.Swarm --json '[ - "/ip4/0.0.0.0/tcp/4001", - "/ip6/::/tcp/4001", - "/ip4/0.0.0.0/udp/4001/quic-v1", - "/ip6/::/udp/4001/quic-v1", - "/ip4/0.0.0.0/udp/4001/quic-v1/webtransport", - "/ip6/::/udp/4001/quic-v1/webtransport", - "/ip4/0.0.0.0/udp/4001/webrtc-direct", - "/ip6/::/udp/4001/webrtc-direct" -]' -# configure the addresses to announce # TODO announce IPv6 -ipfs config Addresses.Announce --json "[ - \"/dns/$KUBO_DOMAIN/tcp/4001\", - \"/dns/$KUBO_DOMAIN/udp/4001/quic-v1\", - \"/dns/$KUBO_DOMAIN/udp/4001/quic-v1/webtransport\", - \"/dns/$KUBO_DOMAIN/udp/4001/webrtc-direct\" -]" - -# --- peering --- -# remove default bootstrap nodes -ipfs bootstrap rm all -# add custom bootstrap (hugo, poka, aya) -ipfs config Bootstrap --json '[ - "/dns/datapod.coinduf.eu/tcp/4001/p2p/12D3KooWFp4JsoDo5FX8CFLtyJjaWWRZ8q3gr8uT2s9To2GYzRNA", - "/dns/gateway.datapod.ipfs.p2p.legal/tcp/4001/p2p/12D3KooWEaBZ3JfeXJayneVdpc71iUYWzeykGxzEq4BFWpPTv5wn", - "/dns/ipfs.asycn.io/tcp/4001/p2p/12D3KooWJnzYzJBtruXZwUQJriF1ePtDQCUQp4aNBV5FjpYVdfhc", - "/dns/datapod.gyroi.de/tcp/4001/p2p/12D3KooWAHf2cyDysXXP1xaAt75dNviRhF2T9QfnQGGZ6kSXvMwK" -]' -# add known peers (poka, hugo, aya) -ipfs config Peering.Peers --json '[ - { - "ID": "12D3KooWEaBZ3JfeXJayneVdpc71iUYWzeykGxzEq4BFWpPTv5wn", - "Addrs": ["/dns/gateway.datapod.ipfs.p2p.legal/tcp/4001"] - }, - { - "ID": "12D3KooWFp4JsoDo5FX8CFLtyJjaWWRZ8q3gr8uT2s9To2GYzRNA", - "Addrs": ["/dns/datapod.coinduf.eu/tcp/4001"] - }, - { - "ID": "12D3KooWJnzYzJBtruXZwUQJriF1ePtDQCUQp4aNBV5FjpYVdfhc", - "Addrs": ["/dns/ipfs.asycn.io/tcp/4001"] - }, - { - "ID": "12D3KooWAHf2cyDysXXP1xaAt75dNviRhF2T9QfnQGGZ6kSXvMwK", - "Addrs": ["/dns/datapod.gyroi.de/tcp/4001"] - } -] -' -# configure as a dht to avoid unnecessary http routing -ipfs config Routing.Type dht - -# --- rpc --- -# allow easy access through ssh tunnel on port 500x -# ssh -NL 5002:localhost:500x datapod -# ipfs --api=/ip4/127.0.0.1/tcp/500x -ipfs config API.HTTPHeaders.Access-Control-Allow-Origin --json '["http://127.0.0.1:5001","http://127.0.0.1:5002","http://127.0.0.1:5003","http://127.0.0.1:5004","http://127.0.0.1:5005"]' -ipfs config API.HTTPHeaders.Access-Control-Allow-Methods --json '["PUT", "POST"]' - -# --- gateway --- -# prevent gateway from fetching foreign data -# ipfs config Gateway.NoFetch --json true -# ipfs config Gateway.NoFetch --json false -# public gateway without subdomain (no wildcard) -# enables /ipfs and /routing (delegated routing) -# public gateway with subdomain (needs wildcard) -ipfs config Gateway.PublicGateways --json "{ - \"$KUBO_GATEWAY_DOMAIN\": { \"UseSubdomains\": false, \"Paths\": [\"/ipfs\", \"/routing\"] }, - \"$KUBO_GATEWAY_SUBDOMAIN\": { \"UseSubdomains\": true, \"Paths\": [\"/ipfs\", \"/ipns\"] } -}" -ipfs config Gateway.ExposeRoutingAPI --json true - -# only reprovide pinned data -# ipfs config Reprovider.Strategy "pinned" -# ipfs config Reprovider.Strategy --json null - -# --- IPNS --- -# use pubsub for IPNS records -# ipfs config --json Ipns.UsePubsub true -# republish records frequently -ipfs config --json Ipns.RepublishPeriod '"5m"' \ No newline at end of file diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh deleted file mode 100755 index 997eb8c185f10714cdbac170f86dc9a7e90985f8..0000000000000000000000000000000000000000 --- a/scripts/docker-build.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -set -e - -# Get the version number from package.json -version_tag=$(grep -oP '"version": "\K[^"]+' package.json) - -# # --- datapod -# docker buildx build -f Dockerfile -t duniter-datapod . - -# # Tag with version and 'latest' -# docker image tag duniter-datapod h30x/duniter-datapod:$version_tag -# docker image tag duniter-datapod h30x/duniter-datapod:latest - -# # Push both -# docker image push h30x/duniter-datapod:$version_tag -# docker image push h30x/duniter-datapod:latest - -# --- kubo -docker buildx build -f Dockerfile.Kubo -t datapod-kubo . - -# Tag with version and 'latest' -docker image tag datapod-kubo h30x/datapod-kubo:$version_tag -docker image tag datapod-kubo h30x/datapod-kubo:latest - -# Push both -docker image push h30x/datapod-kubo:$version_tag -docker image push h30x/datapod-kubo:latest - -# # --- hasura -# docker buildx build -f Dockerfile.Hasura -t datapod-hasura . - -# # Tag with version and 'latest' -# docker image tag datapod-hasura h30x/datapod-hasura:$version_tag -# docker image tag datapod-hasura h30x/datapod-hasura:latest - -# # Push both -# docker image push h30x/datapod-hasura:$version_tag -# docker image push h30x/datapod-hasura:latest \ No newline at end of file