Single Dockerfile for building ATAT.
Dockerfile is now a single multi-stage build that relies on a Python 3.7 base image. Notes: - This builds uWSGI with a `pip install` because the Alpine vendored uWSGI is built against Python 3.6. - Adds a docker-compose file that can be used for testing that the build works. It is not usable for development purposes because it creates a static copy of the application.
This commit is contained in:
parent
1c63a64bb8
commit
6f8ef27bf1
@ -1,9 +1,11 @@
|
||||
# Files to exclude from COPY and ADD commands when
|
||||
# Files to exclude from COPY and ADD commands when
|
||||
# building a docker image from this directory
|
||||
|
||||
# Exclude Docker build related files
|
||||
Dockerfile
|
||||
Dockerfile.nginx
|
||||
.dockerignore
|
||||
docker-compose.yml
|
||||
|
||||
# Exclude the git directory and gitignore file
|
||||
.git
|
||||
@ -27,3 +29,7 @@ requirements.yml
|
||||
|
||||
# Skip kubernetes and Docker config stuff
|
||||
deploy
|
||||
|
||||
# exclude build artifacts and docker directories
|
||||
.venv
|
||||
node_modules
|
||||
|
14
README.md
14
README.md
@ -231,6 +231,20 @@ SVG markup should be cleaned an minified, [Svgsus](http://www.svgs.us/) works we
|
||||
|
||||
## Deployment
|
||||
|
||||
### Docker build
|
||||
|
||||
For testing the Docker build, the repo includes a `docker-compose.yml` that will run the app container with an NGINX server in front of it. To run it, you will need `docker` and `docker-compose` installed, then:
|
||||
|
||||
```
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
The app will be available on http://localhost:8080.
|
||||
|
||||
The build assumes that you have redis and postgres running on their usual ports on your host machine; it does not pull images for those services. The docker-compose build is not suitable for development because it does not mount or reload working files.
|
||||
|
||||
### Dev login
|
||||
|
||||
The `/login-dev` endpoint is protected by HTTP basic auth when deployed. This can be configured for NGINX following the instructions [here](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/). The following config should added within the main server block for the site:
|
||||
|
||||
```nginx
|
||||
|
95
deploy/docker/Dockerfile
Normal file
95
deploy/docker/Dockerfile
Normal file
@ -0,0 +1,95 @@
|
||||
FROM python:3.7.3-alpine3.9 AS builder
|
||||
|
||||
RUN mkdir -p /install/.venv
|
||||
WORKDIR /install
|
||||
|
||||
# Install basic Alpine packages
|
||||
RUN apk update && \
|
||||
apk --no-cache add \
|
||||
build-base \
|
||||
curl \
|
||||
ca-certificates \
|
||||
docker \
|
||||
git \
|
||||
gzip \
|
||||
libffi \
|
||||
libffi-dev \
|
||||
libsass \
|
||||
libsass-dev \
|
||||
linux-headers \
|
||||
nodejs \
|
||||
openssh-client \
|
||||
openssl \
|
||||
openssl-dev \
|
||||
pcre-dev \
|
||||
postgresql-dev \
|
||||
rsync \
|
||||
sudo \
|
||||
tar \
|
||||
util-linux \
|
||||
yarn
|
||||
|
||||
COPY . .
|
||||
|
||||
# Install app dependencies
|
||||
RUN pip install pipenv uwsgi && \
|
||||
PIPENV_VENV_IN_PROJECT=1 pipenv install && \
|
||||
yarn install && \
|
||||
yarn build
|
||||
|
||||
## NEW IMAGE
|
||||
FROM python:3.7.3-alpine3.9
|
||||
|
||||
### Very low chance of changing
|
||||
###############################
|
||||
# Overridable default config
|
||||
ARG APP_DIR=/opt/atat/atst
|
||||
|
||||
# Environment variables
|
||||
ENV APP_DIR "${APP_DIR}"
|
||||
ENV TZ UTC
|
||||
|
||||
# Create application directory
|
||||
RUN set -x ; \
|
||||
mkdir -p ${APP_DIR}
|
||||
|
||||
# Set working dir
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Add group
|
||||
RUN addgroup -g 8000 -S "atat" && \
|
||||
adduser -u 8010 -D -S -G "atat" "atst"
|
||||
|
||||
# Install basic Alpine packages
|
||||
RUN apk update && \
|
||||
apk --no-cache add \
|
||||
dumb-init \
|
||||
postgresql-client \
|
||||
postgresql-dev \
|
||||
postgresql-libs \
|
||||
uwsgi-logfile
|
||||
|
||||
COPY --from=builder /install/.venv/ ./.venv/
|
||||
COPY --from=builder /install/alembic/ ./alembic/
|
||||
COPY --from=builder /install/alembic.ini .
|
||||
COPY --from=builder /install/app.py .
|
||||
COPY --from=builder /install/atst/ ./atst/
|
||||
COPY --from=builder /install/config/ ./config/
|
||||
COPY --from=builder /install/templates/ ./templates/
|
||||
COPY --from=builder /install/translations.yaml .
|
||||
COPY --from=builder /install/static/ ./static/
|
||||
COPY --from=builder /install/uwsgi.ini .
|
||||
COPY --from=builder /usr/local/bin/uwsgi /usr/local/bin/uwsgi
|
||||
|
||||
# Use dumb-init for proper signal handling
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||
|
||||
# Default command is to launch the server
|
||||
CMD ["uwsgi", "--ini", "uwsgi.ini"]
|
||||
|
||||
RUN mkdir /var/run/uwsgi && \
|
||||
chown -R atst:atat /var/run/uwsgi && \
|
||||
chown -R atst:atat "${APP_DIR}"
|
||||
|
||||
# Run as the unprivileged APP user
|
||||
USER atst
|
@ -1,49 +0,0 @@
|
||||
FROM alpine:3.8
|
||||
|
||||
### Very low chance of changing
|
||||
###############################
|
||||
# Overridable default config
|
||||
ARG APP_USER=atst
|
||||
ARG APP_GROUP=atat
|
||||
ARG APP_DIR=/opt/atat/atst
|
||||
ARG APP_PORT=8000
|
||||
ARG LOCAL_BIN_DIR=/usr/bin
|
||||
ARG SITE_PACKAGES_DIR=/usr/lib/python3.6/site-packages
|
||||
|
||||
ENV APP_USER "${APP_USER}"
|
||||
ENV APP_GROUP "${APP_GROUP}"
|
||||
ENV APP_DIR "${APP_DIR}"
|
||||
|
||||
# Set port to open
|
||||
EXPOSE "${APP_PORT}"
|
||||
|
||||
# Use dumb-init for proper signal handling
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||
|
||||
# Default command is to launch the server
|
||||
CMD ["bash", "-c", "${APP_DIR}/script/uwsgi_server"]
|
||||
|
||||
### Items that will change almost every build
|
||||
#############################################
|
||||
# Copy installed python packages from the tester image
|
||||
COPY --from=atst-tester:latest "${SITE_PACKAGES_DIR}" "${SITE_PACKAGES_DIR}"
|
||||
|
||||
# Copy local bin directory (contains python system package wrappers)
|
||||
COPY --from=atst-tester:latest "${LOCAL_BIN_DIR}" "${LOCAL_BIN_DIR}"
|
||||
|
||||
# Copy the app directory contents from the tester image (includes node modules)
|
||||
COPY --from=atst-tester:latest "${APP_DIR}" "${APP_DIR}"
|
||||
|
||||
# Set working dir
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Add required system packages and app user
|
||||
RUN set -x ; \
|
||||
script/alpine_setup "${APP_USER}" "${APP_GROUP}"
|
||||
|
||||
# Update file ownership
|
||||
RUN set -x ; \
|
||||
for subdir in $(find . -type d -maxdepth 1 | grep -Ee '.[^/]' | grep -Fve 'node_modules'); do chown atst:atat -R ${subdir}; done
|
||||
|
||||
# Run as the unprivileged APP user
|
||||
USER "${APP_USER}"
|
24
deploy/docker/sample.nginx.conf
Normal file
24
deploy/docker/sample.nginx.conf
Normal file
@ -0,0 +1,24 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
#charset koi8-r;
|
||||
#access_log /var/log/nginx/host.access.log main;
|
||||
|
||||
location / {
|
||||
try_files $uri @app;
|
||||
}
|
||||
|
||||
location @app {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:///var/run/uwsgi/uwsgi.socket;
|
||||
uwsgi_param HTTP_X_SSL_CLIENT_VERIFY $ssl_client_verify;
|
||||
uwsgi_param HTTP_X_SSL_CLIENT_CERT $ssl_client_raw_cert;
|
||||
uwsgi_param HTTP_X_SSL_CLIENT_S_DN $ssl_client_s_dn;
|
||||
uwsgi_param HTTP_X_SSL_CLIENT_S_DN_LEGACY $ssl_client_s_dn_legacy;
|
||||
uwsgi_param HTTP_X_SSL_CLIENT_I_DN $ssl_client_i_dn;
|
||||
uwsgi_param HTTP_X_SSL_CLIENT_I_DN_LEGACY $ssl_client_i_dn_legacy;
|
||||
uwsgi_param HTTP_X_REQUEST_ID $request_id;
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
FROM registry.atat.code.mil:443/atat-app-builder:latest
|
||||
|
||||
### Very low chance of changing
|
||||
###############################
|
||||
ARG APP_USER=atst
|
||||
ARG APP_GROUP=atat
|
||||
ARG APP_DIR=/opt/atat/atst
|
||||
ARG CIBUILD=true
|
||||
|
||||
ENV APP_DIR "${APP_DIR}"
|
||||
ENV FLASK_ENV ci
|
||||
ENV SKIP_PIPENV true
|
||||
|
||||
# Use dumb-init for proper signal handling
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||
|
||||
# Default command is to run all the tests
|
||||
CMD ["bash", "-c", "${APP_DIR}/script/cibuild"]
|
||||
|
||||
# Create application directory
|
||||
RUN set -x ; \
|
||||
mkdir -p ${APP_DIR}
|
||||
|
||||
# Set working dir
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Copy over setup scripts
|
||||
COPY script/ ./script/
|
||||
|
||||
# Add required system packages and app user
|
||||
RUN set -x ; \
|
||||
script/alpine_setup
|
||||
|
||||
### Items that will change almost every build
|
||||
#############################################
|
||||
# Copy over the rest of the app source
|
||||
COPY . .
|
||||
|
||||
# Install app dependencies
|
||||
RUN set -x ; \
|
||||
script/setup
|
27
docker-compose.yml
Normal file
27
docker-compose.yml
Normal file
@ -0,0 +1,27 @@
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./deploy/docker/Dockerfile
|
||||
volumes:
|
||||
- ./ssl:/opt/atat/atst/ssl
|
||||
- ./config:/opt/atst/atst/config
|
||||
- sockets:/var/run/uwsgi
|
||||
environment:
|
||||
PGHOST: host.docker.internal
|
||||
REDIS_URI: "redis://host.docker.internal:6379"
|
||||
|
||||
frontend:
|
||||
image: nginx:1.13-alpine
|
||||
volumes:
|
||||
- ./deploy/docker/sample.nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- sockets:/var/run/uwsgi
|
||||
depends_on:
|
||||
- backend
|
||||
ports:
|
||||
- 8080:80
|
||||
|
||||
volumes:
|
||||
sockets:
|
Loading…
x
Reference in New Issue
Block a user