This project is a Dad Joke Generator that uses the OpenAI GPT-3 API to generate the funniest dad jokes you've ever heard! The application is built using Go and is composed of a joke-server, joke-worker, Redis, MongoDB, and NATS.
The application consists of the following components:
- joke-server: A web server that listens for incoming HTTP requests and returns a dad joke.
- joke-worker: A background worker that communicates with the OpenAI GPT-3 API, generates dad jokes, caches them in Redis, and stores them in MongoDB.
- Redis: A caching layer that temporarily stores generated dad jokes.
- MongoDB: A NoSQL database that permanently stores generated dad jokes.
- NATS: A messaging system that facilitates communication between the joke-server and joke-worker.
Before you can deploy the Dad Joke Generator, you'll need the following:
- Docker and Docker Compose installed on your machine
- An OpenAI API key
- Access to a Kubernetes cluster,
helm
andkubectl
installed if you want to deploy the application on Kubernetes gpg
command-line available
To deploy the Dad Joke Generator, follow these steps:
- Clone the repository:
git clone https://github.com/vfiftyfive/dadjokes.git
cd dadjokes/deploy/docker
- Create a .env file in the
dadjokes/deploy/docker
directory, with your OpenAI API key:
echo "OPENAI_API_KEY=your_api_key_here" > .env
- Run the deployment script:
cd ../..
make deploy
- Generate a lot of jokes!
for i in {1..30}; do curl http://localhost:8080/joke; echo -e; done
The last 10 jokes should come a lot faster than the first 20, as the joke-worker will retrieve jokes from the Redis cache after that, for a time defined in constants.RedisTTL
.
- Clone the repository and change the directory to
deploy/devspace
:
git clone https://github.com/vfiftyfive/dadjokes.git
cd dadjokes/deploy/devspace
- Install DevSpace:
# AMD64
curl -L -o devspace "https://github.com/loft-sh/devspace/releases/latest/download/devspace-linux-amd64" && sudo install -c -m 0755 devspace /usr/local/bin
# ARM64
curl -L -o devspace "https://github.com/loft-sh/devspace/releases/latest/download/devspace-linux-arm64" && sudo install -c -m 0755 devspace /usr/local/bin
- Install SOPS:
ORG="mozilla"
REPO="sops"
latest_release=$(curl --silent "https://api.github.com/repos/${ORG}/${REPO}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
# AMD64
curl -L https://github.com/mozilla/sops/releases/download/v${latest_release}/sops_${latest_release}_amd64.deb -o sops.deb && sudo apt-get install ./sops.deb && rm sops.deb
# ARM64
curl -L https://github.com/mozilla/sops/releases/download/v${latest_release}/sops_${latest_release}_arm64.deb -o sops.deb && sudo apt-get install ./sops.deb && rm sops.deb
- Generate a GPG key:
gpg --gen-key
#answer the questions
- Create a SOPS configuration file:
first_pgp_key=$(gpg --list-secret-keys --keyid-format LONG | grep -m1 '^sec' | awk '{print $2}' | cut -d '/' -f2)
cat <<EOF > .sops.yaml
creation_rules:
- encrypted_regex: "^(data|stringData)$"
pgp: >-
${first_pgp_key}
EOF
- Create an encrypted Kubernetes ConfigMap with your OpenAI API key:
kubectl create configmap openai-api-key --from-literal=OPENAI_API_KEY=your_api_key_here --dry-run=client -o yaml | sops -e /dev/stdin > deploy/devspace/openai-api-key.enc.yaml
- Specify a namespace to use with DevSpace
devspace use namespace dev
- Run devspace in dev mode
devspace dev
- Generate a lot of jokes:
for i in {1..10}; do curl http://localhost:8080/joke; echo -e; done
- Modify the code
Your local repository is synchronized with the project files within the joke-worker pod. Modify the file internal/joke/joke.go
and change the code so the joke generated is now a Chuck Norris joke. Replace the line:
Prompt: "Tell me a dad joke"
With the line:
Prompt: "Tell me a Chuck Norris joke"
Then save the file. The joke-worker pod will automatically recompile and restart the binary. Now, when you run the curl command again, you should see a Chuck Norris joke instead of a dad joke (provided you have generated less than 20 jokes, as the program will retrieve jokes from the Redis cache after that, for a time defined in constants.RedisTTL
):
for i in {1..10}; do curl http://localhost:8080/joke; echo -e; done
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.