Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions dockerfiles/docker-compose-search.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ services:
# Disable HTTPS on development.
- xpack.security.transport.ssl.enabled=false
- 'ES_JAVA_OPTS=-Xms128m -Xmx128m'
ports:
- "9200:9200"
links:
- web
- celery
Expand Down
15 changes: 7 additions & 8 deletions dockerfiles/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ services:
stop_grace_period: 1s
image: nginx:1.22
ports:
- "80:80"
- "${RTDDEV_PORT_NGINX:-80}:80"
links:
- web
- proxito
Expand All @@ -30,6 +30,12 @@ services:
readthedocs:
volumes:
- ${PWD}/dockerfiles/nginx:/etc/nginx/templates
# Each repository symlinks the templates in this directory from its own templates,
# mounted at the path the relative symlink resolves to inside the container.
- ${PWD}/common/dockerfiles/nginx:/etc/common/dockerfiles/nginx:ro
# Required on Linux by `side-by-side.conf.template`; Docker Desktop resolves it already.
extra_hosts:
- "host.docker.internal:host-gateway"
# Disable logs for NGINX by default because they are too noisy and we have
# better logs in our application code
logging:
Expand Down Expand Up @@ -69,8 +75,6 @@ services:
- ${PWD}/${RTDDEV_PATH_ADDONS:-../addons}/webpack.config.js:/usr/src/app/checkouts/addons/webpack.config.js
tty: true
working_dir: /usr/src/app/checkouts/addons/
ports:
- "8000:8000"
command: [
"npm",
"run",
Expand Down Expand Up @@ -186,8 +190,6 @@ services:
context: ${PWD}/${RTDDEV_PATH_EXT_THEME:-../ext-theme}
dockerfile: ${PWD}/common/dockerfiles/Dockerfile.webpack
working_dir: /usr/src/app/checkouts/ext-theme
ports:
- "10001:10001"
volumes:
- ${PWD}/${RTDDEV_PATH_EXT_THEME:-../ext-theme}/src:/usr/src/app/checkouts/ext-theme/src
- ${PWD}/${RTDDEV_PATH_EXT_THEME:-../ext-theme}/readthedocsext:/usr/src/app/checkouts/ext-theme/readthedocsext
Expand Down Expand Up @@ -445,9 +447,6 @@ services:

storage:
image: rustfs/rustfs:1.0.0-alpha.83
ports:
- "9000:9000"
- "9001:9001"
environment:
- RUSTFS_ADDRESS=:9000
- RUSTFS_ACCESS_KEY=admin
Expand Down
97 changes: 97 additions & 0 deletions dockerfiles/nginx/services.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Development services, served by hostname instead of their own host ports,
# so both environments can run side by side (see `side-by-side.conf.template`).
#
# Upstreams are resolved per request (`resolver` + variable),
# since these containers may start after NGINX, or not at all (`--no-search`).

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

# ext-theme webpack development server, including its live reload websocket.
server {
listen 80;
server_name assets.${NGINX_WEB_SERVER_NAME};
access_log off;
resolver 127.0.0.11 valid=10s;

location / {
set $upstream http://webpack:10001;
proxy_pass $upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
}
}

# Addons development server.
server {
listen 80;
server_name addons.${NGINX_WEB_SERVER_NAME};
access_log off;
resolver 127.0.0.11 valid=10s;

location / {
set $upstream http://addons:8000;
proxy_pass $upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
}
}

# S3 API, used by presigned upload URLs.
server {
listen 80;
server_name storage.${NGINX_WEB_SERVER_NAME};
access_log off;
resolver 127.0.0.11 valid=10s;
client_max_body_size 0;
proxy_request_buffering off;

location / {
set $upstream http://storage:9000;
proxy_pass $upstream;
# S3 clients sign the Host header.
proxy_set_header Host $http_host;
}
}

# S3 web console.
server {
listen 80;
server_name storage-console.${NGINX_WEB_SERVER_NAME};
access_log off;
resolver 127.0.0.11 valid=10s;

location = / {
return 302 /rustfs/console/;
}

# The console calls the S3 and admin APIs on its own origin, signing the Host header.
location / {
set $upstream http://storage:9001;
proxy_pass $upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
}
}

# Elasticsearch.
server {
listen 80;
server_name search.${NGINX_WEB_SERVER_NAME};
access_log off;
resolver 127.0.0.11 valid=10s;

location / {
set $upstream http://search:9200;
proxy_pass $upstream;
proxy_set_header Host $http_host;
}
}
21 changes: 21 additions & 0 deletions dockerfiles/nginx/side-by-side.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Forward the other environment's domains (community <-> business) to its NGINX,
# so both can run side by side: whichever one owns port 80 forwards to the other,
# which publishes its NGINX on another host port (`RTDDEV_PORT_NGINX`).
# Returns a 502 for those domains when the other environment isn't running.
server {
listen 80;
server_name ${NGINX_SIDE_BY_SIDE_SERVER_NAME};
access_log off;
client_max_body_size 0;

location / {
proxy_pass http://host.docker.internal:${NGINX_SIDE_BY_SIDE_PORT};
proxy_set_header Host $http_host;
# Websockets, like webpack's live reload.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 300s;
}
}
45 changes: 44 additions & 1 deletion dockerfiles/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,48 @@
DOCKER_COMPOSE_OVERRIDE = "docker-compose.override.yml"
DOCKER_COMPOSE_COMMAND = f"docker compose --project-directory=. -f {DOCKER_COMPOSE} -f {DOCKER_COMPOSE_OVERRIDE} -f {DOCKER_COMPOSE_SEARCH}"

# Host port for NGINX when the other environment already owns port 80.
# The other environment forwards our domains here (see `nginx/side-by-side.conf.template`).
NGINX_SIDE_BY_SIDE_PORTS = {
"community": "10080",
"commercial": "10081",
}


def compose_project_name():
if os.environ.get("COMPOSE_PROJECT_NAME"):
return os.environ["COMPOSE_PROJECT_NAME"]
with open(".env") as f:
for line in f:
name, _, value = line.strip().partition("=")
if name == "COMPOSE_PROJECT_NAME":
return value
return None


def nginx_port(c):
"""
Host port for NGINX: 80, unless another container already publishes it.

Run community and business at the same time without any configuration:
the second one to start gets its side-by-side port.
``RTDDEV_PORT_NGINX`` overrides it.
"""
if os.environ.get("RTDDEV_PORT_NGINX"):
return os.environ["RTDDEV_PORT_NGINX"]

project = compose_project_name()
side_by_side_port = NGINX_SIDE_BY_SIDE_PORTS.get(project)
if not side_by_side_port:
return "80"

result = c.run("docker ps --filter publish=80 --format '{{.Names}}'", hide=True, warn=True)
for owner in result.stdout.split():
if owner != f"{project}-nginx-1":
print(f"Port 80 is used by {owner}, publishing NGINX on port {side_by_side_port}.")
return side_by_side_port
return "80"


@task(
help={
Expand Down Expand Up @@ -50,7 +92,7 @@ def build(c, cache=False):
)
def compose(c, command):
"""Pass the command to docker compose directly."""
c.run(f"{DOCKER_COMPOSE_COMMAND} {command}", pty=True)
c.run(f"RTDDEV_PORT_NGINX={nginx_port(c)} {DOCKER_COMPOSE_COMMAND} {command}", pty=True)


@task(
Expand Down Expand Up @@ -99,6 +141,7 @@ def up(
cmd.append("INIT=t" if init else "INIT=")
cmd.append("DOCKER_NO_RELOAD=t" if not reload else "DOCKER_NO_RELOAD=")
cmd.append(f"RTD_LOGGING_LEVEL={log_level}")
cmd.append(f"RTDDEV_PORT_NGINX={nginx_port(c)}")

cmd.append("docker compose")
cmd.append("--project-directory=.")
Expand Down
Loading