mirror of
https://github.com/offen/website.git
synced 2024-11-25 10:10:28 +01:00
Merge pull request #32 from offen/static-deployment
Deploy to s3/cloudfront, remove elastic beanstalk deployment
This commit is contained in:
commit
b656329011
@ -1,75 +1,9 @@
|
||||
version: 2
|
||||
|
||||
build_preconditions: &build_preconditions
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- development
|
||||
|
||||
deploy_preconditions: &deploy_preconditions
|
||||
requires:
|
||||
- build
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- development
|
||||
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: docker:18-git
|
||||
working_directory: ~/offen
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-{{ .Branch }}
|
||||
paths:
|
||||
- /caches/website.tar
|
||||
- run:
|
||||
name: Load Docker image layer cache
|
||||
command: |
|
||||
set +o pipefail
|
||||
docker load -i /caches/website.tar | true
|
||||
- run:
|
||||
name: Build application Docker image
|
||||
command: |
|
||||
if [ "${CIRCLE_BRANCH}" == "master" ]; then
|
||||
export SITEURL="https://www.offen.dev"
|
||||
export DOCKER_IMAGE_TAG="stable"
|
||||
export ROBOTS_FILE="robots.txt.production"
|
||||
else
|
||||
export SITEURL="https://staging.offen.dev"
|
||||
export DOCKER_IMAGE_TAG="latest"
|
||||
export ROBOTS_FILE="robots.txt.staging"
|
||||
fi
|
||||
docker build --build-arg siteurl=$SITEURL --build-arg robots=$ROBOTS_FILE -t offen/website:$DOCKER_IMAGE_TAG -f build/Dockerfile .
|
||||
- run:
|
||||
name: Save Docker image layer cache
|
||||
command: |
|
||||
mkdir -p /caches
|
||||
docker save -o /caches/website.tar offen/website
|
||||
- save_cache:
|
||||
key: v1-{{ .Branch }}-{{ epoch }}
|
||||
paths:
|
||||
- /caches/website.tar
|
||||
- deploy:
|
||||
name: Push application Docker image
|
||||
command: |
|
||||
if [ "${CIRCLE_BRANCH}" == "master" ]; then
|
||||
export DOCKER_IMAGE_TAG="stable"
|
||||
else
|
||||
export DOCKER_IMAGE_TAG="latest"
|
||||
fi
|
||||
echo "$DOCKER_ACCESSTOKEN" | docker login --username $DOCKER_USER --password-stdin
|
||||
docker push offen/website:$DOCKER_IMAGE_TAG
|
||||
|
||||
deploy:
|
||||
docker:
|
||||
- image: circleci/golang:1.13
|
||||
- image: circleci/python:3.7
|
||||
working_directory: ~/offen
|
||||
steps:
|
||||
- checkout
|
||||
@ -77,34 +11,29 @@ jobs:
|
||||
- run:
|
||||
name: Install deployment dependencies
|
||||
command: |
|
||||
sudo apt-get update && sudo apt-get install -qq -y python-pip libpython-dev
|
||||
curl -O https://bootstrap.pypa.io/get-pip.py && sudo python get-pip.py
|
||||
sudo pip install -q awscli --upgrade
|
||||
sudo pip install awsebcli --upgrade
|
||||
- run:
|
||||
name: Define target environment
|
||||
name: Build and deploy to S3
|
||||
command: |
|
||||
if [ "${CIRCLE_BRANCH}" == "master" ]; then
|
||||
echo 'export TARGET_ENVIRONMENT="production"' >> $BASH_ENV
|
||||
echo 'export DOCKER_IMAGE_TAG="stable"' >> $BASH_ENV
|
||||
export SITEURL="https://www.offen.dev"
|
||||
export BUCKET="offen-dev-production"
|
||||
export ROBOTS_FILE="robots.txt.production"
|
||||
else
|
||||
echo 'export TARGET_ENVIRONMENT="staging"' >> $BASH_ENV
|
||||
echo 'export DOCKER_IMAGE_TAG="latest"' >> $BASH_ENV
|
||||
export SITEURL="https://staging.offen.dev"
|
||||
export BUCKET="offen-dev-staging"
|
||||
export ROBOTS_FILE="robots.txt.staging"
|
||||
fi
|
||||
- run:
|
||||
name: Run database migrations
|
||||
command: docker run -it offen/offen:offen@sha256:4c0d2d5db9bc749d21ad8659008658bf25318074b7c813b0a694e64816df750d migrate -conn $(aws secretsmanager get-secret-value --secret-id $TARGET_ENVIRONMENT/postgresConnectionString | jq -r '.SecretString')
|
||||
- run:
|
||||
name: Deploy
|
||||
command: |
|
||||
cp Dockerrun.aws.json.$TARGET_ENVIRONMENT Dockerrun.aws.json
|
||||
eb deploy
|
||||
make build
|
||||
aws s3 sync --delete ./output/. s3://$BUCKET
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build_deploy:
|
||||
jobs:
|
||||
- build:
|
||||
<<: *build_preconditions
|
||||
- deploy:
|
||||
<<: *deploy_preconditions
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- development
|
||||
|
@ -1,20 +0,0 @@
|
||||
branch-defaults:
|
||||
master:
|
||||
environment: production
|
||||
group_suffix: null
|
||||
development:
|
||||
environment: staging
|
||||
group_suffix: null
|
||||
global:
|
||||
application_name: offen
|
||||
branch: null
|
||||
default_ec2_keyname: aws-eb
|
||||
default_platform: Multi-container Docker 18.06.1-ce (Generic)
|
||||
default_region: eu-central-1
|
||||
include_git_submodules: true
|
||||
instance_profile: null
|
||||
platform_name: null
|
||||
platform_version: null
|
||||
repository: null
|
||||
sc: null
|
||||
workspace_type: Application
|
@ -1,52 +0,0 @@
|
||||
{
|
||||
"AWSEBDockerrunVersion": 2,
|
||||
"containerDefinitions": [
|
||||
{
|
||||
"name": "proxy",
|
||||
"image": "offen/website:stable",
|
||||
"essential": true,
|
||||
"memory": 128,
|
||||
"portMappings": [
|
||||
{
|
||||
"hostPort": 80,
|
||||
"containerPort": 80
|
||||
}
|
||||
],
|
||||
"dependsOn": [
|
||||
{
|
||||
"containerName": "server",
|
||||
"condition": "START"
|
||||
}
|
||||
],
|
||||
"links": ["server"],
|
||||
"logConfiguration": {
|
||||
"logDriver": "awslogs",
|
||||
"options": {
|
||||
"awslogs-create-group": true,
|
||||
"awslogs-group": "production",
|
||||
"awslogs-region": "eu-central-1",
|
||||
"awslogs-stream-prefix": "proxy"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"image": "offen/offen@sha256:4c0d2d5db9bc749d21ad8659008658bf25318074b7c813b0a694e64816df750d",
|
||||
"essential": true,
|
||||
"memory": 256,
|
||||
"command": ["serve"],
|
||||
"environment": [
|
||||
{ "name": "OFFEN_SERVER_REVERSEPROXY", "value": "1" }
|
||||
],
|
||||
"logConfiguration": {
|
||||
"logDriver": "awslogs",
|
||||
"options": {
|
||||
"awslogs-create-group": true,
|
||||
"awslogs-group": "production",
|
||||
"awslogs-region": "eu-central-1",
|
||||
"awslogs-stream-prefix": "server"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
{
|
||||
"AWSEBDockerrunVersion": 2,
|
||||
"volumes": [],
|
||||
"containerDefinitions": [
|
||||
{
|
||||
"name": "proxy",
|
||||
"image": "offen/website:latest",
|
||||
"essential": true,
|
||||
"memory": 128,
|
||||
"portMappings": [
|
||||
{
|
||||
"hostPort": 80,
|
||||
"containerPort": 80
|
||||
}
|
||||
],
|
||||
"dependsOn": [
|
||||
{
|
||||
"containerName": "server",
|
||||
"condition": "START"
|
||||
}
|
||||
],
|
||||
"links": ["server"],
|
||||
"logConfiguration": {
|
||||
"logDriver": "awslogs",
|
||||
"options": {
|
||||
"awslogs-create-group": true,
|
||||
"awslogs-group": "staging",
|
||||
"awslogs-region": "eu-central-1",
|
||||
"awslogs-stream-prefix": "proxy"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"image": "offen/offen@sha256:4c0d2d5db9bc749d21ad8659008658bf25318074b7c813b0a694e64816df750d",
|
||||
"essential": true,
|
||||
"memory": 256,
|
||||
"command": ["serve"],
|
||||
"environment": [
|
||||
{ "name": "OFFEN_SERVER_REVERSEPROXY", "value": "1" }
|
||||
],
|
||||
"logConfiguration": {
|
||||
"logDriver": "awslogs",
|
||||
"options": {
|
||||
"awslogs-create-group": true,
|
||||
"awslogs-group": "staging",
|
||||
"awslogs-region": "eu-central-1",
|
||||
"awslogs-stream-prefix": "server"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
37
Makefile
37
Makefile
@ -2,14 +2,11 @@ help:
|
||||
@echo " setup"
|
||||
@echo " Build the development containers and install dependencies."
|
||||
@echo " update"
|
||||
@echo " Install / update dependencies in the containers."
|
||||
@echo " bootstrap"
|
||||
@echo " Set up and seed databases."
|
||||
@echo " **IMPORTANT**: this wipes any existing data in your local database."
|
||||
@echo " Install / update dependencies in the development containers."
|
||||
@echo " build"
|
||||
@echo " Build the production images."
|
||||
@echo " Build the production assets."
|
||||
|
||||
setup: dev-build update howto
|
||||
setup: dev-build update
|
||||
|
||||
dev-build:
|
||||
@docker-compose build
|
||||
@ -17,32 +14,20 @@ dev-build:
|
||||
up:
|
||||
@docker-compose up
|
||||
|
||||
howto:
|
||||
@echo "Successfully built containers and installed dependencies."
|
||||
@echo "If this is your initial setup, you can run 'make bootstrap' next"
|
||||
@echo "to create and seed the database."
|
||||
|
||||
bootstrap:
|
||||
@echo "Bootstrapping Server service ..."
|
||||
@docker-compose run server bootstrap
|
||||
@echo ""
|
||||
@echo "You can now log into the development backend using the following credentials:"
|
||||
@echo ""
|
||||
@echo "Email: develop@offen.dev"
|
||||
@echo "Password: develop"
|
||||
@echo ""
|
||||
|
||||
update:
|
||||
@echo "Installing / updating dependencies ..."
|
||||
@docker-compose run homepage pip install --user -r requirements.txt
|
||||
@echo "Applying pending database migrations ..."
|
||||
@docker-compose run server migrate
|
||||
@echo "Successfully built containers and installed dependencies."
|
||||
|
||||
DOCKER_IMAGE_TAG ?= local
|
||||
ROBOTS_FILE ?= robots.txt.staging
|
||||
SITEURL ?= http://localhost:8000
|
||||
|
||||
build:
|
||||
@docker build --build-arg siteurl=${SITEURL} --build-arg robots=${ROBOTS_FILE} -t offen/website:${DOCKER_IMAGE_TAG} -f build/Dockerfile .
|
||||
@docker build --build-arg siteurl=${SITEURL} -t offen/website -f build/Dockerfile .
|
||||
@rm -rf output && mkdir output
|
||||
@docker create --entrypoint=bash -it --name assets offen/website
|
||||
@docker cp assets:/code/homepage/output/. ./output/
|
||||
@cp build/${ROBOTS_FILE} ./output/robots.txt
|
||||
@docker rm assets
|
||||
|
||||
.PHONY: setup build bootstrap build
|
||||
.PHONY: setup build up
|
||||
|
@ -1,29 +1,19 @@
|
||||
FROM nikolaik/python-nodejs:python3.7-nodejs10 as homepage
|
||||
FROM nikolaik/python-nodejs:python3.7-nodejs10
|
||||
|
||||
ENV PATH "/root/.local/bin:$PATH"
|
||||
ENV NODE_PATH="/usr/lib/node_modules"
|
||||
|
||||
ARG siteurl
|
||||
ENV SITEURL=$siteurl
|
||||
|
||||
COPY ./homepage /code/homepage
|
||||
|
||||
RUN npm install -g postcss-cli@^6.1.3 autoprefixer@^9.7.0 svgo@^1.3.0
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y libjpeg-progs optipng \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /code/homepage
|
||||
ENV PATH "/root/.local/bin:$PATH"
|
||||
ENV NODE_PATH="/usr/lib/node_modules"
|
||||
COPY ./homepage/requirements.txt /code/homepage/requirements.txt
|
||||
RUN pip install --user -r requirements.txt
|
||||
RUN make publish
|
||||
|
||||
FROM nginx:1.17-alpine
|
||||
LABEL maintainer="mail@offen.dev"
|
||||
|
||||
ARG robots
|
||||
ENV ROBOTS_FILE=$robots
|
||||
|
||||
COPY --from=homepage /code/homepage/output /www/data
|
||||
COPY ./build/$ROBOTS_FILE /www/data/robots.txt
|
||||
COPY ./build/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
EXPOSE 80
|
||||
COPY ./homepage /code/homepage
|
||||
RUN make publish && rm -rf output/theme/.webassets-cache
|
||||
|
@ -1,96 +0,0 @@
|
||||
events {}
|
||||
|
||||
http {
|
||||
gzip on;
|
||||
gzip_types *;
|
||||
gzip_comp_level 2;
|
||||
gzip_min_length 1000;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
|
||||
include mime.types;
|
||||
upstream server {
|
||||
server server:3000;
|
||||
}
|
||||
|
||||
map $request_uri $expires {
|
||||
default off;
|
||||
"~-[0-9a-z]{10}\.js$" 365d;
|
||||
"~*(woff|woff2|ttf|eot)$" 365d;
|
||||
}
|
||||
|
||||
map $sent_http_content_type $csp {
|
||||
default "";
|
||||
"~^text/html" "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'";
|
||||
}
|
||||
|
||||
server {
|
||||
# 404 for any request that does match the server names defined below
|
||||
listen 80;
|
||||
return 404;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
autoindex on;
|
||||
root /www/data;
|
||||
expires $expires;
|
||||
server_name www.offen.dev staging.offen.dev;
|
||||
add_header Content-Security-Policy $csp;
|
||||
add_header Strict-Transport-Security 'max-age=604800; includeSubDomains';
|
||||
add_header Referrer-Policy 'origin-when-cross-origin';
|
||||
add_header X-Content-Type-Options 'nosniff';
|
||||
add_header X-XSS-Protection '1; mode=block';
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /vault/ {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /auditorium/ {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /script.js {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /healthz {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /versionz {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /normalize.css {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /skeleton.css {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /favicon.ico {
|
||||
root /www/data/theme/images;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
location = /404.html {
|
||||
internal;
|
||||
root /www/data;
|
||||
add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive" always;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,22 +9,6 @@ services:
|
||||
- 8000:80
|
||||
depends_on:
|
||||
- homepage
|
||||
- server
|
||||
|
||||
server:
|
||||
image: offen/offen@sha256:91845f3e0e80f7d1871f58dabd08e8614ec70f6ff37ef7e9b675d0f4f1c9ca13
|
||||
command: serve
|
||||
volumes:
|
||||
- ./bootstrap.yml:/bootstrap.yml
|
||||
- database:/data
|
||||
environment:
|
||||
OFFEN_APP_EVENTRETENTIONPERIOD: 4464h
|
||||
OFFEN_APP_DISABLESECURECOOKIE: '1'
|
||||
OFFEN_DATABASE_CONNECTIONSTRING: /data/offen.db
|
||||
OFFEN_SERVER_PORT: 8080
|
||||
OFFEN_SERVER_REVERSEPROXY: '1'
|
||||
OFFEN_SECRETS_COOKIEEXCHANGE: 8jeKYbbnywoYIZznu4HffQ==
|
||||
OFFEN_SECRETS_EMAILSALT: eypctS7SVKM1Ureb61db5Q==
|
||||
|
||||
homepage:
|
||||
build:
|
||||
@ -40,4 +24,3 @@ services:
|
||||
|
||||
volumes:
|
||||
homepagedeps:
|
||||
database:
|
||||
|
@ -25,8 +25,8 @@
|
||||
{% assets filters="postcss,cssmin", output="css/style.min.css", "css/tachyons.min.css", "css/fix.css", "css/fonts.css" %}
|
||||
<link rel="stylesheet" href="/{{ ASSET_URL }}">
|
||||
{% endassets %}
|
||||
<link rel="preload" href="/theme/fonts/rubik-v9-latin-regular.woff2" as="font">
|
||||
<link rel="preload" href="/theme/fonts/rubik-v9-latin-500.woff2" as="font">
|
||||
<link rel="preload" href="/theme/fonts/rubik-v9-latin-regular.woff2" as="font" crossorigin>
|
||||
<link rel="preload" href="/theme/fonts/rubik-v9-latin-500.woff2" as="font" crossorigin>
|
||||
{% if OFFEN_ACCOUNT_ID and not no_stats %}
|
||||
<script async src="/script.js" data-account-id="{{ OFFEN_ACCOUNT_ID }}"></script>
|
||||
{% endif %}
|
||||
|
48
nginx.conf
48
nginx.conf
@ -7,10 +7,6 @@ http {
|
||||
server homepage:8000;
|
||||
}
|
||||
|
||||
upstream server {
|
||||
server server:8080;
|
||||
}
|
||||
|
||||
map $request_uri $expires {
|
||||
default off;
|
||||
"~-[0-9a-z]{10}\.js$" 1d;
|
||||
@ -31,50 +27,6 @@ http {
|
||||
add_header X-Content-Type-Options 'nosniff';
|
||||
add_header X-XSS-Protection '1; mode=block';
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /vault/ {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /auditorium/ {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /script.js {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /normalize.css {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /skeleton.css {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /healthz {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /versionz {
|
||||
proxy_pass http://server;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /favicon.ico {
|
||||
root /www/data/theme/images;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://homepage;
|
||||
proxy_redirect off;
|
||||
|
Loading…
Reference in New Issue
Block a user