commit abdc6b1c58f2ebec226ccb6654c4ce4186ce00c0 Author: CrazyMax Date: Thu Feb 1 20:36:09 2018 +0100 Initial version based on JetBrains License Server 15802 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3025277 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[{Dockerfile,*.sh,*.yml}] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98df5db --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Jetbrains +/.idea +/*.iml + +# App +/.dev diff --git a/.res/jetbrains-license-server_docker.png b/.res/jetbrains-license-server_docker.png new file mode 100644 index 0000000..6e8c985 Binary files /dev/null and b/.res/jetbrains-license-server_docker.png differ diff --git a/.res/paypal.png b/.res/paypal.png new file mode 100644 index 0000000..620804c Binary files /dev/null and b/.res/paypal.png differ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3c46c60 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,59 @@ +sudo: required + +services: + - docker + +env: + global: + - VERSION=15802 + - GITHUB_REPO=crazy-max/docker-jetbrains-license-server + - DOCKER_USERNAME=crazymax + - DOCKER_REPONAME=jetbrains-license-server + - DOCKER_VERSION=17.12.0~ce-0~ubuntu + - COMPOSE_VERSION=1.18.0 + - secure: JwfXiiIM4c6E+80O6XHQBhw6IdkerfGxlKo+YHvmtkHyz5Fvpc1ZRvWSZYHZhxE1gocThbKUCy4GsgIyiq+dsER27kdAnnvp6JLw8SZ5OSqtOOLjqCKilN2hwFaS/g6Xc3mGvTo+4ScAc9CDJamDCwGY+6r2g/+IdmCbgqOo8yaD4VkhP4eVB3f4el6F7jEwjo626QDzFZ1LVS0qmmeVBSU+xxfL5HolG+j//hLQ/49XIIGnsWtQmHbX1u2trSESyNRTFdY/KZ7qaW8l+BgLhplKu+YXAExb1POGcKJnffSJjCl22ggX1JUHANMgrcQfZe2DKkUJFqr8FvTCktj+lfAuMYwl3k24zcZHe8eTyBFh8YLs7pn++tOFWg0XcKCWO9vzHgbTf/m95F6tpDMx4Y49jRclJIslxkjf8YIuNvDOO4kPKp2bw4ymqjsayPLx3P4xB8vgvyAZeFBQevUkh3ia/3uCfwEwzWimlT1FTeDUj8h4A9y+zRy/AqGf35LneC/Sbwt5dNaCujAwOGFeCvTp43uYd10S5Rz026ecH/8XlcHzuH4+nUvXDnesRI79+6NkaKl8PdcTx0ZC44jIAULn60rur5ybNkQmv5GWjem1C24izosPuC8bLHYY6BSRPn+vacNZH9SYTw2wHiVunxZORWz4FsYAidFkoaygt9E= # DOCKER_PASSWORD + - secure: CRv5ONsqQ7WPkj/AzVId/EnQJVLcnlrAtCACsPisKWgA6QMACaIeVMKrSLP16/GyvERLmyzIGhIlprfmpiNkPeKlzGpJZBjvQ9gyK6YbexITEFjoBOH+rc27kFALCSKxGhr8m+BpHHmcGqCr79v7bFXE0p5TVFn00WbP7CfDjqAiwpcCF1JSDzA0e1mpHk3z7JXceQg9cdhPmhb1GiPMgbONSeTO3ASA9Hmi2JpwYCMaFcDsevVAA+eKSrQEkjYU3L0O4BRVlxUlWHYPSUEZ7vUlgH2imca6pD/WFYEzULj72MLeI9hpLkuXYUVaxLCBPiNoLKCyMIDsAiq5zyhmQyJFFjPo2l/JTKwtO8JCXR7B6sYp8j5gIir4Izbpm8r6VC8SBtafNcgynfehqs9Ov0yBsKKogo3fb/dSWdwANf36jQ766HaBQkp9NN0PFMLzbeXHaQA248MOP6ObqKsFg1c4iJ1UCY9A59hAUyXT+yAm0Y4auxq21/FEZ8pZFqan5qNaxvo0dP8WfeoVdsQAdZ3u7T4wtsxsO8PWKUA4FEoC3Ic9g5DBVte4SQJ5n6Ni2+DFnq4PZhBdCVwWnHh648sUfKncHdmbqTnIq6bN+RI9ZlY8MyeRKVVbbDU9mrmdM2aWlTeu4HQWd7J6ErHrTRDgkRJxKGbPDUemkX4Nhws= # GITHUB_TOKEN + +before_install: + - sudo apt-get update + - sudo apt-cache madison docker-ce + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce=${DOCKER_VERSION} + - docker --version + - curl -L https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose + - chmod +x docker-compose + - sudo mv docker-compose /usr/local/bin + - docker-compose --version + - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi) + - export DOCKER_TAG=$(if [ "$BRANCH" == "master" ]; then echo "latest"; else echo $BRANCH; fi) + - export WAN_IP=$(dig +short myip.opendns.com @resolver1.opendns.com) + - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH, DOCKER_TAG=$DOCKER_TAG" + +install: + - | + docker build --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + --build-arg VCS_REF=${TRAVIS_COMMIT::8} \ + --build-arg VERSION=${VERSION} \ + -t $DOCKER_USERNAME/$DOCKER_REPONAME . + +before_script: + - docker run -d -e JLS_VIRTUAL_HOSTS=$WAN_IP --name $DOCKER_REPONAME $DOCKER_USERNAME/$DOCKER_REPONAME + - sleep 20 + - docker logs $DOCKER_REPONAME + +script: + - docker ps | grep $DOCKER_REPONAME + +after_success: + - test $TRAVIS_PULL_REQUEST = false + && echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin + && docker tag $DOCKER_USERNAME/$DOCKER_REPONAME $DOCKER_USERNAME/$DOCKER_REPONAME:$DOCKER_TAG + && docker tag $DOCKER_USERNAME/$DOCKER_REPONAME $DOCKER_USERNAME/$DOCKER_REPONAME:$VERSION + && docker push $DOCKER_USERNAME/$DOCKER_REPONAME + +branches: + except: + - /^[0-9]/ + +notifications: + webhooks: + secure: aSAfpOXZ2sZF4lR+e0Pi8O1/ePVft0wwSQm6L2nugmk+bIkZO/iC+SaNTK1rbbiba/zEjSmxvtA+3Sx+Sw9eOPZaP3sm6PvaVycukmZeUeVMlDUDDiV1xKshAisYuheVSO4kvRFzqoSo/IwClukHbGtYO9bquxgfy+Nan5wkzx0rzFDNsSChDbAEcnZKXxSrXSlOYVtY1fRcBTq52BwnBJzE4+6zDDNJz47sJY3dhAToodOpg+LkiX6b8kY8iAtEf25HKGrJ+O7mGLJOrtZmHLBQXAhcMHLNGtajuP3xZe/1Nq/rezRzbD/Tv7breXoIABnHR6y7oGf2Iry46Uzeg758AEYNU4FymD2sDz1zF1362OFBDq50pZm/MG2K4YqrKcWoy+TzCm4+H/XzsXG1jootRj2vsy1/QFL6zI/vVk6ZsN2ISSEFrJ2T/SZZWHxhYihGemfaSLoLZ0o316KrJxmzj37YucYjJYY/b+iAQruAFPJLd3vtanHfTaFQdUiXJdU7rrolESKI1zg/1cx5rV8PrnUZJXrSNATXgoyXsEvDRsdekHg8w+6ml6OenhgrNoJYG1c+GFtCf/cUaKe9bw6WniiqXtgw75Tdz0BqzNTu9BibhnDdeKYFBzT6wgsBRs47fgWcnmy++CryMvWymTdiiDnTaljUGB/rikA9QTk= diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d459fc8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 15802-RC1 (2018/02/01) + +* Initial version based on JetBrains License Server 15802 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0364fd1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,44 @@ +FROM openjdk:8-jre-alpine +MAINTAINER CrazyMax + +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION + +LABEL org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.name="jetbrains-license-server" \ + org.label-schema.description="JetBrains License Server image based on Alpine" \ + org.label-schema.version=$VERSION \ + org.label-schema.url="https://github.com/crazy-max/docker-jetbrains-license-server" \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-url="https://github.com/crazy-max/docker-jetbrains-license-server" \ + org.label-schema.vendor="CrazyMax" \ + org.label-schema.schema-version="1.0" + +RUN apk --update --no-cache add \ + ca-certificates curl libressl nginx supervisor tzdata zip \ + && rm -rf /var/cache/apk/* /tmp/* + +ENV JLS_PATH="/opt/jetbrains-license-server" \ + JLS_VERSION="15802" \ + JLS_SHA256="e0030be1fd06e2db19576363a388d8b84e7b33c9d48c54f0cfcdc032ddd96181" + +RUN mkdir -p "$JLS_PATH" "/data/registration" "/run/nginx" \ + && curl -L "https://download.jetbrains.com/lcsrv/license-server-installer.zip" -o "/tmp/lsi.zip" \ + && echo "$JLS_SHA256 /tmp/lsi.zip" | sha256sum -c - | grep OK \ + && unzip "/tmp/lsi.zip" -d "$JLS_PATH" \ + && rm -f "/tmp/lsi.zip" \ + && find "$JLS_PATH" -type f -exec chmod 644 {} \; \ + && chmod a+x "$JLS_PATH/bin/license-server.sh" \ + && ln -sf "$JLS_PATH/bin/license-server.sh" "/usr/local/bin/license-server" \ + && ln -sf "/data/registration" "/root/.jb-license-server" \ + && touch "/data/access-config.json" + +ADD entrypoint.sh /entrypoint.sh +ADD assets / + +EXPOSE 80 +VOLUME [ "/data" ] + +ENTRYPOINT [ "/entrypoint.sh" ] +CMD [ "/usr/bin/supervisord", "-c", "/etc/supervisord.conf" ] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..29b1e96 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 CrazyMax + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5d9be43 --- /dev/null +++ b/README.md @@ -0,0 +1,105 @@ +

+ +

+ Version + Build Status + Docker Stars + Docker Pulls + Say Thanks + Donate Paypal +

+ +## About + +🐳 [Jetbrains License Server](https://www.jetbrains.com/help/license_server/getting_started.html) Docker image based on Alpine Linux.
+If you are interested, [check out](https://hub.docker.com/r/crazymax/) my other 🐳 Docker images! + +## Features + +### Included + +* Nginx reverse proxy +* License server completely customizable via environment variables +* Registration data and configuration in a single directory + +### From docker-compose + +* Reverse proxy with [nginx-proxy](https://github.com/jwilder/nginx-proxy) +* Creation/renewal of Let's Encrypt certificates automatically with [letsencrypt-nginx-proxy-companion](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion) + +## Docker + +### Environment variables + +* `TZ` : The timezone assigned to the container (default to `UTC`) +* `JLS_VIRTUAL_HOSTS` : [Virtual hosts](https://www.jetbrains.com/help/license_server/setting_host_and_port.html#d1010e63) where license server will be available (required ; comma delimited for several hosts) +* `JLS_ACCESS_CONFIG` : JSON file to configure [user restrictions](https://www.jetbrains.com/help/license_server/configuring_user_restrictions.html) (default to `/data/access-config.json`) +* `JLS_STATS_RECIPIENTS` : [Reports recipients](https://www.jetbrains.com/help/license_server/detailed_server_usage_statistics.html#d461e40) email addresses for stats (comma delimited) +* `JLS_SMTP_SERVER` : SMTP server host to use for sending [stats](https://www.jetbrains.com/help/license_server/detailed_server_usage_statistics.html) (stats disabled if empty) +* `JLS_SMTP_PORT` : SMTP server port (default to `25`) +* `JLS_SMTP_USERNAME` : SMTP username (auth disabled if empty) +* `JLS_SMTP_PASSWORD` : SMTP password (auth disabled if empty) +* `JLS_STATS_FROM` : [From address](https://www.jetbrains.com/help/license_server/detailed_server_usage_statistics.html#d461e40) for stats emails +* `JLS_STATS_TOKEN` : Enables an auth token for the [stats API](https://www.jetbrains.com/help/license_server/detailed_server_usage_statistics.html#d461e312) at `/reportApi` (HTTP POST) + +### Volumes + +* `/data` : Contains [registration data](https://www.jetbrains.com/help/license_server/migrate.html) and configuration + +### Ports + +* `80` : HTTP port + +## Usage + +Docker compose is the recommended way to run this image. You can use the following [docker compose template](docker-compose.yml), then run the container : + +```bash +docker-compose up -d +docker-compose logs -f +``` + +Or use the following minimal command : + +```bash +$ docker run -d -p 8000:80 --name jetbrains-license-server \ + -e TZ="Europe/Paris" \ + -e JLS_VIRTUAL_HOSTS=jetbrains-license-server.example.com \ + -v $(pwd)/data:/data \ + crazymax/jetbrains-license-server:latest +``` + +## Update + +You can update Matomo automatically through the UI, it works well. But i recommend to recreate the container whenever i push an update : + +```bash +docker-compose pull +docker-compose up -d +``` + +## Troubleshooting + +If you have any trouble using the license server, check the official [Troubleshooting page](https://www.jetbrains.com/help/license_server/troubleshooting.html) of Jetbrains. + +### Error 403 Passed value of header "Host" is not allowed + +If you've got the following message : + +``` +Passed value of header "Host" is not allowed. Please contact your license server administrator. +``` + +That's because the license server is running behind the Nginx reverse proxy. Please configure virtual hosts using the `JLS_VIRTUAL_HOSTS` variable. + +## How can i help ? + +We welcome all kinds of contributions :raised_hands:!
+The most basic way to show your support is to star :star2: the project, or to raise issues :speech_balloon:
+Any funds donated will be used to help further development on this project! :gift_heart: + +[![Donate Paypal](.res/paypal.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3BXL8EBDJALHQ) + +## License + +MIT. See `LICENSE` for more details. diff --git a/assets/etc/nginx/nginx.conf b/assets/etc/nginx/nginx.conf new file mode 100644 index 0000000..2e524d2 --- /dev/null +++ b/assets/etc/nginx/nginx.conf @@ -0,0 +1,36 @@ +daemon off; +user nginx; +error_log stderr error; + +events { + worker_connections 2048; + use epoll; +} + +http { + include mime.types; + default_type application/octet-stream; + + aio threads; + sendfile on; + keepalive_timeout 15; + keepalive_disable msie6; + keepalive_requests 100; + tcp_nopush on; + tcp_nodelay on; + server_tokens off; + gzip off; + + # https://www.jetbrains.com/help/license_server/configuring_secure_connection.html + server { + listen 80; + location / { + proxy_set_header X-Forwarded-Host $http_host; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:8080/; + } + } +} diff --git a/assets/etc/supervisord.conf b/assets/etc/supervisord.conf new file mode 100644 index 0000000..bd09ea1 --- /dev/null +++ b/assets/etc/supervisord.conf @@ -0,0 +1,25 @@ +[supervisord] +nodaemon=true +pidfile=/var/run/supervisord.pid + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock + +[unix_http_server] +file=/var/run/supervisor.sock + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[program:license-server] +priority=1 +command=/usr/local/bin/license-server run +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +redirect_stderr=true + +[program:nginx] +command=/usr/sbin/nginx +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +redirect_stderr=true diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0fd3650 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,53 @@ +version: '3' + +services: + proxy: + image: jwilder/nginx-proxy:alpine + labels: + - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true + ports: + - 80:80 + - 443:443 + volumes: + - ./proxy/conf.d:/etc/nginx/conf.d:rw + - ./proxy/vhost.d:/etc/nginx/vhost.d:rw + - ./proxy/html:/usr/share/nginx/html:rw + - ./proxy/certs:/etc/nginx/certs:ro + - /etc/localtime:/etc/localtime:ro + - /var/run/docker.sock:/tmp/docker.sock:ro + restart: always + + letsencrypt: + image: jrcs/letsencrypt-nginx-proxy-companion + depends_on: + - proxy + volumes: + - ./proxy/certs:/etc/nginx/certs:rw + - ./proxy/vhost.d:/etc/nginx/vhost.d:rw + - ./proxy/html:/usr/share/nginx/html:rw + - /etc/localtime:/etc/localtime:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + restart: always + + app: + image: crazymax/jetbrains-license-server:latest + depends_on: + - letsencrypt + - proxy + volumes: + - ./data:/data + environment: + - TZ=Europe/Paris + - JLS_VIRTUAL_HOSTS=jetbrains-license-server.example.com,an-other-host.example.com + - JLS_ACCESS_CONFIG=/data/access-config.json + - JLS_STATS_RECIPIENTS=webmaster@example.com,an-other-address@example.com + - JLS_SMTP_SERVER=smtp.example.com + - JLS_SMTP_PORT=25 + - JLS_SMTP_USERNAME=smtp@example.com + - JLS_SMTP_PASSWORD= + - JLS_STATS_FROM=jetbrains@example.com + - JLS_STATS_TOKEN=1BFC67F51AAF99E85C2347B72E62C + - VIRTUAL_HOST=jetbrains-license-server.example.com + - LETSENCRYPT_HOST=jetbrains-license-server.example.com + - LETSENCRYPT_EMAIL=webmaster@example.com + restart: always diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..8e038af --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +JLS_PATH="/opt/jetbrains-license-server" +JLS_LISTEN_ADDRESS="127.0.0.1" +JLS_PORT=8080 +JLS_ACCESS_CONFIG=${JLS_ACCESS_CONFIG:-"/data/access-config.json"} + +# https://www.jetbrains.com/help/license_server/setting_host_and_port.html +echo "Configuring Jetbrains License Server..." +license-server configure --listen ${JLS_LISTEN_ADDRESS} --port ${JLS_PORT} + +# https://www.jetbrains.com/help/license_server/setting_host_and_port.html +if [ ! -z "$JLS_VIRTUAL_HOSTS" ] ; then + echo "Following virtual hosts will be used :" + for JLS_VIRTUAL_HOST in $(echo ${JLS_VIRTUAL_HOSTS} | tr "," "\n"); do + echo "-> ${JLS_VIRTUAL_HOST}" + done + license-server configure --jetty.virtualHosts.names=${JLS_VIRTUAL_HOSTS} +fi + +# https://www.jetbrains.com/help/license_server/configuring_user_restrictions.html +if [ -s "$JLS_ACCESS_CONFIG" ]; then + echo "Enabling user restrictions access from $JLS_ACCESS_CONFIG..." + license-server configure --access.config=file:${JLS_ACCESS_CONFIG} +fi + +# https://www.jetbrains.com/help/license_server/detailed_server_usage_statistics.html +if [ ! -z "$JLS_SMTP_SERVER" -a ! -z "$JLS_STATS_RECIPIENTS" ] ; then + JLS_SMTP_PORT=${JLS_SMTP_PORT:-"25"} + echo "Enabling User Reporting via SMTP at $JLS_SMTP_SERVER:$JLS_SMTP_PORT..." + license-server configure --smtp.server ${JLS_SMTP_SERVER} --smtp.server.port ${JLS_SMTP_PORT} + + if [ ! -z "$JLS_SMTP_USERNAME" -a ! -z "$JLS_SMTP_PASSWORD" ] ; then + echo "Using SMTP username $JLS_SMTP_USERNAME with password..." + license-server configure --smtp.server.username ${JLS_SMTP_USERNAME} + license-server configure --smtp.server.password ${JLS_SMTP_PASSWORD} + fi + + if [ ! -z "$JLS_STATS_FROM" ] ; then + echo "Setting stats sender to $JLS_STATS_FROM..." + license-server configure --stats.from ${JLS_STATS_FROM} + fi + + echo "Stats recipients: $JLS_STATS_RECIPIENTS..." + license-server configure --stats.recipients ${JLS_STATS_RECIPIENTS} +fi + +# https://www.jetbrains.com/help/license_server/detailed_server_usage_statistics.html +if [ ! -z "$JLS_STATS_TOKEN" ] ; then + echo "Enabling stats via API at /$JLS_STATS_TOKEN..." + license-server configure --reporting.token ${JLS_STATS_TOKEN} +fi + +exec "$@"