Skip to content

Instantly share code, notes, and snippets.

@koistya
Last active July 15, 2022 01:00
Show Gist options
  • Select an option

  • Save koistya/08d3654862f654e756674491593e6fe2 to your computer and use it in GitHub Desktop.

Select an option

Save koistya/08d3654862f654e756674491593e6fe2 to your computer and use it in GitHub Desktop.

Revisions

  1. koistya revised this gist Mar 17, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Sample Docker Web Application.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Docker-based Web Application Setup (example)

    This is an example of hosting a standalone [web front-end](https://github.com/kriasoft/react-starter-kit) (web) and [data API](https://github.com/kriasoft/nodejs-api-starter) (api) applications under the same domain via Nginx (acting as a reverse proxy) and Docker, where HTTP requests starting with `example.com/graphql` and `example.com/login/*` are being redirected to http://api:3000 and everything else under the same domain is going to be passed to http://web:3000.
    This is an example of hosting standalone [web front-end](https://github.com/kriasoft/react-starter-kit) (web) and [data API](https://github.com/kriasoft/nodejs-api-starter) (api) applications under the same domain via Nginx (acting as a reverse proxy) and Docker, where HTTP requests starting with `example.com/graphql` and `example.com/login/*` are being redirected to http://api:3000 and everything else under the same domain is going to be passed to http://web:3000.

    ## Folder Structure

  2. koistya revised this gist Mar 17, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions Sample Docker Web Application.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,7 @@
    # Docker-based Web Application Setup (example)

    This is an example of hosting a standalone [web front-end](https://github.com/kriasoft/react-starter-kit) (web) and [data API](https://github.com/kriasoft/nodejs-api-starter) (api) applications under the same domain via Nginx (acting as a reverse proxy) and Docker, where HTTP requests starting with `example.com/graphql` and `example.com/login/*` are being redirected to http://api:3000 and everything else under the same domain is going to be passed to http://web:3000.

    ## Folder Structure

    ```bash
  3. koistya revised this gist Mar 16, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Sample Docker Web Application.md
    Original file line number Diff line number Diff line change
    @@ -85,7 +85,7 @@ services:
    - PORT=3000
    - NODE_ENV=production
    - NODE_DEBUG=false
    - WEBSITE_URL=https://reactstarter.com
    - WEBSITE_URL=https://example.com
    - FRONTEND_HOST_WHITELIST=localhost
    - DATABASE_URL=postgres://user:xxx@db:5432/api
    - DATABASE_DEBUG=false
  4. koistya created this gist Mar 16, 2017.
    197 changes: 197 additions & 0 deletions Sample Docker Web Application.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,197 @@
    # Docker-based Web Application Setup (example)

    ## Folder Structure

    ```bash
    .
    ├── /nginx.sites/ # Server configuration for each of web apps
    ├── /nginx.snippets/ # Nginx code snippets
    ├── docker-compose.yml # Defines Docker services, networks and volumes
    └── nginx.config # Top-level Nginx configuration
    ```

    ### `docker-compose.yml`

    ```yml
    version: '3'

    volumes:
    data:
    redis:

    services:

    nginx:
    image: nginx:1.11.10-alpine
    links:
    - api
    - web
    read_only: true
    tmpfs:
    - /var/cache/nginx
    - /var/log/nginx
    - /var/run
    volumes:
    - ./nginx.snippets:/etc/nginx/snippets:ro
    - ./nginx.sites:/etc/nginx/sites-enabled:ro
    - ./nginx.conf:/etc/nginx/nginx.conf:ro
    - /etc/letsencrypt:/etc/letsencrypt:ro
    - /etc/ssl/certs/dhparam.pem:/etc/ssl/certs/dhparam.pem:ro
    - /var/www:/var/www
    ports:
    - '80:80'
    - '443:443'

    db:
    image: postgres:9.6.2-alpine
    restart: always
    environment:
    - POSTGRES_PASSWORD=xxx
    read_only: true
    tmpfs:
    - /tmp
    - /var/run/postgresql
    volumes:
    - data:/var/lib/postgresql/data

    redis:
    image: redis:3.2.8-alpine
    restart: always
    read_only: true
    volumes:
    - redis:/data

    web:
    image: web
    read_only: true
    restart: always
    environment:
    - PORT=3000
    - NODE_ENV=production
    expose:
    - '3000'

    api:
    image: api
    read_only: true
    restart: always
    depends_on:
    - db
    - redis
    links:
    - db
    - redis
    environment:
    - PORT=3000
    - NODE_ENV=production
    - NODE_DEBUG=false
    - WEBSITE_URL=https://reactstarter.com
    - FRONTEND_HOST_WHITELIST=localhost
    - DATABASE_URL=postgres://user:xxx@db:5432/api
    - DATABASE_DEBUG=false
    - REDIS_URL=redis://redis:6379/1
    - SESSION_SECRET=xxx
    - FACEBOOK_ID=xxx
    - FACEBOOK_SECRET=xxx
    - GOOGLE_ID=xxx
    - GOOGLE_SECRET=xxx
    - TWITTER_KEY=xxx
    - TWITTER_SECRET=xxx
    expose:
    - '3000'
    # ports:
    # - '0.0.0.0:9229:9229' # V8 inspector
    ```

    ### `nginx.sites/example.com`

    ```txt
    server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
    }
    server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.example.com;
    include snippets/ssl-example.com.conf;
    return 301 https://example.com$request_uri;
    }
    server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;
    include snippets/ssl-example.com.conf;
    root /var/www/example.com;
    location ~ /.well-known {
    allow all;
    }
    location ~ ^/login/.+ {
    include snippets/proxy-params.conf;
    proxy_pass http://api:3000;
    }
    location /graphql {
    include snippets/proxy-params.conf;
    proxy_pass http://api:3000;
    }
    location / {
    include snippets/proxy-params.conf;
    proxy_pass http://web:3000;
    }
    }
    ```

    ### `nginx.snippets/proxy-params.conf`

    ```txt
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_max_temp_file_size 0;
    proxy_redirect off;
    proxy_read_timeout 240s;
    ```

    ### `nginx.snippets/ssl-params.conf`

    ```txt
    # https://cipherli.st/
    # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    # Disable preloading HSTS for now. You can use the commented out header line that includes
    # the "preload" directive if you understand the implications.
    #add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ```

    ### `ssl-example.com.conf`

    ```txt
    include snippets/ssl-params.conf;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ```