diff --git a/Deploy/Readme.md b/Deploy/Readme.md new file mode 100644 index 00000000..8600267b --- /dev/null +++ b/Deploy/Readme.md @@ -0,0 +1,24 @@ +Docker Compose +############## + +To run Semaphore in a simple docker configuration run the following command: + + docker-compose up + +You can then access Semaphore directly from the url http://localhost:8081/ + +SSL Termination Using Nginx +########################### + +Generate a cert, ca cert, and key file and place into `Deploy/proxy/cert/` with +these names: + +* `cert.pem` +* `privkey.pem` +* `fullchain.pem` + +(I've used letsencrypt generated certs with success.) + +Run `docker-compose up` and your Semaphore instance will then be at the url +https://localhost:8443 + diff --git a/Deploy/api/Dockerfile b/Deploy/api/Dockerfile new file mode 100644 index 00000000..f7d32d3e --- /dev/null +++ b/Deploy/api/Dockerfile @@ -0,0 +1,26 @@ +FROM fedora + +RUN dnf -y install git ansible mariadb; dnf -y clean all + +ENV SEMAPHORE_DB_USER semaphore +ENV SEMAPHORE_DB_PASS semaphore +ENV SEMAPHORE_DB_HOST mysql +ENV SEMAPHORE_DB_PORT 3306 +ENV SEMAPHORE_DB semaphore +ENV SEMAPHORE_PLAYBOOK_PATH /etc/semaphore/ +ENV SEMAPHORE_ADMIN_PASSWORD cangetin +ENV SEMAPHORE_ADMIN_NAME Default\ Administrator +ENV SEMAPHORE_ADMIN_EMAIL admin@localhost +ENV SEMAPHORE_ADMIN admin + +RUN curl -L https://github.com/ansible-semaphore/semaphore/releases/download/v2.0.4/semaphore_linux_amd64 > /usr/bin/semaphore && chmod +x /usr/bin/semaphore && mkdir -p /etc/semaphore/playbooks + +ADD semaphore-startup.sh /usr/bin/semaphore-startup.sh + +RUN chmod +x /usr/bin/semaphore-startup.sh + +EXPOSE 3000 + +ENTRYPOINT ["/usr/bin/semaphore-startup.sh"] + +CMD ["/usr/bin/semaphore", "-config", "/etc/semaphore/semaphore_config.json"] diff --git a/Deploy/api/semaphore-startup.sh b/Deploy/api/semaphore-startup.sh new file mode 100644 index 00000000..dec350ba --- /dev/null +++ b/Deploy/api/semaphore-startup.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +echoerr() { printf "%s\n" "$*" >&2; } + +# wait on db to be up +echoerr "Attempting to connect to database ${SEMAPHORE_DB} on ${SEMAPHORE_DB_HOST} with user:pass ${SEMAPHORE_DB_USER}:${SEMAPHORE_DB_PASS}" +until mysql -h ${SEMAPHORE_DB_HOST} -u ${SEMAPHORE_DB_USER} --password=${SEMAPHORE_DB_PASS} ${SEMAPHORE_DB} -e "select version();" &>/dev/null; +do + echoerr "waiting"; + sleep 3; +done + +# generate stdin +if [ -f ${SEMAPHORE_PLAYBOOK_PATH}/config.stdin ] +then + echoerr "already generated stdin" +else + echoerr "generating ${SEMAPHORE_PLAYBOOK_PATH}/config.stdin" + cat << EOF > ${SEMAPHORE_PLAYBOOK_PATH}/config.stdin +${SEMAPHORE_DB_HOST}:${SEMAPHORE_DB_PORT} +${SEMAPHORE_DB_USER} +${SEMAPHORE_DB_PASS} +${SEMAPHORE_DB} +${SEMAPHORE_PLAYBOOK_PATH} +yes +${SEMAPHORE_ADMIN} +${SEMAPHORE_ADMIN_EMAIL} +${SEMAPHORE_ADMIN_NAME} +${SEMAPHORE_ADMIN_PASSWORD} +EOF +fi + +# test to see if initialzation is needed +if [ -f ${SEMAPHORE_PLAYBOOK_PATH}/semaphore_config.json ] +then + echoerr "already initialized" +else + echoerr "Initializing semaphore" + /usr/bin/semaphore -setup < ${SEMAPHORE_PLAYBOOK_PATH}/config.stdin +fi + +# run our command +exec "$@" diff --git a/Deploy/docker-compose.yml b/Deploy/docker-compose.yml new file mode 100644 index 00000000..e59fda86 --- /dev/null +++ b/Deploy/docker-compose.yml @@ -0,0 +1,30 @@ +mysql: + image: mysql + environment: + MYSQL_RANDOM_ROOT_PASSWORD: 'yes' + MYSQL_DATABASE: semaphore + MYSQL_USER: semaphore + MYSQL_PASSWORD: semaphore + hostname: mysql + expose: + - 3306 + +semaphore_api: + build: api + expose: + - 3000 + ports: + - 8081:3000 + links: + - mysql:mysql + +semaphore_proxy: + build: proxy + expose: + - 443 + - 80 + ports: + - 8080:80 + - 8443:443 + links: + - semaphore_api:semaphore_api diff --git a/Deploy/proxy/Dockerfile b/Deploy/proxy/Dockerfile new file mode 100644 index 00000000..642382d4 --- /dev/null +++ b/Deploy/proxy/Dockerfile @@ -0,0 +1,5 @@ +FROM nginx + +ADD nginx.conf /etc/nginx/nginx.conf +ADD cert/ /etc/nginx/cert + diff --git a/Deploy/proxy/cert/.gitignore b/Deploy/proxy/cert/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/Deploy/proxy/cert/.gitignore @@ -0,0 +1 @@ +* diff --git a/Deploy/proxy/nginx.conf b/Deploy/proxy/nginx.conf new file mode 100644 index 00000000..0056ec83 --- /dev/null +++ b/Deploy/proxy/nginx.conf @@ -0,0 +1,66 @@ +worker_processes auto; + +events { + worker_connections 1024; + use epoll; + multi_accept on; +} + +http { + tcp_nodelay on; + + # this is necessary for us to be able to disable request buffering in all cases + proxy_http_version 1.1; + + upstream semaphore_api { + server semaphore_api:3000; + } + + server { + listen 443 ssl; + server_name _; + + # SSL + ssl_certificate /etc/nginx/cert/cert.pem; + ssl_certificate_key /etc/nginx/cert/privkey.pem; + + # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + + # disable any limits to avoid HTTP 413 for large image uploads + client_max_body_size 0; + + # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) + chunked_transfer_encoding on; + + location / { + proxy_pass http://semaphore_api/; + proxy_set_header Host $http_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_buffering off; + proxy_request_buffering off; + } + + location /api/ws { + proxy_pass http://semaphore_api/api/ws; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Origin ""; + } + + + } + server { + listen 80; + server_name _; + rewrite ^/(.*) https://$server_name:443/$1 permanent; + } +}