Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build docker container as part of GH action #549

Merged
merged 7 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/build-projectify-backend.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Build docker image

on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
uses: docker/build-push-action@v6
with:
context: "{{defaultContext}}:backend"
push: false
load: true
file: projectify-backend.Dockerfile
cache-from: type=gha
cache-to: type=gha,mode=max
35 changes: 8 additions & 27 deletions backend/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,18 @@
pyproject = ./pyproject.toml;
poetrylock = ./poetry.lock;
groups = [ ];
outputs = [ "out" "static"];
checkGroups = [ ];
outputs = [ "out" "static" ];
postInstall = ''
mkdir -p $out/bin
mkdir -p $out/bin $out/etc
cp manage.py "$out/bin"

cp gunicorn.conf.py gunicorn-error.log $out/etc/

mkdir -p $static
env \
DJANGO_SETTINGS_MODULE=projectify.settings.development_nix \
DJANGO_CONFIGURATION=DevelopmentNix \
DJANGO_SETTINGS_MODULE=projectify.settings.collect_static \
DJANGO_CONFIGURATION=CollectStatic \
STATIC_ROOT=$static \
python $out/bin/manage.py collectstatic --no-input
'';
Expand All @@ -94,43 +97,24 @@
};
# Workaround, since dependencyEnv accidentally forgets any other
# outputs
projectify-backend-static = projectify-backend.static;
in
{
packages = {
projectify-backend = projectify-backend;
default = projectify-backend;
inherit projectify-backend-static;
container = pkgs.dockerTools.buildLayeredImage {
name = "projectify-backend";
tag = "latest";
contents = [
projectify-backend
pkgs.bash
pkgs.coreutils
pkgs.file
];
# Here and below we use relative paths
extraCommands = ''
mkdir -p var/projectify/static
cp -a ${projectify-backend-static}/. var/projectify/static

mkdir -p var/projectify/db
env \
DJANGO_SETTINGS_MODULE=projectify.settings.development_nix \
DJANGO_CONFIGURATION=DevelopmentNix \
STATIC_ROOT=var/projectify/static/ \
DATABASE_URL=sqlite:///var/projectify/db/projectify.sqlite \
"${projectify-backend}/bin/manage.py" migrate --no-input
cp -a ${projectify-backend.static}/. var/projectify/static
'';
config = {
Env = [
"DJANGO_SETTINGS_MODULE=projectify.settings.development_nix"
"DJANGO_CONFIGURATION=DevelopmentNix"
"PORT=8000"
"STATIC_ROOT=/var/projectify/static/"
# Note four /// to denote absolute path
"DATABASE_URL=sqlite:////var/projectify/db/projectify.sqlite"
];
Cmd = [
"gunicorn"
Expand All @@ -142,9 +126,6 @@
ExposedPorts = {
"8000/tcp" = { };
};
Volumes = {
"/var/projectify/db" = { };
};
};
};
};
Expand Down
31 changes: 31 additions & 0 deletions backend/projectify-backend.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
FROM docker.io/nixos/nix:2.22.3 as builder

COPY . /tmp/build
WORKDIR /tmp/build

# https://marcopolo.io/code/nix-and-small-containers/
# https://mitchellh.com/writing/nix-with-dockerfiles
RUN echo "experimental-features = nix-command flakes" > /etc/nix/nix.conf \
&& nix build .#projectify-backend .#projectify-backend.static \
&& mkdir -p /tmp/nix-store-closure \
&& nix-store -qR result > /tmp/nix-store-closure-files \
&& xargs -a /tmp/nix-store-closure-files -I {} cp -a {} /tmp/nix-store-closure/

FROM scratch as web
WORKDIR /app
COPY --from=builder /tmp/nix-store-closure /nix/store
COPY --from=builder /tmp/build/result /app
COPY --from=builder /tmp/build/result-1-static /static
ENV STATIC_ROOT=/static

CMD ["/app/bin/gunicorn", "--config", "/app/etc/gunicorn.conf.py", "--log-config", "/app/etc/gunicorn-error.log"]

FROM scratch as worker
WORKDIR /app
COPY --from=builder /tmp/nix-store-closure /nix/store
COPY --from=builder /tmp/build/result /app
# We might not need STATIC_ROOT for a worker
COPY --from=builder /tmp/build/result-1-static /static
ENV STATIC_ROOT=/static

CMD ["/app/bin/celery", "--app", "projectify", "worker", "--concurrency", "1"]
36 changes: 36 additions & 0 deletions backend/projectify/settings/collect_static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# Copyright (C) 2024 JWP Consulting GK
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Settings used to run ./manage.py collectstatic."""

import os
from pathlib import Path

from .base import Base


class CollectStatic(Base):
"""Only contain the settings necessary to run ./manage.py collectstatic."""

FRONTEND_URL = "collect-static"

STORAGES = {
**Base.STORAGES,
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}
STATIC_ROOT = Path(os.environ["STATIC_ROOT"])
5 changes: 5 additions & 0 deletions heroku.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
build:
docker:
web:
dockerfile: backend/projectify-backend.Dockerfile
target: web