Skip to content

Instantly share code, notes, and snippets.

@vovimayhem
Last active May 25, 2019 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vovimayhem/b21f3575b01732f10c00ee4a83f846d1 to your computer and use it in GitHub Desktop.
Save vovimayhem/b21f3575b01732f10c00ee4a83f846d1 to your computer and use it in GitHub Desktop.
Ejemplo Dockerfile para app compilada de js
# The 2.4 spec is available for Docker versions >= 17.12.0, and it's great for
# development in local environments (i.e. using `docker-compose` instead of
# "swarm mode" commands like `docker stack deploy`), as it lets us specify
# resource constraints such as memory limits on service containers. We can use
# those constraints to replicate low-memory scenarios or debug memory usage in
# our apps:
version: '2.4'
volumes:
frontend_node_modules:
services:
frontend_web: &frontend
image: vovimayhem/demo-frontend:development
build: &frontend_app_build
context: ./frontend
dockerfile: Dockerfile
target: development
volumes:
# Mount the frontend code directory into the container's "/usr/src" folder:
- .:/usr/src
# Replace the mounted node modules folder with a volume:
- frontend_node_modules:/usr/src/node_modules
entrypoint: /usr/src/bin/dev-entrypoint.sh
command: grunt serve
ports:
- ${DEMO_FRONTEND_WEB_PORT:-9000}:9000
- ${DEMO_FRONTEND_LIVE_RELOAD_PORT:-35729}:35729
environment: &frontend_env
DEMO_BACKEND_URL: ${DEMO_BACKEND_URL:-http://localhost:3000}
stdin_open: true
tty: true
labels:
com.icalialabs.plis.group: demo frontend
frontend_release:
<<: *frontend
image: vovimayhem/demo-frontend:latest
build:
<<: *frontend_app_build
target: release
volumes: []
entrypoint: /bin/sh
command: start-web
ports:
- ${DEMO_FRONTEND_WEB_RELEASE_PORT:-80}:80
environment:
DEMO_BACKEND_URL: ${DEMO_BACKEND_URL:-http://localhost:3000}
####################################################################################################
# Stage I - The builder stage: We'll use as much as the same commands (layers) on the dev.Dockerfile
# so we can use the cache as much as possible:
# 1: Use node 8 as base:
FROM node:8-alpine as development
# 2: We'll set the application path as the working directory
WORKDIR /usr/src
# 3: We'll add the app's binaries path to $PATH and set the $HOME to the app folder:
ENV HOME=/usr/src PATH=/usr/src/bin:$PATH
# 4: Install yarn and grunt:
RUN apk add --no-cache yarn ruby && npm install -g grunt-cli grunt
FROM development AS builder
# Next, we proceed with installing dependencies and building the app:
# 5: We'll copy just the package.json + yarn.lock files, so we can ignore changes on the rest of the
# code and cache the app npm dependencies:
ADD package.json yarn.lock /usr/src/
# 6: Install the app npm dependencies within the Docker build context:
RUN set -ex && yarn install
# 7: We'll copy the rest of the app source code:
ADD . /usr/src/
# 8: Build the app:
RUN grunt build
####################################################################################################
# Stage II - Once we have compiled the app in the previous stage, we'll copy the compiled app into
# a new image based on a minimal nginx image, and add custom scripts to make the deployment to
# heroku a productive experience.
# 1: Start off from IcaliaLabs' mini-nginx image:
FROM icalialabs/mini-nginx:latest AS release
# 2: Set the default PORT value:
ENV PORT 80
# 3: Specify the default value for FORCE_SSL:
ENV FORCE_SSL false
# NOTE: We won't configure exposed ports on this Dockerfile, as Heroku assigns the ports
# dynamically... the entrypoint script will configure nginx accordingly.
# 5: Copy the compiled app (which was compiled in the previous stage) into the
# /usr/share/nginx/html folder:
COPY --from=builder /usr/src/dist /usr/share/nginx/html
# 6: Copy the nginx configuration:
ADD ./config/nginx.conf /etc/nginx/example.conf
# 7: Set `nginx` as the owner of the compiled app files, and change permissions on some folders:
RUN mkdir -p /var/cache/nginx/client_temp && chmod a+w /var/cache/nginx/client_temp && \
mkdir -p /var/cache/nginx/proxy_temp && chmod a+w /var/cache/nginx/proxy_temp && \
mkdir -p /var/cache/nginx/fastcgi_temp && chmod a+w /var/cache/nginx/fastcgi_temp
# 8: Add the `start-web` script:
ADD ./bin/start-web.sh /usr/local/bin/start-web
# 9: Set the default command:
CMD [ "start-web" ]
# Custom Web Nginx Server Configuration
#
# This instance of Nginx is configured to serve only the compiled app as static content.
#
# The SSL stuff (if any) is required to be done by Heroku
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request ($must_force_ssl $http_x_forwarded_proto)" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
# Compression options:
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
server_tokens off;
server {
# NOTE: The listen PORT will be interpolated by the entrypoint script:
listen ${PORT} default_server;
listen [::]:${PORT} default_server ipv6only=on;
# Cloud routers such as Heroku Router or AWS ELB will add the
# 'X-Forwarded-Proto' header with the procotol used by the user agent to
# initiate the request.
#
# We will use this in combination with the 'FORCE_SSL' environment
# variable (which will be interpolated here by the entrypoint script) to
# determine whether we must force the user agent to switch to HTTPS or not
set $must_force_ssl '${FORCE_SSL}';
set $allowed_forwarded_proto $http_x_forwarded_proto;
if ($must_force_ssl = 'true') { set $allowed_forwarded_proto 'https'; }
if ($http_x_forwarded_proto != $allowed_forwarded_proto) {
return 301 https://$host$request_uri;
}
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
}
#! /bin/sh
# This is the production entrypoint.
# The main role for this script is to set the nginx listening port on the nginx
# configuration before actually launching nginx.
set -e
# 1: Define the functions that configure nginx and the runtime config for the
# app:
# Interpolates environment variables into a Nginx configuration template to be
# used by Nginx, including the port Nginx will listen to.
#
# Being able to specify the port to listen is required by Heroku to route
# requests from their routing mesh:
# See https://github.com/docker-library/docs/tree/master/nginx#using-environment-variables-in-nginx-configuration
apply_env_to_nginx_conf() {
echo -n "Updating nginx config from current environment variables..."
# Separate with ':' the variables that we want to interpolate... or else
# envsubst won't work!
vars_to_interpolate='$PORT:$FORCE_SSL';
envsubst $vars_to_interpolate < /etc/nginx/example.conf > /tmp/nginx.conf;
echo " Done!"
}
# 2: Generate the nginx configuration valid for this instance:
apply_env_to_nginx_conf
# 3: Set the command to be executed:
set -- nginx -c /tmp/nginx.conf -g 'daemon off;';
# 4: Notify that NGinx will start:
echo "Starting the app's Nginx instance...";
# 5: Execute the given or default command:
exec "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment