Skip to content

Commit cd99956

Browse files
strickvlclaude
andcommitted
feat: add comprehensive login page customization options
Add CLI arguments and environment variables to customize all login page elements: - Login title, subtitle, and welcome text - Password field placeholder and submit button text - Password instruction messages (config file, env var, hashed) - Error messages (rate limit, missing/incorrect password) New CLI options: --login-title, --login-below, --password-placeholder, --submit-text --login-password-msg, --login-env-password-msg, --login-hashed-password-msg --login-rate-limit-msg, --missing-password-msg, --incorrect-password-msg New environment variables: CS_LOGIN_TITLE, CS_LOGIN_BELOW, CS_PASSWORD_PLACEHOLDER, CS_SUBMIT_TEXT CS_LOGIN_PASSWORD_MSG, CS_LOGIN_ENV_PASSWORD_MSG, CS_LOGIN_HASHED_PASSWORD_MSG CS_LOGIN_RATE_LIMIT_MSG, CS_MISSING_PASSWORD_MSG, CS_INCORRECT_PASSWORD_MSG Features: - Full backwards compatibility with existing --app-name/--welcome-text - HTML escaping for security (prevents XSS) - Config file support (YAML) - Priority: CLI args > env vars > config file > defaults - Internationalization preserved for non-customized messages Perfect for Docker deployments and corporate branding. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 1671bf1 commit cd99956

File tree

8 files changed

+413
-11
lines changed

8 files changed

+413
-11
lines changed

docs/FAQ.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,40 @@ You can change the config file's location using the `--config` flag or
8181

8282
The default location respects `$XDG_CONFIG_HOME`.
8383

84+
### Login page customization
85+
86+
You can customize the login page appearance using CLI flags or environment variables:
87+
88+
**CLI flags:**
89+
```bash
90+
code-server --login-title "My Code Server" \
91+
--login-env-password-msg "Password set via environment" \
92+
--password-placeholder "Enter password" \
93+
--submit-text "LOGIN"
94+
```
95+
96+
**Environment variables:**
97+
```bash
98+
export CS_LOGIN_TITLE="My Code Server"
99+
export CS_LOGIN_ENV_PASSWORD_MSG="Password set via environment"
100+
export CS_PASSWORD_PLACEHOLDER="Enter password"
101+
export CS_SUBMIT_TEXT="LOGIN"
102+
code-server
103+
```
104+
105+
**Config file:**
106+
```yaml
107+
bind-addr: 127.0.0.1:8080
108+
auth: password
109+
password: your-password
110+
login-title: "My Code Server"
111+
login-env-password-msg: "Password set via environment"
112+
password-placeholder: "Enter password"
113+
submit-text: "LOGIN"
114+
```
115+
116+
CLI flags take priority over environment variables, which take priority over config file settings.
117+
84118
## How do I make my keyboard shortcuts work?
85119

