Skip to content

Commit 4bc5d7e

Browse files
committed
Move Docker inline scripts to repo files
1 parent 23e17e8 commit 4bc5d7e

13 files changed

Lines changed: 393 additions & 246 deletions

File tree

infra/digitalocean/packer/opencode-marketplace.pkr.hcl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ variable "container_username" {
6161
default = "opencode"
6262
}
6363

64+
variable "opencode_cloud_env" {
65+
type = string
66+
default = "digitalocean_docker_droplet"
67+
}
68+
6469
source "digitalocean" "marketplace" {
6570
api_token = var.do_token
6671
region = var.region
@@ -139,11 +144,12 @@ build {
139144
environment_vars = [
140145
"HOST_CONTAINER_IMAGE=${var.container_image}",
141146
"HOST_CONTAINER_NAME=${var.container_name}",
142-
"CONTAINER_USERNAME=${var.container_username}"
147+
"CONTAINER_USERNAME=${var.container_username}",
148+
"OPENCODE_CLOUD_ENV=${var.opencode_cloud_env}"
143149
]
144150
inline = [
145151
"install -d -m 0700 /etc/opencode-cloud",
146-
"printf '%s\\n' \"HOST_CONTAINER_IMAGE=$HOST_CONTAINER_IMAGE\" \"HOST_CONTAINER_NAME=$HOST_CONTAINER_NAME\" \"CONTAINER_USERNAME=$CONTAINER_USERNAME\" \"PUBLIC_OPENCODE_DOMAIN_URL=\" \"PUBLIC_OPENCODE_ALB_URL=\" > /etc/opencode-cloud/stack.env",
152+
"printf '%s\\n' \"HOST_CONTAINER_IMAGE=$HOST_CONTAINER_IMAGE\" \"HOST_CONTAINER_NAME=$HOST_CONTAINER_NAME\" \"CONTAINER_USERNAME=$CONTAINER_USERNAME\" \"OPENCODE_CLOUD_ENV=$OPENCODE_CLOUD_ENV\" \"PUBLIC_OPENCODE_DOMAIN_URL=\" \"PUBLIC_OPENCODE_ALB_URL=\" > /etc/opencode-cloud/stack.env",
147153
"chmod 0600 /etc/opencode-cloud/stack.env"
148154
]
149155
}

infra/digitalocean/packer/variables.pkr.hcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ application_version = "15.2.0"
99
container_image = "prizz/opencode-cloud-sandbox:15.2.0"
1010
container_name = "opencode-cloud-sandbox"
1111
container_username = "opencode"
12+
opencode_cloud_env = "digitalocean_docker_droplet"

infra/digitalocean/scripts/per-instance-opencode-cloud.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ if [ ! -f "$STACK_ENV" ]; then
1010
HOST_CONTAINER_IMAGE=prizz/opencode-cloud-sandbox:15.2.0
1111
HOST_CONTAINER_NAME=opencode-cloud-sandbox
1212
CONTAINER_USERNAME=opencode
13+
OPENCODE_CLOUD_ENV=digitalocean_docker_droplet
1314
PUBLIC_OPENCODE_DOMAIN_URL=
1415
PUBLIC_OPENCODE_ALB_URL=
1516
EOF_STACK

packages/cli-rust/src/commands/start.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,12 +882,19 @@ pub async fn cmd_start(
882882
.await?;
883883
}
884884

885+
let env_vars = std::env::var("OPENCODE_CLOUD_ENV")
886+
.ok()
887+
.map(|value| value.trim().to_string())
888+
.filter(|value| !value.is_empty())
889+
.map(|value| vec![format!("OPENCODE_CLOUD_ENV={value}")]);
890+
885891
// Start container
886892
let msg = crate::format_host_message(host_name.as_deref(), "Starting container...");
887893
let spinner = CommandSpinner::new_maybe(&msg, quiet);
888894
let container_id = match start_container(
889895
&client,
890896
port,
897+
env_vars,
891898
bind_addr,
892899
config.cockpit_port,
893900
config.cockpit_enabled && COCKPIT_EXPOSED,
@@ -1166,9 +1173,11 @@ fn prompt_image_source_choice(
11661173
}
11671174

11681175
/// Start the container, returning the container ID or error
1176+
#[allow(clippy::too_many_arguments)]
11691177
async fn start_container(
11701178
client: &DockerClient,
11711179
port: u16,
1180+
env_vars: Option<Vec<String>>,
11721181
bind_address: &str,
11731182
cockpit_port: u16,
11741183
cockpit_enabled: bool,
@@ -1178,7 +1187,7 @@ async fn start_container(
11781187
setup_and_start(
11791188
client,
11801189
Some(port),
1181-
None,
1190+
env_vars,
11821191
Some(bind_address),
11831192
Some(cockpit_port),
11841193
Some(cockpit_enabled),

packages/core/src/docker/Dockerfile

Lines changed: 13 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -452,61 +452,12 @@ RUN git config --global init.defaultBranch main \
452452
&& git config --global diff.colorMoved default
453453

454454
# Starship configuration (minimal, fast prompt)
455-
RUN mkdir -p /home/opencode/.config \
456-
&& printf '%s\n' \
457-
'# Minimal starship config for fast prompt' \
458-
'format = """' \
459-
'$directory\' \
460-
'$git_branch\' \
461-
'$git_status\' \
462-
'$character"""' \
463-
'' \
464-
'[directory]' \
465-
'truncation_length = 3' \
466-
'truncate_to_repo = true' \
467-
'' \
468-
'[git_branch]' \
469-
'format = "[$branch]($style) "' \
470-
'style = "bold purple"' \
471-
'' \
472-
'[git_status]' \
473-
'format = '"'"'([$all_status$ahead_behind]($style) )'"'"'' \
474-
'' \
475-
'[character]' \
476-
'success_symbol = "[>](bold green)"' \
477-
'error_symbol = "[>](bold red)"' \
478-
> /home/opencode/.config/starship.toml
455+
COPY --chown=opencode:opencode packages/core/src/docker/files/starship.toml /home/opencode/.config/starship.toml
479456

480457
# Shell aliases
481-
RUN printf '%s\n' \
482-
'' \
483-
'# Modern CLI aliases' \
484-
'alias ls="eza --icons"' \
485-
'alias ll="eza -l --icons"' \
486-
'alias la="eza -la --icons"' \
487-
'alias lt="eza --tree --icons"' \
488-
'alias grep="rg"' \
489-
'alias top="btop"' \
490-
'' \
491-
'# Git aliases' \
492-
'alias g="git"' \
493-
'alias gs="git status"' \
494-
'alias gd="git diff"' \
495-
'alias gc="git commit"' \
496-
'alias gp="git push"' \
497-
'alias gl="git pull"' \
498-
'alias gco="git checkout"' \
499-
'alias gb="git branch"' \
500-
'alias lg="lazygit"' \
501-
'' \
502-
'# Docker aliases (for Docker-in-Docker)' \
503-
'alias d="docker"' \
504-
'alias dc="docker compose"' \
505-
'' \
506-
>> /home/opencode/.bashrc
507-
508-
# Set up pipx path
509-
RUN echo 'export PATH="/home/opencode/.local/bin:$PATH"' >> /home/opencode/.bashrc
458+
COPY --chown=opencode:opencode packages/core/src/docker/files/bashrc.extra /home/opencode/.bashrc.extra
459+
RUN cat /home/opencode/.bashrc.extra >> /home/opencode/.bashrc \
460+
&& rm /home/opencode/.bashrc.extra
510461

511462
# -----------------------------------------------------------------------------
512463
# Stage 2: opencode build
@@ -575,18 +526,8 @@ ENV PATH="/opt/opencode/bin:${PATH}"
575526
# This allows opencode to authenticate users via PAM (same users as Cockpit)
576527
# NOTE: Requires root privileges to write to /etc/pam.d/
577528
USER root
578-
RUN printf '%s\n' \
579-
'# PAM configuration for OpenCode authentication' \
580-
'# Install to /etc/pam.d/opencode' \
581-
'' \
582-
'# Standard UNIX authentication' \
583-
'auth required pam_unix.so' \
584-
'account required pam_unix.so' \
585-
'' \
586-
'# Optional: Enable TOTP 2FA (uncomment when pam_google_authenticator is installed)' \
587-
'# auth required pam_google_authenticator.so' \
588-
> /etc/pam.d/opencode \
589-
&& chmod 644 /etc/pam.d/opencode
529+
COPY packages/core/src/docker/files/pam/opencode /etc/pam.d/opencode
530+
RUN chmod 644 /etc/pam.d/opencode
590531

591532
# Verify PAM config file exists
592533
RUN ls -la /etc/pam.d/opencode && cat /etc/pam.d/opencode
@@ -596,38 +537,7 @@ RUN ls -la /etc/pam.d/opencode && cat /etc/pam.d/opencode
596537
# -----------------------------------------------------------------------------
597538
# Create opencode-broker service for PAM authentication
598539
# NOTE: Requires root privileges to write to /etc/systemd/system/
599-
RUN printf '%s\n' \
600-
'[Unit]' \
601-
'Description=OpenCode Authentication Broker' \
602-
'Documentation=https://github.com/pRizz/opencode' \
603-
'After=network.target' \
604-
'' \
605-
'[Service]' \
606-
'Type=notify' \
607-
'ExecStart=/usr/local/bin/opencode-broker' \
608-
'ExecReload=/bin/kill -HUP $MAINPID' \
609-
'Restart=always' \
610-
'RestartSec=5' \
611-
'' \
612-
'# Security hardening' \
613-
'NoNewPrivileges=false' \
614-
'ProtectSystem=strict' \
615-
'ProtectHome=read-only' \
616-
'PrivateTmp=true' \
617-
'ReadWritePaths=/run/opencode' \
618-
'' \
619-
'# Socket directory' \
620-
'RuntimeDirectory=opencode' \
621-
'RuntimeDirectoryMode=0755' \
622-
'' \
623-
'# Logging' \
624-
'StandardOutput=journal' \
625-
'StandardError=journal' \
626-
'SyslogIdentifier=opencode-broker' \
627-
'' \
628-
'[Install]' \
629-
'WantedBy=multi-user.target' \
630-
> /etc/systemd/system/opencode-broker.service
540+
COPY packages/core/src/docker/files/opencode-broker.service /etc/systemd/system/opencode-broker.service
631541

632542
# Enable opencode-broker service
633543
RUN mkdir -p /etc/systemd/system/multi-user.target.wants \
@@ -638,23 +548,7 @@ RUN mkdir -p /etc/systemd/system/multi-user.target.wants \
638548
# -----------------------------------------------------------------------------
639549
# Create opencode as a systemd service for Cockpit integration
640550
# NOTE: Requires root privileges to write to /etc/systemd/system/
641-
RUN printf '%s\n' \
642-
'[Unit]' \
643-
'Description=opencode Web Interface' \
644-
'After=network.target opencode-broker.service' \
645-
'' \
646-
'[Service]' \
647-
'Type=simple' \
648-
'User=opencode' \
649-
'WorkingDirectory=/home/opencode/workspace' \
650-
'ExecStart=/bin/bash -lc "OPENCODE_PORT=$${OPENCODE_PORT:-$${PORT:-3000}}; OPENCODE_HOST=$${OPENCODE_HOST:-0.0.0.0}; exec /opt/opencode/bin/opencode web --port $${OPENCODE_PORT} --hostname $${OPENCODE_HOST}"' \
651-
'Restart=always' \
652-
'RestartSec=5' \
653-
'Environment=PATH=/opt/opencode/bin:/home/opencode/.local/bin:/home/opencode/.cargo/bin:/home/opencode/.local/share/mise/shims:/home/opencode/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' \
654-
'' \
655-
'[Install]' \
656-
'WantedBy=multi-user.target' \
657-
> /etc/systemd/system/opencode.service
551+
COPY packages/core/src/docker/files/opencode.service /etc/systemd/system/opencode.service
658552

659553
# Enable opencode service to start at boot (manual symlink since systemctl doesn't work during build)
660554
RUN mkdir -p /etc/systemd/system/multi-user.target.wants \
@@ -664,15 +558,9 @@ RUN mkdir -p /etc/systemd/system/multi-user.target.wants \
664558
# opencode Configuration
665559
# -----------------------------------------------------------------------------
666560
# Create opencode.jsonc config file with PAM authentication enabled
667-
RUN mkdir -p /home/opencode/.config/opencode \
668-
&& printf '%s\n' \
669-
'{' \
670-
' "auth": {' \
671-
' "enabled": true' \
672-
' }' \
673-
'}' \
674-
> /home/opencode/.config/opencode/opencode.jsonc \
675-
&& chown -R opencode:opencode /home/opencode/.config/opencode \
561+
RUN mkdir -p /home/opencode/.config/opencode
562+
COPY --chown=opencode:opencode packages/core/src/docker/files/opencode.jsonc /home/opencode/.config/opencode/opencode.jsonc
563+
RUN chown -R opencode:opencode /home/opencode/.config/opencode \
676564
&& chmod 644 /home/opencode/.config/opencode/opencode.jsonc
677565

678566
# Verify config file exists
@@ -684,119 +572,8 @@ RUN ls -la /home/opencode/.config/opencode/opencode.jsonc && cat /home/opencode/
684572
# Supports both tini (default, works everywhere) and systemd (for Cockpit on Linux)
685573
# Set USE_SYSTEMD=1 environment variable to use systemd init
686574
# Note: Entrypoint runs as root to support both modes; tini mode drops to opencode user
687-
RUN printf '%s\n' \
688-
'#!/bin/bash' \
689-
'set -euo pipefail' \
690-
'' \
691-
'log() {' \
692-
' echo "[opencode-cloud] $*"' \
693-
'}' \
694-
'' \
695-
'OPENCODE_PORT="${OPENCODE_PORT:-${PORT:-3000}}"' \
696-
'OPENCODE_HOST="${OPENCODE_HOST:-0.0.0.0}"' \
697-
'export OPENCODE_PORT OPENCODE_HOST' \
698-
'' \
699-
'if [ "${USE_SYSTEMD:-}" = "1" ]; then' \
700-
' exec /sbin/init' \
701-
'else' \
702-
' # Ensure broker socket directory exists' \
703-
' install -d -m 0755 /run/opencode' \
704-
'' \
705-
' # Ensure user records directory exists (ephemeral unless mounted)' \
706-
' install -d -m 0700 /var/lib/opencode-users' \
707-
'' \
708-
' restore_users() {' \
709-
' shopt -s nullglob' \
710-
' local records=(/var/lib/opencode-users/*.json)' \
711-
' if [ ${#records[@]} -eq 0 ]; then' \
712-
' return 1' \
713-
' fi' \
714-
' for record in "${records[@]}"; do' \
715-
' local username password_hash locked' \
716-
' username="$(jq -r ".username // empty" "${record}")"' \
717-
' password_hash="$(jq -r ".password_hash // empty" "${record}")"' \
718-
' locked="$(jq -r ".locked // false" "${record}")"' \
719-
' if [ -z "${username}" ]; then' \
720-
' log "Skipping invalid user record: ${record}"' \
721-
' continue' \
722-
' fi' \
723-
' if ! id -u "${username}" >/dev/null 2>&1; then' \
724-
' log "Creating user: ${username}"' \
725-
' useradd -m -s /bin/bash "${username}"' \
726-
' fi' \
727-
' if [ -n "${password_hash}" ]; then' \
728-
' usermod -p "${password_hash}" "${username}"' \
729-
' fi' \
730-
' if [ "${locked}" = "true" ]; then' \
731-
' passwd -l "${username}" >/dev/null' \
732-
' else' \
733-
' passwd -u "${username}" >/dev/null || true' \
734-
' fi' \
735-
' log "Restored user: ${username}"' \
736-
' done' \
737-
' return 0' \
738-
' }' \
739-
'' \
740-
' persist_user_record() {' \
741-
' local username="$1"' \
742-
' local shadow_hash' \
743-
' shadow_hash="$(getent shadow "${username}" | cut -d: -f2)"' \
744-
' if [ -z "${shadow_hash}" ]; then' \
745-
' log "Failed to read shadow hash for ${username}"' \
746-
' return 1' \
747-
' fi' \
748-
' local status locked' \
749-
' status="$(passwd -S "${username}" | tr -s " " | cut -d" " -f2)"' \
750-
' locked="false"' \
751-
' if [ "${status}" = "L" ]; then' \
752-
' locked="true"' \
753-
' fi' \
754-
' local record_path="/var/lib/opencode-users/${username}.json"' \
755-
' umask 077' \
756-
' jq -n --arg username "${username}" --arg hash "${shadow_hash}" --argjson locked "${locked}" '"'"'{username:$username,password_hash:$hash,locked:$locked}'"'"' > "${record_path}"' \
757-
' chmod 600 "${record_path}"' \
758-
' log "Persisted user record: ${username}"' \
759-
' }' \
760-
'' \
761-
' bootstrap_user() {' \
762-
' local username="${OPENCODE_BOOTSTRAP_USER:-}"' \
763-
' local password="${OPENCODE_BOOTSTRAP_PASSWORD:-}"' \
764-
' local password_hash="${OPENCODE_BOOTSTRAP_PASSWORD_HASH:-}"' \
765-
' if [ -z "${username}" ]; then' \
766-
' return 1' \
767-
' fi' \
768-
' if [ -z "${password_hash}" ] && [ -z "${password}" ]; then' \
769-
' log "OPENCODE_BOOTSTRAP_USER is set but no password or hash provided"' \
770-
' exit 1' \
771-
' fi' \
772-
' if ! id -u "${username}" >/dev/null 2>&1; then' \
773-
' log "Creating bootstrap user: ${username}"' \
774-
' useradd -m -s /bin/bash "${username}"' \
775-
' fi' \
776-
' if [ -n "${password_hash}" ]; then' \
777-
' usermod -p "${password_hash}" "${username}"' \
778-
' else' \
779-
' echo "${username}:${password}" | chpasswd' \
780-
' fi' \
781-
' persist_user_record "${username}"' \
782-
' log "Bootstrap user ready: ${username}"' \
783-
' return 0' \
784-
' }' \
785-
'' \
786-
' if restore_users; then' \
787-
' log "User records restored"' \
788-
' else' \
789-
' if ! bootstrap_user; then' \
790-
' log "No persisted users and no bootstrap user configured"' \
791-
' fi' \
792-
' fi' \
793-
'' \
794-
' log "Starting opencode on ${OPENCODE_HOST}:${OPENCODE_PORT}"' \
795-
' /usr/local/bin/opencode-broker &' \
796-
' # Use runuser to switch to opencode user without password prompt' \
797-
' exec runuser -u opencode -- sh -lc "cd /home/opencode/workspace && /opt/opencode/bin/opencode web --port ${OPENCODE_PORT} --hostname ${OPENCODE_HOST}"' \
798-
'fi' \
799-
> /usr/local/bin/entrypoint.sh && chmod +x /usr/local/bin/entrypoint.sh
575+
COPY packages/core/src/docker/files/entrypoint.sh /usr/local/bin/entrypoint.sh
576+
RUN chmod +x /usr/local/bin/entrypoint.sh
800577

801578
# Note: Don't set USER here - entrypoint needs root to use runuser
802579
# The tini mode drops privileges to opencode user via runuser
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
# Modern CLI aliases
3+
alias ls="eza --icons"
4+
alias ll="eza -l --icons"
5+
alias la="eza -la --icons"
6+
alias lt="eza --tree --icons"
7+
alias grep="rg"
8+
alias top="btop"
9+
10+
# Git aliases
11+
alias g="git"
12+
alias gs="git status"
13+
alias gd="git diff"
14+
alias gc="git commit"
15+
alias gp="git push"
16+
alias gl="git pull"
17+
alias gco="git checkout"
18+
alias gb="git branch"
19+
alias lg="lazygit"
20+
21+
# Docker aliases (for Docker-in-Docker)
22+
alias d="docker"
23+
alias dc="docker compose"
24+
25+
export PATH="/home/opencode/.local/bin:$PATH"

0 commit comments

Comments
 (0)