From b0d1cdccfc9790f3f7390c1d6fa3a36c2e1e0aea Mon Sep 17 00:00:00 2001 From: Hexxa Date: Mon, 1 Feb 2021 21:36:56 +0800 Subject: [PATCH] fix(docker): add dockfile and small fixes (#38) * fix(docker): add dockfile and small fixes * chore(readme): small fixes --- Dockerfile | 16 +++++++++++ README.md | 47 +++++++++++++++++++++++++------ cmd/start/main.go | 4 +++ configs/docker.yml | 21 ++++++++++++++ package.json | 4 +-- scripts/{build => build.sh} | 0 scripts/build_be_docker.sh | 11 ++++++++ scripts/docker_run.sh | 7 +++++ src/client/web/package.json | 3 +- src/handlers/fileshdr/handlers.go | 11 ++++---- src/server/config.go | 38 ++++++++++++------------- 11 files changed, 126 insertions(+), 36 deletions(-) create mode 100644 Dockerfile create mode 100644 configs/docker.yml rename scripts/{build => build.sh} (100%) create mode 100755 scripts/build_be_docker.sh create mode 100644 scripts/docker_run.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a406eb2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM golang:1.15 as build-be +ADD . /quickshare +WORKDIR /quickshare +RUN /quickshare/scripts/build_be_docker.sh + +FROM node as build-fe +COPY --from=build-be /quickshare /quickshare +WORKDIR /quickshare +RUN yarn install \ + && yarn --cwd "src/client/web" run build \ + && cp -R /quickshare/public /quickshare/dist/quickshare + +FROM gcr.io/distroless/base-debian10 +COPY --from=build-fe /quickshare/dist/quickshare /quickshare +ADD configs/docker.yml /quickshare +CMD ["/quickshare/start", "-c", "/quickshare/docker.yml"] diff --git a/README.md b/README.md index 49094be..3565bb9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Quickshare

- Simple file sharing service built with Go/Golang, Typescript, Gin, React, Boltdb, etc. + Quick and simple file sharing between different devices.

@@ -24,26 +24,55 @@ Choose Language: English | [简体中文](./docs/README_zh-cn.md) ## Main Features -- Sharing files among different devices (Adaptive UI) +- Sharing and accessing from different devices (Adaptive UI) - Be compatible with Linux, Mac and Windows - Stopping and resuming uploading/downloading - Do uploading and downloading in web browser +- Manage files in browser or in OS ## Quick Start -**Downloading**: Download last distribution(s) in [Release Page](https://github.com/ihexxa/quickshare/releases). +### Run in Docker -**Unzipping**: Unzip it and run following command `./quickshare`. (You may update its execution permission: e.g. run `chmod u+x quickshare` on Linux) +Following will start a `quickshare` docker and listen to `8686` port. -**Starting**: At the first run, Quickshare will let you input your user name and generate a random password for you (here `quickshare` is the user name). It may output something like following (password is `2fdc98`): +Then you can open `http://127.0.0.1:8686` and log in with user name `qs` and password `1234`: ``` -Please input admin name: quickshare -password is generated: 2fdc98, please update it after login -user (quickshare) is created +docker run \ + --name quickshare \ + -d -p :8686:8686 \ + -v `pwd`/quickshare/root:/quickshare/root \ + -e DEFAULTADMIN=qs \ + -e DEFAULTADMINPWD=1234 \ + hexxa/quickshare:0.3.0 ``` -**Accessing**: At last, open your browser and visit `http://127.0.0.1:8686`. +- `DEFAULTADMIN` is the default user name +- `DEFAULTADMINPWD` is the default user password +- `/quickshare/root` is where Quickshare stores files and directories. + +### Run from source code + +Before start, please ensure Go/Golang (>1.15), Node.js and Yarn are installed on your machine. + +``` +# clone this repo +git clone git@github.com:ihexxa/quickshare.git + +# go to repo's folder +cd quickshare + +DEFAULTADMIN=qs DEFAULTADMINPWD=1234 yarn start +``` + +OK! Open `http://127.0.0.1:8686` in browser, and log in with user name `qs` and password `1234`. + +### Run executable file + +- **Downloading**: Download last distribution(s) in [Release Page](https://github.com/ihexxa/quickshare/releases). +- **Unzipping**: Unzip it and run following command `DEFAULTADMIN=qs DEFAULTADMINPWD=1234 ./quickshare`. (You may update its execution permission: e.g. run `chmod u+x quickshare`) +- **Accessing**: At last, open `http://127.0.0.1:8686` in browser, and log in with user name `qs` and password `1234`. ### FAQ diff --git a/cmd/start/main.go b/cmd/start/main.go index 4e73c2d..07aca62 100644 --- a/cmd/start/main.go +++ b/cmd/start/main.go @@ -31,11 +31,14 @@ func main() { if err != nil { panic(err) } + if len(opts.Configs) > 0 { for _, configPath := range opts.Configs { if strings.HasSuffix(configPath, ".yml") || strings.HasSuffix(configPath, ".yaml") { + fmt.Printf("launching config: %s\n", configPath) cfg, err = cfg.Load(gocfg.YAML(configPath)) } else if strings.HasSuffix(configPath, ".json") { + fmt.Printf("launching config: %s\n", configPath) cfg, err = cfg.Load(gocfg.JSON(configPath)) } else { panic(fmt.Sprintf("unknown config file type (.yml .yaml .json are supported): %s", configPath)) @@ -62,6 +65,7 @@ func main() { panic(err) } + fmt.Printf("quickshare is listening %d\n", cfg.GrabInt("Server.Port")) err = srv.Start() if err != nil { panic(err) diff --git a/configs/docker.yml b/configs/docker.yml new file mode 100644 index 0000000..d354a60 --- /dev/null +++ b/configs/docker.yml @@ -0,0 +1,21 @@ +fs: + root: "/quickshare/root" + opensLimit: 128 + openTTL: 60 # 1 min +secrets: + tokenSecret: "" +server: + debug: false + host: "0.0.0.0" + port: 8686 + readTimeout: 2000 + writerTimeout: 86400000 # 1 day + maxHeaderBytes: 512 + publicPath: "/quickshare/public" +users: + enableAuth: true + defaultAdmin: "" + defaultAdminPwd: "" + cookieTTL: 604800 # 1 week + cookieSecure: false + cookieHttpOnly: true diff --git a/package.json b/package.json index 2488b97..08dc5f1 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "src/client/web" ], "scripts": { - "build": "scripts/build", - "start": "go run cmd/start/main.go -c `pwd`/configs/dev.yml" + "build": "scripts/build.sh", + "start": "cd src/client/web/ && yarn && yarn build && cd ../../.. && go run cmd/start/main.go -c `pwd`/configs/dev.yml" } } diff --git a/scripts/build b/scripts/build.sh similarity index 100% rename from scripts/build rename to scripts/build.sh diff --git a/scripts/build_be_docker.sh b/scripts/build_be_docker.sh new file mode 100755 index 0000000..96a3910 --- /dev/null +++ b/scripts/build_be_docker.sh @@ -0,0 +1,11 @@ +export QSROOT=`pwd` +rm -r dist && mkdir dist + +# set this for builders behind GFW... +go env -w GOPROXY=https://goproxy.cn,direct +go get -d -v ./... +go get github.com/mitchellh/gox +cd cmd/start +gox \ + -osarch="linux/amd64" \ + -output "$QSROOT/dist/quickshare/start" diff --git a/scripts/docker_run.sh b/scripts/docker_run.sh new file mode 100644 index 0000000..8d81b96 --- /dev/null +++ b/scripts/docker_run.sh @@ -0,0 +1,7 @@ +docker run \ + --name quickshare \ + -d -p :8686:8686 \ + -v `pwd`/quickshare/root:/quickshare/root \ + -e DEFAULTADMIN=qs \ + -e DEFAULTADMINPWD=1234 \ + hexxa/quickshare:0.3.0 diff --git a/src/client/web/package.json b/src/client/web/package.json index 50e15f7..4b4c3e9 100644 --- a/src/client/web/package.json +++ b/src/client/web/package.json @@ -4,7 +4,8 @@ "description": "web client for quickshare", "main": "", "scripts": { - "build": "yarn prod:addjs && webpack --config webpack.app.prod.js", + "build": "yarn prod:addjs && yarn build:prod:wp", + "build:prod:wp": "webpack --config webpack.app.prod.js", "build:watch": "webpack --config webpack.app.prod.js --watch", "build:dev": "yarn dev:addjs && webpack --config webpack.app.dev.js --watch", "test": "jest test --maxWorkers=2", diff --git a/src/handlers/fileshdr/handlers.go b/src/handlers/fileshdr/handlers.go index 5f2aa5f..e478134 100644 --- a/src/handlers/fileshdr/handlers.go +++ b/src/handlers/fileshdr/handlers.go @@ -46,6 +46,7 @@ type FileHandlers struct { func NewFileHandlers(cfg gocfg.ICfg, deps *depidx.Deps) (*FileHandlers, error) { var err error + if err = deps.FS().MkdirAll(UploadDir); err != nil { return nil, err } @@ -113,7 +114,7 @@ func (h *FileHandlers) Create(c *gin.Context) { } userName := c.MustGet(singleuserhdr.UserParam).(string) - tmpFilePath := getTmpPath(req.Path) + tmpFilePath := h.getTmpPath(req.Path) locker := h.NewAutoLocker(c, lockName(userName, tmpFilePath)) locker.Exec(func() { err := h.deps.FS().Create(tmpFilePath) @@ -261,7 +262,7 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) { } userName := c.MustGet(singleuserhdr.UserParam).(string) - tmpFilePath := getTmpPath(req.Path) + tmpFilePath := h.getTmpPath(req.Path) locker := h.NewAutoLocker(c, lockName(userName, tmpFilePath)) locker.Exec(func() { var err error @@ -331,7 +332,7 @@ func (h *FileHandlers) UploadStatus(c *gin.Context) { } userName := c.MustGet(singleuserhdr.UserParam).(string) - tmpFilePath := getTmpPath(filePath) + tmpFilePath := h.getTmpPath(filePath) locker := h.NewAutoLocker(c, lockName(userName, tmpFilePath)) locker.Exec(func() { _, fileSize, uploaded, err := h.uploadMgr.GetInfo(userName, tmpFilePath) @@ -468,7 +469,7 @@ func (h *FileHandlers) CopyDir(c *gin.Context) { c.JSON(q.NewMsgResp(501, "Not Implemented")) } -func getTmpPath(filePath string) string { +func (h *FileHandlers) getTmpPath(filePath string) string { return path.Join(UploadDir, fmt.Sprintf("%x", sha1.Sum([]byte(filePath)))) } @@ -504,7 +505,7 @@ func (h *FileHandlers) DelUploading(c *gin.Context) { userName := c.MustGet(singleuserhdr.UserParam).(string) var err error - tmpFilePath := getTmpPath(filePath) + tmpFilePath := h.getTmpPath(filePath) locker := h.NewAutoLocker(c, lockName(userName, tmpFilePath)) locker.Exec(func() { err = h.deps.FS().Remove(tmpFilePath) diff --git a/src/server/config.go b/src/server/config.go index 49ef828..f1d94dd 100644 --- a/src/server/config.go +++ b/src/server/config.go @@ -9,33 +9,33 @@ type FSConfig struct { } type UsersCfg struct { - EnableAuth bool `json:"enableAuth"` - DefaultAdmin string `json:"defaultAdmin" cfg:"env"` - DefaultAdminPwd string `json:"defaultAdminPwd" cfg:"env"` - CookieTTL int `json:"cookieTTL"` - CookieSecure bool `json:"cookieSecure"` - CookieHttpOnly bool `json:"cookieHttpOnly"` + EnableAuth bool `json:"enableAuth" yaml:"enableAuth"` + DefaultAdmin string `json:"defaultAdmin" yaml:"defaultAdmin" cfg:"env"` + DefaultAdminPwd string `json:"defaultAdminPwd" yaml:"defaultAdminPwd" cfg:"env"` + CookieTTL int `json:"cookieTTL" yaml:"cookieTTL"` + CookieSecure bool `json:"cookieSecure" yaml:"cookieSecure"` + CookieHttpOnly bool `json:"cookieHttpOnly" yaml:"cookieHttpOnly"` } type Secrets struct { - TokenSecret string `json:"tokenSecret" cfg:"env"` + TokenSecret string `json:"tokenSecret" yaml:"tokenSecret" cfg:"env"` } type ServerCfg struct { - Debug bool `json:"debug"` - Host string `json:"host"` - Port int `json:"port"` - ReadTimeout int `json:"readTimeout"` - WriteTimeout int `json:"writeTimeout"` - MaxHeaderBytes int `json:"maxHeaderBytes"` - PublicPath string `json:"publicPath"` + Debug bool `json:"debug" yaml:"debug"` + Host string `json:"host" yaml:"host"` + Port int `json:"port" yaml:"port"` + ReadTimeout int `json:"readTimeout" yaml:"readTimeout"` + WriteTimeout int `json:"writeTimeout" yaml:"writeTimeout"` + MaxHeaderBytes int `json:"maxHeaderBytes" yaml:"maxHeaderBytes"` + PublicPath string `json:"publicPath" yaml:"publicPath"` } type Config struct { - Fs *FSConfig `json:"fs"` - Secrets *Secrets `json:"secrets"` - Server *ServerCfg `json:"server"` - Users *UsersCfg `json:"users"` + Fs *FSConfig `json:"fs" yaml:"fs"` + Secrets *Secrets `json:"secrets" yaml:"secrets"` + Server *ServerCfg `json:"server" yaml:"server"` + Users *UsersCfg `json:"users" yaml:"users"` } func NewConfig() *Config { @@ -45,7 +45,7 @@ func NewConfig() *Config { func DefaultConfig() (string, error) { defaultCfg := &Config{ Fs: &FSConfig{ - Root: ".", + Root: "root", OpensLimit: 128, OpenTTL: 60, // 1 min },