mirror of
https://github.com/go-shiori/shiori.git
synced 2025-09-07 05:24:54 +08:00
feat: fixes to webroot feature and improvements to development using it (#1046)
* feat: Add nginx service to test shiori webroot configuration chore: Update nginx configuration to resolve 502 gateway error fix: Update SHIORI_WEBROOT to SHIORI_HTTP_ROOT_PATH in docker-compose feat: Add debug log level flag to shiori service refactor: Update docker-compose with simplified command and log configuration fix: Change nginx port mapping from 80 to 8081 feat: Add volume for Go module cache in docker-compose style: Add type attribute to script tags in index.html feat: Update import statements to use RootPath variable in index.html * docs: Update contribution guide with server and docker instructions * docs: Add Docker and nginx documentation for local development * test: IsValid()
This commit is contained in:
parent
d75de89701
commit
45bd4d693f
8 changed files with 125 additions and 31 deletions
5
Makefile
5
Makefile
|
@ -57,11 +57,6 @@ help:
|
|||
clean:
|
||||
rm -rf dist
|
||||
|
||||
## Runs the legacy http API for local development
|
||||
.PHONY: serve
|
||||
serve:
|
||||
SHIORI_DEVELOPMENT=$(SHIORI_DEVELOPMENT) SHIORI_DIR=$(SHIORI_DIR) go run main.go serve
|
||||
|
||||
## Runs server for local development
|
||||
.PHONY: run-server
|
||||
run-server:
|
||||
|
|
|
@ -1,25 +1,39 @@
|
|||
# Docker compose for development purposes only.
|
||||
# Edit it to fit your current development needs.
|
||||
version: "3"
|
||||
services:
|
||||
shiori:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.compose
|
||||
container_name: shiori
|
||||
command:
|
||||
- "server"
|
||||
- "--log-level"
|
||||
- "debug"
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "./dev-data:/srv/shiori"
|
||||
- ".:/src/shiori"
|
||||
- "go-mod-cache:/go/pkg/mod"
|
||||
restart: unless-stopped
|
||||
links:
|
||||
- "postgres"
|
||||
- "mariadb"
|
||||
environment:
|
||||
SHIORI_DIR: /srv/shiori
|
||||
#SHIORI_DATABASE_URL: mysql://shiori:shiori@(mariadb)/shiori?charset=utf8mb4
|
||||
SHIORI_DATABASE_URL: postgres://shiori:shiori@postgres/shiori?sslmode=disable
|
||||
# SHIORI_HTTP_ROOT_PATH: /shiori/
|
||||
# SHIORI_DATABASE_URL: mysql://shiori:shiori@(mariadb)/shiori?charset=utf8mb4
|
||||
# SHIORI_DATABASE_URL: postgres://shiori:shiori@postgres/shiori?sslmode=disable
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "8081:8081"
|
||||
volumes:
|
||||
- "./testdata/nginx.conf:/etc/nginx/nginx.conf:ro"
|
||||
depends_on:
|
||||
- shiori
|
||||
|
||||
postgres:
|
||||
image: postgres:15
|
||||
|
@ -38,3 +52,6 @@ services:
|
|||
MYSQL_PASSWORD: shiori
|
||||
ports:
|
||||
- "3306:3306"
|
||||
|
||||
volumes:
|
||||
go-mod-cache:
|
||||
|
|
|
@ -9,18 +9,10 @@
|
|||
|
||||
To run the current development server with the defaults you can run the following command:
|
||||
|
||||
```bash
|
||||
make serve
|
||||
```
|
||||
|
||||
If you want to run the refactored server, you can run the following command:
|
||||
|
||||
```bash
|
||||
make run-server
|
||||
```
|
||||
|
||||
> **ℹ️ Note:** For more information into what the _refactored server_ means, please check this issue: https://github.com/go-shiori/shiori/issues/640
|
||||
|
||||
## Updating the API documentation
|
||||
|
||||
> **ℹ️ Note:** This only applies for the Rest API documentation under the `internal/http` folder, **not** the one under `internal/webserver`.
|
||||
|
@ -94,3 +86,33 @@ mkdocs serve
|
|||
This will start a local server at `http://127.0.0.1:8000` where you can preview your changes in real-time.
|
||||
|
||||
Documentation for production is generated automatically on every release and published using github pages.
|
||||
|
||||
## Running the server with docker
|
||||
|
||||
To run the development server using Docker, you can use the provided `docker-compose.yaml` file which includes both PostgreSQL and MariaDB databases:
|
||||
|
||||
```bash
|
||||
docker compose up shiori
|
||||
```
|
||||
|
||||
This will start the Shiori server on port 8080 with hot-reload enabled. Any changes you make to the code will automatically rebuild and restart the server.
|
||||
|
||||
By default, it uses SQLite mounting the local `dev-data` folder in the source code path. To use MariaDB or PostgreSQL instead, uncomment the `SHIORI_DATABASE_URL` line for the appropriate engine in the `docker-compose.yaml` file.
|
||||
|
||||
## Running the server using an nginx reverse proxy and a custom webroot
|
||||
|
||||
To test Shiori behind an nginx reverse proxy with a custom webroot (e.g., `/shiori/`), you can use the provided nginx configuration:
|
||||
|
||||
1. First, ensure the `SHIORI_HTTP_ROOT_PATH` environment variable is uncommented in `docker-compose.yaml`:
|
||||
```yaml
|
||||
SHIORI_HTTP_ROOT_PATH: /shiori/
|
||||
```
|
||||
|
||||
2. Then start both Shiori and nginx services:
|
||||
```bash
|
||||
docker compose up shiori nginx
|
||||
```
|
||||
|
||||
This will start the shiori service along with nginx. You can access Shiori using [http://localhost:8081/shiori](http://localhost:8081/shiori).
|
||||
|
||||
The nginx configuration in `testdata/nginx.conf` handles all the necessary configuration.
|
||||
|
|
|
@ -80,6 +80,10 @@ func initShiori(ctx context.Context, cmd *cobra.Command) (*config.Config, *depen
|
|||
|
||||
cfg.SetDefaults(logger, portableMode)
|
||||
|
||||
if err := cfg.IsValid(); err != nil {
|
||||
logger.WithError(err).Fatal("invalid configuration detected")
|
||||
}
|
||||
|
||||
err := os.MkdirAll(cfg.Storage.DataDir, model.DataDirPerm)
|
||||
if err != nil {
|
||||
logger.WithError(err).Fatal("error creating data directory")
|
||||
|
|
|
@ -79,6 +79,14 @@ func (c *HttpConfig) SetDefaults(logger *logrus.Logger) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *HttpConfig) IsValid() error {
|
||||
if !strings.HasSuffix(c.RootPath, "/") {
|
||||
return fmt.Errorf("root path should end with a slash")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
DBMS string `env:"DBMS"` // Deprecated
|
||||
// DBMS requires more environment variables. Check the database package for more information.
|
||||
|
@ -140,6 +148,14 @@ func (c *Config) DebugConfiguration(logger *logrus.Logger) {
|
|||
logger.Debugf(" SHIORI_HTTP_DISABLE_PARSE_MULTIPART_FORM: %t", c.Http.DisablePreParseMultipartForm)
|
||||
}
|
||||
|
||||
func (c *Config) IsValid() error {
|
||||
if err := c.Http.IsValid(); err != nil {
|
||||
return fmt.Errorf("http configuration is invalid: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseServerConfiguration parses the configuration from the enabled lookupers
|
||||
func ParseServerConfiguration(ctx context.Context, logger *logrus.Logger) *Config {
|
||||
var cfg Config
|
||||
|
|
|
@ -101,3 +101,19 @@ func TestConfigSetDefaults(t *testing.T) {
|
|||
require.NotEmpty(t, cfg.Storage.DataDir)
|
||||
require.NotEmpty(t, cfg.Database.URL)
|
||||
}
|
||||
|
||||
func TestConfigIsValid(t *testing.T) {
|
||||
log := logrus.New()
|
||||
|
||||
t.Run("valid configuration", func(t *testing.T) {
|
||||
cfg := ParseServerConfiguration(context.TODO(), log)
|
||||
cfg.SetDefaults(log, false)
|
||||
require.NoError(t, cfg.IsValid())
|
||||
})
|
||||
|
||||
t.Run("invalid http root path", func(t *testing.T) {
|
||||
cfg := ParseServerConfiguration(context.TODO(), log)
|
||||
cfg.Http.RootPath = "/invalid"
|
||||
require.Error(t, cfg.IsValid())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -16,27 +16,27 @@
|
|||
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
<script src="assets/js/vue.min.js"></script>
|
||||
<script src="assets/js/url.min.js"></script>
|
||||
<script src="assets/js/vue.min.js" type="text/javascript"></script>
|
||||
<script src="assets/js/url.min.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<login-view v-if="isLoggedIn === false && loginRequired" @login-success="onLoginSuccess"></login-view>
|
||||
<div id="main-scene" v-else-if="isLoggedIn === true">
|
||||
<div id="main-sidebar">
|
||||
<a v-for="item in sidebarItems" :title="item.title" :class="{active: activePage === item.page}" @click="switchPage(item.page)">
|
||||
<i class="fas fa-fw" :class="item.icon"></i>
|
||||
</a>
|
||||
<div class="spacer"></div>
|
||||
<a title="Logout" @click="logout">
|
||||
<i class="fas fa-fw fa-sign-out-alt"></i>
|
||||
</a>
|
||||
</div>
|
||||
<keep-alive>
|
||||
<component :is="activePage" :active-account="activeAccount" :app-options="appOptions" @setting-changed="saveSetting"></component>
|
||||
</keep-alive>
|
||||
<custom-dialog v-bind="dialog" />
|
||||
<div id="main-sidebar">
|
||||
<a v-for="item in sidebarItems" :title="item.title" :class="{active: activePage === item.page}" @click="switchPage(item.page)">
|
||||
<i class="fas fa-fw" :class="item.icon"></i>
|
||||
</a>
|
||||
<div class="spacer"></div>
|
||||
<a title="Logout" @click="logout">
|
||||
<i class="fas fa-fw fa-sign-out-alt"></i>
|
||||
</a>
|
||||
</div>
|
||||
<keep-alive>
|
||||
<component :is="activePage" :active-account="activeAccount" :app-options="appOptions" @setting-changed="saveSetting"></component>
|
||||
</keep-alive>
|
||||
<custom-dialog v-bind="dialog"></custom-dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
24
testdata/nginx.conf
vendored
Normal file
24
testdata/nginx.conf
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
server {
|
||||
listen 8081;
|
||||
server_name localhost;
|
||||
|
||||
location /shiori/ {
|
||||
proxy_pass http://shiori:8080/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue