2
0
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:
Frederik Ring 2020-01-07 13:00:54 +01:00 committed by GitHub
commit b656329011
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 35 additions and 419 deletions

View File

@ -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

View File

@ -1,2 +0,0 @@
*
!Dockerrun.aws.json

View File

@ -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

View File

@ -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"
}
}
}
]
}

View File

@ -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"
}
}
}
]
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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:

View File

@ -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 %}

View File

@ -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;