Add script and instructions for deployment #11

Merged
nabarun merged 8 commits from pm-deploy-script into main 2025-02-06 12:24:58 +00:00
6 changed files with 315 additions and 1 deletions

View File

@ -17,16 +17,19 @@ This project is a Solana-based meme generator that allows users to connect their
## Setup
- Install dependencies:
```sh
npm install
```
- Copy the `.env.example` file to `.env.local` and add your API keys:
```sh
cp .env.example .env.local
```
- Add your FAL AI key to the `.env.local` file:
```env
# Get key from https://fal.ai/
FAL_AI_KEY=your_fal_ai_key
@ -34,7 +37,7 @@ This project is a Solana-based meme generator that allows users to connect their
- Setup a project on <https://app.pinata.cloud>
- Visit https://app.pinata.cloud/developers/api-keys and click the `New Key` button to create a new key
- Visit <https://app.pinata.cloud/developers/api-keys> and click the `New Key` button to create a new key
- Choose the `Admin` scope and create the API key
@ -53,6 +56,7 @@ This project is a Solana-based meme generator that allows users to connect their
```
- Run the development server:
```sh
npm run dev
```
@ -64,3 +68,7 @@ This project is a Solana-based meme generator that allows users to connect their
- Connect your Solflare or Phantom wallet using the "Connect Wallet" button.
- Select an AI model and enter a prompt to generate a meme.
- Pay the required MTM tokens and wait for the meme to be generated.
## Deploy
Follow [instructions](./deploy/README.md) for deploying `sol-mem-gen` and `sol-token-locker`

View File

@ -0,0 +1,10 @@
# ENV for registry operations
# Bond to use
REGISTRY_BOND_ID=
# Target deployer LRN
DEPLOYER_LRN=
# Authority to deploy the app under
AUTHORITY=

40
deploy/Dockerfile Normal file
View File

@ -0,0 +1,40 @@
ARG VARIANT=20-bullseye
FROM node:${VARIANT}
ARG USERNAME=node
ARG NPM_GLOBAL=/usr/local/share/npm-global
# Add NPM global to PATH.
ENV PATH=${NPM_GLOBAL}/bin:${PATH}
RUN \
# Configure global npm install location, use group to adapt to UID/GID changes
if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
&& usermod -a -G npm ${USERNAME} \
&& umask 0002 \
&& mkdir -p ${NPM_GLOBAL} \
&& touch /usr/local/etc/npmrc \
&& chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \
&& chmod g+s ${NPM_GLOBAL} \
&& npm config -g set prefix ${NPM_GLOBAL} \
&& su ${USERNAME} -c "npm config -g set prefix ${NPM_GLOBAL}" \
# Install eslint
&& su ${USERNAME} -c "umask 0002 && npm install -g eslint" \
&& npm cache clean --force > /dev/null 2>&1
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends jq bash
# laconic-so
RUN curl -LO https://git.vdb.to/cerc-io/stack-orchestrator/releases/download/latest/laconic-so && \
chmod +x ./laconic-so && \
mv ./laconic-so /usr/bin/laconic-so
# Configure the npm registry
RUN npm config set @cerc-io:registry https://git.vdb.to/api/packages/cerc-io/npm/
# DEBUG, remove
RUN yarn info @cerc-io/laconic-registry-cli
# Globally install the cli package
RUN yarn global add @cerc-io/laconic-registry-cli

120
deploy/README.md Normal file
View File

@ -0,0 +1,120 @@
# Deploy
## Setup
### sol-mem-gen
* Clone the repo:
```bash
git clone git@git.vdb.to:deep-stack/sol-mem-gen.git
cd sol-mem-gen/deploy
```
* Build registry CLI image:
```bash
docker build -t cerc/laconic-registry-cli .
# Builds image cerc/laconic-registry-cli:latest
```
* Configure `userKey` and `bondId` in the registry CLI config:
```bash
nano config.yml
```
* Add configuration for registry operations:
```bash
cp .registry.env.example .registry.env
# Fill in the required values
nano .registry.env
```
* Add configuration for the app:
```bash
curl -s https://git.vdb.to/deep-stack/sol-mem-gen/raw/branch/main/.env.example -o .app.env
# Fill in the required values
nano .app.env
```
### sol-token-locker
* Create a dir for `sol-token-locker` deployment:
```bash
# In deployments dir
mkdir sol-token-locker
cd sol-token-locker
```
* Follow [instructions](https://git.vdb.to/deep-stack/sol-token-locker/src/branch/main/stack-orchestrator/stacks/sol-token-locker/README.md) to setup the `sol-token-locker` stack in `sol-token-locker` directory
## Run
### sol-mem-gen
* Update configuration for the app as required:
```bash
# In sol-mem-gen/deploy dir
nano sol-mem-gen/.app.env
```
* Deploy `sol-mem-gen` App:
```bash
docker run -it \
-v ./:/app/deploy -w /app/deploy \
-e DEPLOYMENT_DNS=memes.markto.market \
cerc/laconic-registry-cli:latest \
./deploy.sh
```
* Check deployment logs on deployer UI: <https://webapp-deployer-ui.apps.vaasl.io/>
* Visit deployed app: <https://memes.markto.market>
* To redeploy the app (using <https://git.vdb.to/deep-stack/sol-mem-gen> `main` branch), repeat the previous steps
### sol-token-locker
* Update configuration for token locker as required:
```bash
# In deployments dir
cd sol-token-locker
nano sol-token-locker-deployment/config.env
```
* [Config reference](https://git.vdb.to/deep-stack/sol-token-locker/src/branch/main/stack-orchestrator/stacks/sol-token-locker/README.md#configuration)
* Start the deployment:
```bash
laconic-so deployment --dir sol-token-locker-deployment start
```
* Follow logs:
```bash
laconic-so deployment --dir sol-token-locker-deployment logs sol-token-locker -f
```
* For updating the deployment:
```bash
# Stop the deployment
laconic-so deployment --dir sol-token-locker-deployment stop
# Update the config as required
nano sol-token-locker-deployment/config.env
# Re-start deployment
laconic-so deployment --dir sol-token-locker-deployment start
```

10
deploy/config.yml Normal file
View File

@ -0,0 +1,10 @@
# Registry CLI config
services:
registry:
rpcEndpoint: 'https://laconicd-sapo.laconic.com'
gqlEndpoint: 'https://laconicd-sapo.laconic.com/api'
userKey:
bondId:
chainId: laconic-testnet-2
fees: 2.5
gasPrice: 0.01alnt

126
deploy/deploy.sh Executable file
View File

@ -0,0 +1,126 @@
#!/bin/bash
# Fail on error
set -e
source .registry.env
echo "Using REGISTRY_BOND_ID: $REGISTRY_BOND_ID"
echo "Using DEPLOYER_LRN: $DEPLOYER_LRN"
echo "Using AUTHORITY: $AUTHORITY"
# Repository URL
REPO_URL="https://git.vdb.to/deep-stack/sol-mem-gen"
# Get the latest commit hash from the repository
LATEST_HASH=$(git ls-remote $REPO_URL HEAD | awk '{print $1}')
PACKAGE_VERSION=$(curl -s $REPO_URL/raw/branch/main/package.json | jq -r .version)
APP_NAME=sol-mem-gen
echo "Repo: ${REPO_URL}"
echo "Latest hash: ${LATEST_HASH}"
echo "App version: ${PACKAGE_VERSION}"
echo "Deployment DNS: ${DEPLOYMENT_DNS}"
# Current date and time for note
CURRENT_DATE_TIME=$(date -u)
CONFIG_FILE=config.yml
# Reference: https://git.vdb.to/cerc-io/test-progressive-web-app/src/branch/main/scripts
# Get latest version from registry and increment application-record version
NEW_APPLICATION_VERSION=$(laconic -c $CONFIG_FILE registry record list --type ApplicationRecord --all --name "$APP_NAME" 2>/dev/null | jq -r -s ".[] | sort_by(.createTime) | reverse | [ .[] | select(.bondId == \"$REGISTRY_BOND_ID\") ] | .[0].attributes.version" | awk -F. -v OFS=. '{$NF += 1 ; print}')
if [ -z "$NEW_APPLICATION_VERSION" ] || [ "1" == "$NEW_APPLICATION_VERSION" ]; then
# Set application-record version if no previous records were found
NEW_APPLICATION_VERSION=0.0.1
fi
# Generate application-record.yml with incremented version
mkdir records
RECORD_FILE=./records/application-record.yml
cat >$RECORD_FILE <<EOF
record:
type: ApplicationRecord
version: $NEW_APPLICATION_VERSION
repository_ref: $LATEST_HASH
repository: ["$REPO_URL"]
app_type: webapp
name: $APP_NAME
app_version: $PACKAGE_VERSION
EOF
echo "Application record generated successfully: $RECORD_FILE"
# Publish ApplicationRecord
publish_response=$(laconic -c $CONFIG_FILE registry record publish --filename $RECORD_FILE)
rc=$?
if [ $rc -ne 0 ]; then
echo "FATAL: Failed to publish record"
exit $rc
fi
RECORD_ID=$(echo $publish_response | jq -r '.id')
echo "ApplicationRecord published, setting names next"
echo $RECORD_ID
# Set name to record
REGISTRY_APP_LRN="lrn://$AUTHORITY/applications/$APP_NAME"
name1="$REGISTRY_APP_LRN@${PACKAGE_VERSION}"
sleep 2
laconic -c $CONFIG_FILE registry name set "$name1" "$RECORD_ID"
rc=$?
if [ $rc -ne 0 ]; then
echo "FATAL: Failed to set name: $REGISTRY_APP_LRN@${PACKAGE_VERSION}"
exit $rc
fi
echo "$name1 set for ApplicationRecord"
name2="$REGISTRY_APP_LRN@${LATEST_HASH}"
sleep 2
laconic -c $CONFIG_FILE registry name set "$name2" "$RECORD_ID"
rc=$?
if [ $rc -ne 0 ]; then
echo "FATAL: Failed to set hash"
exit $rc
fi
echo "$name2 set for ApplicationRecord"
name3="$REGISTRY_APP_LRN"
sleep 2
# Set name if latest release
laconic -c $CONFIG_FILE registry name set "$name3" "$RECORD_ID"
rc=$?
if [ $rc -ne 0 ]; then
echo "FATAL: Failed to set release"
exit $rc
fi
echo "$name3 set for ApplicationRecord"
# Check if record found for REGISTRY_APP_LRN
query_response=$(laconic -c $CONFIG_FILE registry name resolve "$REGISTRY_APP_LRN")
rc=$?
if [ $rc -ne 0 ]; then
echo "FATAL: Failed to query name"
exit $rc
fi
APP_RECORD=$(echo $query_response | jq '.[0]')
if [ -z "$APP_RECORD" ] || [ "null" == "$APP_RECORD" ]; then
echo "No record found for $REGISTRY_APP_LRN."
exit 1
fi
echo "Name resolution successful"
sleep 2
echo "Requesting a webapp deployment for $name2, using deployer $DEPLOYER_LRN"
laconic-so request-webapp-deployment \
--laconic-config $CONFIG_FILE \
--deployer $DEPLOYER_LRN \
--app $name2 \
--env-file ./.app.env \
--dns $DEPLOYMENT_DNS \
--make-payment auto
echo "Done"