import os
from base64 import b64encode
from shutil import copyfile, rmtree

from boto.gs.connection import GSConnection
from flask.ext.scrypt import generate_password_hash
from boto.s3.connection import S3Connection
from boto.s3.key import Key
from werkzeug.utils import secure_filename
import magic

from app.settings import get_settings

#################
# STORAGE SCHEMA
#################

UPLOAD_PATHS = {
    'sessions': {
        'video': 'events/{event_id}/sessions/{id}/video',
        'audio': 'events/{event_id}/audios/{id}/audio',
        'slides': 'events/{event_id}/slides/{id}/slides'
    },
    'speakers': {
        'photo': 'events/{event_id}/speakers/{id}/photo',
        'thumbnail': 'events/{event_id}/speakers/{id}/thumbnail',
        'small': 'events/{event_id}/speakers/{id}/small',
        'icon': 'events/{event_id}/speakers/{id}/icon'
    },
    'event': {
        'logo': 'events/{event_id}/logo',
        'background_url': 'events/{event_id}/background',
        'thumbnail': 'events/{event_id}/thumbnail',
        'large': 'events/{event_id}/large',
        'icon': 'events/{event_id}/icon'
    },
    'sponsors': {
        'logo': 'events/{event_id}/sponsors/{id}/logo'
    },
    'tracks': {
        'track_image_url': 'events/{event_id}/tracks/{id}/track_image'
    },
    'user': {
        'avatar': 'users/{user_id}/avatar',
        'thumbnail': 'users/{user_id}/thumbnail',
        'small': 'users/{user_id}/small',
        'icon': 'users/{user_id}/icon'
    },
    'temp': {
        'event': 'events/temp/{uuid}'
    }
}


################
# HELPER CLASSES
################

class UploadedFile(object):
    """
    Helper for a disk-file to replicate request.files[ITEM] class
    """
    def __init__(self, file_path, filename):
        self.file_path = file_path
        self.filename = filename
        self.file = open(file_path)

    def save(self, new_path):
        copyfile(self.file_path, new_path)

    def read(self):
        return self.file.read()

    def __exit__(self, *args, **kwargs):
        self.file.close()


class UploadedMemory(object):
    """
    Helper for a memory file to replicate request.files[ITEM] class
    """
    def __init__(self, data, filename):
        self.data = data
        self.filename = filename

    def read(self):
        return self.data

    def save(self, path):
        f = open(path, 'w')
        f.write(self.data)
        f.close()


#########
# MAIN
#########

def upload(uploaded_file, key, **kwargs):
    """
    Upload handler
    """
    # refresh settings
    aws_bucket_name = get_settings()['aws_bucket_name']
    aws_key = get_settings()['aws_key']
    aws_secret = get_settings()['aws_secret']

    gs_bucket_name = get_settings()['gs_bucket_name']
    gs_key = get_settings()['gs_key']
    gs_secret = get_settings()['gs_secret']

    storage_place = get_settings()['storage_place']

    # upload
    if aws_bucket_name and aws_key and aws_secret and storage_place == 's3':
        return upload_to_aws(aws_bucket_name, aws_key, aws_secret, uploaded_file, key, **kwargs)
    elif gs_bucket_name and gs_key and gs_secret and storage_place == 'gs':
        return upload_to_gs(gs_bucket_name, gs_key, gs_secret, uploaded_file, key, **kwargs)
    else:
        return upload_local(uploaded_file, key, **kwargs)


def upload_local(uploaded_file, key, **kwargs):
    """
    Uploads file locally. Base dir - static/media/
    """
    filename = secure_filename(uploaded_file.filename)
    file_path = 'static/media/' + key + '/' + generate_hash(key) + '/' + filename
    dir_path = file_path.rsplit('/', 1)[0]
    # delete current
    try:
        rmtree(dir_path)
    except OSError:
        pass
    # create dirs
    if not os.path.isdir(dir_path):
        os.makedirs(dir_path)
    uploaded_file.save(file_path)
    return '/serve_' + file_path


