From 45bd4d693f5e3f3cd3afdf25538bcb7e39fbf2f7 Mon Sep 17 00:00:00 2001 From: Felipe Martin <812088+fmartingr@users.noreply.github.com> Date: Wed, 1 Jan 2025 16:22:30 +0100 Subject: [PATCH] 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() --- Makefile | 5 ----- docker-compose.yaml | 23 +++++++++++++++++--- docs/Contribute.md | 38 +++++++++++++++++++++++++++------- internal/cmd/root.go | 4 ++++ internal/config/config.go | 16 ++++++++++++++ internal/config/config_test.go | 16 ++++++++++++++ internal/view/index.html | 30 +++++++++++++-------------- testdata/nginx.conf | 24 +++++++++++++++++++++ 8 files changed, 125 insertions(+), 31 deletions(-) create mode 100644 testdata/nginx.conf diff --git a/Makefile b/Makefile index bbac69fae..0588088a4 100644 --- a/Makefile +++ b/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: diff --git a/docker-compose.yaml b/docker-compose.yaml index 96fd9d73d..444ca2789 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -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: diff --git a/docs/Contribute.md b/docs/Contribute.md index ca0d7c65b..6cef5a55a 100644 --- a/docs/Contribute.md +++ b/docs/Contribute.md @@ -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. diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 88b2dde48..48586c9f6 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -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") diff --git a/internal/config/config.go b/internal/config/config.go index 5b7aa96f8..f62769410 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -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 diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 36f22717a..4c18e2f79 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -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()) + }) +} diff --git a/internal/view/index.html b/internal/view/index.html index c23f677a0..aba8a7ffb 100644 --- a/internal/view/index.html +++ b/internal/view/index.html @@ -16,27 +16,27 @@ - - + +