1
This commit is contained in:
commit
72c4d16448
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# production
|
||||||
|
build/
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env*
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
requests.rest
|
||||||
|
.prettierrc
|
||||||
|
CSV_FILES/
|
||||||
|
log/
|
266
.gitlab-ci.yml
Normal file
266
.gitlab-ci.yml
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
---
|
||||||
|
stages:
|
||||||
|
- preperations
|
||||||
|
- test
|
||||||
|
- build
|
||||||
|
- postbuild_test
|
||||||
|
- deploy_api
|
||||||
|
- deploy_web
|
||||||
|
|
||||||
|
variables:
|
||||||
|
ANSIBLE_IMAGE_TAG: "${CI_REGISTRY_IMAGE}/ansible:latest"
|
||||||
|
API_IMAGE_TAG: "${CI_REGISTRY_IMAGE}/api:${CI_COMMIT_SHORT_SHA}"
|
||||||
|
CLIENT_IMAGE_TAG: "${CI_REGISTRY_IMAGE}/client:${CI_COMMIT_SHORT_SHA}"
|
||||||
|
SERVER_IMAGE_TAG: "${CI_REGISTRY_IMAGE}/server:${CI_COMMIT_SHORT_SHA}"
|
||||||
|
FRONTEND_PATH: ${CI_PROJECT_DIR}/client
|
||||||
|
DEPLOY_PROJECT_NAME: "selfservice"
|
||||||
|
WEB_DOMAIN: "selfservice.example.org"
|
||||||
|
TRAEFIK_VERSION: "2.11"
|
||||||
|
|
||||||
|
|
||||||
|
.ansible-template:
|
||||||
|
before_script:
|
||||||
|
- chmod 0640 ${CI_PROJECT_DIR} -R
|
||||||
|
- chmod 0600 ${PROJECT_SSH_KEY}
|
||||||
|
|
||||||
|
build-debian-ansible:
|
||||||
|
image: docker:latest
|
||||||
|
stage: preperations
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd ansible/debian
|
||||||
|
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
|
||||||
|
- docker build -t ${CI_REGISTRY_IMAGE}/debian-ansible:${CI_COMMIT_SHORT_SHA} .
|
||||||
|
- docker tag ${CI_REGISTRY_IMAGE}/debian-ansible:${CI_COMMIT_SHORT_SHA} ${CI_REGISTRY_IMAGE}/debian-ansible:latest
|
||||||
|
- docker tag ${CI_REGISTRY_IMAGE}/debian-ansible:${CI_COMMIT_SHORT_SHA} ${ANSIBLE_IMAGE_TAG}
|
||||||
|
- docker push ${CI_REGISTRY_IMAGE}/debian-ansible:${CI_COMMIT_SHORT_SHA}
|
||||||
|
- docker push ${CI_REGISTRY_IMAGE}/debian-ansible:latest
|
||||||
|
- docker push ${ANSIBLE_IMAGE_TAG}
|
||||||
|
|
||||||
|
build-alma-ansible:
|
||||||
|
image: docker:latest
|
||||||
|
stage: preperations
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd ansible/alma
|
||||||
|
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
|
||||||
|
- docker build -t ${CI_REGISTRY_IMAGE}/alma-ansible:${CI_COMMIT_SHORT_SHA} .
|
||||||
|
- docker tag ${CI_REGISTRY_IMAGE}/alma-ansible:${CI_COMMIT_SHORT_SHA} ${CI_REGISTRY_IMAGE}/alma-ansible:latest
|
||||||
|
- docker tag ${CI_REGISTRY_IMAGE}/alma-ansible:${CI_COMMIT_SHORT_SHA} ${ANSIBLE_IMAGE_TAG}
|
||||||
|
- docker push ${CI_REGISTRY_IMAGE}/alma-ansible:${CI_COMMIT_SHORT_SHA}
|
||||||
|
- docker push ${CI_REGISTRY_IMAGE}/alma-ansible:latest
|
||||||
|
- docker push ${ANSIBLE_IMAGE_TAG}
|
||||||
|
|
||||||
|
build-python-ansible:
|
||||||
|
image: docker:latest
|
||||||
|
stage: preperations
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd ansible/python
|
||||||
|
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
|
||||||
|
- docker build -t ${CI_REGISTRY_IMAGE}/python-ansible:${CI_COMMIT_SHORT_SHA} .
|
||||||
|
- docker tag ${CI_REGISTRY_IMAGE}/python-ansible:${CI_COMMIT_SHORT_SHA} ${CI_REGISTRY_IMAGE}/python-ansible:latest
|
||||||
|
- docker tag ${CI_REGISTRY_IMAGE}/python-ansible:${CI_COMMIT_SHORT_SHA} ${ANSIBLE_IMAGE_TAG}
|
||||||
|
- docker push ${CI_REGISTRY_IMAGE}/python-ansible:${CI_COMMIT_SHORT_SHA}
|
||||||
|
- docker push ${CI_REGISTRY_IMAGE}/python-ansible:latest
|
||||||
|
- docker push ${ANSIBLE_IMAGE_TAG}
|
||||||
|
|
||||||
|
build-api:
|
||||||
|
image: docker:latest
|
||||||
|
stage: build
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd api
|
||||||
|
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
|
||||||
|
- docker build -t ${API_IMAGE_TAG} .
|
||||||
|
- docker push ${API_IMAGE_TAG}
|
||||||
|
|
||||||
|
build-server:
|
||||||
|
image: docker:latest
|
||||||
|
stage: build
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd server
|
||||||
|
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
|
||||||
|
- docker build -t ${SERVER_IMAGE_TAG} .
|
||||||
|
- docker push ${SERVER_IMAGE_TAG}
|
||||||
|
|
||||||
|
build-client:
|
||||||
|
image: docker:latest
|
||||||
|
stage: build
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd client
|
||||||
|
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
|
||||||
|
- docker build -t ${CLIENT_IMAGE_TAG} .
|
||||||
|
- docker push ${CLIENT_IMAGE_TAG}
|
||||||
|
|
||||||
|
test-client:
|
||||||
|
image: docker:latest
|
||||||
|
stage: test
|
||||||
|
allow_failure: true
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd client
|
||||||
|
- docker build -t ${CLIENT_IMAGE_TAG} -f Dockerfile.test .
|
||||||
|
|
||||||
|
test-server:
|
||||||
|
image: docker:latest
|
||||||
|
stage: test
|
||||||
|
allow_failure: true
|
||||||
|
when: manual
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd server
|
||||||
|
- docker build -t ${CLIENT_IMAGE_TAG} -f Dockerfile.test .
|
||||||
|
|
||||||
|
.deploy-api:
|
||||||
|
extends: .ansible-template
|
||||||
|
image: ${ANSIBLE_IMAGE_TAG}
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: all
|
||||||
|
stage: deploy_api
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --limit ${HOSTS_LIMIT} --inventory inventory deploy-api.yml --private-key ${PROJECT_SSH_KEY} \
|
||||||
|
--extra-vars project_name=${DEPLOY_PROJECT_NAME}_api --extra-vars config_dir=/etc/app-${DEPLOY_PROJECT_NAME}-api \
|
||||||
|
--extra-vars registry_url=${CI_REGISTRY} --extra-vars registry_username=${CI_REGISTRY_USER} \
|
||||||
|
--extra-vars registry_password=${CI_REGISTRY_PASSWORD} --extra-vars api_image=${API_IMAGE_TAG}
|
||||||
|
|
||||||
|
deploy-api-201:
|
||||||
|
extends: .deploy-api
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.101
|
||||||
|
|
||||||
|
deploy-api-202:
|
||||||
|
extends: .deploy-api
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.102
|
||||||
|
|
||||||
|
deploy-api-203:
|
||||||
|
extends: .deploy-api
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.103
|
||||||
|
|
||||||
|
deploy-dev-api:
|
||||||
|
extends: .deploy-api
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.104
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --limit ${HOSTS_LIMIT} --inventory inventory deploy-api.yml --private-key ${PROJECT_SSH_KEY} \
|
||||||
|
--extra-vars project_name=${DEPLOY_PROJECT_NAME}_api --extra-vars config_dir=/etc/app-${DEPLOY_PROJECT_NAME}-dev-api \
|
||||||
|
--extra-vars registry_url=${CI_REGISTRY} --extra-vars registry_username=${CI_REGISTRY_USER} \
|
||||||
|
--extra-vars registry_password=${CI_REGISTRY_PASSWORD} --extra-vars api_image=${API_IMAGE_TAG}
|
||||||
|
|
||||||
|
.deploy-web:
|
||||||
|
extends: .ansible-template
|
||||||
|
image: ${ANSIBLE_IMAGE_TAG}
|
||||||
|
stage: deploy_web
|
||||||
|
when: manual
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: all
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --limit ${HOSTS_LIMIT} --inventory inventory deploy-web.yml --private-key ${PROJECT_SSH_KEY} \
|
||||||
|
--extra-vars project_name=${DEPLOY_PROJECT_NAME}-web --extra-vars config_dir=/etc/app-${DEPLOY_PROJECT_NAME} \
|
||||||
|
--extra-vars registry_url=${CI_REGISTRY} --extra-vars registry_username=${CI_REGISTRY_USER} \
|
||||||
|
--extra-vars registry_password=${CI_REGISTRY_PASSWORD} --extra-vars client_image=${CLIENT_IMAGE_TAG} \
|
||||||
|
--extra-vars server_image=${SERVER_IMAGE_TAG} \
|
||||||
|
--extra-vars project_domain=${WEB_DOMAIN}
|
||||||
|
|
||||||
|
deploy-web-231:
|
||||||
|
extends: .deploy-web
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.111
|
||||||
|
|
||||||
|
deploy-web-232:
|
||||||
|
extends: .deploy-web
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.112
|
||||||
|
|
||||||
|
deploy-web-233:
|
||||||
|
extends: .deploy-web
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.113
|
||||||
|
|
||||||
|
deploy-dev-web:
|
||||||
|
extends: .deploy-web
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: 172.17.200.114
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --limit ${HOSTS_LIMIT} --inventory inventory deploy-web.yml --private-key ${PROJECT_SSH_KEY} \
|
||||||
|
--extra-vars project_name=${DEPLOY_PROJECT_NAME}-web --extra-vars config_dir=/etc/app-${DEPLOY_PROJECT_NAME}-dev \
|
||||||
|
--extra-vars registry_url=${CI_REGISTRY} --extra-vars registry_username=${CI_REGISTRY_USER} \
|
||||||
|
--extra-vars registry_password=${CI_REGISTRY_PASSWORD} --extra-vars client_image=${CLIENT_IMAGE_TAG} \
|
||||||
|
--extra-vars server_image=${SERVER_IMAGE_TAG} \
|
||||||
|
--extra-vars project_domain=$dev-{WEB_DOMAIN}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
deploy-traefik:
|
||||||
|
extends: .ansible-template
|
||||||
|
image: ${ANSIBLE_IMAGE_TAG}
|
||||||
|
stage: preperations
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --inventory inventory deploy-traefik.yml --private-key ${PROJECT_SSH_KEY} \
|
||||||
|
--extra-vars config_dir=/etc/app-traefik
|
||||||
|
|
||||||
|
deploy-docker:
|
||||||
|
extends: .ansible-template
|
||||||
|
image: ${ANSIBLE_IMAGE_TAG}
|
||||||
|
stage: preperations
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --inventory inventory deploy-docker-ce.yml --private-key ${PROJECT_SSH_KEY}
|
||||||
|
|
||||||
|
deploy-portainer:
|
||||||
|
extends: .ansible-template
|
||||||
|
image: ${ANSIBLE_IMAGE_TAG}
|
||||||
|
stage: preperations
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --inventory inventory deploy-portainer.yml --private-key ${PROJECT_SSH_KEY} \
|
||||||
|
--extra-vars config_dir=/etc/app-portainer
|
||||||
|
|
||||||
|
|
||||||
|
deploy-node-exporter:
|
||||||
|
extends: .ansible-template
|
||||||
|
image: ${ANSIBLE_IMAGE_TAG}
|
||||||
|
variables:
|
||||||
|
HOSTS_LIMIT: all
|
||||||
|
stage: preperations
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
ansible-playbook --limit ${HOSTS_LIMIT} --inventory inventory deploy-node-exporter.yml --private-key ${PROJECT_SSH_KEY}
|
||||||
|
|
9
ansible.cfg
Normal file
9
ansible.cfg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[defaults]
|
||||||
|
host_key_checking = False
|
||||||
|
|
||||||
|
#[inventory]
|
||||||
|
#enable_plugins = yaml
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
pipelining = True
|
||||||
|
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
|
39
ansible/alma/Dockerfile
Normal file
39
ansible/alma/Dockerfile
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
FROM almalinux:9
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
|
||||||
|
# Install requirements.
|
||||||
|
RUN yum -y install rpm dnf-plugins-core \
|
||||||
|
&& yum -y config-manager --set-enabled crb \
|
||||||
|
&& yum -y update \
|
||||||
|
&& yum -y install --allowerasing \
|
||||||
|
epel-release \
|
||||||
|
sudo \
|
||||||
|
which \
|
||||||
|
hostname \
|
||||||
|
libyaml-devel \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
python3-pyyaml \
|
||||||
|
rsync \
|
||||||
|
wget \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
ruby \
|
||||||
|
&& yum clean all
|
||||||
|
|
||||||
|
RUN python3 -m pip install --no-cache-dir --upgrade pip \
|
||||||
|
&& pip3 install --no-cache-dir ansible
|
||||||
|
|
||||||
|
RUN ansible-galaxy collection install community.general && \
|
||||||
|
ansible-galaxy collection install ansible.posix && \
|
||||||
|
ansible-galaxy collection install community.docker && \
|
||||||
|
ansible-galaxy collection list
|
||||||
|
|
||||||
|
RUN mkdir -p /root/.ssh
|
||||||
|
|
||||||
|
# Disable requiretty.
|
||||||
|
RUN sed -i -e 's/^\(Defaults\s*requiretty\)/#--- \1/' /etc/sudoers
|
||||||
|
|
||||||
|
CMD ["ansible-playbook"]
|
||||||
|
|
5
ansible/alma/requirements.yml
Normal file
5
ansible/alma/requirements.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- community.general
|
||||||
|
- ansible.posix
|
||||||
|
- community.docker
|
19
ansible/debian/Dockerfile
Normal file
19
ansible/debian/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FROM debian:bullseye
|
||||||
|
|
||||||
|
RUN apt update && \
|
||||||
|
apt install -y gnupg2 python3 python3-pip curl wget && \
|
||||||
|
apt update && \
|
||||||
|
apt install -y ansible && \
|
||||||
|
pip3 install "ansible-lint[community,yamllint]" && \
|
||||||
|
pip3 install --upgrade docker && \
|
||||||
|
pip3 install --upgrade docker-compose && \
|
||||||
|
rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
RUN ansible-galaxy collection install \
|
||||||
|
community.docker
|
||||||
|
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
RUN chmod +x /entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||||
|
CMD ["ansible-playbook"]
|
8
ansible/debian/entrypoint.sh
Normal file
8
ansible/debian/entrypoint.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
## Do whatever you need with env vars here ...
|
||||||
|
|
||||||
|
chmod 0600 ${PROJECT_SSH_KEY}
|
||||||
|
|
||||||
|
# Hand off to the CMD
|
||||||
|
exec "$@"
|
18
ansible/python/Dockerfile
Normal file
18
ansible/python/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
FROM python:3.10
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install sshpass rsync curl wget ruby socat netcat git -y && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN pip install --upgrade pip --no-cache-dir && \
|
||||||
|
pip install ansible --no-cache-dir
|
||||||
|
|
||||||
|
RUN ansible-galaxy collection install community.general && \
|
||||||
|
ansible-galaxy collection install ansible.posix && \
|
||||||
|
ansible-galaxy collection install community.docker && \
|
||||||
|
ansible-galaxy collection list
|
||||||
|
|
||||||
|
RUN mkdir -p /root/.ssh
|
||||||
|
|
||||||
|
CMD ["ansible-playbook"]
|
5
ansible/python/requirements.yml
Normal file
5
ansible/python/requirements.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- community.general
|
||||||
|
- ansible.posix
|
||||||
|
- community.docker
|
25
api/Dockerfile
Normal file
25
api/Dockerfile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
ARG NODE_IMAGE="node"
|
||||||
|
ARG NODE_VERSION="16.17-slim"
|
||||||
|
|
||||||
|
FROM ${NODE_IMAGE}:${NODE_VERSION}
|
||||||
|
|
||||||
|
ENV TZ=Asia/Jerusalem
|
||||||
|
|
||||||
|
WORKDIR /project
|
||||||
|
|
||||||
|
COPY package.json package-lock.json /project/
|
||||||
|
|
||||||
|
RUN npm ci --no-audit --no-fund
|
||||||
|
|
||||||
|
COPY --chown=node:node . /project/
|
||||||
|
|
||||||
|
RUN chown node:node /project -R && \
|
||||||
|
find /project -type d -exec chmod 0750 {} \; && \
|
||||||
|
find /project -type f -exec chmod 0650 {} \; && \
|
||||||
|
ls -la /project && \
|
||||||
|
find /project ! -path '/project/node_modules/*'
|
||||||
|
|
||||||
|
# Run as node (user id 1000)
|
||||||
|
USER node
|
||||||
|
|
||||||
|
CMD ["node", "/project/app.js"]
|
15
api/app.js
Normal file
15
api/app.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
var app = express();
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
const port = 3002;
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Server running on http://localhost:${port}`);
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = app;
|
41
client/Dockerfile
Normal file
41
client/Dockerfile
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
ARG NGINX_IMAGE="nginx"
|
||||||
|
ARG NGINX_VERSION="alpine"
|
||||||
|
|
||||||
|
ARG NODE_IMAGE="node"
|
||||||
|
ARG NODE_VERSION="16.17.1-alpine"
|
||||||
|
|
||||||
|
|
||||||
|
## Builder image (builds the static content from JS sources)
|
||||||
|
FROM ${NODE_IMAGE}:${NODE_VERSION} AS appbuild
|
||||||
|
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json /app/
|
||||||
|
|
||||||
|
RUN npm ci --no-audit --no-fund \
|
||||||
|
&& ls -la /app \
|
||||||
|
&& find /app ! -path '/app/node_modules/*'
|
||||||
|
|
||||||
|
COPY . /app/
|
||||||
|
|
||||||
|
RUN npm ci \
|
||||||
|
&& npm run build \
|
||||||
|
&& ls -la /app \
|
||||||
|
&& find /app ! -path '/app/node_modules/*'
|
||||||
|
|
||||||
|
|
||||||
|
## Client web server image
|
||||||
|
FROM ${NGINX_IMAGE}:${NGINX_VERSION}
|
||||||
|
|
||||||
|
|
||||||
|
COPY --from=appbuild app/build/ /usr/share/nginx/html/
|
||||||
|
|
||||||
|
# Copy the custom Nginx configuration
|
||||||
|
COPY default.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
RUN ls -la /usr/share/nginx/html/ \
|
||||||
|
&& chown root:root -R /usr/share/nginx/html/ \
|
||||||
|
&& chmod 755 -R /usr/share/nginx/html/ \
|
||||||
|
&& ls -la /usr/share/nginx/html/ \
|
||||||
|
&& find /usr/share/nginx/html/
|
11
client/Dockerfile.test
Normal file
11
client/Dockerfile.test
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
ARG NODE_IMAGE="node"
|
||||||
|
ARG NODE_VERSION="16.17.1-alpine"
|
||||||
|
|
||||||
|
FROM ${NODE_IMAGE}:${NODE_VERSION} AS appbuild
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . /app/
|
||||||
|
|
||||||
|
RUN npm test
|
||||||
|
|
8
client/default.conf
Normal file
8
client/default.conf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
4
client/dockerignore
Normal file
4
client/dockerignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Dokckerfile
|
||||||
|
Dokckerfile.*
|
||||||
|
node_modules
|
||||||
|
dockerignore
|
68
deploy-api.yml
Normal file
68
deploy-api.yml
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
- name: Deploy Application
|
||||||
|
hosts: api
|
||||||
|
remote_user: root
|
||||||
|
pre_tasks:
|
||||||
|
- name: "Assert project_name is provided and not empty"
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- project_name is not undefined and project_name != ""
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
# debug section
|
||||||
|
- debug: var=inventory_hostname
|
||||||
|
|
||||||
|
- name: check resolv.conf file exists
|
||||||
|
stat:
|
||||||
|
path: /etc/resolv.conf
|
||||||
|
register: resolv_conf
|
||||||
|
|
||||||
|
- name: print a debug message when resolv.config file does not exists
|
||||||
|
debug:
|
||||||
|
msg: "The resolv.conf path doesn't exist."
|
||||||
|
when: resolv_conf.stat.exists == False
|
||||||
|
|
||||||
|
- name: "read /etc/resolv.conf"
|
||||||
|
command: /bin/cat /etc/resolv.conf
|
||||||
|
register: resolv_content
|
||||||
|
|
||||||
|
- debug: msg="{{ resolv_content.stdout_lines | quote }}"
|
||||||
|
|
||||||
|
## Login
|
||||||
|
- name: Login to registry
|
||||||
|
docker_login:
|
||||||
|
registry_url: "{{ registry_url }}"
|
||||||
|
username: "{{ registry_username }}"
|
||||||
|
password: "{{ registry_password }}"
|
||||||
|
reauthorize: true
|
||||||
|
|
||||||
|
|
||||||
|
# Deploy image
|
||||||
|
- name: Create config directory
|
||||||
|
file:
|
||||||
|
path: "{{ config_dir }}" # /etc/app-x-y
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: Create .env file
|
||||||
|
file:
|
||||||
|
state: touch
|
||||||
|
path: "{{ config_dir }}/.env"
|
||||||
|
mode: '0600'
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose down
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: "Upload docker-compose template" # fills the tempalte with variables from ansile
|
||||||
|
template:
|
||||||
|
src: "templates/docker-compose-api.yml"
|
||||||
|
dest: "{{ config_dir }}/docker-compose.yml"
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose up -d
|
||||||
|
|
||||||
|
- name: Create log file
|
||||||
|
file:
|
||||||
|
path: "/var/log/{{ project_name }}"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
49
deploy-docker-ce.yml
Normal file
49
deploy-docker-ce.yml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
- name: Deploy Docker ce on Debian Based Systems
|
||||||
|
hosts: all
|
||||||
|
remote_user: root
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
- meta: end_play
|
||||||
|
when: ansible_facts['os_family'] != 'Debian'
|
||||||
|
|
||||||
|
- name: "install dependencies"
|
||||||
|
apt:
|
||||||
|
pkg:
|
||||||
|
- python3-pip
|
||||||
|
- apt-transport-https
|
||||||
|
|
||||||
|
- name: "Get docker signing key"
|
||||||
|
block:
|
||||||
|
- name: "Fetch docker text signing key"
|
||||||
|
get_url:
|
||||||
|
url: "https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}/gpg"
|
||||||
|
dest: "/usr/share/keyrings/docker.asc"
|
||||||
|
register: docker_gpg_key
|
||||||
|
- name: "De-armor docker gpg key"
|
||||||
|
shell: gpg --no-tty --yes -o /etc/apt/keyrings/docker.gpg --dearmor "/usr/share/keyrings/docker.asc"
|
||||||
|
when: docker_gpg_key.changed
|
||||||
|
|
||||||
|
- name: "Add docker repo"
|
||||||
|
apt_repository:
|
||||||
|
repo: deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }} {{ ansible_distribution_release }} stable
|
||||||
|
filename: docker
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: "Install docker packages"
|
||||||
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
pkg:
|
||||||
|
- docker-ce
|
||||||
|
- docker-ce-cli
|
||||||
|
- containerd.io
|
||||||
|
- docker-compose-plugin
|
||||||
|
|
||||||
|
- name: "install docker-compose"
|
||||||
|
pip:
|
||||||
|
name: docker-compose
|
||||||
|
executable: pip3
|
||||||
|
|
||||||
|
- name: "Create traefik docker network"
|
||||||
|
shell: docker network create --driver=bridge --subnet=172.28.0.0/16 --ip-range=172.28.5.0/24 --gateway=172.28.5.254 traefik_http
|
||||||
|
ignore_errors: yes
|
55
deploy-node-exporter.yml
Normal file
55
deploy-node-exporter.yml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
tasks:
|
||||||
|
- name: "Ensure group \"prometheus\" exists with correct gid"
|
||||||
|
group:
|
||||||
|
name: prometheus
|
||||||
|
state: present
|
||||||
|
gid: 2998
|
||||||
|
|
||||||
|
- name: "Add the user prometheus"
|
||||||
|
user:
|
||||||
|
name: prometheus
|
||||||
|
groups: prometheus
|
||||||
|
state: present
|
||||||
|
uid: 2998
|
||||||
|
|
||||||
|
- name: "Ensure group \"node_exporter\" exists with correct gid"
|
||||||
|
group:
|
||||||
|
name: node_exporter
|
||||||
|
state: present
|
||||||
|
gid: 2997
|
||||||
|
|
||||||
|
- name: "Add the user node_exporter"
|
||||||
|
user:
|
||||||
|
name: node_exporter
|
||||||
|
groups: node_exporter
|
||||||
|
state: present
|
||||||
|
uid: 2997
|
||||||
|
|
||||||
|
- name: Creating /opt/src
|
||||||
|
shell: |
|
||||||
|
mkdir -p /opt/src
|
||||||
|
|
||||||
|
- name: "Syncing dir to servers"
|
||||||
|
synchronize:
|
||||||
|
src: node_exportoer/node_exporter-1.7.0.linux-amd64.tar.gz
|
||||||
|
dest: /opt/src/node_exporter-1.7.0.linux-amd64.tar.gz
|
||||||
|
when:
|
||||||
|
|
||||||
|
- name: "Extracting node_exporter-1.4.0"
|
||||||
|
shell: |
|
||||||
|
tar xvf /opt/src/node_exporter-1.7.0.linux-amd64.tar.gz -C /opt/src/
|
||||||
|
cd /opt/src/node_exporter-*.linux-amd64 && cp -fv node_exporter /usr/local/bin/
|
||||||
|
|
||||||
|
- name: "Syncing service file to servers"
|
||||||
|
synchronize:
|
||||||
|
src: node_exporter/node-exporter.service
|
||||||
|
dest: /etc/systemd/system/node-exporter.service
|
||||||
|
|
||||||
|
- name: "Restart and enable the service node-exporter"
|
||||||
|
systemd:
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: yes
|
||||||
|
name: node-exporter
|
||||||
|
enabled: yes
|
41
deploy-portainer.yml
Normal file
41
deploy-portainer.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
- name: Deploy Portainer
|
||||||
|
hosts: all
|
||||||
|
remote_user: root
|
||||||
|
pre_tasks:
|
||||||
|
- name: "Assert config_dir is provided and not empty"
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- config_dir is not undefined and config_dir != ""
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
##
|
||||||
|
- name: "Create config directory"
|
||||||
|
file:
|
||||||
|
path: "{{ config_dir }}"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose down
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: "Upload docker-compose template"
|
||||||
|
template:
|
||||||
|
src: templates/docker-compose-portainer.yml
|
||||||
|
dest: "{{ config_dir }}/docker-compose.yml"
|
||||||
|
|
||||||
|
- name: "Upload gen-admin-passwd.sh"
|
||||||
|
copy:
|
||||||
|
src: portainer/gen-admin-passwd.sh
|
||||||
|
dest: "{{ config_dir }}/gen-admin-passwd.sh"
|
||||||
|
mode: a+x
|
||||||
|
|
||||||
|
- name: "Upload reset-admin-passwd.sh"
|
||||||
|
copy:
|
||||||
|
src: portainer/reset-admin-passwd.sh
|
||||||
|
dest: "{{ config_dir }}/reset-admin-passwd.sh"
|
||||||
|
mode: a+x
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose up -d
|
86
deploy-traefik.yml
Normal file
86
deploy-traefik.yml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
- name: Deploy Traefik Reverse Proxy
|
||||||
|
hosts: all
|
||||||
|
remote_user: root
|
||||||
|
pre_tasks:
|
||||||
|
- name: "Assert config_dir is provided and not empty"
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- config_dir is not undefined and config_dir != ""
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
##
|
||||||
|
- name: "Create config directory"
|
||||||
|
file:
|
||||||
|
path: "{{ config_dir }}"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: "Create config sub-directory certs"
|
||||||
|
file:
|
||||||
|
path: "{{ config_dir }}/certs"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: "Create config sub-directory traefik-config"
|
||||||
|
file:
|
||||||
|
path: "{{ config_dir }}/traefik-config"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
##
|
||||||
|
|
||||||
|
- name: "Upload config file: {{ config_dir }}/traefik.toml"
|
||||||
|
copy:
|
||||||
|
src: "traefik/traefik.toml"
|
||||||
|
dest: "{{ config_dir }}/traefik.toml"
|
||||||
|
|
||||||
|
- name: "Upload config file: {{ config_dir }}/traefik-config/auth-middleware.yml"
|
||||||
|
copy:
|
||||||
|
src: "traefik/auth-middleware.yml"
|
||||||
|
dest: "{{ config_dir }}/traefik-config/auth-middleware.yml"
|
||||||
|
|
||||||
|
- name: "Upload config file: {{ config_dir }}/traefik-config/certificates.yml"
|
||||||
|
copy:
|
||||||
|
src: "traefik/certificates.yml"
|
||||||
|
dest: "{{ config_dir }}/traefik-config/certificates.yml"
|
||||||
|
|
||||||
|
##
|
||||||
|
- name: "Check if \"{{ config_dir }}/certs/cert.pem\" file exists"
|
||||||
|
stat:
|
||||||
|
path: "{{ config_dir }}/certs/cert.pem"
|
||||||
|
register: certfile
|
||||||
|
|
||||||
|
- name: "copy file: \"{{ config_dir }}/certs/cert.pem\" if it doesn't exist"
|
||||||
|
copy:
|
||||||
|
src: traefik/cert.pem
|
||||||
|
dest: "{{ config_dir }}/certs/cert.pem"
|
||||||
|
when: not certfile.stat.exists
|
||||||
|
|
||||||
|
|
||||||
|
- name: "Check if \"{{ config_dir }}/certs/key.pem\" file exists"
|
||||||
|
stat:
|
||||||
|
path: "{{ config_dir }}/certs/key.pem"
|
||||||
|
register: keyfile
|
||||||
|
|
||||||
|
- name: "copy file: \"{{ config_dir }}/certs/key.pem\" if it doesn't exist"
|
||||||
|
copy:
|
||||||
|
src: traefik/key.pem
|
||||||
|
dest: "{{ config_dir }}/certs/key.pem"
|
||||||
|
when: not keyfile.stat.exists
|
||||||
|
##
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose down
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: "Upload docker-compose template"
|
||||||
|
template:
|
||||||
|
src: templates/docker-compose-traefik.yml
|
||||||
|
dest: "{{ config_dir }}/docker-compose.yml"
|
||||||
|
|
||||||
|
- name: "Create traefik docker network"
|
||||||
|
shell: docker network create --driver=bridge --subnet=172.28.0.0/16 --ip-range=172.28.5.0/24 --gateway=172.28.5.254 traefik_http
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose up -d
|
54
deploy-web.yml
Normal file
54
deploy-web.yml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
- name: Deploy Application
|
||||||
|
hosts: web
|
||||||
|
remote_user: root
|
||||||
|
pre_tasks:
|
||||||
|
- name: "Assert project_name is provided and not empty"
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- project_name is not undefined and project_name != ""
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
## Login
|
||||||
|
- name: Login to registry
|
||||||
|
docker_login:
|
||||||
|
registry_url: "{{ registry_url }}"
|
||||||
|
username: "{{ registry_username }}"
|
||||||
|
password: "{{ registry_password }}"
|
||||||
|
reauthorize: true
|
||||||
|
|
||||||
|
# Deploy image
|
||||||
|
- name: Create config directory
|
||||||
|
file:
|
||||||
|
path: "{{ config_dir }}" # /etc/app-x-y
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: Create .env file
|
||||||
|
file:
|
||||||
|
state: touch
|
||||||
|
path: "{{ config_dir }}/.env"
|
||||||
|
mode: '0600'
|
||||||
|
|
||||||
|
- name: Create .env.local file
|
||||||
|
file:
|
||||||
|
state: touch
|
||||||
|
path: "{{ config_dir }}/.env.local"
|
||||||
|
mode: '0600'
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose down
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: "Upload docker-compose template" # fills the tempalte with variables from ansile
|
||||||
|
template:
|
||||||
|
src: "templates/docker-compose-web.yml"
|
||||||
|
dest: "{{ config_dir }}/docker-compose.yml"
|
||||||
|
|
||||||
|
- name: Execute docker-compose
|
||||||
|
shell: cd "{{ config_dir }}" && docker-compose up -d
|
||||||
|
|
||||||
|
- name: Create log file
|
||||||
|
file:
|
||||||
|
path: "/var/log/{{ project_name }}"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
11
inventory
Normal file
11
inventory
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[api]
|
||||||
|
172.17.200.101 traefik_dashboard_hostname=traefik-service101.example.org api_domain=api201-service.example.org
|
||||||
|
172.17.200.102 traefik_dashboard_hostname=traefik-service102.example.org api_domain=api202-service.example.org
|
||||||
|
172.17.200.103 traefik_dashboard_hostname=traefik-service103.example.org api_domain=api203-service.example.org
|
||||||
|
172.17.200.104 traefik_dashboard_hostname=traefik-dev-service.example.org api_domain=dev-api-service.example.org
|
||||||
|
|
||||||
|
[web]
|
||||||
|
172.17.200.111 traefik_dashboard_hostname=traefik-service111.example.org web_status_id=service231.example.org web_domain=service231.example.org
|
||||||
|
172.17.200.112 traefik_dashboard_hostname=traefik-service112.example.org web_status_id=service232.example.org web_domain=service232.example.org
|
||||||
|
172.17.200.113 traefik_dashboard_hostname=traefik-service113.example.org web_status_id=service233.example.org web_domain=service233.example.org
|
||||||
|
172.17.200.114 traefik_dashboard_hostname=traefik-dev-service.example.org web_status_id=dev-service.example.org web_domain=dev-service.example.org
|
13
node_exportoer/node-exporter.service
Normal file
13
node_exportoer/node-exporter.service
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Prometheus Node Exporter
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=node_exporter
|
||||||
|
Group=node_exporter
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/node_exporter
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
BIN
node_exportoer/node_exporter-1.7.0.linux-amd64.tar.gz
Normal file
BIN
node_exportoer/node_exporter-1.7.0.linux-amd64.tar.gz
Normal file
Binary file not shown.
19
portainer/gen-admin-passwd.sh
Normal file
19
portainer/gen-admin-passwd.sh
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
USERNAME="admin"
|
||||||
|
PASSWORD="$1"
|
||||||
|
if [ -z "\${PASSWORD}" ]; then
|
||||||
|
echo -e "\\nPlease call '\$0 <password>' to run this command!\\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
which htpasswd
|
||||||
|
if [ "$?" -gt "0" ]
|
||||||
|
then
|
||||||
|
PASS=$(docker run --entrypoint htpasswd httpd:2 -bn -B ${USERNAME} ${PASSWORD} | cut -d ":" -f 2 )
|
||||||
|
else
|
||||||
|
PASS=$(htpasswd -nb -B admin ${PASSWORD} | cut -d ":" -f 2)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "plaintext encryption: ${PASS}"
|
||||||
|
echo "docker-compse.yml escaped: ${PASS}"|sed -e "s@\\\$@\\\$\\\$@g"
|
7
portainer/reset-admin-passwd.sh
Normal file
7
portainer/reset-admin-passwd.sh
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
docker run --rm -v portainer_data:/data/ portainer/helper-reset-password
|
||||||
|
|
||||||
|
docker-compose up -d
|
23
server/Dockerfile
Normal file
23
server/Dockerfile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
ARG NODE_IMAGE="node"
|
||||||
|
ARG NODE_VERSION="16.17.1-slim"
|
||||||
|
|
||||||
|
FROM ${NODE_IMAGE}:${NODE_VERSION}
|
||||||
|
|
||||||
|
WORKDIR /project
|
||||||
|
|
||||||
|
COPY package.json package-lock.json /project/
|
||||||
|
|
||||||
|
RUN npm ci --no-audit --no-fund
|
||||||
|
|
||||||
|
COPY --chown=node:node . /project/
|
||||||
|
|
||||||
|
RUN chown node:node /project -R && \
|
||||||
|
find /project -type d -exec chmod 0750 {} \; && \
|
||||||
|
find /project -type f -exec chmod 0650 {} \; && \
|
||||||
|
ls -la /project && \
|
||||||
|
find /project ! -path '/project/node_modules/*'
|
||||||
|
|
||||||
|
# Run as node (user id 1000)
|
||||||
|
USER node
|
||||||
|
|
||||||
|
CMD ["node", "/project/app.js"]
|
10
server/Dockerfile.test
Normal file
10
server/Dockerfile.test
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
ARG NODE_IMAGE="node"
|
||||||
|
ARG NODE_VERSION="16.17.1-slim"
|
||||||
|
|
||||||
|
FROM ${NODE_IMAGE}:${NODE_VERSION}
|
||||||
|
|
||||||
|
WORKDIR /project
|
||||||
|
|
||||||
|
COPY . /project/
|
||||||
|
|
||||||
|
RUN npm test
|
23
server/app.js
Normal file
23
server/app.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
require('dotenv').config();
|
||||||
|
const express = require('express');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const port = 3001;
|
||||||
|
const session = require('express-session');
|
||||||
|
|
||||||
|
app.use(session({
|
||||||
|
resave: false,
|
||||||
|
saveUninitialized: false,
|
||||||
|
cookie: {
|
||||||
|
secure: process.env.SECURE === 'true',
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Server running on http://localhost:${port}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
4
server/dockerignore
Normal file
4
server/dockerignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Dokckerfile
|
||||||
|
Dokckerfile.*
|
||||||
|
node_modules
|
||||||
|
dockerignore
|
26
templates/docker-compose-api.yml
Normal file
26
templates/docker-compose-api.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
api:
|
||||||
|
image: "{{ api_image }}"
|
||||||
|
volumes:
|
||||||
|
- /var/log/{{ project_name }}:/var/log
|
||||||
|
env_file:
|
||||||
|
- "{{ config_dir }}/.env"
|
||||||
|
environment:
|
||||||
|
PORT: 3002
|
||||||
|
expose:
|
||||||
|
- 3002
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.{{ project_name }}-client.rule: 'Host(`{{ api_domain }}`)'
|
||||||
|
traefik.http.routers.{{ project_name }}-client.entryPoints: https
|
||||||
|
traefik.http.routers.{{ project_name }}-client.tls: true
|
||||||
|
networks:
|
||||||
|
- http
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
networks:
|
||||||
|
http:
|
||||||
|
external: true
|
||||||
|
name: traefik_http
|
19
templates/docker-compose-portainer.yml
Normal file
19
templates/docker-compose-portainer.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
portainer:
|
||||||
|
image: portainer/portainer-ce:latest
|
||||||
|
command: [ "--admin-password=$$2y$$05$$7pyfUY3vUdgTe/CMoV.jT.t01EU71OgqjIu.jd9pQGLEVCW.GFqbO" ]
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- portainer_data:/data
|
||||||
|
labels:
|
||||||
|
traefik.enable: 'false'
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
portainer_data:
|
||||||
|
driver: local
|
||||||
|
name: portainer_data
|
29
templates/docker-compose-traefik.yml
Normal file
29
templates/docker-compose-traefik.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:v2.11
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- "{{ config_dir }}/traefik.toml:/etc/traefik/traefik.toml:ro"
|
||||||
|
- "{{ config_dir }}/traefik-config:/etc/traefik-config:ro"
|
||||||
|
- "{{ config_dir }}/certs:/certs:ro"
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
labels:
|
||||||
|
traefik.enable: 'true'
|
||||||
|
traefik.http.routers.dashboard-secure.rule: 'Host(`{{ traefik_dashboard_hostname }}`)'
|
||||||
|
traefik.http.routers.dashboard-secure.service: 'api@internal'
|
||||||
|
traefik.http.routers.dashboard-secure.middlewares: 'auth@file'
|
||||||
|
traefik.http.routers.dashboard-secure.entrypoints: 'https'
|
||||||
|
traefik.http.routers.dashboard-secure.tls: 'true'
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- http
|
||||||
|
|
||||||
|
networks:
|
||||||
|
http:
|
||||||
|
external: true
|
||||||
|
name: traefik_http
|
40
templates/docker-compose-web.yml
Normal file
40
templates/docker-compose-web.yml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
version: '3.9'
|
||||||
|
|
||||||
|
services:
|
||||||
|
client:
|
||||||
|
image: "{{ client_image }}"
|
||||||
|
env_file:
|
||||||
|
- "{{ config_dir }}/.env.local"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.{{ project_name }}-client.rule: '( Host(`{{ web_domain }}`) || Host(`{{ project_domain }}`) )'
|
||||||
|
traefik.http.routers.{{ project_name }}-client.entryPoints: https
|
||||||
|
traefik.http.routers.{{ project_name }}-client.tls: true
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- http
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
server:
|
||||||
|
image: "{{ server_image }}"
|
||||||
|
env_file:
|
||||||
|
- "{{ config_dir }}/.env"
|
||||||
|
environment:
|
||||||
|
PORT: 3001
|
||||||
|
CHECK_STATUS_ID: "{{ web_status_id }}"
|
||||||
|
|
||||||
|
expose:
|
||||||
|
- 3001
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.{{ project_name }}-server.rule: '( Host(`{{ web_domain }}`) || Host(`{{ project_domain }}`) ) && ( PathPrefix(`/api`) || PathPrefix(`/app`) )'
|
||||||
|
traefik.http.routers.{{ project_name }}-server.entryPoints: https
|
||||||
|
traefik.http.routers.{{ project_name }}-server.tls: true
|
||||||
|
networks:
|
||||||
|
- http
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
networks:
|
||||||
|
http:
|
||||||
|
external: true
|
||||||
|
name: traefik_http
|
6
traefik/auth-middleware.yml
Normal file
6
traefik/auth-middleware.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
auth:
|
||||||
|
basicauth:
|
||||||
|
users:
|
||||||
|
- 'admin:!!!'
|
26
traefik/certificates.yml
Normal file
26
traefik/certificates.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
tls:
|
||||||
|
stores:
|
||||||
|
default:
|
||||||
|
defaultCertificate:
|
||||||
|
certFile: /certs/star_example.org/fullchain.cer
|
||||||
|
keyFile: /certs/star_example.org/star_example.org.key
|
||||||
|
certificates:
|
||||||
|
- certFile: /certs/star_example.org/fullchain.cer
|
||||||
|
keyFile: /certs/star_example.org/star_example.org.key
|
||||||
|
|
||||||
|
stores:
|
||||||
|
- default
|
||||||
|
options:
|
||||||
|
default:
|
||||||
|
minVersion: VersionTLS12
|
||||||
|
alpnProtocols:
|
||||||
|
- http/1.1
|
||||||
|
- h2
|
||||||
|
preferServerCipherSuites: true
|
||||||
|
cipherSuites:
|
||||||
|
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
|
23
traefik/traefik.toml
Normal file
23
traefik/traefik.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[entryPoints.http]
|
||||||
|
address = ":80"
|
||||||
|
[entryPoints.http.http.redirections.entryPoint]
|
||||||
|
to = "https"
|
||||||
|
scheme = "https"
|
||||||
|
[entryPoints.https]
|
||||||
|
address = ":443"
|
||||||
|
|
||||||
|
[http.middleware]
|
||||||
|
|
||||||
|
[api]
|
||||||
|
dashboard = true
|
||||||
|
|
||||||
|
[providers]
|
||||||
|
[providers.docker]
|
||||||
|
useBindPortIP = true
|
||||||
|
exposedByDefault = false
|
||||||
|
[providers.file]
|
||||||
|
directory = "/etc/traefik-config/"
|
||||||
|
watch = true
|
||||||
|
debugLogGeneratedTemplate = true
|
||||||
|
|
||||||
|
[accessLog]
|
Loading…
Reference in New Issue
Block a user