├── .env-db
├── .gitignore
├── LICENSE
├── README.md
├── commands.md
├── data
├── container.txt
├── custom.css
├── hello.txt
├── helloworld.txt
└── index.html
├── django-app
├── .devcontainer
│ └── devcontainer.json
├── .env-dev
├── .env-dj
├── Dockerfile.dev
├── Dockerfile.django-app
├── cfehome
│ ├── __init__.py
│ ├── asgi.py
│ ├── celery
│ │ ├── __init__.py
│ │ └── conf.py
│ ├── db.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── django
├── manage.py
├── requirements.txt
├── run-worker.sh
├── run.sh
├── static
│ └── css
│ │ └── custom.css
├── staticfiles
│ └── blank-on-purpose.txt
├── todo.md
└── triggers
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ └── __init__.py
│ ├── models.py
│ ├── tasks.py
│ ├── tests.py
│ └── views.py
├── docker-compose.dev.yaml
├── docker-compose.hub.yaml
├── docker-compose.yaml
├── docker-dc.code-workspace
├── express-app
├── Dockerfile.express-app
├── commands.md
├── package.json
├── run.sh
└── server.js
├── go-app
├── Dockerfile.go-app
├── commands.md
├── run.sh
└── server.go
├── nginx
├── Dockerfile.nginx
├── commands.md
├── index.html
├── static.conf
└── world.html
├── php-app
├── Dockerfile.php-app
├── commands.md
├── index.php
├── run.sh
└── super.php
├── py-app
├── Dockerfile.py-app
├── commands.md
├── hello.txt
├── requirements.txt
├── run.sh
└── server.py
└── staticfiles
└── blank.txt
/.env-db:
--------------------------------------------------------------------------------
1 | POSTGRES_DB=dockerdc
2 | POSTGRES_PASSWORD=mysecretpassword
3 | POSTGRES_USER=myuser
4 | POSTGRES_HOST=db
5 | POSTGRES_PORT=5432
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | staticfiles/admin/
2 | staticfiles/css/
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | pip-wheel-metadata/
26 | share/python-wheels/
27 | *.egg-info/
28 | .installed.cfg
29 | *.egg
30 | MANIFEST
31 |
32 | # PyInstaller
33 | # Usually these files are written by a python script from a template
34 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
35 | *.manifest
36 | *.spec
37 |
38 | # Installer logs
39 | pip-log.txt
40 | pip-delete-this-directory.txt
41 |
42 | # Unit test / coverage reports
43 | htmlcov/
44 | .tox/
45 | .nox/
46 | .coverage
47 | .coverage.*
48 | .cache
49 | nosetests.xml
50 | coverage.xml
51 | *.cover
52 | *.py,cover
53 | .hypothesis/
54 | .pytest_cache/
55 |
56 | # Translations
57 | *.mo
58 | *.pot
59 |
60 | # Django stuff:
61 | *.log
62 | local_settings.py
63 | db.sqlite3
64 | db.sqlite3-journal
65 |
66 | # Flask stuff:
67 | instance/
68 | .webassets-cache
69 |
70 | # Scrapy stuff:
71 | .scrapy
72 |
73 | # Sphinx documentation
74 | docs/_build/
75 |
76 | # PyBuilder
77 | target/
78 |
79 | # Jupyter Notebook
80 | .ipynb_checkpoints
81 |
82 | # IPython
83 | profile_default/
84 | ipython_config.py
85 |
86 | # pyenv
87 | .python-version
88 |
89 | # pipenv
90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
93 | # install all needed dependencies.
94 | #Pipfile.lock
95 |
96 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
97 | __pypackages__/
98 |
99 | # Celery stuff
100 | celerybeat-schedule
101 | celerybeat.pid
102 |
103 | # SageMath parsed files
104 | *.sage.py
105 |
106 | # Environments
107 | .env
108 | .venv
109 | env/
110 | venv/
111 | ENV/
112 | env.bak/
113 | venv.bak/
114 |
115 | # Spyder project settings
116 | .spyderproject
117 | .spyproject
118 |
119 | # Rope project settings
120 | .ropeproject
121 |
122 | # mkdocs documentation
123 | /site
124 |
125 | # mypy
126 | .mypy_cache/
127 | .dmypy.json
128 | dmypy.json
129 |
130 | # Pyre type checker
131 | .pyre/
132 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Coding For Entrepreneurs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.codingforentrepreneurs.com/projects/docker-and-docker-compose)
2 |
3 | # [Docker & Docker Compose](https://www.codingforentrepreneurs.com/projects/docker-and-docker-compose)
4 |
5 |
6 | **Docker** helps us isolate our apps from everything else. It's *almost* as if our apps have their very own computer and I think that's pretty cool.
7 |
8 | **Docker Compose** helps us build local networks with many apps attached to it.
9 |
10 | This series will show you the fundamentals of using both in together.
11 |
12 | But why?
13 |
14 | Let's pretend I need Django, Express.js, and FastAPI to run on the *same domain*. Django will handle all the primary routes, Express.js will handle `/notifications` routes, FastAPI will handle the `/api/` routes.
15 |
16 | But how do we run these all on the *same domain*? **nginx** to the rescue! That's true, nginx can help us run all of these apps as illustrated above.
17 |
18 | But there's another problem. How can I use Docker for each of these apps?
19 |
20 | This is where **docker compose** comes in. **Docker Compose** will orchestrate containers in a network of their own.
21 |
22 | **Uh oh! This sounds complicated...**
23 |
24 | That's true. This does sound complicated but it's not. It's really just a bunch of configuration to get this stuff working correctly. Once you understand it fully, you'll be ready to use it in all kinds of projects.
25 |
26 | The goal of this series is to unpack what I mentioned above while building something real.
27 |
--------------------------------------------------------------------------------
/commands.md:
--------------------------------------------------------------------------------
1 | ```
2 | docker compose build --no-cache
3 | ```
4 |
5 |
6 | ```
7 | docker compose up --build
8 | ```
9 |
10 | ```
11 | docker compose down
12 | ```
13 |
14 |
15 |
16 | Delete all containers
17 | ```
18 | docker rm -vf $(docker ps -a -q)
19 | ```
20 |
21 | Delete all images
22 | ```
23 | docker rmi -f $(docker images -a -q)
24 | ```
25 | Found [here](https://stackoverflow.com/a/44785784)
26 |
27 |
28 |
29 | Automated Volume Creation
30 | ```
31 | docker run -v myvol:/where/to/mount container-image
32 | ```
33 | > `docker run --name ironman-1 -v ironmanvol:/app/data3 py-app-1`
34 | ```
35 | docker volume ls
36 | ```
37 |
38 | Manual Volume Creation
39 | ```
40 | docker run -v /abs/path/to/local/data/:/where/to/mount/ py-app-1
41 | ```
42 | > `docker run --name ironman -v /Users/cfe/Dev/docker-dc/data/:/app/data py-app-1`
43 |
44 |
45 |
46 | ### Databases
47 |
48 | ```
49 | docker pull postgres
50 | ```
51 |
52 |
53 | ```
54 | docker run -p 6543:5432 -e POSTGRES_USER=myuser -e POSTGRES_PASSWORD=mytestpw postgres
55 | ```
56 |
57 | ```
58 | docker run -it --rm postgres /bin/bash
59 | # psql -U myuser
60 | ```
61 |
62 |
63 |
64 | ## Pushing to Docker Hub
65 |
66 | ### 1. Tag images for dockerhub:
67 |
68 | Tags must be:
69 | `docker-hub-username`/`reponame`
70 | or
71 | `docker-hub-username`/`reponame:v1`
72 |
73 | Such as:
74 |
75 | ```
76 | docker build -t codingforentrepreneurs/myrepo -f Dockerfile .
77 | ```
78 |
79 | or
80 |
81 | ```
82 | docker build -t codingforentrepreneurs/myrepo:v3 -f Dockerfile .
83 | ```
84 |
85 | or
86 |
87 | ```
88 | docker image ls
89 | ```
90 | I have an image with the id of `f52105e1ba2b` that I am going to tag to `codingforentrepreneurs/docker-dc-goapp`
91 |
92 | ```
93 | docker tag f52105e1ba2b codingforentrepreneurs/docker-dc-goapp
94 | ```
95 |
96 | The format is
97 | ```
98 | docker tag This is working
--------------------------------------------------------------------------------
/django-app/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.166.1/containers/docker-existing-dockerfile
3 | {
4 | "name": "Existing Dockerfile",
5 |
6 | // Sets the run context to one level up instead of the .devcontainer folder.
7 | "context": "..",
8 |
9 | // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
10 | "dockerFile": "../Dockerfile.dev",
11 |
12 | // Set *default* container specific settings.json values on container create.
13 | "settings": {
14 | "terminal.integrated.shell.linux": null
15 | },
16 |
17 | // Add the IDs of extensions you want installed when the container is created.
18 | "extensions": []
19 |
20 | // Use 'forwardPorts' to make a list of ports inside the container available locally.
21 | // "forwardPorts": [],
22 |
23 | // Uncomment the next line to run commands after the container is created - for example installing curl.
24 | // "postCreateCommand": "apt-get update && apt-get install -y curl",
25 |
26 | // Uncomment when using a ptrace-based debugger like C++, Go, and Rust
27 | // "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
28 |
29 | // Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker.
30 | // "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],
31 |
32 | // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
33 | // "remoteUser": "vscode"
34 | }
35 |
--------------------------------------------------------------------------------
/django-app/.env-dev:
--------------------------------------------------------------------------------
1 | DJANGO_SUPERUSER_USERNAME=admin
2 | DJANGO_SUPERUSER_PASSWORD=mydjangopw
3 | DJANGO_SUERPUSER_EMAIL=hello@teamcfe.com
4 |
5 | POSTGRES_DB=dockerdc
6 | POSTGRES_PASSWORD=mysecretpassword
7 | POSTGRES_USER=myuser
8 | POSTGRES_HOST=host.docker.internal
9 | POSTGRES_PORT=5433
10 |
11 | REDIS_HOST=host.docker.internal
12 | REDIS_PORT=6380
--------------------------------------------------------------------------------
/django-app/.env-dj:
--------------------------------------------------------------------------------
1 | DJANGO_SUPERUSER_USERNAME=admin
2 | DJANGO_SUPERUSER_PASSWORD=mydjangopw
3 | DJANGO_SUERPUSER_EMAIL=hello@teamcfe.com
--------------------------------------------------------------------------------
/django-app/Dockerfile.dev:
--------------------------------------------------------------------------------
1 | FROM python:3.9-slim
2 |
3 | COPY . /app
4 | WORKDIR /app
5 |
6 | RUN pip install pip --upgrade
7 | RUN pip install -r requirements.txt
8 |
9 | RUN chmod +x run.sh
10 | RUN chmod +x run-worker.sh
11 |
12 |
13 | ENV USE_DOTENV_PKG=1
14 |
15 | CMD ["./run.sh"]
--------------------------------------------------------------------------------
/django-app/Dockerfile.django-app:
--------------------------------------------------------------------------------
1 | FROM python:3.9-slim
2 |
3 | COPY . /app
4 | WORKDIR /app
5 |
6 | RUN pip install pip --upgrade
7 | RUN pip install -r requirements.txt
8 |
9 | RUN chmod +x run.sh
10 | RUN chmod +x run-worker.sh
11 |
12 | CMD ["./run.sh"]
--------------------------------------------------------------------------------
/django-app/cfehome/__init__.py:
--------------------------------------------------------------------------------
1 | from .celery import app as celery_app
2 |
3 | __all__ = ('celery_app', )
--------------------------------------------------------------------------------
/django-app/cfehome/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for cfehome project.
3 |
4 | It exposes the ASGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.asgi import get_asgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cfehome.settings')
15 |
16 | application = get_asgi_application()
17 |
--------------------------------------------------------------------------------
/django-app/cfehome/celery/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pathlib
3 | import dotenv
4 | from celery import Celery
5 |
6 |
7 | USE_DOTENV = os.environ.get("USE_DOTENV_PKG")
8 | if str(USE_DOTENV) == "1":
9 | base_path = pathlib.Path(__file__).resolve().parent.parent.parent
10 | dotenv.read_dotenv(base_path / ".env-dev")
11 |
12 | # from django.conf import settings
13 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cfehome.settings')
14 |
15 | REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
16 | REDIS_PORT = os.environ.get("REDIS_PORT", 6379)
17 | REDIS_URL = f"redis://{REDIS_HOST}:{REDIS_PORT}"
18 |
19 | app = Celery('cfehome')
20 | app.config_from_object("django.conf:settings", namespace='CELERY')
21 | app.autodiscover_tasks()
22 | app.conf.broker_url = REDIS_URL
23 | app.conf.beat_scheduler = "django_celery_beat.schedulers.DatabaseScheduler"
24 |
--------------------------------------------------------------------------------
/django-app/cfehome/celery/conf.py:
--------------------------------------------------------------------------------
1 | CELERY_RESULT_BACKEND = "django-db"
--------------------------------------------------------------------------------
/django-app/cfehome/db.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | '''
4 | POSTGRES_DB=dockerdc
5 | POSTGRES_PASSWORD=mysecretpassword
6 | POSTGRES_USER=myuser
7 | POSTGRES_HOST=db
8 | POSTGRES_PORT=5432
9 | '''
10 | POSTGRES_DB=os.environ.get("POSTGRES_DB")
11 | POSTGRES_PASSWORD=os.environ.get("POSTGRES_PASSWORD")
12 | POSTGRES_USER=os.environ.get("POSTGRES_USER")
13 | POSTGRES_HOST=os.environ.get("POSTGRES_HOST")
14 | POSTGRES_PORT=os.environ.get("POSTGRES_PORT")
15 |
16 | POSTGRES_READY = (
17 | POSTGRES_DB is not None and
18 | POSTGRES_PASSWORD is not None and
19 | POSTGRES_USER is not None and
20 | POSTGRES_HOST is not None and
21 | POSTGRES_PORT is not None
22 | )
23 |
24 | if POSTGRES_READY:
25 | DATABASES = {
26 | "default": {
27 | "ENGINE": "django.db.backends.postgresql",
28 | "NAME": POSTGRES_DB,
29 | "USER": POSTGRES_USER,
30 | "PASSWORD":POSTGRES_PASSWORD,
31 | "HOST": POSTGRES_HOST,
32 | "PORT":POSTGRES_PORT
33 | }
34 | }
--------------------------------------------------------------------------------
/django-app/cfehome/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for cfehome project.
3 |
4 | Generated by 'django-admin startproject' using Django 3.2.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.2/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/3.2/ref/settings/
11 | """
12 |
13 | from pathlib import Path
14 |
15 | # Build paths inside the project like this: BASE_DIR / 'subdir'.
16 | BASE_DIR = Path(__file__).resolve().parent.parent
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = 'django-insecure-o&(4ribu%e!3it*f20l!&45_&05=rqb@l=+_kir5yle@ueo14f'
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = True
27 |
28 | ALLOWED_HOSTS = []
29 |
30 |
31 | # Application definition
32 |
33 | INSTALLED_APPS = [
34 | 'django.contrib.admin',
35 | 'django.contrib.auth',
36 | 'django.contrib.contenttypes',
37 | 'django.contrib.sessions',
38 | 'django.contrib.messages',
39 | 'django.contrib.staticfiles',
40 | 'django_celery_beat',
41 | 'django_celery_results',
42 | 'triggers',
43 | ]
44 |
45 | MIDDLEWARE = [
46 | 'django.middleware.security.SecurityMiddleware',
47 | 'django.contrib.sessions.middleware.SessionMiddleware',
48 | 'django.middleware.common.CommonMiddleware',
49 | 'django.middleware.csrf.CsrfViewMiddleware',
50 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
51 | 'django.contrib.messages.middleware.MessageMiddleware',
52 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
53 | ]
54 |
55 | ROOT_URLCONF = 'cfehome.urls'
56 |
57 | TEMPLATES = [
58 | {
59 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
60 | 'DIRS': [],
61 | 'APP_DIRS': True,
62 | 'OPTIONS': {
63 | 'context_processors': [
64 | 'django.template.context_processors.debug',
65 | 'django.template.context_processors.request',
66 | 'django.contrib.auth.context_processors.auth',
67 | 'django.contrib.messages.context_processors.messages',
68 | ],
69 | },
70 | },
71 | ]
72 |
73 | WSGI_APPLICATION = 'cfehome.wsgi.application'
74 |
75 |
76 | # Database
77 | # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
78 |
79 | DATABASES = {
80 | 'default': {
81 | 'ENGINE': 'django.db.backends.sqlite3',
82 | 'NAME': BASE_DIR / 'db.sqlite3',
83 | }
84 | }
85 | from .db import * # noqa
86 |
87 |
88 | # Password validation
89 | # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
90 |
91 | AUTH_PASSWORD_VALIDATORS = [
92 | {
93 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
94 | },
95 | {
96 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
97 | },
98 | {
99 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
100 | },
101 | {
102 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
103 | },
104 | ]
105 |
106 |
107 | # Internationalization
108 | # https://docs.djangoproject.com/en/3.2/topics/i18n/
109 |
110 | LANGUAGE_CODE = 'en-us'
111 |
112 | TIME_ZONE = 'UTC'
113 |
114 | USE_I18N = True
115 |
116 | USE_L10N = True
117 |
118 | USE_TZ = True
119 |
120 |
121 | # Static files (CSS, JavaScript, Images)
122 | # https://docs.djangoproject.com/en/3.2/howto/static-files/
123 |
124 | STATIC_URL = '/static/' # http://localhost/static/
125 | STATIC_ROOT = BASE_DIR / "staticfiles" # collectstatic
126 |
127 | STATICFILES_DIRS = [
128 | BASE_DIR / "static"
129 | ]
130 |
131 |
132 | # STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
133 | # Default primary key field type
134 | # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
135 |
136 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
137 |
--------------------------------------------------------------------------------
/django-app/cfehome/urls.py:
--------------------------------------------------------------------------------
1 | """cfehome URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/3.2/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.urls import include, path
14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 | """
16 | from django.contrib import admin
17 | from django.urls import path
18 |
19 | urlpatterns = [
20 | path('admin/', admin.site.urls),
21 | ]
22 |
--------------------------------------------------------------------------------
/django-app/cfehome/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for cfehome project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cfehome.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/django-app/django:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Docker-Docker-Compose/665c5c01762ee95546dd9a7902159e530a7932f2/django-app/django
--------------------------------------------------------------------------------
/django-app/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import dotenv
5 | import sys
6 | import pathlib
7 | # django-dotenv
8 |
9 | def main():
10 | USE_DOTENV = os.environ.get("USE_DOTENV_PKG")
11 | if str(USE_DOTENV) == "1":
12 | base_path = pathlib.Path(__file__).resolve().parent
13 | dotenv.read_dotenv(base_path / ".env-dev")
14 | """Run administrative tasks."""
15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cfehome.settings')
16 | try:
17 | from django.core.management import execute_from_command_line
18 | except ImportError as exc:
19 | raise ImportError(
20 | "Couldn't import Django. Are you sure it's installed and "
21 | "available on your PYTHONPATH environment variable? Did you "
22 | "forget to activate a virtual environment?"
23 | ) from exc
24 | execute_from_command_line(sys.argv)
25 |
26 |
27 | if __name__ == '__main__':
28 | main()
29 |
--------------------------------------------------------------------------------
/django-app/requirements.txt:
--------------------------------------------------------------------------------
1 | django>=3.2.0,<3.3.0
2 | django-celery-beat
3 | django-celery-results
4 | celery==5.0.5
5 | django-dotenv
6 | gunicorn
7 | psycopg2-binary
8 | redis
--------------------------------------------------------------------------------
/django-app/run-worker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | /usr/local/bin/celery -A cfehome worker --beat -S django -l info
--------------------------------------------------------------------------------
/django-app/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | /usr/local/bin/python manage.py migrate --noinput
4 |
5 | /usr/local/bin/python manage.py createsuperuser --noinput
6 |
7 | /usr/local/bin/python manage.py collectstatic --noinput
8 |
9 | RUN_PORT=${PORT:-8000}
10 | /usr/local/bin/gunicorn cfehome.wsgi:application --bind "0.0.0.0:${RUN_PORT}"
--------------------------------------------------------------------------------
/django-app/static/css/custom.css:
--------------------------------------------------------------------------------
1 | body {
2 | color:red;
3 | }
--------------------------------------------------------------------------------
/django-app/staticfiles/blank-on-purpose.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Docker-Docker-Compose/665c5c01762ee95546dd9a7902159e530a7932f2/django-app/staticfiles/blank-on-purpose.txt
--------------------------------------------------------------------------------
/django-app/todo.md:
--------------------------------------------------------------------------------
1 | - get a prod database -> psql
2 | - run migrate `python manage.py migrate --noinput`
3 | - create a superuser `python manage.py createsuperuser --noinput`
4 | - `DJANGO_SUPERUSER_USERNAME`
5 | - `DJANGO_SUPERUSER_PASSWORD`
6 | - `DJANGO_SUERPUSER_EMAIL`
--------------------------------------------------------------------------------
/django-app/triggers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Docker-Docker-Compose/665c5c01762ee95546dd9a7902159e530a7932f2/django-app/triggers/__init__.py
--------------------------------------------------------------------------------
/django-app/triggers/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/django-app/triggers/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class TriggersConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'triggers'
7 |
--------------------------------------------------------------------------------
/django-app/triggers/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Docker-Docker-Compose/665c5c01762ee95546dd9a7902159e530a7932f2/django-app/triggers/migrations/__init__.py
--------------------------------------------------------------------------------
/django-app/triggers/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/django-app/triggers/tasks.py:
--------------------------------------------------------------------------------
1 | import time
2 | from celery import shared_task
3 |
4 | @shared_task
5 | def hello_world(num=10):
6 | time.sleep(num)
7 | print(f"Hello world {num}")
--------------------------------------------------------------------------------
/django-app/triggers/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/django-app/triggers/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | # Create your views here.
4 |
--------------------------------------------------------------------------------
/docker-compose.dev.yaml:
--------------------------------------------------------------------------------
1 | version: '3.9'
2 | services:
3 | db:
4 | image: postgres
5 | restart: always
6 | env_file: .env-db
7 | ports:
8 | - "5433:5432"
9 | volumes:
10 | - postgres_data:/var/lib/postgresql/data/
11 | redis:
12 | image: redis
13 | restart: always
14 | ports:
15 | - "6380:6379"
16 | volumes:
17 | - redis_data:/data
18 | entrypoint: redis-server --appendonly yes
19 |
20 | volumes:
21 | redis_data:
22 | postgres_data:
--------------------------------------------------------------------------------
/docker-compose.hub.yaml:
--------------------------------------------------------------------------------
1 | version: '3.9'
2 | services:
3 | db:
4 | image: postgres
5 | restart: always
6 | env_file: .env-db
7 | expose:
8 | - 5432
9 | volumes:
10 | - postgres_data:/var/lib/postgresql/data/
11 | myredis:
12 | image: redis
13 | restart: always
14 | expose:
15 | - 6379
16 | volumes:
17 | - redis_data:/data
18 | entrypoint: redis-server --appendonly yes
19 | thor:
20 | build:
21 | context: ./django-app
22 | dockerfile: Dockerfile.django-app
23 | environment:
24 | - PORT=8001
25 | env_file:
26 | - ./django-app/.env-dj
27 | - ./.env-db
28 | expose:
29 | - 8001
30 | volumes:
31 | - ./staticfiles:/app/staticfiles/
32 | depends_on:
33 | - db
34 | loki:
35 | build:
36 | context: ./django-app
37 | dockerfile: Dockerfile.django-app
38 | command: ./run-worker.sh
39 | environment:
40 | - REDIS_HOST=myredis
41 | env_file:
42 | - ./django-app/.env-dj
43 | - ./.env-db
44 | volumes:
45 | - ./staticfiles:/app/staticfiles/
46 | depends_on:
47 | - thor
48 | - db
49 | ironman:
50 | build:
51 | context: ./py-app
52 | dockerfile: Dockerfile.py-app
53 | environment:
54 | - PORT=8081
55 | volumes:
56 | - ./data:/app/data
57 | - mydatavol:/app/mydatavol
58 | expose:
59 | - 8081
60 | depends_on:
61 | - db
62 | falcon:
63 | build:
64 | context: ./express-app
65 | dockerfile: Dockerfile.express-app
66 | environment:
67 | - PORT=8082
68 | volumes:
69 | - ./data:/app/data
70 | expose:
71 | - 8082
72 | zemo:
73 | build:
74 | context: ./php-app
75 | dockerfile: Dockerfile.php-app
76 | environment:
77 | - PORT=8083
78 | expose:
79 | - 8083
80 | batman:
81 | image: codingforentrepreneurs/docker-dc-go-app
82 | environment:
83 | - PORT=8084
84 | expose:
85 | - 8084
86 | nginx:
87 | build:
88 | context: ./nginx
89 | dockerfile: Dockerfile.nginx
90 | ports:
91 | - 8080:80
92 | volumes:
93 | - ./staticfiles:/www/static/
94 | depends_on:
95 | - thor
96 | - ironman
97 | - falcon
98 | - zemo
99 | - batman
100 |
101 | volumes:
102 | redis_data:
103 | postgres_data:
104 | data:
105 | external: true
106 | staticfiles:
107 | external: true
108 | mydatavol:
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.9'
2 | services:
3 | db:
4 | image: postgres
5 | restart: always
6 | env_file: .env-db
7 | expose:
8 | - 5432
9 | volumes:
10 | - postgres_data:/var/lib/postgresql/data/
11 | myredis:
12 | image: redis
13 | restart: always
14 | expose:
15 | - 6379
16 | volumes:
17 | - redis_data:/data
18 | entrypoint: redis-server --appendonly yes
19 | thor:
20 | build:
21 | context: ./django-app
22 | dockerfile: Dockerfile.django-app
23 | environment:
24 | - PORT=8001
25 | env_file:
26 | - ./django-app/.env-dj
27 | - ./.env-db
28 | expose:
29 | - 8001
30 | volumes:
31 | - ./staticfiles:/app/staticfiles/
32 | depends_on:
33 | - db
34 | loki:
35 | build:
36 | context: ./django-app
37 | dockerfile: Dockerfile.django-app
38 | command: ./run-worker.sh
39 | environment:
40 | - REDIS_HOST=myredis
41 | env_file:
42 | - ./django-app/.env-dj
43 | - ./.env-db
44 | volumes:
45 | - ./staticfiles:/app/staticfiles/
46 | depends_on:
47 | - thor
48 | - db
49 | ironman:
50 | build:
51 | context: ./py-app
52 | dockerfile: Dockerfile.py-app
53 | environment:
54 | - PORT=8081
55 | volumes:
56 | - ./data:/app/data
57 | - mydatavol:/app/mydatavol
58 | expose:
59 | - 8081
60 | depends_on:
61 | - db
62 | falcon:
63 | build:
64 | context: ./express-app
65 | dockerfile: Dockerfile.express-app
66 | environment:
67 | - PORT=8082
68 | volumes:
69 | - ./data:/app/data
70 | expose:
71 | - 8082
72 | zemo:
73 | build:
74 | context: ./php-app
75 | dockerfile: Dockerfile.php-app
76 | environment:
77 | - PORT=8083
78 | expose:
79 | - 8083
80 | batman:
81 | build:
82 | context: ./go-app
83 | dockerfile: Dockerfile.go-app
84 | environment:
85 | - PORT=8084
86 | expose:
87 | - 8084
88 | nginx:
89 | build:
90 | context: ./nginx
91 | dockerfile: Dockerfile.nginx
92 | ports:
93 | - 8080:80
94 | volumes:
95 | - ./staticfiles:/www/static/
96 | depends_on:
97 | - thor
98 | - ironman
99 | - falcon
100 | - zemo
101 | - batman
102 |
103 | volumes:
104 | redis_data:
105 | postgres_data:
106 | data:
107 | external: true
108 | staticfiles:
109 | external: true
110 | mydatavol:
--------------------------------------------------------------------------------
/docker-dc.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": "."
5 | }
6 | ],
7 | "settings": {}
8 | }
--------------------------------------------------------------------------------
/express-app/Dockerfile.express-app:
--------------------------------------------------------------------------------
1 | FROM node:lts-slim
2 |
3 | COPY . /app
4 | WORKDIR /app
5 |
6 | # package.json
7 | RUN npm install
8 |
9 | RUN chmod +x run.sh
10 |
11 | # test
12 | ENV PORT=9000
13 |
14 | CMD ["./run.sh"]
--------------------------------------------------------------------------------
/express-app/commands.md:
--------------------------------------------------------------------------------
1 |
2 | ```
3 | docker build -t express-app -f Dockerfile.express-app .
4 | ```
5 |
6 | ```
7 | docker run -p 8082:8000 -e PORT=8000 express-app
8 | ```
9 |
10 | ```
11 | docker run -it --rm express-app /bin/bash
12 | ```
13 |
14 | ```
15 | docker ps
16 | ```
--------------------------------------------------------------------------------
/express-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-app",
3 | "version": "1.0.0",
4 | "dependencies": {
5 | "express": "^4.17.1"
6 | }
7 | }
--------------------------------------------------------------------------------
/express-app/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | /usr/local/bin/node server.js
--------------------------------------------------------------------------------
/express-app/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express")
2 | const app = express()
3 | const port = process.env.PORT || 3000
4 | // function handleIndex (req, res) {
5 | // res.send("Hello world")
6 | // }
7 |
8 | app.get("/", (req, res)=>{
9 | res.send("Hello World")
10 | })
11 |
12 | app.get("/world", (req, res)=>{
13 | res.send("The World")
14 | })
15 |
16 |
17 | app.listen(port, ()=>{
18 | console.log(`Listening on http://localhost:${port}`)
19 | })
--------------------------------------------------------------------------------
/go-app/Dockerfile.go-app:
--------------------------------------------------------------------------------
1 | FROM golang:1.16
2 |
3 | COPY . /go/src/app
4 | WORKDIR /go/src/app
5 |
6 | RUN chmod +x run.sh
7 |
8 | CMD ["./run.sh"]
--------------------------------------------------------------------------------
/go-app/commands.md:
--------------------------------------------------------------------------------
1 |
2 | ```
3 | docker build -t go-app -f Dockerfile.go-app .
4 | ```
5 |
6 | ```
7 | docker build -t codingforentrepreneurs/docker-dc-go-app -f Dockerfile.go-app .
8 | ```
9 |
10 | ```
11 | docker run -p 8084:8000 -e PORT=8000 go-app
12 | ```
13 |
14 | ```
15 | docker run -it --rm go-app /bin/bash
16 | ```
17 |
18 | ```
19 | docker ps
20 | ```
21 |
22 |
23 | ```
24 | docker push codingforentrepreneurs/docker-dc-go-app
25 | ```
--------------------------------------------------------------------------------
/go-app/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | RUN_PORT=${PORT-:8030}
4 |
5 | /usr/local/go/bin/go run server.go
--------------------------------------------------------------------------------
/go-app/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "net/http"
7 | )
8 |
9 | func getEnv(key, fallback string) string {
10 | if value, ok := os.LookupEnv(key); ok {
11 | return value
12 | }
13 | return fallback
14 | }
15 |
16 | func main() {
17 | var port string
18 | port = getEnv("PORT", "8012")
19 | http.HandleFunc("/", HelloServer)
20 | fmt.Println("Running from http://localhost:" + port)
21 | http.ListenAndServe(":" + port, nil)
22 | }
23 |
24 | func HelloServer(w http.ResponseWriter, r *http.Request) {
25 | fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
26 | }
--------------------------------------------------------------------------------
/nginx/Dockerfile.nginx:
--------------------------------------------------------------------------------
1 | FROM nginx:latest
2 |
3 | COPY . /www/data
4 | COPY ./static.conf /etc/nginx/conf.d/default.conf
--------------------------------------------------------------------------------
/nginx/commands.md:
--------------------------------------------------------------------------------
1 |
2 | ```
3 | docker build -t my-nginx -f Dockerfile.nginx .
4 | ```
5 |
6 | ```
7 | docker run -p 8080:80 my-nginx
8 | ```
9 |
10 | ```
11 | docker ps
12 | ```
--------------------------------------------------------------------------------
/nginx/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hello World
5 |
6 |
--------------------------------------------------------------------------------
/nginx/static.conf:
--------------------------------------------------------------------------------
1 | upstream thor {
2 | server thor:8001;
3 | }
4 |
5 | upstream ironman {
6 | server ironman:8081;
7 | }
8 |
9 | upstream falcon {
10 | server falcon:8082;
11 | }
12 |
13 |
14 | upstream zemodancing {
15 | server zemo:8083;
16 | }
17 |
18 | upstream gobatman {
19 | server batman:8084;
20 | }
21 |
22 | server {
23 | listen 80;
24 | server_name localhost;
25 | root /www/data/;
26 |
27 |
28 | location / {
29 | proxy_pass http://thor;
30 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
31 | proxy_set_header Host $host;
32 | proxy_redirect off;
33 | }
34 |
35 | location /iron {
36 | proxy_pass http://ironman;
37 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
38 | proxy_set_header Host $host;
39 | proxy_redirect off;
40 | }
41 |
42 | location /world {
43 | proxy_pass http://falcon;
44 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
45 | proxy_set_header Host $host;
46 | proxy_redirect off;
47 | }
48 |
49 | location /super {
50 | proxy_pass http://zemodancing;
51 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
52 | proxy_set_header Host $host;
53 | proxy_redirect off;
54 | }
55 |
56 | location /darkknight {
57 | proxy_pass http://gobatman;
58 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
59 | proxy_set_header Host $host;
60 | proxy_redirect off;
61 | }
62 |
63 | location /static {
64 | autoindex on;
65 | alias /www/static/;
66 | }
67 |
68 | error_page 500 502 503 504 /50x.html;
69 | location = /50x.html {
70 | root /usr/share/nginx/html;
71 | }
72 | }
--------------------------------------------------------------------------------
/nginx/world.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The World
5 |
6 |
--------------------------------------------------------------------------------
/php-app/Dockerfile.php-app:
--------------------------------------------------------------------------------
1 | FROM php:8.0.3
2 |
3 | COPY . ./app
4 | WORKDIR /app
5 |
6 | RUN chmod +x run.sh
7 |
8 | CMD ["./run.sh"]
--------------------------------------------------------------------------------
/php-app/commands.md:
--------------------------------------------------------------------------------
1 |
2 | ```
3 | docker build -t php-app -f Dockerfile.php-app .
4 | ```
5 |
6 | ```
7 | docker run -p 8083:8001 -e PORT=8001 php-app
8 | ```
9 |
10 | ```
11 | docker run -it --rm php-app /bin/bash
12 | ```
13 |
14 | ```
15 | docker ps
16 | ```
--------------------------------------------------------------------------------
/php-app/index.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |