serve frontend + backend as a one binary
This commit is contained in:
parent
5954ec2501
commit
e378db58b8
@ -7,13 +7,15 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gitserver.in/patialtech/mux"
|
"gitserver.in/patialtech/mux"
|
||||||
"gitserver.in/patialtech/mux/middleware"
|
"gitserver.in/patialtech/mux/middleware"
|
||||||
"gitserver.in/patialtech/rano/cmd/server/handler"
|
"gitserver.in/patialtech/rano/bin/server/handler"
|
||||||
"gitserver.in/patialtech/rano/config"
|
"gitserver.in/patialtech/rano/config"
|
||||||
"gitserver.in/patialtech/rano/graph"
|
"gitserver.in/patialtech/rano/graph"
|
||||||
"gitserver.in/patialtech/rano/util/logger"
|
"gitserver.in/patialtech/rano/util/logger"
|
||||||
|
"gitserver.in/patialtech/rano/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -24,6 +26,7 @@ func main() {
|
|||||||
// CORS
|
// CORS
|
||||||
r.Use(middleware.CORS(middleware.CORSOption{
|
r.Use(middleware.CORS(middleware.CORSOption{
|
||||||
AllowedHeaders: []string{"Content-Type"},
|
AllowedHeaders: []string{"Content-Type"},
|
||||||
|
AllowedOrigins: []string{config.Read().WebURL},
|
||||||
MaxAge: 60,
|
MaxAge: 60,
|
||||||
}))
|
}))
|
||||||
// Secure Headers
|
// Secure Headers
|
||||||
@ -40,7 +43,37 @@ func main() {
|
|||||||
|
|
||||||
// catch all
|
// catch all
|
||||||
r.GET("/", func(w http.ResponseWriter, r *http.Request) {
|
r.GET("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte("hello there"))
|
var (
|
||||||
|
resourcePath string
|
||||||
|
path = r.URL.Path
|
||||||
|
)
|
||||||
|
|
||||||
|
if strings.HasPrefix(path, "/_app") {
|
||||||
|
resourcePath = "public/build" + path
|
||||||
|
} else if strings.HasSuffix(path, ".png") ||
|
||||||
|
strings.HasSuffix(path, ".ico") ||
|
||||||
|
strings.HasSuffix(path, ".svg") ||
|
||||||
|
strings.HasSuffix(path, "robot.txt") ||
|
||||||
|
strings.HasSuffix(path, "site.webmanifest") {
|
||||||
|
resourcePath = "public" + path
|
||||||
|
} else {
|
||||||
|
resourcePath = "public/build/fallback.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
if b, err := web.Public.ReadFile(resourcePath); err != nil {
|
||||||
|
_, _ = w.Write([]byte("hello there"))
|
||||||
|
} else {
|
||||||
|
if strings.HasSuffix(path, ".js") {
|
||||||
|
w.Header().Set("Content-Type", "text/javascript")
|
||||||
|
} else if strings.HasSuffix(path, ".css") {
|
||||||
|
w.Header().Set("Content-Type", "text/css")
|
||||||
|
} else {
|
||||||
|
w.Header().Set("Content-Type", http.DetectContentType(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
_, _ = w.Write(b)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Serve(func(srv *http.Server) error {
|
r.Serve(func(srv *http.Server) error {
|
@ -18,17 +18,13 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// projDir need to be same as project code root dir name
|
// projDir need to be same as project code root dir name
|
||||||
projDir = "rano"
|
projDir = "rano"
|
||||||
EnvDev = "development"
|
|
||||||
EnvProd = "production"
|
|
||||||
EnvStage = "staging"
|
|
||||||
|
|
||||||
AuthUserCtxKey = "AuthUser"
|
AuthUserCtxKey = "AuthUser"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
conf *Config
|
conf *Config
|
||||||
AppEnv Env = EnvDev
|
AppEnv = "development" // production | staging
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -47,7 +43,7 @@ type (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var base string
|
var base string
|
||||||
if AppEnv == EnvDev {
|
if AppEnv == "development" { // AppEnv will be changed on build time using ldflags -X
|
||||||
wd, _ := os.Getwd()
|
wd, _ := os.Getwd()
|
||||||
idx := strings.Index(wd, projDir)
|
idx := strings.Index(wd, projDir)
|
||||||
if idx > -1 {
|
if idx > -1 {
|
||||||
@ -57,6 +53,8 @@ func init() {
|
|||||||
base, _ = os.Executable()
|
base, _ = os.Executable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Info("*** %s", AppEnv)
|
||||||
|
|
||||||
envVar, err := dotenv.Read(base, fmt.Sprintf(".env.%s", AppEnv))
|
envVar, err := dotenv.Read(base, fmt.Sprintf(".env.%s", AppEnv))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import path from 'node:path';
|
|
||||||
import adapter from '@sveltejs/adapter-static';
|
import adapter from '@sveltejs/adapter-static';
|
||||||
|
|
||||||
const webDir = path.resolve('.', 'web');
|
|
||||||
|
|
||||||
/** @type {import('@sveltejs/kit').Config} */
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
const config = {
|
const config = {
|
||||||
@ -9,16 +7,15 @@ const config = {
|
|||||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||||
adapter: adapter(),
|
|
||||||
files: {
|
files: {
|
||||||
appTemplate: path.resolve(webDir, 'app.html'),
|
appTemplate: "web/app.html" ,
|
||||||
routes: path.resolve(webDir, 'routes'),
|
routes: "web/routes",
|
||||||
lib: path.resolve(webDir, 'lib'),
|
lib: "web/lib",
|
||||||
assets: path.resolve(webDir, 'public')
|
assets: "public/lib"
|
||||||
},
|
},
|
||||||
alias: {
|
alias: {
|
||||||
$image: path.resolve(webDir, 'assets', 'image'),
|
$image: "web/assets/image",
|
||||||
$svg: path.resolve(webDir, 'assets', 'svg')
|
$svg: "web/assets/svg"
|
||||||
},
|
},
|
||||||
paths: {
|
paths: {
|
||||||
assets: process.env.ASSETS_HOST ?? ''
|
assets: process.env.ASSETS_HOST ?? ''
|
||||||
@ -28,8 +25,8 @@ const config = {
|
|||||||
pollInterval: 1000 * 60 * 1 // 5 minutes
|
pollInterval: 1000 * 60 * 1 // 5 minutes
|
||||||
},
|
},
|
||||||
adapter: adapter({
|
adapter: adapter({
|
||||||
pages: path.resolve(webDir, 'public', 'build'),
|
pages: "web/public/build",
|
||||||
assets: path.resolve(webDir, 'public', 'build'),
|
assets: "web/public/build",
|
||||||
fallback: 'fallback.html',
|
fallback: 'fallback.html',
|
||||||
strict: true
|
strict: true
|
||||||
})
|
})
|
||||||
|
28
taskfile.yml
28
taskfile.yml
@ -1,9 +1,12 @@
|
|||||||
version: '3'
|
version: '3'
|
||||||
|
|
||||||
|
dotenv: ['.env.{{.ENV}}']
|
||||||
|
|
||||||
env:
|
env:
|
||||||
ENV: development
|
ENV: development
|
||||||
|
|
||||||
dotenv: ['.env.{{.ENV}}']
|
vars:
|
||||||
|
MOD_NAME: gitserver.in/patialtech/rano
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
install:
|
install:
|
||||||
@ -14,7 +17,7 @@ tasks:
|
|||||||
start-graph:
|
start-graph:
|
||||||
desc: run graph server
|
desc: run graph server
|
||||||
cmds:
|
cmds:
|
||||||
- cmd: go run ./cmd/server
|
- cmd: go run ./bin/server
|
||||||
|
|
||||||
start-web:
|
start-web:
|
||||||
desc: run web in dev mode
|
desc: run web in dev mode
|
||||||
@ -44,11 +47,11 @@ tasks:
|
|||||||
- cmd: deno task codegen
|
- cmd: deno task codegen
|
||||||
|
|
||||||
ent-new:
|
ent-new:
|
||||||
desc: create new db Emtity
|
desc: create new db Entity
|
||||||
cmd: cd ./db && go run -mod=mod entgo.io/ent/cmd/ent new {{.name}}
|
cmd: cd ./db && go run -mod=mod entry.io/ent/cmd/ent new {{.name}}
|
||||||
|
|
||||||
ent-gen:
|
ent-gen:
|
||||||
desc: genertate from ent schema
|
desc: generate from ent schema
|
||||||
cmds:
|
cmds:
|
||||||
- go generate ./db/ent
|
- go generate ./db/ent
|
||||||
|
|
||||||
@ -61,4 +64,17 @@ tasks:
|
|||||||
desc: apply automatically migration using Ent schema
|
desc: apply automatically migration using Ent schema
|
||||||
cmds:
|
cmds:
|
||||||
- task: ent-gen
|
- task: ent-gen
|
||||||
- go run ./cmd/migrate-up
|
- go run ./bin/migrate-up
|
||||||
|
|
||||||
|
build-web-prod:
|
||||||
|
desc: apply automatically migration using Ent schema
|
||||||
|
cmds:
|
||||||
|
- deno task build
|
||||||
|
env:
|
||||||
|
ASSETS_HOST:
|
||||||
|
|
||||||
|
build-prod:
|
||||||
|
desc: apply automatically migration using Ent schema
|
||||||
|
cmds:
|
||||||
|
- task: build-web-prod
|
||||||
|
- CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -ldflags "-X '{{.MOD_NAME}}/config.AppEnv=production'" -o ./server ./bin/server
|
BIN
web/public/android-chrome-192x192.png
Normal file
BIN
web/public/android-chrome-192x192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
BIN
web/public/android-chrome-512x512.png
Normal file
BIN
web/public/android-chrome-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
web/public/apple-touch-icon.png
Normal file
BIN
web/public/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
BIN
web/public/favicon-16x16.png
Normal file
BIN
web/public/favicon-16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 262 B |
BIN
web/public/favicon-32x32.png
Normal file
BIN
web/public/favicon-32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 548 B |
BIN
web/public/favicon.ico
Normal file
BIN
web/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
11
web/public/site.webmanifest
Normal file
11
web/public/site.webmanifest
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"short_name": "",
|
||||||
|
"icons": [
|
||||||
|
{ "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
|
||||||
|
{ "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
|
||||||
|
],
|
||||||
|
"theme_color": "#ffffff",
|
||||||
|
"background_color": "#ffffff",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
6
web/web.go
Normal file
6
web/web.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package web
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed public public/build/_app
|
||||||
|
var Public embed.FS
|
Loading…
Reference in New Issue
Block a user