Set up demo deployment.
gitea/icedream/rekt-theme/master There was a failure building this commit Details

header/meta/side-by-side
Icedream 2018-07-13 14:21:24 +02:00
parent 185a5e2e16
commit cfc86cb543
Signed by: icedream
GPG Key ID: 1573F6D8EFE4D0CF
6 changed files with 205 additions and 0 deletions

39
.dockerignore Normal file
View File

@ -0,0 +1,39 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
# webpack output
dist
# checkstyle results
checkstyle_*.xml
###
# only pass pre-built files to Docker
.*
*
!Caddyfile.dist
!dist/

3
Caddyfile.dist Normal file
View File

@ -0,0 +1,3 @@
http://:80
root /htdocs/

5
Dockerfile.dist Normal file
View File

@ -0,0 +1,5 @@
FROM icedream/caddy
WORKDIR /data/
COPY Caddyfile.dist /data/Caddyfile
COPY dist/ /htdocs/

114
Jenkinsfile vendored
View File

@ -1,7 +1,37 @@
def gitBranchSlugUnderscore = env.BRANCH_NAME.replaceAll(/[^A-Za-z0-9]/, "_") def gitBranchSlugUnderscore = env.BRANCH_NAME.replaceAll(/[^A-Za-z0-9]/, "_")
def gitBranchSlugDash = env.BRANCH_NAME.replaceAll(/[^A-Za-z0-9]/, "-") def gitBranchSlugDash = env.BRANCH_NAME.replaceAll(/[^A-Za-z0-9]/, "-")
// Stack name under which to deploy the stack, must not conflict with other
// projects!
def dockerStackName = "rekttheme_${gitBranchSlugUnderscore}"
// Hostnames
/*
| Component | master | develop | other branches |
| --- | --- | --- | --- |
| Frontend | https://rekt-theme.icedream.tech | https://develop.review.rekt-theme.icedream.tech | https://${gitBranchSlugDash}.review.rekt-theme.icedream.tech |
*/
def projectDomainBase = 'rekt-theme.icedream.tech'
def projectReviewDomainBase = "review.${projectDomainBase}"
def projectTag = "latest"
def projectFrontendHostname = projectDomainBase
if (env.BRANCH_NAME != "master") {
projectTag = gitBranchSlugDash
projectFrontendHostname = "${gitBranchSlugDash}.${projectReviewDomainBase}"
}
// How to access the swarm manager of the deployment infrastructure
def dockerSwarmManagerUrl = 'tcp://prod-docker-mgr.dmz.dreamnetwork.oss:2375'
def dockerSwarmManagerCredentials = 'docker_socket_project_gitea_icedream'
// Docker image version tags
def dockerVersion = '18.03'
def dockerComposeVersion = '1.21.2'
// Fully qualified docker images to pull // Fully qualified docker images to pull
def dockerImage = "docker:${dockerVersion}"
def dockerComposeImage = "docker/compose:${dockerComposeVersion}"
def nodeImage = "node:8" def nodeImage = "node:8"
// Abort build under some conditions // Abort build under some conditions
@ -37,6 +67,9 @@ pipeline {
options { options {
ansiColor('xterm') ansiColor('xterm')
} }
environment {
REKTTHEME_FRONTEND_HOSTNAME = "${projectFrontendHostname}"
}
stages { stages {
stage('yarn:install') { stage('yarn:install') {
agent { agent {
@ -50,6 +83,7 @@ pipeline {
stash name: 'node_modules', includes: 'node_modules/**' stash name: 'node_modules', includes: 'node_modules/**'
} }
} }
stage('code-quality:lint') { stage('code-quality:lint') {
parallel { parallel {
stage('code-quality:lint:eslint') { stage('code-quality:lint:eslint') {
@ -86,6 +120,7 @@ pipeline {
} }
} }
} }
stage('code-quality:lint-publish') { stage('code-quality:lint-publish') {
agent { agent {
docker { docker {
@ -99,6 +134,7 @@ pipeline {
checkstyle canRunOnFailed: true, pattern: 'checkstyle_*.xml' checkstyle canRunOnFailed: true, pattern: 'checkstyle_*.xml'
} }
} }
stage('build') { stage('build') {
agent { agent {
docker { docker {
@ -114,5 +150,83 @@ pipeline {
} }
} }
} }
stage('build:image') {
agent {
docker {
label 'docker && linux && amd64'
image dockerImage
// pass through to host Docker instance
args '-v /var/run/docker.sock:/var/run/docker.sock'
}
}
environment {
REKTTHEME_FRONTEND_IMAGE = "${dockerProjectFrontendImageName}:${projectTag}"
}
steps {
sh """
apk add --no-cache python3 py3-pip
pip3 install docker-compose==${dockerComposeVersion}
"""
sh """
export PATH="$PATH:/var/tmp/deps/docker-compose"
cd deployment
docker-compose build \"frontend\"
docker-compose push \"frontend\"
"""
sh "docker inspect -f \"REKTTHEME_FRONTEND_IMAGE={{index .RepoDigests 0}}\" \"${dockerProjectFrontendImageName}:${projectTag}\" > deployment/frontend.env"
stash includes: 'deployment/frontend.env', name: 'deploymentFrontendEnv'
}
}
stage('predeploy') {
parallel {
stage('predeploy:stack-config') {
agent {
docker {
label 'docker'
image dockerImage
}
}
steps {
sh """
apk add --no-cache python3 py3-pip
pip3 install docker-compose==${dockerComposeVersion}
"""
unstash "deploymentFrontendEnv"
sh """
export PATH="$PATH:/var/tmp/deps/docker-compose"
cd deployment
for envfile in ./*.env; do
source \"\${envfile}\"
done
export REKTTHEME_FRONTEND_IMAGE
docker-compose config > .docker-compose.yml
"""
archive "deployment/.docker-compose.yml"
stash includes: 'deployment/.docker-compose.yml', name: 'finalStackConfig'
}
}
}
}
stage('deploy') {
agent {
label 'docker'
}
steps {
unstash "finalStackConfig"
script {
docker.withServer(dockerSwarmManagerUrl, dockerSwarmManagerCredentials) {
sh "docker stack rm ${dockerStackName}"
sleep 10
sh "cd deployment && docker stack deploy -c .docker-compose.yml ${dockerStackName}"
}
currentBuild.description = """
- Frontend web server:\thttps://${env.REKTTHEME_FRONTEND_HOSTNAME}
"""
}
}
}
} }
} }

1
deployment/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.env

View File

@ -0,0 +1,43 @@
# Docker Compose project stack
# This will be used by Jenkins to fire up the project on the server.
version: "3.5"
networks:
# Private network with all containers that will be published via HTTP/HTTPS
overlay_web_front:
external: true
x-security-headers: &security_headers
traefik.frontend.headers.SSLRedirect: "true"
traefik.frontend.headers.ForceSTSHeader: "true"
traefik.frontend.headers.STSSeconds: "315360000"
traefik.frontend.headers.referrerPolicy: "same-origin"
traefik.frontend.headers.contentTypeNosniff: "true"
traefik.frontend.headers.browserXSSFilter: "true"
traefik.frontend.headers.frameDeny: "true"
#traefik.frontend.headers.contentSecurityPolicy: "default-src 'none'; base-uri 'none'; form-action 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self'; media-src 'none'; frame-src 'none'; frame-ancestors 'none'; font-src 'self'; connect-src 'self'"
services:
# Single page frontend application
frontend:
image: ${REKTTHEME_FRONTEND_IMAGE:-docker.dreamnetwork.oss:5000/rekt-theme/rekt-theme-frontend}
build:
context: ..
dockerfile: Dockerfile.dist
env_file:
- frontend.env
deploy:
mode: global
placement:
constraints:
- node.labels.deployment.production == 1
- node.platform.os == linux
- node.platform.arch == x86_64
labels:
<<: *security_headers
traefik.port: "80"
traefik.frontend.rule: "Host:${REKTTHEME_FRONTEND_HOSTNAME:-rekt-theme.icedream.tech}"
traefik.docker.network: overlay_web_front
networks:
overlay_web_front: