Skip to content

Commit

Permalink
💾 Saved.
Browse files Browse the repository at this point in the history
  • Loading branch information
k33g committed Feb 20, 2024
1 parent 1f08dce commit 03e991e
Show file tree
Hide file tree
Showing 13 changed files with 350 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/github-actions-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Docker Compose
run-name: Docker Compose 🐳
on: [push]
jobs:
Thest-The-Application:
runs-on: ubuntu-latest
steps:
- name: Deploy Application & Database
run: |
docker-compose -f ./compose.yaml up -d
1 change: 1 addition & 0 deletions all-things-compose
Submodule all-things-compose added at 0f40e4
16 changes: 16 additions & 0 deletions api/api.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM node:21-slim

WORKDIR /app
# COPY package.json
COPY package.json /app
# Installing dependencies
RUN yarn install

# Copying all the files in our project
COPY . /app

# Exposing server port
#EXPOSE 8080

# Starting our application
CMD [ "node", "index.js" ]
53 changes: 53 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const fastify = require('fastify')({logger: true})

const path = require('node:path')

fastify.register(require('@fastify/redis'), {
host: 'redis-server',
port: 6379
})

fastify.register(require('@fastify/cors'), (instance) => {
return (req, callback) => {
const corsOptions = {
origin: process.env.FRONT_URL || "http://localhost:7070"
};
// callback expects two parameters: error and options
callback(null, corsOptions)
}
})


const { ADDRESS = '0.0.0.0', PORT = '8080' } = process.env;

fastify.get('/counter/:animal', (request, reply) => {
const { animal } = request.params;

const { redis } = fastify

redis.get(animal, (err, counter_value) => {
var counter = err ? 0 : Number(counter_value)
reply.send(counter)
})
})

fastify.post('/counter', (request, reply) => {
const { redis } = fastify
let animal = request.body.animal

redis.get(animal, (err, counter_value) => {
var counter = err ? 0 : Number(counter_value)

redis.set(animal, counter+1, (err) => {
reply.send(err || { status: 'ok' })
})
})
})

fastify.listen({ host: ADDRESS, port: parseInt(PORT, 10) }, (err, address) => {
if (err) {
console.error(err)
process.exit(1)
}
console.log(`Server listening at ${address}`)
})
13 changes: 13 additions & 0 deletions api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "all-things",
"version": "1.0.0",
"description": "compose demo - API",
"main": "index.js",
"author": "@k33g",
"license": "MIT",
"dependencies": {
"@fastify/redis": "^6.1.1",
"fastify": "^4.26.0",
"@fastify/cors": "^8.0.0"
}
}
51 changes: 51 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
include:
- redis-server.yaml

services:
api:
build:
context: ./api
dockerfile: api.Dockerfile
environment:
- FRONT_URL=http://localhost:7070
# to allow the front to connect to the API (CORS, Cross-Origin Resource Sharing)
ports:
- 6060:8080
# query the API on http://localhost:6060/counter
depends_on:
redis-server:
condition: service_started
networks:
- backend
- frontend

webapp:
build:
context: ./web
dockerfile: web.Dockerfile
environment:
- API_URL=http://localhost:6060
# docker compose watch
develop:
watch:
- action: sync
path: web/templates
target: app/templates
ports:
- 7070:8080
# open the webapp http://localhost:7070/
depends_on:
api:
condition: service_started
networks:
- frontend

networks:
frontend:
backend:

volumes:
redis-data:
#external: true

# https://docs.docker.com/compose/compose-file/compose-file-v2/#external
11 changes: 11 additions & 0 deletions redis-server.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
redis-server:
image: redis:7.2.4
environment:
- REDIS_ARGS="--save 30 1"
volumes:
- redis-data:/data
ports:
- 6379:6379
networks:
- backend
15 changes: 15 additions & 0 deletions web/demo/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createClient } from 'redis'

const client = createClient({
url: 'redis://redis-server:6379'
})

client.on('error', err => console.log('Redis Client Error', err))

await client.connect()

const keys = await client.keys("*")

console.log(keys)


30 changes: 30 additions & 0 deletions web/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const fastify = require('fastify')({logger: true})

const path = require('node:path')


fastify.register(require('@fastify/static'), {
root: path.join(__dirname, 'public'),
})

fastify.register(require("point-of-view"), {
engine: {
ejs: require("ejs"),
},
})

const { ADDRESS = '0.0.0.0', PORT = '8080' } = process.env;


fastify.get('/', (req, res) => {
return res.view("/templates/index.ejs", {apiURL: process.env.API_URL})
})


