├── expires.conf ├── start-container.sh ├── Dockerfile ├── nginx-site.conf └── README.md /expires.conf: -------------------------------------------------------------------------------- 1 | # Expires map 2 | map $sent_http_content_type $expires { 3 | default off; 4 | text/html epoch; 5 | text/css epoch; 6 | application/javascript epoch; 7 | application/json epoch; 8 | ~image/ 12h; 9 | } 10 | -------------------------------------------------------------------------------- /start-container.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $CONFIG_VARS ]]; then 4 | 5 | SPLIT=$(echo $CONFIG_VARS | tr "," "\n") 6 | ARGS= 7 | for VAR in ${SPLIT}; do 8 | ARGS="${ARGS} -v ${VAR} " 9 | done 10 | 11 | JSON=`json_env --json $ARGS` 12 | 13 | echo " ==> Writing ${CONFIG_FILE_PATH}/config.js with ${JSON}" 14 | 15 | echo "window.__env = ${JSON}" > ${CONFIG_FILE_PATH}/config.js 16 | fi 17 | 18 | exec "$@" 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | 3 | MAINTAINER Stepan Mazurov 4 | 5 | # This tool converts env vars into json to be injected into the config 6 | ADD https://s3.amazonaws.com/se-com-docs/bins/json_env /usr/local/bin/ 7 | RUN chmod +x /usr/local/bin/json_env 8 | 9 | # Do not start daemon for nginx 10 | RUN echo "daemon off;" >> /etc/nginx/nginx.conf 11 | 12 | # Overwrite default config 13 | COPY nginx-site.conf /etc/nginx/conf.d/default.conf 14 | COPY expires.conf /etc/nginx/conf.d/expires.conf 15 | 16 | # Set a path to config file to be written, can be changed at runtime 17 | ENV CONFIG_FILE_PATH /app 18 | 19 | RUN mkdir /app 20 | 21 | RUN echo "Add your index.html to /app: COPY index.html /app/index.html" > /app/index.html 22 | 23 | # Copy our start script 24 | COPY start-container.sh /usr/local/bin/start-container 25 | 26 | ENTRYPOINT ["start-container"] 27 | 28 | CMD ["nginx"] 29 | -------------------------------------------------------------------------------- /nginx-site.conf: -------------------------------------------------------------------------------- 1 | # pushState friendly! 2 | # The setup: 3 | # * website name is `_` 4 | # * javascript app is located at `/app` 5 | 6 | charset utf-8; 7 | 8 | tcp_nopush on; 9 | tcp_nodelay off; 10 | client_header_timeout 10s; 11 | client_body_timeout 10s; 12 | client_max_body_size 128k; 13 | reset_timedout_connection on; 14 | 15 | gzip on; 16 | gzip_types 17 | text/css 18 | text/javascript 19 | text/xml 20 | text/plain 21 | application/javascript 22 | application/x-javascript 23 | application/json 24 | application/xml 25 | application/rss+xml 26 | application/atom+xml 27 | font/truetype 28 | font/opentype 29 | image/svg+xml; 30 | 31 | server { 32 | listen 80; 33 | server_name localhost; 34 | root /app; 35 | 36 | expires $expires; 37 | 38 | # To make sure any assets can get through :) 39 | location / { 40 | try_files $uri @rewrites; 41 | } 42 | 43 | # If no asset matches, send it to your javascript app. Hopefully it's a route in the app! 44 | location @rewrites { 45 | rewrite ^(.+)$ /index.html last; 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![docker pull socialengine/nginx-spa][image shield]][docker hub] 2 | 3 | This is a Docker image used to serve a Single Page App (pure frontend javascript) using nginx, it support PushState, and includes a way to pass configuration at run time. 4 | 5 | ## Supported tags and `Dockerfile` links 6 | 7 | - [`latest` (*Dockerfile*)][latest] 8 | 9 | ## Included on top of [base][base image] nginx image 10 | 11 | - [pushState][push state] support. Every request is routed to `/app/index.html`. Useful for the clean urls (no `!#`) 12 | - [ENV-based Config](#env-config) 13 | 14 | # App Setup 15 | 16 | This docker image is built for `index.html` file being in the `/app` directory. `pushState` is enabled. 17 | 18 | At a minimum, you will want this in your `Dockerfile`: 19 | 20 | ```Dockerfile 21 | FROM socialengine/nginx-spa 22 | 23 | COPY build/ /app 24 | COPY index.html /app/index.html 25 | ``` 26 | 27 | Then you can build & run your app in the docker container. It will be served by a nginx static server. 28 | 29 | ```bash 30 | $ docker build -t your-app-image . 31 | $ docker run -e API_KEY=yourkey -e API_URL=http://myapi.example.com \ 32 | -e CONFIG_VARS=API_URL,API_KEY -p 8000:80 your-app-image 33 | ``` 34 | 35 | You can then go to `http://docker-ip:8000/` to see it in action. 36 | 37 | ## Env Config 38 | 39 | Included is ability to pass `run` time environmental variables to your app. 40 | 41 | This is very useful in case your API is on a different domain, or if you want to configure central error logging. 42 | 43 | ```bash 44 | $ docker run -e RAVEN_DSN=yourkey -e API_URL=http://myapi.example.com \ 45 | -e CONFIG_VARS=API_URL,RAVEN_DSN -p 8000:80 socialengine/nginx-spa:latest 46 | ==> Writing /app/config.js with {"RAVEN_DSN":"yourkey", "API_URL":"http://myapi.example.com"} 47 | ``` 48 | 49 | This will create a `config.js` file, which you can then add to your index.html, or load asynchronously. The path can be controlled with `CONFIG_FILE_PATH` environmental variable. 50 | 51 | [push state]: https://developer.mozilla.org/en-US/docs/Web/API/History_API 52 | [latest]: https://github.com/SocialEngine/docker-nginx-spa/blob/master/Dockerfile 53 | [base image]: https://github.com/nginxinc/docker-nginx 54 | [image shield]: https://img.shields.io/badge/dockerhub-socialengine%2Fnginx--spa-blue.svg 55 | [docker hub]: https://registry.hub.docker.com/u/socialengine/nginx-spa/ 56 | --------------------------------------------------------------------------------