Merge pull request #5 from sadnub/docker-fix

Docker fix and cleanup
This commit is contained in:
wh1te909 2020-02-22 13:19:22 -08:00 committed by GitHub
commit 811ad89430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 216 additions and 22 deletions

View File

@ -17,5 +17,13 @@ SALT_PASS=password
ADMIN_URL=admin
DJANGO_SEKRET=secret12341234123412341234
DJANGO_DEBUG=False
TWO_FACTOR_OTP=3HTDZVFRYP4OPXHL
EMAIL_TLS=True
EMAIL_HOST=smtp.gmail.com
EMAIL_USER=example@gmail.com
EMAIL_PASS=changeme
EMAIL_PORT=587
EMAIL_RECIPIENTS="example@gmail.com",

View File

@ -46,6 +46,11 @@ http {
alias /app/log/;
}
location /protectedscripts/ {
internal;
add_header "Access-Control-Allow-Origin" "https://${APP_HOST}";
alias /srv/salt/scripts/userdefined/;
}
location / {
uwsgi_pass tacticalrmm;

View File

@ -1,6 +1,9 @@
FROM tiangolo/uwsgi-nginx:python3.7
WORKDIR /app
ARG DJANGO_SEKRET
ARG DJANGO_DEBUG
ARG POSTGRES_USER
ARG POSTGRES_PASS
ARG POSTGRES_HOST
@ -14,16 +17,29 @@ ARG APP_HOST
ARG API_HOST
ARG ADMIN_URL
ARG TWO_FACTOR_OTP
ARG EMAIL_TLS
ARG EMAIL_HOST
ARG EMAIL_USER
ARG EMAIL_PASS
ARG EMAIL_PORT
ARG EMAIL_RECIPIENTS
EXPOSE 80
RUN apt-get update && apt-get install -y gettext-base
COPY ./api/tacticalrmm .
COPY ./api/tacticalrmm/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY ./api/tacticalrmm/ .
COPY ./docker/api/prestart.sh .
COPY ./docker/api/uwsgi.ini .
COPY ./docker/api/api.conf /app/api.conf.tmp
RUN envsubst '\$APP_HOST, \$API_HOST' < /app/api.conf.tmp > /app/nginx.conf && \
rm /app/api.conf.tmp
COPY ./docker/api/local_settings.py ./tacticalrmm/local_settings.py.tmp
RUN envsubst < /app/tacticalrmm/local_settings.py.tmp > /app/tacticalrmm/local_settings.py && rm /app/tacticalrmm/local_settings.py.tmp
COPY ./docker/api/local_settings.py.keep ./tacticalrmm/local_settings.py.tmp
RUN envsubst < /app/tacticalrmm/local_settings.py.tmp > /app/tacticalrmm/local_settings.py && rm /app/tacticalrmm/local_settings.py.tmp
COPY ./_modules /srv/salt/_modules
COPY ./scripts /srv/salt/scripts
RUN mkdir /srv/salt/scripts/userdefined && \
chown -R 1000:nginx /srv/salt/scripts/userdefined && \
chmod -R 771 /srv/salt/scripts/userdefined

View File

@ -0,0 +1,53 @@
SECRET_KEY = '${DJANGO_SEKRET}'
ALLOWED_HOSTS = ['${API_HOST}']
ADMIN_URL = "${ADMIN_URL}"
CORS_ORIGIN_WHITELIST = ["https://${APP_HOST}",]
DEBUG = ${DJANGO_DEBUG}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'tacticalrmm',
'USER': '${POSTGRES_USER}',
'PASSWORD': '${POSTGRES_PASS}',
'HOST': '${POSTGRES_HOST}',
'PORT': '5432',
}
}
REST_FRAMEWORK = {
'DATETIME_FORMAT': "%b-%d-%Y - %H:%M",
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'knox.auth.TokenAuthentication',
),
}
if not DEBUG:
REST_FRAMEWORK.update({
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
)
})
EMAIL_USE_TLS = ${EMAIL_TLS}
EMAIL_HOST = '${EMAIL_HOST}'
EMAIL_HOST_USER = '${EMAIL_USER}'
EMAIL_HOST_PASSWORD = '${EMAIL_PASS}'
EMAIL_PORT = ${EMAIL_PORT}
EMAIL_ALERT_RECIPIENTS = [${EMAIL_RECIPIENTS}]
SALT_USERNAME = "${SALT_USER}"
SALT_PASSWORD = "${SALT_PASS}"
MESH_USERNAME = "${MESH_USER}"
MESH_SITE = "https://${MESH_HOST}"
REDIS_HOST = "${REDIS_HOST}"
SALT_HOST = "${SALT_HOST}"
TWO_FACTOR_OTP = "${TWO_FACTOR_OTP}"