fastify.listen({ host: ADDRESS, port: parseInt(PORT, 10) }, (err, address) => {
if (err) {
console.error(err)
process.exit(1)
}
console.log(`Server listening at ${address}`)
})
15 changes: 15 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "all-things",
"version": "1.0.0",
"description": "compose demo - FrontEnd",
"main": "index.js",
"author": "@k33g",
"license": "MIT",
"dependencies": {
"@fastify/static": "^7.0.1",
"fastify": "^4.26.0",
"ejs": "^3.1.9",
"point-of-view": "^6.3.0",
"redis": "^4.6.13"
}
}
1 change: 1 addition & 0 deletions web/public/css/bulma.min.css

Large diffs are not rendered by default.

121 changes: 121 additions & 0 deletions web/templates/index.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<!doctype html>
<html lang="en">
<head>
<title>🐳 Compose 💙</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta charset="utf-8">

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<link rel="stylesheet" href="./css/bulma.min.css">

</head>
<body>
<div class="container">
<section class="hero is-medium">
<div class="hero-body">
<p class="title is-1">
All things 🐳 Compose
</p>
<p class="subtitle is-1">
Vote for your favourite animal
</p>

<div class="content">
<div class="buttons are-large">
<button id="btn_panda" class="button is-info is-light">🐼 Panda</button>
<button id="btn_tiger" class="button is-success is-light">🐯 Tiger</button>
<button id="btn_fox" class="button is-warning is-light">🦊 Fox</button>
<button id="btn_hamster" class="button is-danger is-light">🐹 Hamster</button>
</div>
</div>

<div class="content">
<div class="tags are-medium">
<span id="tag_panda" class="tag is-info is-light">Panda</span>
<span id="tag_tiger" class="tag is-success is-light">Tiger</span>
<span id="tag_fox" class="tag is-warning is-light">Fox</span>
<span id="tag_hamster" class="tag is-danger is-light">Hamster</span>
</div>
</div>

</div>
</section>
</div>
<script>
let tag_panda = document.querySelector("#tag_panda")
let tag_tiger = document.querySelector("#tag_tiger")
let tag_fox = document.querySelector("#tag_fox")
let tag_hamster = document.querySelector("#tag_hamster")
let counters = []
counters["Panda"] = 0
counters["Tiger"] = 0
counters["Fox"] = 0
counters["Hamster"] = 0
function allVotes() {
return counters["Panda"] + counters["Tiger"] + counters["Fox"] + counters["Hamster"]
}
function setTagValue(tag, label, value) {
counters[label] = Number(value)
tag.innerHTML = label+": "+((Number(value)/allVotes())*100).toFixed(2)+"%"
}
const intervalID = setInterval(function() {
fetch("<%= apiURL %>/counter/panda").then(response => response.json()).then(data => setTagValue(tag_panda, `Panda`, data)).catch(err => console.log(err))
fetch("<%= apiURL %>/counter/tiger").then(response => response.json()).then(data => setTagValue(tag_tiger, `Tiger`, data)).catch(err => console.log(err))
fetch("<%= apiURL %>/counter/fox").then(response => response.json()).then(data => setTagValue(tag_fox, `Fox`, data)).catch(err => console.log(err))
fetch("<%= apiURL %>/counter/hamster").then(response => response.json()).then(data => setTagValue(tag_hamster, `Hamster`, data)).catch(err => console.log(err))
}, 1000);
async function postJSON(data) {
try {
const response = await fetch("<%= apiURL %>/counter", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
})
const result = await response.json()
return result
} catch (error) {
return error
}
}
let btn_panda = document.querySelector("#btn_panda")
let btn_tiger = document.querySelector("#btn_tiger")
let btn_fox = document.querySelector("#btn_fox")
let btn_hamster = document.querySelector("#btn_hamster")
btn_panda.addEventListener("click", async _ => {
let result = await postJSON({animal: "panda"})
console.log(result)
})
btn_tiger.addEventListener("click", async _ => {
let result = await postJSON({animal: "tiger"})
console.log(result)
})
btn_fox.addEventListener("click", async _ => {
let result = await postJSON({animal: "fox"})
console.log(result)
})
btn_hamster.addEventListener("click", async _ => {
let result = await postJSON({animal: "hamster"})
console.log(result)
})
</script>
</body>

</html>
13 changes: 13 additions & 0 deletions web/web.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM node:21-slim

WORKDIR /app
# COPY package.json
COPY package.json /app
# Installing dependencies
RUN yarn install

# Copying all the files in our project
COPY . /app

# Starting our application
CMD [ "node", "index.js" ]

0 comments on commit 03e991e

Please sign in to comment.