Revert to docker build using gitlab ci
This commit is contained in:
parent
6d375c751a
commit
fe1a24da28
9 changed files with 96 additions and 212 deletions
|
@ -1,36 +0,0 @@
|
||||||
image: freebsd/12.x
|
|
||||||
packages:
|
|
||||||
- python39
|
|
||||||
- py39-sqlite3
|
|
||||||
- jpeg-turbo
|
|
||||||
- py37-ansible
|
|
||||||
sources:
|
|
||||||
- https://git.sr.ht/~crocmagnon/blog
|
|
||||||
secrets:
|
|
||||||
- ea931da1-9acd-47b0-b6c9-52b8b61c4647 # Ansible hosts file
|
|
||||||
- 5c948915-48c2-4542-8fc1-a5676f4d7126 # Deploy SSH key
|
|
||||||
environment:
|
|
||||||
POETRY_VERSION: 1.1.4
|
|
||||||
tasks:
|
|
||||||
- install_poetry: |
|
|
||||||
mkdir $HOME/bin
|
|
||||||
ln -s $(which python3.9) $HOME/bin/python
|
|
||||||
python -m ensurepip
|
|
||||||
python -m pip install poetry==$POETRY_VERSION
|
|
||||||
- install_deps: |
|
|
||||||
cd blog
|
|
||||||
python -m poetry install -n
|
|
||||||
- test: |
|
|
||||||
cd blog
|
|
||||||
python -m poetry run ./docker/runtests.sh
|
|
||||||
- check-branch: |
|
|
||||||
cd blog
|
|
||||||
if [ "$(git rev-parse master)" != "$(git rev-parse HEAD)" ]; then \
|
|
||||||
complete-build; \
|
|
||||||
fi
|
|
||||||
- deploy: |
|
|
||||||
ansible-playbook -i ~/ansiblehosts --ssh-common-args "-o StrictHostKeyChecking=no" blog/ansible/playbook.yml
|
|
||||||
triggers:
|
|
||||||
- action: email
|
|
||||||
condition: failure
|
|
||||||
to: Gabriel Augendre <gabriel@augendre.info>
|
|
83
.gitlab-ci.yml
Normal file
83
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
- publish
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# Can't compose variables with user-defined ones, so we repeat ourselves :'(
|
||||||
|
# See https://gitlab.com/gitlab-org/gitlab-runner/-/issues/1809
|
||||||
|
IMAGE_REGISTRY: rg.fr-par.scw.cloud/crocmagnon
|
||||||
|
IMAGE_TESTS: $CI_REGISTRY_IMAGE:tests-latest
|
||||||
|
IMAGE_DEPS_TESTS: $CI_REGISTRY_IMAGE:tests-deps
|
||||||
|
IMAGE_LATEST: rg.fr-par.scw.cloud/crocmagnon/blog:latest
|
||||||
|
IMAGE_DEPS_LATEST: $CI_REGISTRY_IMAGE:deps
|
||||||
|
|
||||||
|
PRE_COMMIT_IMAGE: rg.fr-par.scw.cloud/crocmagnon/pre-commit:latest
|
||||||
|
|
||||||
|
.build: &build
|
||||||
|
script:
|
||||||
|
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||||
|
- docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD $IMAGE_REGISTRY
|
||||||
|
- docker pull $IMAGE || true
|
||||||
|
- docker pull $DEPS || true
|
||||||
|
# Build this first stage separately so that we can cache it
|
||||||
|
- docker build --pull --build-arg POETRY_OPTIONS --target venv --cache-from $DEPS -t $DEPS .
|
||||||
|
# Build the final image. The "cache from" deps is necessary to take advantage of the intermediate image cache.
|
||||||
|
# See https://stackoverflow.com/a/52649913/2758732 and https://github.com/moby/moby/issues/34715
|
||||||
|
- docker build --pull --build-arg POETRY_OPTIONS --cache-from $IMAGE --cache-from $DEPS -t $IMAGE .
|
||||||
|
- docker push $IMAGE
|
||||||
|
- docker push $DEPS
|
||||||
|
|
||||||
|
build-tests:
|
||||||
|
<<: *build
|
||||||
|
stage: build
|
||||||
|
variables:
|
||||||
|
POETRY_OPTIONS: ""
|
||||||
|
before_script:
|
||||||
|
- export IMAGE=$IMAGE_TESTS
|
||||||
|
- export DEPS=$IMAGE_DEPS_TESTS
|
||||||
|
|
||||||
|
.tests: &tests
|
||||||
|
stage: test
|
||||||
|
image: $IMAGE_TESTS
|
||||||
|
|
||||||
|
unit_tests:
|
||||||
|
<<: *tests
|
||||||
|
script:
|
||||||
|
- cd /app
|
||||||
|
- python -m pytest
|
||||||
|
|
||||||
|
pre_commit:
|
||||||
|
stage: test
|
||||||
|
image: $PRE_COMMIT_IMAGE
|
||||||
|
script:
|
||||||
|
- pre-commit run --all-files --color always --show-diff-on-failure
|
||||||
|
|
||||||
|
missing_migrations:
|
||||||
|
<<: *tests
|
||||||
|
script:
|
||||||
|
- cd /app
|
||||||
|
- python manage.py makemigrations --check
|
||||||
|
|
||||||
|
publish:
|
||||||
|
<<: *build
|
||||||
|
stage: publish
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: none
|
||||||
|
POETRY_OPTIONS: "--no-dev"
|
||||||
|
before_script:
|
||||||
|
- export IMAGE=$IMAGE_LATEST
|
||||||
|
- export DEPS=$IMAGE_DEPS_LATEST
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
#deploy:
|
||||||
|
# tags:
|
||||||
|
# - it4nw
|
||||||
|
# stage: deploy
|
||||||
|
# image: tobedefined # todo: look for image with ssh
|
||||||
|
# script:
|
||||||
|
# - exit 1
|
||||||
|
# only:
|
||||||
|
# - master
|
10
Dockerfile
10
Dockerfile
|
@ -2,22 +2,20 @@
|
||||||
FROM python:3.8.6-buster AS venv
|
FROM python:3.8.6-buster AS venv
|
||||||
|
|
||||||
# https://python-poetry.org/docs/#installation
|
# https://python-poetry.org/docs/#installation
|
||||||
ENV POETRY_VERSION=1.0.10
|
ENV POETRY_VERSION=1.1.4
|
||||||
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
|
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
|
||||||
|
|
||||||
ENV PATH /root/.poetry/bin:$PATH
|
ENV PATH /root/.poetry/bin:$PATH
|
||||||
ENV PYTHONPATH $PYTHONPATH:/root/.poetry/lib
|
ENV PYTHONPATH $PYTHONPATH:/root/.poetry/lib
|
||||||
|
ARG POETRY_OPTIONS
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY pyproject.toml poetry.lock ./
|
COPY pyproject.toml poetry.lock ./
|
||||||
# Will install dev deps as well, so that we can run tests in this image
|
|
||||||
RUN python -m venv --copies /app/venv \
|
RUN python -m venv --copies /app/venv \
|
||||||
&& . /app/venv/bin/activate \
|
&& . /app/venv/bin/activate \
|
||||||
&& poetry config cache-dir /app/poetry-cache \
|
&& poetry config cache-dir /app/poetry-cache \
|
||||||
&& (python -c "from poetry.factory import Factory; l = Factory().create_poetry('.').locker; exit(0) if l.is_locked() and l.is_fresh() else exit(1)" \
|
&& poetry install $POETRY_OPTIONS
|
||||||
&& echo "poetry.lock is up to date") \
|
|
||||||
|| (>&2 echo "poetry.lock is outdated. Run `poetry lock` on your machine and commit the file." && exit 1) \
|
|
||||||
&& poetry install
|
|
||||||
|
|
||||||
|
|
||||||
## Get git versions
|
## Get git versions
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# PROVIDE: blog
|
|
||||||
# REQUIRE: LOGIN NETWORKING
|
|
||||||
# KEYWORD: shutdown
|
|
||||||
|
|
||||||
. /etc/rc.subr
|
|
||||||
|
|
||||||
name=blog
|
|
||||||
rcvar="blog_enable"
|
|
||||||
|
|
||||||
load_rc_config $name
|
|
||||||
: ${blog_enable="NO"}
|
|
||||||
: ${blog_listen_addr="127.0.0.1:8000"}
|
|
||||||
|
|
||||||
pidfile="/var/run/${name}.pid"
|
|
||||||
logfile="/var/log/${name}.log"
|
|
||||||
|
|
||||||
blog_env_file="/srv/blog/.env"
|
|
||||||
command_interpreter="/srv/blogvenv/bin/python"
|
|
||||||
command="/srv/blogvenv/bin/gunicorn"
|
|
||||||
blog_flags="-D --chdir /srv/blog -b ${blog_listen_addr} --log-file ${logfile} --pid ${pidfile}"
|
|
||||||
command_args="blog.wsgi"
|
|
||||||
|
|
||||||
start_precmd="${name}_prestart"
|
|
||||||
blog_prestart()
|
|
||||||
{
|
|
||||||
. /srv/blog/.env
|
|
||||||
yes yes | /srv/blogvenv/bin/python /srv/blog/manage.py migrate
|
|
||||||
/srv/blogvenv/bin/python /srv/blog/manage.py collectstatic --noinput --clear
|
|
||||||
/srv/blogvenv/bin/python /srv/blog/manage.py assets build --manifest django
|
|
||||||
}
|
|
||||||
|
|
||||||
run_rc_command "$1"
|
|
|
@ -1 +0,0 @@
|
||||||
blognas ansible_host=192.168.0.54 ansible_port=22 ansible_python_interpreter=/usr/local/bin/python
|
|
|
@ -1,59 +0,0 @@
|
||||||
worker_processes 1;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
include mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
sendfile on;
|
|
||||||
keepalive_timeout 65;
|
|
||||||
|
|
||||||
server {
|
|
||||||
server_name localhost:80;
|
|
||||||
|
|
||||||
client_max_body_size 10M;
|
|
||||||
|
|
||||||
gzip on;
|
|
||||||
gzip_types
|
|
||||||
application/javascript
|
|
||||||
application/x-javascript
|
|
||||||
application/json
|
|
||||||
application/rss+xml
|
|
||||||
application/xml
|
|
||||||
image/svg+xml
|
|
||||||
image/x-icon
|
|
||||||
application/vnd.ms-fontobject
|
|
||||||
application/font-sfnt
|
|
||||||
text/css
|
|
||||||
text/plain;
|
|
||||||
gzip_min_length 256;
|
|
||||||
gzip_comp_level 5;
|
|
||||||
gzip_http_version 1.1;
|
|
||||||
gzip_vary on;
|
|
||||||
|
|
||||||
location /static/ {
|
|
||||||
alias /srv/blog/staticfiles/;
|
|
||||||
expires 30d;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /media/ {
|
|
||||||
alias /srv/blog/media/;
|
|
||||||
expires 30d;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_pass http://localhost:8000;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
|
|
||||||
listen [::]:80;
|
|
||||||
listen 80;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
---
|
|
||||||
- name: deploy blog
|
|
||||||
hosts: blognas
|
|
||||||
remote_user: root
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: install system dependencies
|
|
||||||
pkgng:
|
|
||||||
name: git,python39,py39-sqlite3,jpeg-turbo,nginx,curl,vim
|
|
||||||
- name: make python3.9 default
|
|
||||||
file:
|
|
||||||
path: /usr/local/bin/python3
|
|
||||||
src: /usr/local/bin/python3.9
|
|
||||||
state: link
|
|
||||||
- name: install pip
|
|
||||||
shell:
|
|
||||||
cmd: python -m ensurepip
|
|
||||||
creates: /usr/local/lib/python3.9/site-packages/pip
|
|
||||||
- name: fetch code
|
|
||||||
git:
|
|
||||||
repo: https://git.sr.ht/~crocmagnon/blog
|
|
||||||
dest: /srv/blog
|
|
||||||
force: yes
|
|
||||||
- name: create venv
|
|
||||||
shell:
|
|
||||||
cmd: python -m venv /srv/blogvenv
|
|
||||||
creates: /srv/blogvenv/bin/python
|
|
||||||
- name: install poetry
|
|
||||||
shell:
|
|
||||||
cmd: . /srv/blogvenv/bin/activate && python -m pip install poetry==1.1.4
|
|
||||||
creates: /srv/blogvenv/bin/poetry
|
|
||||||
- name: install python dependencies
|
|
||||||
shell:
|
|
||||||
chdir: /srv/blog
|
|
||||||
cmd: . /srv/blogvenv/bin/activate && python -m poetry install --no-dev
|
|
||||||
- name: install service
|
|
||||||
copy:
|
|
||||||
remote_src: yes
|
|
||||||
src: /srv/blog/ansible/blog.service
|
|
||||||
dest: /usr/local/etc/rc.d/blog
|
|
||||||
owner: root
|
|
||||||
group: wheel
|
|
||||||
mode: 0755
|
|
||||||
- name: enable and restart blog service
|
|
||||||
service:
|
|
||||||
name: blog
|
|
||||||
state: restarted
|
|
||||||
enabled: yes
|
|
||||||
- name: backup old nginx conf
|
|
||||||
copy:
|
|
||||||
remote_src: yes
|
|
||||||
src: /usr/local/etc/nginx/nginx.conf
|
|
||||||
dest: /usr/local/etc/nginx/nginx.conf.BKP
|
|
||||||
- name: install nginx conf
|
|
||||||
copy:
|
|
||||||
remote_src: yes
|
|
||||||
src: /srv/blog/ansible/nginx.conf
|
|
||||||
dest: /usr/local/etc/nginx/nginx.conf
|
|
||||||
owner: root
|
|
||||||
group: wheel
|
|
||||||
mode: 0644
|
|
||||||
notify:
|
|
||||||
- restart nginx
|
|
||||||
- name: enable nginx service
|
|
||||||
service:
|
|
||||||
name: nginx
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
handlers:
|
|
||||||
- name: restart nginx
|
|
||||||
service:
|
|
||||||
name: nginx
|
|
||||||
state: restarted
|
|
|
@ -10,10 +10,12 @@ server {
|
||||||
application/json
|
application/json
|
||||||
application/rss+xml
|
application/rss+xml
|
||||||
application/xml
|
application/xml
|
||||||
image/svg+xml
|
|
||||||
image/x-icon
|
|
||||||
application/vnd.ms-fontobject
|
application/vnd.ms-fontobject
|
||||||
application/font-sfnt
|
application/font-sfnt
|
||||||
|
image/svg+xml
|
||||||
|
image/x-icon
|
||||||
|
text/xml
|
||||||
|
text/javascript
|
||||||
text/css
|
text/css
|
||||||
text/plain;
|
text/plain;
|
||||||
gzip_min_length 256;
|
gzip_min_length 256;
|
||||||
|
@ -40,7 +42,9 @@ server {
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_header Content-Security-Policy "frame-ancestors 'none'; default-src 'none'; img-src https:; script-src 'self' https://plausible.augendre.info; connect-src https://plausible.augendre.info; style-src 'self' 'unsafe-inline'; font-src 'self'" always;
|
add_header Content-Security-Policy "frame-ancestors 'none'; default-src 'none'; img-src https:; script-src 'self'
|
||||||
|
https://plausible.augendre.info; connect-src https://plausible.augendre.info; style-src 'self' 'unsafe-inline';
|
||||||
|
font-src 'self'; manifest-src 'self';" always;
|
||||||
add_header X-Frame-Options "DENY" always;
|
add_header X-Frame-Options "DENY" always;
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
|
2
pre-commit.Dockerfile
Normal file
2
pre-commit.Dockerfile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
FROM python:3.8.6-buster
|
||||||
|
RUN python3 -m pip install pre-commit==2.9.3
|
Reference in a new issue