86120
Many shortcuts will not work by default, since they'll be "caught" by the browser.

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ code-server.
6161
We also have an in-depth [setup and
6262
configuration](https://coder.com/docs/code-server/latest/guide) guide.
6363

64+
You can also customize the login page appearance - see our [customization guide](./customization.md).
65+
6466
## Questions?
6567

6668
See answers to [frequently asked

docs/customization.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Login Page Customization
2+
3+
code-server allows you to customize the login page appearance and messages through CLI arguments, environment variables, or configuration files.
4+
5+
## Available Customization Options
6+
7+
### Branding and Appearance
8+
- **Login Title**: Customize the main title on the login page
9+
- **Welcome Text**: Set custom welcome message
10+
- **App Name**: Change the application branding throughout the interface
11+
12+
### Login Messages
13+
- **Password Instructions**: Customize the message explaining where to find the password
14+
- **Environment Password Message**: Custom message when password is set via `$PASSWORD`
15+
- **Hashed Password Message**: Custom message when password is set via `$HASHED_PASSWORD`
16+
17+
### Form Elements
18+
- **Password Placeholder**: Custom placeholder text for the password field
19+
- **Submit Button**: Custom text for the login button
20+
21+
### Error Messages
22+
- **Rate Limit Message**: Custom message when login attempts are rate limited
23+
- **Missing Password**: Custom message for empty password submissions
24+
- **Incorrect Password**: Custom message for wrong password attempts
25+
26+
## Configuration Methods
27+
28+
### CLI Arguments
29+
30+
```bash
31+
code-server \
32+
--app-name "My Development Server" \
33+
--welcome-text "Welcome to the development environment" \
34+
--login-title "Secure Access Portal" \
35+
--login-below "Please authenticate to continue" \
36+
--password-placeholder "Enter your access code" \
37+
--submit-text "AUTHENTICATE" \
38+
--login-env-password-msg "Access code provided via environment variable" \
39+
--login-rate-limit-msg "Too many attempts. Please wait before trying again." \
40+
--missing-password-msg "Access code is required" \
41+
--incorrect-password-msg "Invalid access code"
42+
```
43+
44+
### Environment Variables
45+
46+
Perfect for Docker deployments and containerized environments:
47+
48+
```bash
49+
# Basic branding
50+
export CS_APP_NAME="My Development Server"
51+
export CS_WELCOME_TEXT="Welcome to the development environment"
52+
53+
# Login page customization
54+
export CS_LOGIN_TITLE="Secure Access Portal"
55+
export CS_LOGIN_BELOW="Please authenticate to continue"
56+
export CS_PASSWORD_PLACEHOLDER="Enter your access code"
57+
export CS_SUBMIT_TEXT="AUTHENTICATE"
58+
59+
# Message customization
60+
export CS_LOGIN_ENV_PASSWORD_MSG="Access code provided via environment variable"
61+
export CS_LOGIN_RATE_LIMIT_MSG="Too many attempts. Please wait before trying again."
62+
export CS_MISSING_PASSWORD_MSG="Access code is required"
63+
export CS_INCORRECT_PASSWORD_MSG="Invalid access code"
64+
65+
code-server
66+
```
67+
68+
### Configuration File
69+
70+
Add to your `~/.config/code-server/config.yaml`:
71+
72+
```yaml
73+
bind-addr: 127.0.0.1:8080
74+
auth: password
75+
password: your-password
76+
77+
# Branding
78+
app-name: "My Development Server"
79+
welcome-text: "Welcome to the development environment"
80+
81+
# Login page
82+
login-title: "Secure Access Portal"
83+
login-below: "Please authenticate to continue"
84+
password-placeholder: "Enter your access code"
85+
submit-text: "AUTHENTICATE"
86+
87+
# Messages
88+
login-env-password-msg: "Access code provided via environment variable"
89+
login-rate-limit-msg: "Too many attempts. Please wait before trying again."
90+
missing-password-msg: "Access code is required"
91+
incorrect-password-msg: "Invalid access code"
92+
```
93+
94+
## Docker Examples
95+
96+
### Basic Docker Deployment with Customization
97+
98+
```bash
99+
docker run -it --name code-server -p 127.0.0.1:8080:8080 \
100+
-v "$PWD:/home/coder/project" \
101+
-e "CS_LOGIN_TITLE=Development Environment" \
102+
-e "CS_LOGIN_ENV_PASSWORD_MSG=Password configured in container environment" \
103+
-e "CS_PASSWORD_PLACEHOLDER=Enter development password" \
104+
-e "CS_SUBMIT_TEXT=ACCESS ENVIRONMENT" \
105+
codercom/code-server:latest
106+
```
107+
108+
### Corporate Branding Example
109+
110+
```bash
111+
docker run -it --name code-server -p 127.0.0.1:8080:8080 \
112+
-v "$PWD:/home/coder/project" \
113+
-e "CS_APP_NAME=ACME Corporation Dev Portal" \
114+
-e "CS_LOGIN_TITLE=ACME Development Portal" \
115+
-e "CS_LOGIN_BELOW=Enter your corporate credentials" \
116+
-e "CS_PASSWORD_PLACEHOLDER=Corporate Password" \
117+
-e "CS_SUBMIT_TEXT=SIGN IN" \
118+
-e "CS_LOGIN_ENV_PASSWORD_MSG=Password managed by IT department" \
119+
codercom/code-server:latest
120+
```
121+
122+
## Priority Order
123+
124+
Settings are applied in the following priority order (highest to lowest):
125+
126+
1. **CLI arguments** - Highest priority
127+
2. **Environment variables** - Medium priority
128+
3. **Config file** - Lowest priority
129+
130+
This allows you to set defaults in your config file and override them with environment variables or CLI arguments as needed.
131+
132+
## Complete Reference
133+
134+
| CLI Argument | Environment Variable | Description |
135+
|--------------|---------------------|-------------|
136+
| `--app-name` | `CS_APP_NAME` | Application name used throughout the interface |
137+
| `--welcome-text` | `CS_WELCOME_TEXT` | Welcome message on login page |
138+
| `--login-title` | `CS_LOGIN_TITLE` | Main title on login page |
139+
| `--login-below` | `CS_LOGIN_BELOW` | Text below the login title |
140+
| `--password-placeholder` | `CS_PASSWORD_PLACEHOLDER` | Password field placeholder text |
141+
| `--submit-text` | `CS_SUBMIT_TEXT` | Login button text |
142+
| `--login-password-msg` | `CS_LOGIN_PASSWORD_MSG` | Message for config file password |
143+
| `--login-env-password-msg` | `CS_LOGIN_ENV_PASSWORD_MSG` | Message when using `$PASSWORD` env var |
144+
| `--login-hashed-password-msg` | `CS_LOGIN_HASHED_PASSWORD_MSG` | Message when using `$HASHED_PASSWORD` env var |
145+
| `--login-rate-limit-msg` | `CS_LOGIN_RATE_LIMIT_MSG` | Rate limiting error message |
146+
| `--missing-password-msg` | `CS_MISSING_PASSWORD_MSG` | Empty password error message |
147+
| `--incorrect-password-msg` | `CS_INCORRECT_PASSWORD_MSG` | Wrong password error message |

docs/install.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,30 @@ docker run -it --name code-server -p 127.0.0.1:8080:8080 \
287287
codercom/code-server:latest
288288
```
289289

290+
### Customizing the login page
291+
292+
You can customize the login page by setting environment variables:
293+
294+
```bash
295+
# Example with login customization
296+
docker run -it --name code-server -p 127.0.0.1:8080:8080 \
297+
-v "$PWD:/home/coder/project" \
298+
-e "CS_LOGIN_TITLE=My Development Environment" \
299+
-e "CS_LOGIN_ENV_PASSWORD_MSG=Password configured via environment variable" \
300+
-e "CS_PASSWORD_PLACEHOLDER=Enter your secure password" \
301+
-e "CS_SUBMIT_TEXT=ACCESS" \
302+
codercom/code-server:latest
303+
```
304+
305+
Available customization environment variables:
306+
- `CS_LOGIN_TITLE` - Custom login page title
307+
- `CS_LOGIN_BELOW` - Custom text below the login title
308+
- `CS_PASSWORD_PLACEHOLDER` - Custom password field placeholder
309+
- `CS_SUBMIT_TEXT` - Custom submit button text
310+
- `CS_LOGIN_PASSWORD_MSG` - Custom message for config file password
311+
- `CS_LOGIN_ENV_PASSWORD_MSG` - Custom message when using `$PASSWORD` env var
312+
- `CS_LOGIN_HASHED_PASSWORD_MSG` - Custom message when using `$HASHED_PASSWORD` env var
313+
290314
Our official image supports `amd64` and `arm64`. For `arm32` support, you can
291315
use a [community-maintained code-server
292316
alternative](https://hub.docker.com/r/linuxserver/code-server).

src/node/cli.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
9292
verbose?: boolean
9393
"app-name"?: string
9494
"welcome-text"?: string
95+
"login-title"?: string
96+
"login-below"?: string
97+
"password-placeholder"?: string
98+
"submit-text"?: string
99+
"login-password-msg"?: string
100+
"login-env-password-msg"?: string
101+
"login-hashed-password-msg"?: string
102+
"login-rate-limit-msg"?: string
103+
"missing-password-msg"?: string
104+
"incorrect-password-msg"?: string
95105
"abs-proxy-base-path"?: string
96106
/* Positional arguments. */
97107
_?: string[]
@@ -291,6 +301,46 @@ export const options: Options<Required<UserProvidedArgs>> = {
291301
short: "w",
292302
description: "Text to show on login page",
293303
},
304+
"login-title": {
305+
type: "string",
306+
description: "Custom login page title",
307+
},
308+
"login-below": {
309+
type: "string",
310+
description: "Custom text to show below login title",
311+
},
312+
"password-placeholder": {
313+
type: "string",
314+
description: "Custom placeholder text for password field",
315+
},
316+
"submit-text": {
317+
type: "string",
318+
description: "Custom text for login submit button",
319+
},
320+
"login-password-msg": {
321+
type: "string",
322+
description: "Custom message for config file password",
323+
},
324+
"login-env-password-msg": {
325+
type: "string",
326+
description: "Custom message when password is set from $PASSWORD environment variable",
327+
},
328+
"login-hashed-password-msg": {
329+
type: "string",
330+
description: "Custom message when password is set from $HASHED_PASSWORD environment variable",
331+
},
332+
"login-rate-limit-msg": {
333+
type: "string",
334+
description: "Custom message for login rate limiting",
335+
},
336+
"missing-password-msg": {
337+
type: "string",
338+
description: "Custom message for missing password error",
339+
},
340+
"incorrect-password-msg": {
341+
type: "string",
342+
description: "Custom message for incorrect password error",
343+
},
294344
"abs-proxy-base-path": {
295345
type: "string",
296346
description: "The base path to prefix to all absproxy requests",
@@ -593,6 +643,47 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
593643
args["disable-proxy"] = true
594644
}
595645

646+
// Login message customization via environment variables
647+
if (process.env.CS_LOGIN_TITLE) {
648+
args["login-title"] = process.env.CS_LOGIN_TITLE
649+
}
650+
651+
if (process.env.CS_LOGIN_BELOW) {
652+
args["login-below"] = process.env.CS_LOGIN_BELOW
653+
}
654+
655+
if (process.env.CS_PASSWORD_PLACEHOLDER) {
656+
args["password-placeholder"] = process.env.CS_PASSWORD_PLACEHOLDER
657+
}
658+
659+
if (process.env.CS_SUBMIT_TEXT) {
660+
args["submit-text"] = process.env.CS_SUBMIT_TEXT
661+
}
662+
663+
if (process.env.CS_LOGIN_PASSWORD_MSG) {
664+
args["login-password-msg"] = process.env.CS_LOGIN_PASSWORD_MSG
665+
}
666+
667+
if (process.env.CS_LOGIN_ENV_PASSWORD_MSG) {
668+
args["login-env-password-msg"] = process.env.CS_LOGIN_ENV_PASSWORD_MSG
669+
}
670+
671+
if (process.env.CS_LOGIN_HASHED_PASSWORD_MSG) {
672+
args["login-hashed-password-msg"] = process.env.CS_LOGIN_HASHED_PASSWORD_MSG
673+
}
674+
675+
if (process.env.CS_LOGIN_RATE_LIMIT_MSG) {
676+
args["login-rate-limit-msg"] = process.env.CS_LOGIN_RATE_LIMIT_MSG
677+
}
678+
679+
if (process.env.CS_MISSING_PASSWORD_MSG) {
680+
args["missing-password-msg"] = process.env.CS_MISSING_PASSWORD_MSG
681+
}
682+
683+
if (process.env.CS_INCORRECT_PASSWORD_MSG) {
684+
args["incorrect-password-msg"] = process.env.CS_INCORRECT_PASSWORD_MSG
685+
}
686+
596687
const usingEnvHashedPassword = !!process.env.HASHED_PASSWORD
597688
if (process.env.HASHED_PASSWORD) {
598689
args["hashed-password"] = process.env.HASHED_PASSWORD

0 commit comments

Comments
 (0)