Skip to content

Commit 620d3aa

Browse files
github-actionsclaude
andcommitted
Move build-time setup from startup script to Dockerfile
Packages, user creation, SAS config, and Apache proxy setup now run at image build time instead of every container start, making restarts faster. The startup script retains only runtime steps that depend on the /data volume. Also removes initializeCommand from devcontainer configs and adds tmpfs for /data/workspace. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0aa8a82 commit 620d3aa

5 files changed

Lines changed: 71 additions & 113 deletions

File tree

src/aou-sas/.devcontainer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"runServices": ["app", "wondershaper"],
66
"shutdownAction": "none",
77
"workspaceFolder": "/workspace",
8-
"initializeCommand": "umount -f /tmp/wb-mount/*; rm -rf /tmp/wb-mount/*",
98
"postCreateCommand": [
109
"./startupscript/post-startup.sh",
1110
"aou",

src/aou-sas/Dockerfile

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,72 @@ USER root
66
# This must be in the Dockerfile because it references a build context (load-envs).
77
COPY --from=load-envs /dist/load-env /dist/load-env.sh /opt/sas/aou/
88

9+
###############################################################################
10+
# Package-manager compatibility
11+
# Workbench startup scripts (post-startup.sh, resource-mount.sh) expect
12+
# apt-get / apt. These shims delegate to yum on this RHEL-based SAS image.
13+
###############################################################################
14+
RUN printf '#!/bin/bash\ncase "$1" in\n update) exec yum makecache -y ;;\n install) shift; exec yum install -y "$@" ;;\n *) exec yum "$@" ;;\nesac\n' > /usr/local/bin/apt-get && \
15+
chmod +x /usr/local/bin/apt-get && \
16+
cp /usr/local/bin/apt-get /usr/local/bin/apt && \
17+
chmod +x /usr/local/bin/apt
18+
19+
###############################################################################
20+
# System packages required by Workbench startup scripts
21+
###############################################################################
22+
RUN yum install -y jq curl fuse fuse-libs tar wget sudo git && \
23+
yum clean all
24+
25+
###############################################################################
26+
# gcsfuse — GCS bucket mounting
27+
###############################################################################
28+
RUN printf '[gcsfuse]\nname=gcsfuse (packages.cloud.google.com)\nbaseurl=https://packages.cloud.google.com/yum/repos/gcsfuse-el7-x86_64\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=0\ngpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg\n https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg\n' > /etc/yum.repos.d/gcsfuse.repo && \
29+
yum install -y gcsfuse && \
30+
yum clean all
31+
32+
###############################################################################
33+
# Google Cloud SDK
34+
###############################################################################
35+
RUN curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-565.0.0-linux-x86_64.tar.gz && \
36+
tar -xf google-cloud-cli-565.0.0-linux-x86_64.tar.gz && \
37+
./google-cloud-sdk/install.sh -q && \
38+
ln -sf /google-cloud-sdk/bin/* /bin/ && \
39+
rm -f google-cloud-cli-565.0.0-linux-x86_64.tar.gz
40+
41+
###############################################################################
42+
# AoU user (non-root, no sudo)
43+
###############################################################################
44+
RUN groupadd -g 1001 aougroup && \
45+
useradd -u 1001 -g aougroup -m -d /data -s /bin/bash aou && \
46+
echo "aou:aou" | chpasswd && \
47+
rm -f /etc/sudoers.d/aou
48+
49+
###############################################################################
50+
# SAS configuration
51+
###############################################################################
52+
RUN echo "-work /data/saswork" >> /opt/sas/viya/config/etc/workspaceserver/default/sasv9_usermods.cfg && \
53+
echo "-utilloc /data/utilloc" >> /opt/sas/viya/config/etc/workspaceserver/default/sasv9_usermods.cfg && \
54+
sed -Ei 's#^USERMODS=(.*)#USERMODS=-allowxcmd \1#g' \
55+
/opt/sas/viya/config/etc/spawner/default/spawner_usermods.sh
56+
57+
###############################################################################
58+
# Apache proxy — auto-login, header cleanup, and HTTPS scheme fix
59+
#
60+
# ServerName https://localhost: Apache only receives HTTP (the Workbench proxy
61+
# terminates TLS upstream), but it must still generate https:// Location
62+
# headers in redirects (RedirectMatch, Redirect, etc.). Without this setting,
63+
# browsers receive http:// redirect URLs that fail behind the HTTPS proxy.
64+
###############################################################################
65+
RUN PROXY_CONF=/etc/httpd/conf.d/dkrapro-proxy.conf && \
66+
sed -i "s/RequestHeader/#RequestHeader/g" "${PROXY_CONF}" && \
67+
sed -i 's|^ServerName localhost$|ServerName https://localhost|' "${PROXY_CONF}" && \
68+
sed -i '/ProxyPreserveHost On/a # AOU-CONFIGURED' "${PROXY_CONF}" && \
69+
sed -i '/AOU-CONFIGURED/a RequestHeader set X-SAS-Authorization "Basic YW91OmFvdQ=="' "${PROXY_CONF}" && \
70+
sed -i '/AOU-CONFIGURED/a RequestHeader set X-Forwarded-Proto "https"' "${PROXY_CONF}" && \
71+
sed -i '/AOU-CONFIGURED/a Header unset X-Frame-Options' "${PROXY_CONF}" && \
72+
sed -i '/AOU-CONFIGURED/a Header unset Content-Security-Policy' "${PROXY_CONF}" && \
73+
sed -i '/AOU-CONFIGURED/a Header edit Set-Cookie "^(.*SameSite=None.*)\$" "\$1; Secure"' "${PROXY_CONF}"
74+
975
# Wrapper entrypoint: copies the SAS license from Mikey Secrets (if active)
1076
# to /sasinside/ before handing off to the SAS entrypoint.
1177
COPY sas-entrypoint.sh /opt/sas/aou/sas-entrypoint.sh

src/aou-sas/docker-compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ services:
2121
# With Mikey Secrets, the entrypoint wrapper populates /sasinside/ from
2222
# the SAS_LICENSE_PATH file descriptor instead.
2323
- ./sasinside:/sasinside
24+
tmpfs:
25+
- /data/workspace:uid=1001,gid=1001
2426
environment:
2527
HOST_AUTH: ""
2628
SAS_DEBUG: "0"

src/aou-sas/sas-startup.sh

Lines changed: 3 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,16 @@
11
#!/bin/bash
2-
# sas-startup.sh — Pre-deployment setup for SAS Analytics Pro on VWB GCE.
2+
# sas-startup.sh — Runtime setup for SAS Analytics Pro on VWB GCE.
33
#
44
# Mounted at /opt/sas/aou/sas-startup.sh and invoked via PRE_DEPLOY_SCRIPT
5-
# before SAS services start. The entrypoint writes PRE_DEPLOY_SCRIPT to
6-
# /tmp/pre_deploy.sh and runs it, so we must NOT mount at that path.
5+
# before SAS services start. Only handles steps that depend on the /data
6+
# volume or runtime state; build-time setup is in the Dockerfile.
77
#
88
# All steps are idempotent so container restarts are fast.
99

1010
set -o errexit
1111
set -o nounset
1212
set -o pipefail
1313

14-
###############################################################################
15-
# Package-manager compatibility
16-
# Workbench startup scripts (post-startup.sh, resource-mount.sh) expect
17-
# apt-get / apt. These shims delegate to yum on this RHEL-based SAS image.
18-
###############################################################################
19-
if [ ! -f /usr/local/bin/apt-get ]; then
20-
cat > /usr/local/bin/apt-get << 'SHIM'
21-
#!/bin/bash
22-
case "$1" in
23-
update) exec yum makecache -y ;;
24-
install) shift; exec yum install -y "$@" ;;
25-
*) exec yum "$@" ;;
26-
esac
27-
SHIM
28-
chmod +x /usr/local/bin/apt-get
29-
cp /usr/local/bin/apt-get /usr/local/bin/apt
30-
chmod +x /usr/local/bin/apt
31-
fi
32-
33-
###############################################################################
34-
# System packages required by Workbench startup scripts
35-
###############################################################################
36-
yum install -y jq curl fuse fuse-libs tar wget sudo git 2>/dev/null || true
37-
38-
###############################################################################
39-
# gcsfuse — GCS bucket mounting
40-
###############################################################################
41-
if ! command -v gcsfuse &>/dev/null; then
42-
cat > /etc/yum.repos.d/gcsfuse.repo << 'EOF'
43-
[gcsfuse]
44-
name=gcsfuse (packages.cloud.google.com)
45-
baseurl=https://packages.cloud.google.com/yum/repos/gcsfuse-el7-x86_64
46-
enabled=1
47-
gpgcheck=1
48-
repo_gpgcheck=0
49-
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
50-
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
51-
EOF
52-
yum install -y gcsfuse || true
53-
fi
54-
55-
###############################################################################
56-
# Google Cloud SDK
57-
###############################################################################
58-
if ! command -v gcloud &>/dev/null; then
59-
curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-565.0.0-linux-x86_64.tar.gz \
60-
&& tar -xf google-cloud-cli-565.0.0-linux-x86_64.tar.gz \
61-
&& ./google-cloud-sdk/install.sh -q \
62-
&& ln -sf /google-cloud-sdk/bin/* /bin/ \
63-
&& rm -f google-cloud-cli-565.0.0-linux-x86_64.tar.gz \
64-
|| true
65-
fi
66-
67-
###############################################################################
68-
# AoU user (non-root, no sudo)
69-
###############################################################################
70-
AOU_GID=${AOU_GID:-1001}
71-
groupadd -f -g "${AOU_GID}" aougroup
72-
id aou &>/dev/null || useradd -g aougroup -m -d /data -s /bin/bash aou
73-
echo "aou:aou" | chpasswd
74-
rm -f /etc/sudoers.d/aou
75-
7614
###############################################################################
7715
# Data directories (on the sas-data volume)
7816
###############################################################################
@@ -98,49 +36,3 @@ if [ -d /opt/sas/aou ]; then
9836
grep -q "load-env.sh" /data/.bashrc 2>/dev/null || \
9937
echo "source /data/load-env.sh" >> /data/.bashrc
10038
fi
101-
102-
###############################################################################
103-
# SAS configuration
104-
###############################################################################
105-
USERMODS_CFG=/opt/sas/viya/config/etc/workspaceserver/default/sasv9_usermods.cfg
106-
grep -q "saswork" "${USERMODS_CFG}" 2>/dev/null || \
107-
echo "-work /data/saswork" >> "${USERMODS_CFG}"
108-
grep -q "utilloc" "${USERMODS_CFG}" 2>/dev/null || \
109-
echo "-utilloc /data/utilloc" >> "${USERMODS_CFG}"
110-
111-
sed -Ei 's#^USERMODS=(.*)#USERMODS=-allowxcmd \1#g' \
112-
/opt/sas/viya/config/etc/spawner/default/spawner_usermods.sh
113-
114-
###############################################################################
115-
# Apache proxy — auto-login and header cleanup
116-
###############################################################################
117-
PROXY_CONF=/etc/httpd/conf.d/dkrapro-proxy.conf
118-
119-
# Comment out default RequestHeader lines from the SAS image, then re-add
120-
# exactly the ones we need. Use a marker so restarts are idempotent.
121-
if ! grep -q "AOU-CONFIGURED" "${PROXY_CONF}"; then
122-
sed -i "s/RequestHeader/#RequestHeader/g" "${PROXY_CONF}"
123-
124-
# Force Apache to generate https:// URLs in redirects (RedirectMatch etc.)
125-
# since the Workbench proxy terminates TLS upstream.
126-
sed -i 's|^ServerName localhost$|ServerName https://localhost|' "${PROXY_CONF}"
127-
128-
sed -i '/ProxyPreserveHost On/a # AOU-CONFIGURED' "${PROXY_CONF}"
129-
130-
# Auto-login (base64 of "aou:aou" = YW91OmFvdQ==)
131-
sed -i '/AOU-CONFIGURED/a RequestHeader set X-SAS-Authorization "Basic YW91OmFvdQ=="' \
132-
"${PROXY_CONF}"
133-
sed -i '/AOU-CONFIGURED/a RequestHeader set X-Forwarded-Proto "https"' \
134-
"${PROXY_CONF}"
135-
136-
# Strip framing restrictions so SAS Studio can be iframed by the Workbench UI.
137-
sed -i '/AOU-CONFIGURED/a Header unset X-Frame-Options' \
138-
"${PROXY_CONF}"
139-
sed -i '/AOU-CONFIGURED/a Header unset Content-Security-Policy' \
140-
"${PROXY_CONF}"
141-
142-
# SameSite=None cookies require the Secure flag. The app sees HTTP
143-
# (proxy terminates TLS) so SAS omits it — add it via Apache.
144-
sed -i '/AOU-CONFIGURED/a Header edit Set-Cookie "^(.*SameSite=None.*)$" "$1; Secure"' \
145-
"${PROXY_CONF}"
146-
fi

src/jupyter-aou/.devcontainer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"runServices": ["app", "wondershaper"],
66
"shutdownAction": "none",
77
"workspaceFolder": "/workspace",
8-
"initializeCommand": "umount -f /tmp/wb-mount/*; rm -rf /tmp/wb-mount/*",
98
"postCreateCommand": "./startupscript/post-startup.sh jupyter /home/jupyter \"${templateOption:cloud}\" \"${templateOption:login}\"",
109
// re-mount bucket files on container start up
1110
"postStartCommand": "./startupscript/remount-on-restart.sh jupyter /home/jupyter \"${templateOption:cloud}\" \"${templateOption:login}\"",

0 commit comments

Comments
 (0)