def upload_to_aws(bucket_name, aws_key, aws_secret, file, key, acl='public-read'):
    """
    Uploads to AWS at key
    http://{bucket}.s3.amazonaws.com/{key}
    """
    conn = S3Connection(aws_key, aws_secret)
    bucket = conn.get_bucket(bucket_name)
    k = Key(bucket)
    # generate key
    filename = secure_filename(file.filename)
    key_dir = key + '/' + generate_hash(key) + '/'
    k.key = key_dir + filename
    # delete old data
    for item in bucket.list(prefix='/' + key_dir):
        item.delete()
    # set object settings

    file_data = file.read()
    file_mime = magic.from_buffer(file_data, mime=True)
    size = len(file_data)
    sent = k.set_contents_from_string(
        file_data,
        headers={
            'Content-Disposition': 'attachment; filename=%s' % filename,
            'Content-Type': '%s' % file_mime
        }
    )
    k.set_acl(acl)
    s3_url = 'https://%s.s3.amazonaws.com/' % bucket_name
    if sent == size:
        return s3_url + k.key
    return False


def upload_to_gs(bucket_name, client_id, client_secret, file, key, acl='public-read'):
    conn = GSConnection(client_id, client_secret)
    bucket = conn.get_bucket(bucket_name)
    k = Key(bucket)
    # generate key
    filename = secure_filename(file.filename)
    key_dir = key + '/' + generate_hash(key) + '/'
    k.key = key_dir + filename
    # delete old data
    for item in bucket.list(prefix='/' + key_dir):
        item.delete()
    # set object settings

    file_data = file.read()
    file_mime = magic.from_buffer(file_data, mime=True)
    size = len(file_data)
    sent = k.set_contents_from_string(
        file_data,
        headers={
            'Content-Disposition': 'attachment; filename=%s' % filename,
            'Content-Type': '%s' % file_mime
        }
    )
    k.set_acl(acl)
    gs_url = 'https://storage.googleapis.com/%s/' % bucket_name
    if sent == size:
        return gs_url + key
    return False

# ########
# HELPERS
# ########


def generate_hash(key):
    """
    Generate hash for key
    """
    phash = generate_password_hash(key, get_settings()['secret'])
    return b64encode(phash)[:10]  # limit len to 10, is sufficient

app/helpers/storage.py
import os
from base64 import b64encode
from shutil import copyfile, rmtree

from boto.gs.connection import GSConnection
from flask.ext.scrypt import generate_password_hash
from boto.s3.connection import S3Connection
from boto.s3.key import Key
from werkzeug.utils import secure_filename
import magic

from app.settings import get_settings

#################
# STORAGE SCHEMA
#################

UPLOAD_PATHS = {
    'sessions': {
        'video': 'events/{event_id}/sessions/{id}/video',
        'audio': 'events/{event_id}/audios/{id}/audio',
        'slides': 'events/{event_id}/slides/{id}/slides'
    },
    'speakers': {
        'photo': 'events/{event_id}/speakers/{id}/photo',
        'thumbnail': 'events/{event_id}/speakers/{id}/thumbnail',
        'small': 'events/{event_id}/speakers/{id}/small',
        'icon': 'events/{event_id}/speakers/{id}/icon'
    },
    'event': {
        'logo': 'events/{event_id}/logo',
        'background_url': 'events/{event_id}/background',
        'thumbnail': 'events/{event_id}/thumbnail',
        'large': 'events/{event_id}/large',
        'icon': 'events/{event_id}/icon'
    },
    'sponsors': {
        'logo': 'events/{event_id}/sponsors/{id}/logo'
    },
    'tracks': {
        'track_image_url': 'events/{event_id}/tracks/{id}/track_image'
    },
    'user': {
        'avatar': 'users/{user_id}/avatar',
        'thumbnail': 'users/{user_id}/thumbnail',
        'small': 'users/{user_id}/small',
        'icon': 'users/{user_id}/icon'
    },
    'temp': {
        'event': 'events/temp/{uuid}'
    }
}


################
# HELPER CLASSES
################

class UploadedFile(object):
    """
    Helper for a disk-file to replicate request.files[ITEM] class
    """
    def __init__(self, file_path, filename):
        self.file_path = file_path
        self.filename = filename
        self.file = open(file_path)

    def save(self, new_path):
        copyfile(self.file_path, new_path)

    def read(self):
        return self.file.read()

    def __exit__(self, *args, **kwargs):
        self.file.close()


class UploadedMemory(object):
    """
    Helper for a memory file to replicate request.files[ITEM] class
    """
    def __init__(self, data, filename):
        self.data = data
        self.filename = filename

    def read(self):
        return self.data

    def save(self, path):
        f = open(path, 'w')
        f.write(self.data)
        f.close()


#########
# MAIN
#########

def upload(uploaded_file, key, **kwargs):
    """
    Upload handler
    """
    # refresh settings
    aws_bucket_name = get_settings()['aws_bucket_name']
    aws_key = get_settings()['aws_key']
    aws_secret = get_settings()['aws_secret']

    gs_bucket_name = get_settings()['gs_bucket_name']
    gs_key = get_settings()['gs_key']
    gs_secret = get_settings()['gs_secret']

    storage_place = get_settings()['storage_place']

    # upload
    if aws_bucket_name and aws_key and aws_secret and storage_place == 's3':
        return upload_to_aws(aws_bucket_name, aws_key, aws_secret, uploaded_file, key, **kwargs)
    elif gs_bucket_name and gs_key and gs_secret and storage_place == 'gs':
        return upload_to_gs(gs_bucket_name, gs_key, gs_secret, uploaded_file, key, **kwargs)
    else:
        return upload_local(uploaded_file, key, **kwargs)


def upload_local(uploaded_file, key, **kwargs):
    """
    Uploads file locally. Base dir - static/media/
    """
    filename = secure_filename(uploaded_file.filename)
    file_path = 'static/media/' + key + '/' + generate_hash(key) + '/' + filename
    dir_path = file_path.rsplit('/', 1)[0]
    # delete current
    try:
        rmtree(dir_path)
    except OSError:
        pass
    # create dirs
    if not os.path.isdir(dir_path):
        os.makedirs(dir_path)
    uploaded_file.save(file_path)
    return '/serve_' + file_path


def upload_to_aws(bucket_name, aws_key, aws_secret, file, key, acl='public-read'):
    """
    Uploads to AWS at key
    http://{bucket}.s3.amazonaws.com/{key}
    """
    conn = S3Connection(aws_key, aws_secret)
    bucket = conn.get_bucket(bucket_name)
    k = Key(bucket)
    # generate key
    filename = secure_filename(file.filename)
    key_dir = key + '/' + generate_hash(key) + '/'
    k.key = key_dir + filename
    # delete old data
    for item in bucket.list(prefix='/' + key_dir):
        item.delete()
    # set object settings

    file_data = file.read()
    file_mime = magic.from_buffer(file_data, mime=True)
    size = len(file_data)
    sent = k.set_contents_from_string(
        file_data,
        headers={
            'Content-Disposition': 'attachment; filename=%s' % filename,
            'Content-Type': '%s' % file_mime
        }
    )
    k.set_acl(acl)
    s3_url = 'https://%s.s3.amazonaws.com/' % bucket_name
    if sent == size:
        return s3_url + k.key
    return False


def upload_to_gs(bucket_name, client_id, client_secret, file, key, acl='public-read'):
    conn = GSConnection(client_id, client_secret)
    bucket = conn.get_bucket(bucket_name)
    k = Key(bucket)
    # generate key
    filename = secure_filename(file.filename)
    key_dir = key + '/' + generate_hash(key) + '/'
    k.key = key_dir + filename
    # delete old data
    for item in bucket.list(prefix='/' + key_dir):
        item.delete()
    # set object settings

    file_data = file.read()
    file_mime = magic.from_buffer(file_data, mime=True)
    size = len(file_data)
    sent = k.set_contents_from_string(
        file_data,
        headers={
            'Content-Disposition': 'attachment; filename=%s' % filename,
            'Content-Type': '%s' % file_mime
        }
    )
    k.set_acl(acl)
    gs_url = 'https://storage.googleapis.com/%s/' % bucket_name
    if sent == size:
        return gs_url + k.key
    return False

# ########
# HELPERS
# ########


def generate_hash(key):
    """
    Generate hash for key
    """
    phash = generate_password_hash(key, get_settings()['secret'])
    return b64encode(phash)[:10]  # limit len to 10, is sufficient

app/helpers/storage.py
diff --git a/.travis.yml b/.travis.yml
index 16619c635c..4e42d8e01a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,7 +29,7 @@ after_success:
   - bash <(curl -s https://codecov.io/bash)
   - coveralls
   - codeclimate-test-reporter
-  - bash kubernetes/deployment/deploy.sh
+  - bash kubernetes/travis/deploy.sh
   - bash scripts/push_api_docs.sh
 addons:
   code_climate:
diff --git a/app/helpers/storage.py b/app/helpers/storage.py
index 74ea80c49d..cd1b14e2cd 100644
--- a/app/helpers/storage.py
+++ b/app/helpers/storage.py
@@ -199,7 +199,7 @@ def upload_to_gs(bucket_name, client_id, client_secret, file, key, acl='public-r
     k.set_acl(acl)
     gs_url = 'https://storage.googleapis.com/%s/' % bucket_name
     if sent == size:
-        return gs_url + key
+        return gs_url + k.key
     return False
 
 # ########
diff --git a/docs/INSTALLATION_GCE_KUBERNETES.md b/docs/INSTALLATION_GCE_KUBERNETES.md
index a2a897e524..f73fd9f388 100644
--- a/docs/INSTALLATION_GCE_KUBERNETES.md
+++ b/docs/INSTALLATION_GCE_KUBERNETES.md
@@ -90,7 +90,7 @@ _You can delete the instance if your not planning to use it for anything else. B
 - Create a cluster via the `gcloud` command line tool:
 
     ```
-    gcloud container clusters create opev-cluster
+    gcloud container clusters create opev-cluster --image-type=container_vm
     ```
 
 - Get the credentials for `kubectl` to use.
diff --git a/kubernetes/deploy.sh b/kubernetes/deploy.sh
new file mode 100755
index 0000000000..53dab01330
--- /dev/null
+++ b/kubernetes/deploy.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+echo "Deploying the project to kubernetes cluster"
+export DIR=${BASH_SOURCE%/*}
+# Start KubeLego deployment
+kubectl create -f ${DIR}/yamls/lego
+# Start nginx deployment, ingress & service
+kubectl create -f ${DIR}/yamls/nginx
+# Start postgres persistent volume, deployment & service
+kubectl create -f ${DIR}/yamls/postgres
+# Start the redirector deployment & service
+kubectl create -f ${DIR}/yamls/redirector
+# Start Redis deployment & service
+kubectl create -f ${DIR}/yamls/redis
+# Starting nfs deployment for persistent storage. Tricky. So, we'll go file by file.
+# create the persistent volume using a GCE persistent disk
+kubectl create -f ${DIR}/yamls/persistent-store/nfs-data-disk-pv.yml
+sleep 10
+# create the persistent volume claim
+kubectl create -f ${DIR}/yamls/persistent-store/nfs-data-disk-pv-claim.yml
+echo "Waiting for the NFS disk to initialize"
+sleep 40
+# create the NFS Server deployment
+kubectl create -f ${DIR}/yamls/persistent-store/nfs-server.yml
+# Let us give the NFS server ample amount of time to start up
+echo "Waiting for NFS server to start up"
+sleep 60
+# create the NFS deployment service to expose ports
+kubectl create -f ${DIR}/yamls/persistent-store/nfs-server-service.yml
+# create the persistent volume entry for the NFS Server with a ReadWriteMany access mode
+kubectl create -f ${DIR}/yamls/persistent-store/nfs-pv.yml
+# create the required claim for the NFS Server persistent volume
+kubectl create -f ${DIR}/yamls/persistent-store/nfs-pv-claim.yml
+echo "Waiting longer for NFS server to start up"
+# I found the sometimes NFS required a little bit longer to start up after all this. So, let's just give it some more time.
+sleep 30
+# Start celery deployment
+kubectl create -f ${DIR}/yamls/celery
+# Start web deployment & service
+kubectl create -f ${DIR}/yamls/web
+echo "Done. The project was deployed to kubernetes. :)"
diff --git a/kubernetes/images/nfs-server/Dockerfile b/kubernetes/images/nfs-server/Dockerfile
new file mode 100644
index 0000000000..873423e56b
--- /dev/null
+++ b/kubernetes/images/nfs-server/Dockerfile
@@ -0,0 +1,23 @@
+# Copyright 2016 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM centos
+MAINTAINER Niranjan Rajendran <niranjan94@yahoo.com>
+RUN yum -y install /usr/bin/ps nfs-utils && yum clean all
+RUN mkdir -p /data
+ADD run_nfs.sh /usr/local/bin/
+
+EXPOSE 2049/tcp 20048/tcp 111/tcp 111/udp
+
+ENTRYPOINT ["/usr/local/bin/run_nfs.sh", "/data"]
diff --git a/kubernetes/images/nfs-server/run_nfs.sh b/kubernetes/images/nfs-server/run_nfs.sh
new file mode 100755
index 0000000000..e6eb8f9462
--- /dev/null
+++ b/kubernetes/images/nfs-server/run_nfs.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+# Copyright 2015 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+function start()
+{
+
+    # prepare /etc/exports
+    for i in "$@"; do
+        # fsid=0: needed for NFSv4
+        echo "$i *(rw,fsid=0,insecure,no_root_squash)" >> /etc/exports
+        # move index.html to here
+        /bin/cp /tmp/index.html $i/
+        chmod 644 $i/index.html
+        echo "Serving $i"
+    done
+
+    # start rpcbind if it is not started yet
+    /usr/sbin/rpcinfo 127.0.0.1 > /dev/null; s=$?
+    if [ $s -ne 0 ]; then
+       echo "Starting rpcbind"
+       /usr/sbin/rpcbind -w
+    fi
+
+    mount -t nfsd nfds /proc/fs/nfsd
+
+    # -N 4.x: disable NFSv4
+    # -V 3: enable NFSv3
+    /usr/sbin/rpc.mountd -N 2 -V 3 -N 4 -N 4.1
+
+    /usr/sbin/exportfs -r
+    # -G 10 to reduce grace time to 10 seconds (the lowest allowed)
+    /usr/sbin/rpc.nfsd -G 10 -N 2 -V 3 -N 4 -N 4.1 2
+    /usr/sbin/rpc.statd --no-notify
+    echo "NFS started"
+}
+
+function stop()
+{
+    echo "Stopping NFS"
+
+    /usr/sbin/rpc.nfsd 0
+    /usr/sbin/exportfs -au
+    /usr/sbin/exportfs -f
+
+    kill $( pidof rpc.mountd )
+    umount /proc/fs/nfsd
+    echo > /etc/exports
+    exit 0
+}
+
+
+trap stop TERM
+
+start "$@"
+
+# Ugly hack to do nothing and wait for SIGTERM
+while true; do
+    sleep 5
+done
diff --git a/kubernetes/image/Dockerfile b/kubernetes/images/web/Dockerfile
similarity index 100%
rename from kubernetes/image/Dockerfile
rename to kubernetes/images/web/Dockerfile
diff --git a/kubernetes/image/setup.sh b/kubernetes/images/web/setup.sh
similarity index 100%
rename from kubernetes/image/setup.sh
rename to kubernetes/images/web/setup.sh
diff --git a/kubernetes/run.sh b/kubernetes/run.sh
old mode 100644
new mode 100755
diff --git a/kubernetes/deployment/deploy.sh b/kubernetes/travis/deploy.sh
similarity index 98%
rename from kubernetes/deployment/deploy.sh
rename to kubernetes/travis/deploy.sh
index 05b7416967..72651fc6c2 100755
--- a/kubernetes/deployment/deploy.sh
+++ b/kubernetes/travis/deploy.sh
@@ -26,7 +26,7 @@ gcloud auth activate-service-account --key-file eventyay-8245fde7ab8a.json
 export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/eventyay-8245fde7ab8a.json
 gcloud config set project eventyay
 gcloud container clusters get-credentials eventyay-cluster
-cd kubernetes/image
+cd kubernetes/images/web
 docker build --build-arg COMMIT_HASH=$TRAVIS_COMMIT --build-arg BRANCH=$DEPLOY_BRANCH --build-arg REPOSITORY=$REPOSITORY --no-cache -t gcr.io/eventyay/web:$TRAVIS_COMMIT .
 docker tag gcr.io/eventyay/web:$TRAVIS_COMMIT gcr.io/eventyay/web:latest
 gcloud docker -- push gcr.io/eventyay/web
diff --git a/kubernetes/yamls/celery/celery-deployment.yml b/kubernetes/yamls/celery/celery-deployment.yml
index 47acdbec6b..cf5ba6c08c 100644
--- a/kubernetes/yamls/celery/celery-deployment.yml
+++ b/kubernetes/yamls/celery/celery-deployment.yml
@@ -2,7 +2,6 @@ kind: Deployment
 apiVersion: extensions/v1beta1
 metadata:
   name: celery
-  creationTimestamp:
 spec:
   replicas: 1
   template:
@@ -20,5 +19,11 @@ spec:
           value: 'true'
         - name: DEPLOYMENT
           value: 'celery'
-        resources: {}
+        volumeMounts:
+          - mountPath: /opev/open_event/static/uploads/
+            name: nfs-storage
       restartPolicy: Always
+      volumes:
+        - name: nfs-storage
+          persistentVolumeClaim:
+            claimName: nfs-claim
diff --git a/kubernetes/yamls/debug/busybox.yml b/kubernetes/yamls/debug/busybox.yml
new file mode 100644
index 0000000000..babb7652f5
--- /dev/null
+++ b/kubernetes/yamls/debug/busybox.yml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: busybox
+  namespace: default
+spec:
+  containers:
+  - image: busybox
+    command:
+      - sleep
+      - "3600"
+    imagePullPolicy: IfNotPresent
+    name: busybox
+  restartPolicy: Always
diff --git a/kubernetes/yamls/persistent-store/nfs-data-disk-pv-claim.yml b/kubernetes/yamls/persistent-store/nfs-data-disk-pv-claim.yml
new file mode 100644
index 0000000000..0127847b61
--- /dev/null
+++ b/kubernetes/yamls/persistent-store/nfs-data-disk-pv-claim.yml
@@ -0,0 +1,11 @@
+kind: PersistentVolumeClaim
+apiVersion: v1
+metadata:
+  name: nfs-data-claim
+spec:
+  volumeName: nfs-data-disk
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 10Gi
diff --git a/kubernetes/yamls/persistent-store/nfs-data-disk-pv.yml b/kubernetes/yamls/persistent-store/nfs-data-disk-pv.yml
new file mode 100644
index 0000000000..574a96b80e
--- /dev/null
+++ b/kubernetes/yamls/persistent-store/nfs-data-disk-pv.yml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+  name: nfs-data-disk
+  labels:
+    name: nfs-data-disk
+spec:
+  capacity:
+    storage: 10Gi
+  accessModes:
+    - ReadWriteOnce
+  gcePersistentDisk:
+    pdName: "nfs-data-disk"
+    fsType: "ext4"
diff --git a/kubernetes/yamls/persistent-store/nfs-pv-claim.yml b/kubernetes/yamls/persistent-store/nfs-pv-claim.yml
new file mode 100644
index 0000000000..3b53ab240d
--- /dev/null
+++ b/kubernetes/yamls/persistent-store/nfs-pv-claim.yml
@@ -0,0 +1,11 @@
+kind: PersistentVolumeClaim
+apiVersion: v1
+metadata:
+  name: nfs-claim
+spec:
+  volumeName: nfs
+  accessModes:
+    - ReadWriteMany
+  resources:
+    requests:
+      storage: 10Gi
diff --git a/kubernetes/yamls/persistent-store/nfs-pv.yml b/kubernetes/yamls/persistent-store/nfs-pv.yml
new file mode 100644
index 0000000000..d33c25185b
--- /dev/null
+++ b/kubernetes/yamls/persistent-store/nfs-pv.yml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+  name: nfs
+  labels:
+    name: nfs
+spec:
+  capacity:
+    storage: 10Gi
+  accessModes:
+    - ReadWriteMany
+  nfs:
+    server: 10.3.244.20
+    path: "/data"
diff --git a/kubernetes/yamls/persistent-store/nfs-server-service.yml b/kubernetes/yamls/persistent-store/nfs-server-service.yml
new file mode 100644
index 0000000000..a1945464f3
--- /dev/null
+++ b/kubernetes/yamls/persistent-store/nfs-server-service.yml
@@ -0,0 +1,15 @@
+kind: Service
+apiVersion: v1
+metadata:
+  name: nfs-server
+spec:
+  ports:
+    - name: nfs
+      port: 2049
+    - name: mountd
+      port: 20048
+    - name: rpcbind
+      port: 111
+  selector:
+    role: nfs-server
+  clusterIP: 10.3.244.20
diff --git a/kubernetes/yamls/persistent-store/nfs-server.yml b/kubernetes/yamls/persistent-store/nfs-server.yml
new file mode 100644
index 0000000000..af0ca80430
--- /dev/null
+++ b/kubernetes/yamls/persistent-store/nfs-server.yml
@@ -0,0 +1,31 @@
+kind: Deployment
+apiVersion: extensions/v1beta1
+metadata:
+  name: nfs-server
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        role: nfs-server
+    spec:
+      hostname: nfs-server
+      containers:
+      - name: nfs-server
+        image: gcr.io/eventyay/nfs-server:latest
+        ports:
+          - name: nfs
+            containerPort: 2049
+          - name: mountd
+            containerPort: 20048
+          - name: rpcbind
+            containerPort: 111
+        securityContext:
+          privileged: true
+        volumeMounts:
+          - mountPath: /data
+            name: data-pvc
+      volumes:
+        - name: data-pvc
+          persistentVolumeClaim:
+            claimName: nfs-data-claim
diff --git a/kubernetes/yamls/postgres/postgres-persistence.yml b/kubernetes/yamls/postgres/postgres-persistence.yml
index 711064b042..852b29f8b2 100644
--- a/kubernetes/yamls/postgres/postgres-persistence.yml
+++ b/kubernetes/yamls/postgres/postgres-persistence.yml
@@ -6,7 +6,7 @@ metadata:
     name: pg-data-disk
 spec:
   capacity:
-    storage: 1Gi
+    storage: 10Gi
   accessModes:
     - ReadWriteOnce
   gcePersistentDisk:
diff --git a/kubernetes/yamls/web/web-deployment.yml b/kubernetes/yamls/web/web-deployment.yml
index 90ece84d7b..2f86a94927 100644
--- a/kubernetes/yamls/web/web-deployment.yml
+++ b/kubernetes/yamls/web/web-deployment.yml
@@ -32,4 +32,11 @@ spec:
           value: 'web'
         - name: FORCE_SSL
           value: 'yes'
+        volumeMounts:
+          - mountPath: /opev/open_event/static/uploads/
+            name: nfs-storage
       restartPolicy: Always
+      volumes:
+        - name: nfs-storage
+          persistentVolumeClaim:
+            claimName: nfs-claim

Import not working on Kubernetes deployment
The file upload for import is not working on Kubernetes deployment. (but works locally and on heroku)


