forked from mito-systems/sol-mem-gen
Add script and instructions for deployment #11
10
README.md
10
README.md
@ -17,16 +17,19 @@ This project is a Solana-based meme generator that allows users to connect their
|
|||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
- Install dependencies:
|
- Install dependencies:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
- Copy the `.env.example` file to `.env.local` and add your API keys:
|
- Copy the `.env.example` file to `.env.local` and add your API keys:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cp .env.example .env.local
|
cp .env.example .env.local
|
||||||
```
|
```
|
||||||
|
|
||||||
- Add your FAL AI key to the `.env.local` file:
|
- Add your FAL AI key to the `.env.local` file:
|
||||||
|
|
||||||
```env
|
```env
|
||||||
# Get key from https://fal.ai/
|
# Get key from https://fal.ai/
|
||||||
FAL_AI_KEY=your_fal_ai_key
|
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>
|
- 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
|
- 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:
|
- Run the development server:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run dev
|
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.
|
- Connect your Solflare or Phantom wallet using the "Connect Wallet" button.
|
||||||
- Select an AI model and enter a prompt to generate a meme.
|
- 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.
|
- 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`
|
||||||
|
10
deploy/.registry.env.example
Normal file
10
deploy/.registry.env.example
Normal 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
40
deploy/Dockerfile
Normal 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
120
deploy/README.md
Normal 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
10
deploy/config.yml
Normal 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
126
deploy/deploy.sh
Executable 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"
|
Loading…
Reference in New Issue
Block a user