diff --git a/CHANGELOG.md b/CHANGELOG.md index bc85c34..5b42f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # CHANGELOG +## 2.2.6 - 2023/04/06 + +_Quick update for an outdated application to make it more useful for docker setups. Keep in mind that PHP 7.4 which is used by ts3web is still EOL!_ + +* Made it possible to use environment variable to define location of bootstrapping `env` file in docker containers (natively, set php-fpm `ENV[]` properly!) + * `ENV_DIR`: location of the **PARENT** folder which has the `env` file inside + * Falls back to application `$appDir/config/env` file if not set +* Added new `env` file variables to easily configure + * `log_dir`: location of the log dir, _without trailing slash_ + * `snapshot_dir` location of the snapshots dir, _without trailing slash_ + ## 2.2.5 - 2022/12/17 * Updated `Dockerfile` (as long as alpine 3.15 shipping PHP7 is kept updated, `ts3web` docker images are kept) * Updated some symfony dependencies diff --git a/Dockerfile b/Dockerfile index 312117f..6263606 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,12 @@ FROM alpine:3.15 -LABEL maintainer="Varakh " \ - description="ts3web" \ - org.opencontainers.image.authors="Varakh" \ - org.opencontainers.image.revision="${REVISION}" \ - org.opencontainers.image.vendor="Varakh" \ - org.opencontainers.image.title="ts3web" \ - org.opencontainers.image.description="ts3web" \ - org.opencontainers.image.base.name="alpine:3.15" \ - org.opencontainers.artifact.created=${CREATED} \ - org.opencontainers.image.source=${SOURCE_URL} +LABEL maintainer="Varakh" -ENV APP_HOME /var/www/html/application +ENV APP_HOME=/var/www/html/application \ + PHP_MEMORY_LIMIT=512M \ + MAX_UPLOAD=1024M \ + PHP_MAX_FILE_UPLOAD=200 \ + PHP_MAX_POST=1024M # setup folder structure RUN mkdir -p ${APP_HOME}/data/snapshots && \ @@ -19,6 +14,9 @@ RUN mkdir -p ${APP_HOME}/data/snapshots && \ touch ${APP_HOME}/log/application.log && \ mkdir -p ${APP_HOME}/config +# entrypoint +ADD docker/configure.php /configure.php + # add upstream application ADD src ${APP_HOME}/src ADD public ${APP_HOME}/public @@ -26,16 +24,11 @@ ADD composer.json ${APP_HOME}/composer.json ADD composer.lock ${APP_HOME}/composer.lock ADD data ${APP_HOME}/data ADD config ${APP_HOME}/config -RUN mv ${APP_HOME}/config/env.example ${APP_HOME}/config/env - -# php.ini -ENV PHP_MEMORY_LIMIT=512M \ - MAX_UPLOAD=1024M \ - PHP_MAX_FILE_UPLOAD=200 \ - PHP_MAX_POST=1024M # install dependencies -RUN apk add --update --no-cache \ +RUN cp ${APP_HOME}/config/env.example ${APP_HOME}/config/env && \ + apk add --update --no-cache \ + bash \ nginx \ s6 \ curl \ @@ -80,10 +73,13 @@ RUN apk add --update --no-cache \ # Add nginx config ADD docker/nginx.conf /etc/nginx/nginx.conf +# Add required environment variables to php-fpm +RUN echo "env[ENV_DIR]=%%%ENV_DIR%%%" >> /etc/php7/php-fpm.d/www.conf + EXPOSE 80 # add overlay ADD docker/s6 /etc/s6/ # expose start -CMD exec s6-svscan /etc/s6/ +CMD /usr/bin/php /configure.php && exec s6-svscan /etc/s6/ diff --git a/README.md b/README.md index 3592bb8..9b98af7 100644 --- a/README.md +++ b/README.md @@ -12,29 +12,211 @@ The minimalistic approach of this application is intentional. There are many TeamSpeak 3 web interfaces out. Why should I pick ts3web? Free, simple, stateless, easy to extend, standard bootstrap theme. -The main git repository is hosted at _[https://git.myservermanager.com/varakh/ts3web](https://git.myservermanager.com/varakh/ts3web)_. +The main git repository is hosted at +_[https://git.myservermanager.com/varakh/ts3web](https://git.myservermanager.com/varakh/ts3web)_. Other repositories are mirrors and pull requests, issues, and planning are managed there. Contributions are very welcome! +## Limitations + +TeamSpeak has a detailed interface for permissions and uploading files, therefore the following features are not +supported: + +* uploading files (only viewing and deleting, use the official client for uploading) +* editing permissions (only viewing, use the client for editing) + ## READ BEFORE USING -This web interface makes **heavy use of TeamSpeak 3 server query commands**. Please ensure that you _increase query +This web interface makes **heavy use of TeamSpeak 3 server query commands**. Please ensure that you _increase query limits_ and whitelist the requesting IP address to a `whitelist.txt` when in a docker environment (see below). -Please read the next FAQ section carefully! +Please read the next sections carefully. -## F.A.Q +## Setup + +_ts3web_ can be deployed natively or via docker. It's recommended to use docker with docker-compose. Those steps are +outlined below. + +### docker-compose + +General remarks: + +* By default, `/var/www/html/application/config/env` is used for bootstrapping necessary configuration, can be set to another parent directory with `ENV_DIR` in docker environment variable, e.g., `ENV_DIR=/data` +* By default, `/var/www/html/application/data/snapshots` is used for storing snapshots, path can be changed in the `env` file with `snapshot_dir` +* By default, `/var/www/html/application/log` is used for storing and reading logs, path can be changed in the `env` file with `log_dir` +* Other `env` configuration values are outlined in the [env.example](./config/env.example) file which is also present in the default docker image. + +It's recommended to use the `network=HOST` option for the docker setup, and it will be the only example in this `README` file. + +Let's create the docker volumes first. You could also use automatically generated ones by the `docker-compose` file, you +would need to remove the `external: true` in the `volumes` section of the `docker-compose.yml` then. + +Create the external volumes: + +```shell +docker volume create ts3-vol +docker volume create ts3web-vol +``` + +Paste the example `docker-compose.yml` into a file on your machine: + +```yaml +version: '2.1' +networks: + teamspeak: + external: false + +services: + app: + container_name: teamspeak_app + image: teamspeak:latest + volumes: + - ts3-vol:/var/ts3server + # ports are all public here in the HOST mode example + environment: + - TS3SERVER_LICENSE=accept + - TS3SERVER_IP_WHITELIST=/var/ts3server/whitelist.txt + restart: unless-stopped + network_mode: "host" + + web: + container_name: teamspeak_web + image: varakh/ts3web:latest + volumes: + - ts3web-vol:/data + environment: + # volume needs to contain the env file! + - ENV_DIR=/data + ports: + - 127.0.0.1:8181:80 + depends_on: + - app + restart: unless-stopped + networks: + - teamspeak + +volumes: + ts3-vol: + ts3web-vol: +``` + +Let's populate our docker volumes **before** we start! + +```shell +docker run -d --rm --name ts3web_creator -v ts3web-vol:/mnt alpine tail -f /dev/null +docker exec -it ts3web_creator sh + +# inside the container, edit the env by copying the example to the docker volume mount path at /data/env +cp /var/www/html/application/config/env /data/env + +# edit the env file to your liking +# +# the teamspeak_host should point to your public ip address and must be whitelisted inside the teamspeak server itself +vi env + +# create necessary directories and set permissions +mkdir -p /data/log +touch /data/log/application.log +mkdir -p /data/snapshots +chown -R 65534:65534 /data + +# exit the container +exit + +# on the host system, stop the creator container +docker stop ts3web_creator +``` + +Let's populate the teamspeak container with a proper `whitelist.txt` file. See [ensure that you're whitelisting the IP from which the webinterface will issue commands](#whitelisttextfile). + +```shell +docker run -d --rm --name ts3_creator -v ts3-vol:/mnt alpine tail -f /dev/null +docker exec -it ts3_creator sh + +# edit the whitelist.txt file at /var/ts3server/whitelist.txt +# it should contain the following entries +# +# 127.0.0.1 +# ::1 +# your-public-ip +# +vi /var/ts3server/whitelist.txt + +# exit the container +exit + +# on the host system, stop the creator container +docker stop ts3_creator +``` + +Maybe you like to copy valid license files into the `ts3-vol` docker volume before stopping. + +_Finally_, start the stack with `docker-compose up -d`. Please see the **Reverse proxy** section for a nginx example. + +### Reverse proxy + +Here's an example on how to configure a reverse proxy for the web interface docker container + +```shell +root .../public; +index index.php; + +# enable and setup if you have a certificate (highly recommended) +#ssl on; +#ssl_certificate fullchain.pem; +#ssl_certificate_key privkey.pem; + +rewrite_log on; + +location / { +try_files $uri $uri/ @ee; +} + +location @ee { +rewrite ^(.*) /index.php?$1 last; +} + +# php fpm +location ~ \.php$ { +fastcgi_split_path_info ^(.+\.php)(/.+)$; +fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; +include fastcgi_params; +} +``` + +## Native application + +**Prerequisite**: `php`, `composer` and probably `php-fpm` installed on the server. + +### Install + +* Clone repository +* Change directory to project home +* Execute `composer install` +* `composer install` +* Do the configuration by coping the `env.example` file (see information above) +* Use a web server _or_ run directly via the embedded PHP server: `php -S localhost:8080 -t public public/index.php`. +* Point your browser to [localhost:8080](http://localhost:8080) +* Apply any [whitelist.txt](#whitelist-text-file) changes if you configured `teamspeak_host` differently + than `localhost` + +### Upgrade + +* Change directory to project home +* `git pull` +* `composer update` + +## Troubleshooting / F.A.Q - ### How to overcome server query limit? You might get one of these messages: > I always get `flood client` message when clicking anywhere in the web interface. -The web UI uses query commands _a lot_! When your instance is up and running, you should be able to change the following +The web UI uses query commands _a lot_! When your instance is up and running, you should be able to change the following setting, e.g. directly in your database (MySQL or sqlite). ```ini @@ -44,193 +226,28 @@ serverinstance_serverquery_flood_time = 1 ``` - > I always get `TSException: Error: host isn't a ts3 instance!` when selecting a server. You're probably on a docker environment and the TeamSpeak server is queried through the web UI which -resides behind a web server, so the TeamSpeak server thinks that the _remote web server IP address_ invokes the query +resides behind a web server, so the TeamSpeak server thinks that the _remote web server IP address_ invokes the query commands and thus blacklists it. -You need define an exception for you server's IP in a [`whitelist.txt` file](#whitelist-text-file) and include it in +You need define an exception for you server's IP in a [`whitelist.txt`](#whitelisttextfile) file and include it in your TeamSpeak application. -You can also add the desired IP to `query_ip_allowlist.txt` and `query_ip_whitelist.txt` within the TeamSpeak 3 Server -data directory (in example it's `./ts3server` where your `docker-compose.yml` resides). +You can also add the desired IP to `query_ip_allowlist.txt` and `query_ip_whitelist.txt` within the TeamSpeak 3 Server +data directory. - ### I always get `no write permissions` or something similar when trying to save snapshots or when a log entry is created. -This probably happens when you're in the docker setup. Ensure that host binds have permissions set up properly. The user -which is used in the docker container is `nobody` with id `65534`. If, e.g. logs are host bound, then execute -`chown -R 65534:65534 host/path/to/log`. The same holds true for snapshots. +This probably happens when you're in the docker setup. Ensure that host binds have permissions set up properly and also files inside any +docker volume has the correct permissions. The user which is used in the docker container is `nobody` with id `65534`. -In the below `docker-compose.yml` file it's advised to execute the following command when you're in the _same_ directory -as the `docker-compose.yml` file resides in: `chown -R 65534:65534 env snapshots log`. +Change owner permissions recursively with `chown -R 65534:65534 /path/to/dir`. -## Configuration - -The main configuration file for the *web interface* is the `env` file located in `config/`. There's an example file -called `env.example` which you **need** to copy to `config/env`. Defaults will assume you're running your TeamSpeak -server on `localhost` with default port. Docker deployments can and *should* host bind this file into the container -directly and just maintain the `env` file. - -## Deployment - -The application can be deployed two different ways. See below for more information. For each deployment type a running -TeamSpeak 3 instance is a prerequisite. - -In the `docker-compose.yml` [example](#docker-compose), a setup together with a teamspeak server instance is shown. - -### Docker - -**Important. Read before setup!** - -- [README](#readme) - - [READ BEFORE USING](#read-before-using) - - [F.A.Q](#faq) - - [How to overcome server query limit?](#how-to-overcome-server-query-limit) - - [I always get `no write permissions` or something similar when trying to save snapshots or when a log entry is created.](#i-always-get-no-write-permissions-or-something-similar-when-trying-to-save-snapshots-or-when-a-log-entry-is-created) - - [Configuration](#configuration) - - [Deployment](#deployment) - - [Docker](#docker) - - [docker standalone](#docker-standalone) - - [docker-compose](#docker-compose) - - [whitelist text file](#whitelist-text-file) - - [As native PHP application](#as-native-php-application) - - [Install:](#install) - - [Upgrade:](#upgrade) - - [Reverse proxy](#reverse-proxy) - - [Limitations](#limitations) - - [Development](#development) - - [Release](#release) - - [Prepare next development cycle](#prepare-next-development-cycle) - - [Helpers](#helpers) - - [Translations](#translations) - - [Theme](#theme) - -#### docker standalone - -The following section outlines a manual setup. Feel free to use the provided `docker-compose.yml` as quick setup. - -1. Create docker volumes for `snapshots`, `log` and `env`. Alternative is to host bind them into your containers. -2. Create a docker network with a fixed IP range or later use host network. -3. Depending on your setup, you need to change `teamspeak_host` of your `env` file to point either to `your IP` or to a - `fixed docker IP` which your teamspeak uses. `localhost` is not valid if you're using it in docker. If you're unsure, - please take a look at the example `docker-compose.yml` files. -4. Start a container using the docker image `varakh/ts3web` and provide the following bindings for volumes: - * `{env_file_volume|host_file}:/var/www/html/applicationconfig/env` - * `{snapshot_volume|host_folder}:/var/www/html/application/data/snapshots` - * `{log_volume|host_folder}:/var/www/html/application/log` -5. [Ensure that you're whitelisting the IP from which the webinterface will issue commands.](#whitelist-text-file) -6. Run the `docker run` command including your settings, volumes and networks (if - any): `docker run --name teamspeak_web -v ./env:/var/www/html/application/config/env -p 8181:80 varakh/ts3web:latest` - . - -#### docker-compose - -In order for TeamSpeak to show correct IP and country flags, the `network_mode = "host"` is advised. It's also possible -to set everything up without using the host network mode and use fixed IPs. - -The examples will use host binds for volumes. Feel free to adapt the `docker-compose.yml` template and use docker -volumes instead if you like. - -Ensure to [apply permissions](#i-always-get-no-write-permissions-or-something-similar-when-trying-to-save-snapshots-or-when-a-log-entry-is-created) for volumes though. - -
- docker host mode example - -``` -version: '2.1' -networks: - teamspeak: - external: false -services: - app: - container_name: teamspeak_app - image: teamspeak:latest - volumes: - - ./ts3server:/var/ts3server - - ./whitelist.txt:/whitelist.txt - ports: - - 10011:10011 - - 30033:30033 - - 9987:9987/udp - environment: - - TS3SERVER_LICENSE=accept - - TS3SERVER_IP_WHITELIST=/whitelist.txt - restart: always - network_mode: "host" - web: - container_name: teamspeak_web - image: varakh/ts3web:latest - volumes: - - ./env:/var/www/html/application/config/env - - ./snapshots:/var/www/html/application/data/snapshots - - ./log:/var/www/html/application/log - ports: - - 127.0.0.1:8181:80 - depends_on: - - app - restart: always - networks: - - teamspeak -``` -
- - - -
- docker without host mode example - -``` -version: '2.1' -networks: - teamspeak: - driver: bridge - ipam: - config: - - subnet: 10.5.0.0/16 - gateway: 10.5.0.1 - -services: - app: - container_name: teamspeak_app - image: teamspeak:latest - volumes: - - ./ts3server:/var/ts3server - - ./whitelist.txt:/whitelist.txt - environment: - - TS3SERVER_LICENSE=accept - - TS3SERVER_IP_WHITELIST=/whitelist.txt - restart: always - ports: - - 10011:10011 - - 30033:30033 - - 9987:9987/udp - networks: - teamspeak: - ipv4_address: 10.5.0.5 - web: - container_name: teamspeak_web - image: varakh/ts3web:latest - volumes: - - ./env:/var/www/html/application/config/env - - ./snapshots:/var/www/html/application/data/snapshots - - ./log:/var/www/html/application/log - ports: - - 127.0.0.1:8181:80 - depends_on: - - app - restart: always - networks: - teamspeak: - ipv4_address: 10.5.0.6 - -``` -
- -#### whitelist text file + +### What's a whitelist.txt and why do I need it? The following illustrates a valid `whitelist.txt` file which can be used for the above `docker-compose` setups. You need to replace `your-public-ip` with the TeamSpeak's public IP address if required or remove the fixed internal docker IP if @@ -243,81 +260,9 @@ you're on 'host' mode. your-public-ip ``` -Now execute `docker-compose up -d` to start those containers. If you like to update, do `docker-compose down`, -`docker-compose pull` and then `docker-compose up -d` again. - -Your TeamSpeak 3 Server will be available under `public-server-ip:9987`. The web interface will be available on -`127.0.0.1:8181`. You need to add a [reverse proxy](#reverseproxy) and probably you also want SSL configured if you -expose it via domain. For testing purposes, change `- 127.0.0.1:8181:80` to `- 8181:80`. The web interface will then be -available under -`public-server-ip:8181`. - -This is **not recommended**! Secure your setup properly via [reverse proxy and SSL](#reverse-proxy). - -### As native PHP application - -**Prerequisite**: `php`, `composer` and probably `php-fpm` installed on the server. - -#### Install: - -* Clone repository -* Change directory to project home -* Execute `composer install` -* `composer install` -* Do the configuration by coping the `env.example` file (see information above) -* Use a web server _or_ run directly via the embedded PHP server: `php -S localhost:8080 -t public public/index.php`. -* Point your browser to [localhost:8080](http://localhost:8080) -* Apply any [whitelist.txt](#whitelist-text-file) changes if you configured `teamspeak_host` differently - than `localhost` - -#### Upgrade: - -* Change directory to project home -* `git pull` -* `composer update` - -### Reverse proxy - -Here's an example on how to configure a reverse proxy for the web interface docker container - - ``` - root .../public; - index index.php; - - # enable and setup if you have a certificate (highly recommended) - #ssl on; - #ssl_certificate fullchain.pem; - #ssl_certificate_key privkey.pem; - - rewrite_log on; - - location / { - try_files $uri $uri/ @ee; - } - - location @ee { - rewrite ^(.*) /index.php?$1 last; - } - - # php fpm - location ~ \.php$ { - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; - include fastcgi_params; - } - ``` - -## Limitations - -TeamSpeak has a detailed interface for permissions and uploading files, therefore the following features are not -supported: - -* uploading files (only viewing and deleting, use the official client for uploading) -* editing permissions (only viewing, use the client for editing) - ## Development -If you're willing to contribute, here's some information. +Contributions are welcome! ### Release diff --git a/config/Constants.php b/config/Constants.php index 7943499..2b6dac8 100644 --- a/config/Constants.php +++ b/config/Constants.php @@ -13,7 +13,7 @@ class Constants /** * Version tag */ - const VERSION = '2.2.5'; + const VERSION = '2.2.6'; /** * Return constant by its class name diff --git a/config/EnvConstants.php b/config/EnvConstants.php index 41998b2..3ef2de0 100644 --- a/config/EnvConstants.php +++ b/config/EnvConstants.php @@ -8,12 +8,27 @@ class EnvConstants /** * Example env file */ - const ENV_FILE_EXAMPLE = "env.example"; + const FILE_NAME_EXAMPLE_ENV = "env.example"; /** * Custom env file */ - const ENV_FILE = "env"; + const FILE_NAME_ENV = "env"; + + /** + * The path to the env file + */ + const ENV_DIR = "ENV_DIR"; + + /** + * The path to the logs directory + */ + const LOG_DIR = "log_dir"; + + /** + * The path to the snapshots directory + */ + const SNAPSHOT_DIR = "snapshot_dir"; /** * Site title @@ -31,7 +46,7 @@ class EnvConstants const SITE_DATE_FORMAT = "site_date_format"; /** - * THeme + * Theme */ const THEME = "theme"; @@ -86,4 +101,4 @@ class EnvConstants EnvConstants::LOG_NAME, EnvConstants::LOG_LEVEL ]; -} \ No newline at end of file +} diff --git a/config/env.example b/config/env.example index 7276a34..515b3bd 100644 --- a/config/env.example +++ b/config/env.example @@ -8,12 +8,16 @@ theme="bootstrap4" # values: bootstrap4 (foldernames are used to determine theme theme_cache=false # values: true|false (cache view/twig. makes it faster, disable for debug) # teamspeak -teamspeak_host="localhost" # 'localhost' or 'name_of_docker_container' if running locally +teamspeak_host="app" # 'localhost' or 'name_of_docker_container|name_of_the_docker-compose_service' if running locally teamspeak_query_port=10011 teamspeak_user="serveradmin" teamspeak_tree_view="true" # show a tree view in the details of online clients if a server has been selected teamspeak_log_lines=100 # show this amount of latest log lines # log +log_dir=/var/www/html/application/log log_name="ts3web" # values: all strings -log_level="INFO" # values: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY \ No newline at end of file +log_level="INFO" # values: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY + +# snapshots +snapshot_dir=/var/www/html/application/data/snapshots diff --git a/docker/configure.php b/docker/configure.php new file mode 100644 index 0000000..0c3a162 --- /dev/null +++ b/docker/configure.php @@ -0,0 +1,22 @@ +#!/usr/bin/env php +info("Starting ts3web version " . Constants::VERSION); $container['logger'] = function () use ($logger) { return $logger; diff --git a/src/Control/Actions/SnapshotCreateAction.php b/src/Control/Actions/SnapshotCreateAction.php index 89abeb3..6baebec 100644 --- a/src/Control/Actions/SnapshotCreateAction.php +++ b/src/Control/Actions/SnapshotCreateAction.php @@ -19,7 +19,7 @@ final class SnapshotCreateAction extends AbstractAction $fileSystem = new Filesystem(); $name = Carbon::now()->getTimestamp(); - $path = FileHelper::SNAPSHOTS_PATH . DIRECTORY_SEPARATOR . $sid . DIRECTORY_SEPARATOR . $name; + $path = FileHelper::getSnapshotsDir() . DIRECTORY_SEPARATOR . $sid . DIRECTORY_SEPARATOR . $name; if ($fileSystem->exists($path)) { $this->flash->addMessage('error', $this->translator->trans('file.exists')); @@ -35,4 +35,4 @@ final class SnapshotCreateAction extends AbstractAction return $response->withRedirect('/snapshots/' . $sid); } -} \ No newline at end of file +} diff --git a/src/Control/Actions/SnapshotDeleteAction.php b/src/Control/Actions/SnapshotDeleteAction.php index 380680e..a827fbf 100644 --- a/src/Control/Actions/SnapshotDeleteAction.php +++ b/src/Control/Actions/SnapshotDeleteAction.php @@ -16,14 +16,14 @@ final class SnapshotDeleteAction extends AbstractAction $this->ts->getInstance()->selectServer($sid, 'serverId'); $fileSystem = new Filesystem(); - $path = FileHelper::SNAPSHOTS_PATH . DIRECTORY_SEPARATOR . $sid . DIRECTORY_SEPARATOR . $name; + $path = FileHelper::getSnapshotsDir() . DIRECTORY_SEPARATOR . $sid . DIRECTORY_SEPARATOR . $name; if (!$fileSystem->exists($path)) { $this->flash->addMessage('error', $this->translator->trans('file.notexists')); } else { try { $fileSystem->remove($path); - $serverPath = FileHelper::SNAPSHOTS_PATH . DIRECTORY_SEPARATOR . $sid; + $serverPath = FileHelper::getSnapshotsDir() . DIRECTORY_SEPARATOR . $sid; if (count(FileHelper::getFiles($serverPath)) == 0) { $fileSystem->remove($serverPath); diff --git a/src/Control/Actions/SnapshotDeployAction.php b/src/Control/Actions/SnapshotDeployAction.php index 62909c1..6c01d69 100644 --- a/src/Control/Actions/SnapshotDeployAction.php +++ b/src/Control/Actions/SnapshotDeployAction.php @@ -15,7 +15,7 @@ final class SnapshotDeployAction extends AbstractAction $this->ts->getInstance()->selectServer($sid, 'serverId'); $fileSystem = new Filesystem(); - $path = FileHelper::SNAPSHOTS_PATH . DIRECTORY_SEPARATOR . $sid . DIRECTORY_SEPARATOR . $name; + $path = FileHelper::getSnapshotsDir() . DIRECTORY_SEPARATOR . $sid . DIRECTORY_SEPARATOR . $name; if (!$fileSystem->exists($path)) { $this->flash->addMessage('error', $this->translator->trans('file.notexists')); @@ -32,4 +32,4 @@ final class SnapshotDeployAction extends AbstractAction return $response->withRedirect('/snapshots/' . $sid); } -} \ No newline at end of file +} diff --git a/src/Control/Actions/SnapshotsAction.php b/src/Control/Actions/SnapshotsAction.php index ed41134..164f829 100644 --- a/src/Control/Actions/SnapshotsAction.php +++ b/src/Control/Actions/SnapshotsAction.php @@ -12,7 +12,7 @@ final class SnapshotsAction extends AbstractAction $this->ts->login($this->auth->getIdentity()['user'], $this->auth->getIdentity()['password']); $this->ts->getInstance()->selectServer($sid, 'serverId'); - $snapshots = FileHelper::getFiles(FileHelper::SNAPSHOTS_PATH . DIRECTORY_SEPARATOR . $sid); + $snapshots = FileHelper::getFiles(FileHelper::getSnapshotsDir() . DIRECTORY_SEPARATOR . $sid); $this->view->render($response, 'snapshots.twig', [ 'title' => $this->translator->trans('snapshots.title'), @@ -20,4 +20,4 @@ final class SnapshotsAction extends AbstractAction 'sid' => $sid ]); } -} \ No newline at end of file +} diff --git a/src/Util/BootstrapHelper.php b/src/Util/BootstrapHelper.php index 65b40c8..499e742 100644 --- a/src/Util/BootstrapHelper.php +++ b/src/Util/BootstrapHelper.php @@ -22,20 +22,39 @@ class BootstrapHelper */ public static function bootEnvironment() { - $envPath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config'; - $envFileExample = $envPath . DIRECTORY_SEPARATOR . EnvConstants::ENV_FILE_EXAMPLE; - $envFile = $envPath . DIRECTORY_SEPARATOR . EnvConstants::ENV_FILE; + $envDir = getenv(EnvConstants::ENV_DIR, true); + $externalEnvDir = true; - try { - $fileSystem = new Filesystem(); - if (!$fileSystem->exists($envFile)) { - $fileSystem->copy($envFileExample, $envFile); - } - } catch (IOException $e) { - die('Could not copy example env file ' . $envFileExample . ' to ' . $envFile); + if ($envDir === false) { + $envDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config'; + $externalEnvDir = false; } - $env = new Dotenv($envPath, EnvConstants::ENV_FILE); + $envFile = $envDir . DIRECTORY_SEPARATOR . EnvConstants::FILE_NAME_ENV; + + if ($externalEnvDir === false) { + $envFileFallback = $envDir . DIRECTORY_SEPARATOR . EnvConstants::FILE_NAME_EXAMPLE_ENV; + + try { + $fileSystem = new Filesystem(); + if (!$fileSystem->exists($envFile)) { + $fileSystem->copy($envFileFallback, $envFile); + } + } catch (IOException $e) { + die('Could not copy example env file ' . $envFileFallback . ' to ' . $envFile); + } + } else { + try { + $fileSystem = new Filesystem(); + if (!$fileSystem->exists($envFile)) { + die('env file ' . $envFile . ' does not exist'); + } + } catch (IOException $e) { + die('Could determine env file ' . $envFile); + } + } + + $env = new Dotenv($envDir, EnvConstants::FILE_NAME_ENV); $res = $env->load(); try { @@ -142,7 +161,13 @@ class BootstrapHelper */ public static function getLogDir() { - return __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'log'; + $logDir = getenv(EnvConstants::LOG_DIR); + + if ($logDir === false) { + return __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'log'; + } + + return $logDir; } /** @@ -154,4 +179,4 @@ class BootstrapHelper { return self::getLogDir() . DIRECTORY_SEPARATOR . 'application.log'; } -} \ No newline at end of file +} diff --git a/src/Util/FileHelper.php b/src/Util/FileHelper.php index 9071da9..33fb648 100644 --- a/src/Util/FileHelper.php +++ b/src/Util/FileHelper.php @@ -1,15 +1,31 @@ host = getenv(EnvConstants::TEAMSPEAK_HOST); $this->queryPort = getenv(EnvConstants::TEAMSPEAK_QUERY_PORT); + $this->logger->debug(sprintf('Trying to connect to to %s:%s', $this->host, $this->queryPort)); + $ts = new ts3admin($this->host, $this->queryPort); $ts = new TS3AdminProxy($ts, $logger);