fix(docker): add dockfile and small fixes (#38)
* fix(docker): add dockfile and small fixes * chore(readme): small fixes
This commit is contained in:
parent
c8a3f911e8
commit
b0d1cdccfc
11 changed files with 126 additions and 36 deletions
16
Dockerfile
Normal file
16
Dockerfile
Normal file
|
@ -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"]
|
47
README.md
47
README.md
|
@ -2,7 +2,7 @@
|
|||
Quickshare
|
||||
</h1>
|
||||
<p align="center">
|
||||
Simple file sharing service built with Go/Golang, Typescript, Gin, React, Boltdb, etc.
|
||||
Quick and simple file sharing between different devices.
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/ihexxa/quickshare/actions">
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
21
configs/docker.yml
Normal file
21
configs/docker.yml
Normal file
|
@ -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
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
11
scripts/build_be_docker.sh
Executable file
11
scripts/build_be_docker.sh
Executable file
|
@ -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"
|
7
scripts/docker_run.sh
Normal file
7
scripts/docker_run.sh
Normal file
|
@ -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
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue