Skip to content

Commit

Permalink
draft deploy with ui
Browse files Browse the repository at this point in the history
  • Loading branch information
ochom committed Jun 13, 2024
1 parent e5ad22d commit 090b96f
Show file tree
Hide file tree
Showing 26 changed files with 493 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tmp_dir = "tmp"
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ./cmd/main.go"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_dir = ["assets", "tmp", "vendor", "testdata", "web", "build"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
tmp
secret.sh
secret.sh
build
18 changes: 17 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,31 @@ COPY . ./

RUN go build -o /server ./cmd/main.go

##
## Build UI
##

FROM oven/bun:1.0 AS ui

WORKDIR /app

COPY web ./

RUN bun install

RUN bun run build

##
## Deploy
##
FROM gcr.io/distroless/base-debian12:nonroot
FROM busybox:1.35.0-uclibc AS deploy

WORKDIR /

RUN mkdir -p /web

COPY --from=build /server .
COPY --from=ui /app/build /web/build

EXPOSE 16321
EXPOSE 6321
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ tidy:
lint:
@echo "Running linter..."
@golangci-lint run

ui:
@cd web && bun run build

docker:
@docker build -t quickmq:latest .
25 changes: 21 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,29 @@ import (
"time"

"github.com/ochom/gutils/logs"
"github.com/ochom/quickmq/src/api"
"github.com/ochom/quickmq/src/app"
)

func main() {
svr := app.New()
port := ":16321"
coreServer := app.New()
webServer := api.New()

// run core
go func() {
if err := svr.Listen(port); err != nil {
if err := coreServer.Listen(":6321"); err != nil {
panic(err)
}
}()

// run api and web
go func() {
if err := webServer.Listen(":16321"); err != nil {
panic(err)
}
}()

// go run consumer daemon
go func() {
stopSignal := make(chan bool, 1)
logs.Info("starting consumers daemon")
Expand All @@ -34,7 +45,13 @@ func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

if err := svr.ShutdownWithContext(ctx); err != nil {
// shutdown core server
if err := coreServer.ShutdownWithContext(ctx); err != nil {
panic(err)
}

// shutdown api server
if err := webServer.ShutdownWithContext(ctx); err != nil {
panic(err)
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/gofiber/utils/v2 v2.0.0-beta.4 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/klauspost/compress v1.17.9 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/gofiber/fiber/v3 v3.0.0-beta.2 h1:mVVgt8PTaHGup3NGl/+7U7nEoZaXJ5OComV
github.com/gofiber/fiber/v3 v3.0.0-beta.2/go.mod h1:w7sdfTY0okjZ1oVH6rSOGvuACUIt0By1iK0HKUb3uqM=
github.com/gofiber/utils/v2 v2.0.0-beta.4 h1:1gjbVFFwVwUb9arPcqiB6iEjHBwo7cHsyS41NeIW3co=
github.com/gofiber/utils/v2 v2.0.0-beta.4/go.mod h1:sdRsPU1FXX6YiDGGxd+q2aPJRMzpsxdzCXo9dz+xtOY=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
Expand Down
21 changes: 21 additions & 0 deletions src/api/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package api

import (
"github.com/gofiber/fiber/v3"
)

func New() *fiber.App {
app := fiber.New()

// rest apis
app.Post("/login", login)
app.Get("/user", loadUSer)

// serve other static files
app.Static("/", "web/build")
app.Get("*", func(c fiber.Ctx) error {
return c.SendFile("web/build/index.html")
})

return app
}
61 changes: 61 additions & 0 deletions src/api/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package api

import (
"time"

"github.com/gofiber/fiber/v3"
"github.com/ochom/gutils/auth"
"github.com/ochom/gutils/env"
"github.com/ochom/gutils/uuid"
)

func login(c fiber.Ctx) error {
var data struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := c.Bind().Body(&data); err != nil {
return err
}

username := env.Get("QUICK_MQ_USERNAME", "admin")
password := env.Get("QUICK_MQ_PASSWORD", "admin")

if data.Username != username {
return c.Status(400).JSON(fiber.Map{"status": "error", "message": "Invalid username"})
}

if data.Password != password {
return c.Status(400).JSON(fiber.Map{"status": "error", "message": "Invalid password"})
}

token, err := auth.GenerateAuthTokens(map[string]string{"user": "admin", "session_id": uuid.New()})
if err != nil {
return err
}

// Set a cookie
cookie := fiber.Cookie{
Name: "jwt",
Value: token["token"],
Expires: time.Now().Add(time.Hour * 24),
HTTPOnly: true,
}
c.Cookie(&cookie)

return c.JSON(fiber.Map{"status": "success", "message": "Logged in", "username": "admin"})
}

func loadUSer(c fiber.Ctx) error {
token := c.Cookies("jwt")
claims, err := auth.GetAuthClaims(token)
if err != nil {
return c.Status(401).JSON(fiber.Map{"status": "error", "message": "Unauthorized", "data": err.Error()})
}

if claims["user"] != "admin" {
return c.Status(401).JSON(fiber.Map{"status": "error", "message": "Unauthorized"})
}

return c.JSON(fiber.Map{"status": "success", "message": "Logged in", "username": "admin"})
}
14 changes: 14 additions & 0 deletions web/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:react/jsx-runtime', 'plugin:react-hooks/recommended'],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
'react/prop-types': 'off'
}
};
24 changes: 24 additions & 0 deletions web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
7 changes: 7 additions & 0 deletions web/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"singleQuote": true,
"jsxSingleQuote": true,
"arrowParens": "avoid",
"trailingComma": "none",
"printWidth": 200
}
8 changes: 8 additions & 0 deletions web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# React + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
Binary file added web/bun.lockb
Binary file not shown.
22 changes: 22 additions & 0 deletions web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet">
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>

</html>
26 changes: 26 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "web",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"vite": "^5.2.0"
}
}
1 change: 1 addition & 0 deletions web/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions web/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
}
Loading

0 comments on commit 090b96f

Please sign in to comment.