View File

@ -0,0 +1,2 @@
VUE_APP_PROD_URL = "https://${API_HOST}"
VUE_APP_DEV_URL = "https://${API_HOST}"

View File

@ -5,8 +5,8 @@ EXPOSE 80
WORKDIR /home/node
RUN apk add gettext
COPY ./web .
COPY ./docker/app/.env.local /home/.env.local.tmp
RUN envsubst '\$APP_HOST, \$API_HOST' < /home/.env.local.tmp > /home/node/.env.local && rm /home/.env.local.tmp
COPY ./docker/app/.env.local.keep /home/.env.local.tmp
RUN envsubst '\$API_HOST' < /home/.env.local.tmp > /home/node/.env.local && rm /home/.env.local.tmp
RUN npm install && npm run build
COPY ./docker/app/app.conf /home/node/app.conf.tmp
RUN envsubst '\$APP_HOST' < /home/node/app.conf.tmp > /home/node/app.conf

View File

@ -1,5 +1,6 @@
version: '3.5'
# Userdefined Networks
networks:
database:
redis:
@ -10,7 +11,14 @@ networks:
config:
- subnet: 172.20.0.0/24
# Docker managed persistent volumes
volumes:
# Volume for userdefined scripts
scripts:
services:
# Postgres Database for API service
db:
image: "postgres"
restart: "always"
@ -20,14 +28,25 @@ services:
- POSTGRES_PASS=${POSTGRES_PASS}
networks:
- database
# Salt Master and API
salt:
image: "saltstack/salt"
volumes:
- ./salt:/etc/salt/master.d
build:
context: ..
dockerfile: ./docker/salt/dockerfile
args:
- SALT_USER=${SALT_USER}
- SALT_PASS=${SALT_PASS}
ports:
- "8123:8123"
- "4505:4505"
- "4506:4506"
volumes:
- scripts:/srv:ro
networks:
- proxy
# MeshCentral Container
meshcentral:
build:
context: ./meshcentral
@ -35,6 +54,10 @@ services:
- MESH_HOST=${MESH_HOST}
networks:
- proxy
depends_on:
- nginx-proxy
# Nginx Container Reverse Proxy that handles all http/https traffic
nginx-proxy:
build:
context: ./nginx-proxy
@ -48,14 +71,14 @@ services:
networks:
proxy:
ipv4_address: 172.20.0.20
depends_on:
- app
- api
- meshcentral
# Redis Container for Celery tasks
redis:
image: redis
networks:
- redis
# Container that hosts Vue frontend
app:
build:
context: ..
@ -65,12 +88,15 @@ services:
- API_HOST=${API_HOST}
networks:
- proxy
# Container for Django backend
api:
build:
context: ..
dockerfile: "./docker/api/dockerfile"
args:
- DJANGO_SEKRET=${DJANGO_SEKRET}
- DJANGO_DEBUG=${DJANGO_DEBUG}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASS=${POSTGRES_PASS}
- POSTGRES_HOST=${POSTGRES_HOST}
@ -84,18 +110,29 @@ services:
- API_HOST=${API_HOST}
- ADMIN_URL=${ADMIN_URL}
- TWO_FACTOR_OTP=${TWO_FACTOR_OTP}
- EMAIL_TLS=${EMAIL_TLS}
- EMAIL_HOST=${EMAIL_HOST}
- EMAIL_USER=${EMAIL_USER}
- EMAIL_PASS=${EMAIL_PASS}
- EMAIL_PORT=${EMAIL_PORT}
- EMAIL_RECIPIENTS=${EMAIL_RECIPIENTS}
networks:
- proxy
- database
- redis
volumes:
- scripts:/srv
depends_on:
- db
# Container for Celery worker service
celery-service:
build:
context: ..
dockerfile: "./docker/api/dockerfile"
args:
- DJANGO_SEKRET=${DJANGO_SEKRET}
- DJANGO_DEBUG=${DJANGO_DEBUG}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASS=${POSTGRES_PASS}
- POSTGRES_HOST=${POSTGRES_HOST}
@ -109,6 +146,12 @@ services:
- API_HOST=${API_HOST}
- ADMIN_URL=${ADMIN_URL}
- TWO_FACTOR_OTP=${TWO_FACTOR_OTP}
- EMAIL_TLS=${EMAIL_TLS}
- EMAIL_HOST=${EMAIL_HOST}
- EMAIL_USER=${EMAIL_USER}
- EMAIL_PASS=${EMAIL_PASS}
- EMAIL_PORT=${EMAIL_PORT}
- EMAIL_RECIPIENTS=${EMAIL_RECIPIENTS}
command: celery -A tacticalrmm worker -l info
networks:
- redis
@ -116,12 +159,15 @@ services:
depends_on:
- db
- redis
# Container for Celery beat service
celery-beat:
build:
context: ..
dockerfile: "./docker/api/dockerfile"
args:
- DJANGO_SEKRET=${DJANGO_SEKRET}
- DJANGO_DEBUG=${DJANGO_DEBUG}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASS=${POSTGRES_PASS}
- POSTGRES_HOST=${POSTGRES_HOST}
@ -135,6 +181,12 @@ services:
- API_HOST=${API_HOST}
- ADMIN_URL=${ADMIN_URL}
- TWO_FACTOR_OTP=${TWO_FACTOR_OTP}
- EMAIL_TLS=${EMAIL_TLS}
- EMAIL_HOST=${EMAIL_HOST}
- EMAIL_USER=${EMAIL_USER}
- EMAIL_PASS=${EMAIL_PASS}
- EMAIL_PORT=${EMAIL_PORT}
- EMAIL_RECIPIENTS=${EMAIL_RECIPIENTS}
command: celery -A tacticalrmm beat -l info
networks:
- redis
@ -142,12 +194,15 @@ services:
depends_on:
- db
- redis
# Container for Celery Winupdate tasks
celery-winupdate:
build:
context: ..
dockerfile: "./docker/api/dockerfile"
args:
- DJANGO_SEKRET=${DJANGO_SEKRET}
- DJANGO_DEBUG=${DJANGO_DEBUG}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASS=${POSTGRES_PASS}
- POSTGRES_HOST=${POSTGRES_HOST}
@ -161,6 +216,12 @@ services:
- API_HOST=${API_HOST}
- ADMIN_URL=${ADMIN_URL}
- TWO_FACTOR_OTP=${TWO_FACTOR_OTP}
- EMAIL_TLS=${EMAIL_TLS}
- EMAIL_HOST=${EMAIL_HOST}
- EMAIL_USER=${EMAIL_USER}
- EMAIL_PASS=${EMAIL_PASS}
- EMAIL_PORT=${EMAIL_PORT}
- EMAIL_RECIPIENTS=${EMAIL_RECIPIENTS}
command: celery -A tacticalrmm worker -Q wupdate
networks:
- redis

View File

@ -1,8 +1,13 @@
server {
resolver 127.0.0.11 valid=30s;
server_name ${API_HOST};
location / {
proxy_pass http://api;
#Using variable to disable start checks
set $api http://api;
proxy_pass $api;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
@ -19,6 +24,8 @@ server {
error_log /var/log/nginx/api-error.log;
access_log /var/log/nginx/api-access.log;
client_max_body_size 300M;
listen 443 ssl;
ssl_certificate /cert/fullchain.pem;
ssl_certificate_key /cert/privkey.pem;

View File

@ -1,8 +1,13 @@
server {
resolver 127.0.0.11 valid=30s;
server_name ${APP_HOST};
location / {
proxy_pass http://app;
#Using variable to disable start checks
set $app http://app;
proxy_pass $app;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;

View File

@ -1,10 +1,14 @@
server {
resolver 127.0.0.11 valid=30s;
listen 80;
server_name ${MESH_HOST};
location / {
proxy_pass http://meshcentral;
#Using variable to disable start checks
set $meshcentral http://meshcentral;
proxy_pass $meshcentral;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host:$server_port;
@ -14,6 +18,7 @@ server {
}
server {
resolver 127.0.0.11 valid=30s;
listen 443 ssl;
proxy_send_timeout 330s;
@ -26,7 +31,10 @@ server {
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://meshcentral:443;
#Using variable to disable start checks
set $meshcentral http://meshcentral:443;
proxy_pass $meshcentral;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;

View File

@ -3,7 +3,7 @@
- install docker and docker-compose
- Obtain wildcard cert or individual certs for each subdomain
## Optional - Generate certificates with certbot
## Generate certificates with certbot
Install Certbot
@ -13,13 +13,19 @@ sudo apt-get install certbot
Generate the wildcard certificate. Add the DNS entry for domain validation.
```sudo certbot certonly --manual -d *.example.com --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns
```
sudo certbot certonly --manual -d *.example.com --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns
```
Copy the fullchain.pem and privkey.pem to the cert directory.
## Configure DNS and Firewall
You will need to add DNS entries so that the three subdomains resolve to the IP of the docker host. There is a reverse proxy running that will route the hostnames to the correct container. On the host, you will need to ensure the firewall is open on tcp ports 80, 443, 8123, 4505, 4506.
## Run the environment with Docker
Change values in .env to match your environment
Copy the .env.example to .env then
change values in .env to match your environment
```
cd docker
@ -55,3 +61,15 @@ Use the generated code and the username to generate a bar code for your authenti
```
sudo docker exec -it docker_api_1 python manage.py generate_barcode [OTP_CODE] [username]
```
## Connect to a container instance shell
run `docker ps` to get the name of the running container instance.
Then use the name in the below command. It will use the api container instance as an example
```
sudo docker exec -it docker_api_1 /bin/bash
```
If /bin/bash doesn't work then /bin/sh might need to be used.

View File

@ -3,7 +3,7 @@ gather_job_timeout: 30
max_event_size: 30485760
external_auth:
pam:
saltapi:
${SALT_USER}:
- .*
- '@runner'
- '@wheel'
@ -11,4 +11,4 @@ external_auth:
rest_cherrypy:
port: 8123
disable_ssl: True
max_request_body_size: 30485760
max_request_body_size: 30485760

12
docker/salt/dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM saltstack/salt
ARG SALT_USER
ARG SALT_PASS
RUN adduser --no-create-home --disabled-password --gecos "" ${SALT_USER} && \
echo "${SALT_USER}:${SALT_PASS}" | chpasswd
RUN apk add gettext
COPY ./docker/salt/api.conf /etc/salt/master.d/api.conf.tmp
RUN envsubst '\$SALT_USER' < /etc/salt/master.d/api.conf.tmp > /etc/salt/master.d/api.conf && \
rm /etc/salt/master.d/api.conf.tmp

View File

@ -1 +0,0 @@
{"user": "salt"}