mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-13 11:10:02 -04:00
Merge pull request #1185 from aliasvault/1181-optimize-all-in-one-docker-container-config-and-add-documentation
Optimize all in one docker container config and add documentation
This commit is contained in:
@@ -26,6 +26,9 @@ HTTPS_PORT=443
|
||||
SMTP_PORT=25
|
||||
SMTP_TLS_PORT=587
|
||||
|
||||
# Whether to force redirect all HTTP traffic (80) to HTTPS (443). Defaults to true.
|
||||
FORCE_HTTPS_REDIRECT=true
|
||||
|
||||
# ===========================================
|
||||
# EMAIL SERVER CONFIGURATION
|
||||
# ===========================================
|
||||
|
||||
4
.github/workflows/docker-build.yml
vendored
4
.github/workflows/docker-build.yml
vendored
@@ -109,8 +109,8 @@ jobs:
|
||||
echo "🔧 Testing admin password reset flow..."
|
||||
|
||||
# Run the reset password script with auto-confirm
|
||||
echo "Running reset-admin-password.sh script..."
|
||||
password_output=$(docker exec aliasvault-test reset-admin-password.sh -y 2>&1)
|
||||
echo "Running reset-admin-password command..."
|
||||
password_output=$(docker exec aliasvault-test aliasvault reset-admin-password -y 2>&1)
|
||||
echo "Script output:"
|
||||
echo "$password_output"
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -404,6 +404,7 @@ certificates/**/*.crt
|
||||
certificates/**/*.key
|
||||
certificates/**/*.pfx
|
||||
certificates/**/*.pem
|
||||
certificates/**/.hostname_marker
|
||||
certificates/letsencrypt/**
|
||||
|
||||
# Secrets
|
||||
|
||||
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@@ -199,7 +199,7 @@
|
||||
{
|
||||
"label": "Build and watch Docs",
|
||||
"type": "shell",
|
||||
"command": "docker compose up",
|
||||
"command": "docker compose build && docker compose up",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
|
||||
26
README.md
26
README.md
@@ -65,33 +65,31 @@ AliasVault is available on:
|
||||
[<img width="700" alt="Screenshot of AliasVault" src="docs/assets/img/screenshot.png">](https://app.aliasvault.net)
|
||||
|
||||
## Self-hosting
|
||||
For full control over your own data you can self-host and install AliasVault on your own servers.
|
||||
> [!NOTE]
|
||||
> **Requirements:** 1 vCPU, 1GB RAM, 16GB disk, Docker ≥ 20.10, 64-bit Linux
|
||||
|
||||
### Install using install script
|
||||
AliasVault can be self-hosted on your own servers using two different installation methods. Both use Docker, but they differ in how much is automated versus how much you manage yourself.
|
||||
|
||||
This method uses pre-built Docker images and works on minimal hardware specifications:
|
||||
- **Option 1: Install Script** - Managed solution with automatic SSL (recommended for VPS/cloud)
|
||||
|
||||
- 64-bit Linux VM (Ubuntu/AlmaLinux) or Raspberry Pi, with root access
|
||||
- Minimum: 1 vCPU, 1GB RAM, 16GB disk
|
||||
- Docker ≥ 20.10 and Docker Compose ≥ 2.0
|
||||
- **Option 2: Docker Compose** - Single container with manual setup for use with existing SSL infrastructure (NAS, homelab)
|
||||
|
||||
### Quick Start (Install Script)
|
||||
```bash
|
||||
# Download install script from latest stable release
|
||||
# Download and run install script
|
||||
curl -L -o install.sh https://github.com/aliasvault/aliasvault/releases/latest/download/install.sh
|
||||
|
||||
# Make install script executable and run it. This will create the .env file, pull the Docker images, and start the AliasVault containers.
|
||||
chmod +x install.sh
|
||||
|
||||
./install.sh install
|
||||
```
|
||||
|
||||
The install script will output the URL where the app is available. By default this is:
|
||||
- Client: https://localhost
|
||||
- Admin portal: https://localhost/admin
|
||||
For other installation methods and more detailed steps, please read the [full installation guide](https://docs.aliasvault.net/installation) in the official docs.
|
||||
|
||||
> Note: If you want to change the default AliasVault ports you can do so in the `.env` file.
|
||||
|
||||
## Technical documentation
|
||||
## Documentation
|
||||
For more information about the installation process, manual setup instructions and other topics, please see the official documentation website:
|
||||
|
||||
- [Documentation website (docs.aliasvault.net) 📚](https://docs.aliasvault.net)
|
||||
|
||||
## Security Architecture
|
||||
@@ -135,7 +133,7 @@ Core features that are being worked on:
|
||||
👉 [View the full AliasVault roadmap here](https://github.com/aliasvault/aliasvault/issues/731)
|
||||
|
||||
### Got feedback or ideas?
|
||||
Feel free to open an issue or join our [Discord](https://discord.gg/DsaXMTEtpF)! Contributions are warmly welcomed—whether in feature development, testing, or spreading the word. Get in touch on Discord if you're interested in contributing.
|
||||
Feel free to open an issue or discussion on GitHub. We warmly welcome all contributions: whether it’s translating, testing, helping to build features, sharing feedback - or helping spread the word about AliasVault. Every bit of support helps the project grow, so don’t hesitate to jump in and [say hi to us on Discord](https://discord.gg/DsaXMTEtpF)!
|
||||
|
||||
### Support the mission
|
||||
AliasVault is open-source and community-driven. If you like what we’re building, consider supporting us through [Open Collective](https://opencollective.com/aliasvault) or through:
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<SonarLint>
|
||||
<Rules>
|
||||
<Rule>
|
||||
<Key>S1135</Key>
|
||||
<Parameters>
|
||||
<Parameter>
|
||||
<Name>sonarlint.rule.enabled</Name>
|
||||
<Value>false</Value>
|
||||
</Parameter>
|
||||
</Parameters>
|
||||
</Rule>
|
||||
</Rules>
|
||||
</SonarLint>
|
||||
@@ -1,4 +1,5 @@
|
||||
@page "/user/login"
|
||||
@using AliasVault.RazorComponents.Alerts
|
||||
@using AliasVault.Shared.Models.Enums
|
||||
|
||||
<LayoutPageTitle>Log in</LayoutPageTitle>
|
||||
@@ -11,29 +12,29 @@
|
||||
|
||||
@if (!IsAdminConfigured)
|
||||
{
|
||||
<div class="mt-8 p-6 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
|
||||
<div class="flex items-start">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
|
||||
Admin User Not Configured
|
||||
</h3>
|
||||
<div class="mt-2 text-sm text-yellow-700 dark:text-yellow-300">
|
||||
<p class="mb-3">The admin user has not been configured yet. To set up admin access:</p>
|
||||
<ol class="list-decimal list-inside space-y-1 mb-3">
|
||||
<li>Connect to your Docker container: <code class="bg-yellow-100 dark:bg-yellow-800 px-1 py-0.5 rounded text-xs">docker exec -it [container-name] /bin/bash</code></li>
|
||||
<li>Run the password reset script: <code class="bg-yellow-100 dark:bg-yellow-800 px-1 py-0.5 rounded text-xs">reset-admin-password.sh</code></li>
|
||||
<li>Restart the container to apply changes: <code class="bg-yellow-100 dark:bg-yellow-800 px-1 py-0.5 rounded text-xs">docker restart [container-name]</code></li>
|
||||
</ol>
|
||||
<p class="text-xs">Replace <code class="bg-yellow-100 dark:bg-yellow-800 px-1 py-0.5 rounded">[container-name]</code> with your actual container name, e.g. "aliasvault".</p>
|
||||
<MessageInfo Title="Admin User Not Configured">
|
||||
The admin user has not been configured yet. To set up admin access:
|
||||
<ol class="list-decimal list-inside space-y-1 mb-3">
|
||||
<li>
|
||||
Connect to your Docker container:
|
||||
<div>
|
||||
<code class="bg-gray-700 text-white px-1 py-0.5 rounded text-xs">$ docker compose exec -it aliasvault /bin/bash</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
Run the password reset script:
|
||||
<div>
|
||||
<code class="bg-gray-700 text-white px-1 py-0.5 rounded text-xs">$ aliasvault reset-admin-password</code>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
Exit out of the container, then restart the container to apply changes:
|
||||
<div>
|
||||
<code class="bg-gray-700 text-white px-1 py-0.5 rounded text-xs">$ docker compose restart</code>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</MessageInfo>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ public static class StartupTasks
|
||||
if (string.IsNullOrEmpty(config.AdminPasswordHash))
|
||||
{
|
||||
Console.WriteLine("Admin password hash not configured - skipping admin user creation.");
|
||||
Console.WriteLine("Run 'reset-admin-password.sh' to configure the admin password.");
|
||||
Console.WriteLine("Run '$ aliasvault reset-admin-password' to configure the admin password.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1270,11 +1270,6 @@ video {
|
||||
border-color: rgb(239 68 68 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-yellow-200 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(254 240 138 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-yellow-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(234 179 8 / var(--tw-border-opacity));
|
||||
@@ -1370,6 +1365,11 @@ video {
|
||||
background-color: rgb(21 128 61 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-orange-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 237 213 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-orange-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(251 146 60 / var(--tw-bg-opacity));
|
||||
@@ -1454,6 +1454,10 @@ video {
|
||||
--tw-bg-opacity: 0.5;
|
||||
}
|
||||
|
||||
.fill-current {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.fill-primary-600 {
|
||||
fill: #d68338;
|
||||
}
|
||||
@@ -1774,11 +1778,21 @@ video {
|
||||
color: rgb(22 101 52 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-orange-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(249 115 22 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-orange-600 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(234 88 12 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-orange-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(194 65 12 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-primary-600 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(214 131 56 / var(--tw-text-opacity));
|
||||
@@ -1814,11 +1828,6 @@ video {
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-yellow-600 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(202 138 4 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-yellow-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(161 98 7 / var(--tw-text-opacity));
|
||||
@@ -2150,11 +2159,6 @@ video {
|
||||
border-color: rgb(234 179 8 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:border-yellow-800:is(.dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(133 77 14 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:bg-blue-800:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(30 64 175 / var(--tw-bg-opacity));
|
||||
@@ -2251,10 +2255,6 @@ video {
|
||||
background-color: rgb(113 63 18 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:bg-yellow-900\/20:is(.dark *) {
|
||||
background-color: rgb(113 63 18 / 0.2);
|
||||
}
|
||||
|
||||
.dark\:bg-opacity-80:is(.dark *) {
|
||||
--tw-bg-opacity: 0.8;
|
||||
}
|
||||
@@ -2359,16 +2359,6 @@ video {
|
||||
color: rgb(254 240 138 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-yellow-300:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(253 224 71 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-yellow-400:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(250 204 21 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:placeholder-gray-400:is(.dark *)::-moz-placeholder {
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
<p class="text-lg text-gray-600 dark:text-gray-300 mb-8">
|
||||
@Localizer["TaglineText"]
|
||||
</p>
|
||||
@if (_isHttpWarning)
|
||||
{
|
||||
<MessageInfo Title="@Localizer["HttpsWarningTitle"]">
|
||||
@Localizer["HttpsWarningMessage"]
|
||||
</MessageInfo>
|
||||
}
|
||||
<div class="space-y-4">
|
||||
@if (Config.PublicRegistrationEnabled)
|
||||
{
|
||||
@@ -50,6 +56,7 @@
|
||||
|
||||
@code {
|
||||
private IStringLocalizer Localizer => LocalizerFactory.Create("Pages.Auth.Start", "AliasVault.Client");
|
||||
private bool _isHttpWarning = false;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task OnInitializedAsync()
|
||||
@@ -62,5 +69,20 @@
|
||||
// Already authenticated, redirect to home page.
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
|
||||
CheckHttpProtocol();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current URL is using HTTP and shows warning if needed.
|
||||
/// Only shows warning for non-localhost hostnames since browsers allow crypto operations on localhost via HTTP.
|
||||
/// </summary>
|
||||
private void CheckHttpProtocol()
|
||||
{
|
||||
var uri = new Uri(NavigationManager.Uri);
|
||||
var isLocalhost = uri.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase) ||
|
||||
uri.Host.Equals("127.0.0.1", StringComparison.OrdinalIgnoreCase) ||
|
||||
uri.Host.Equals("::1", StringComparison.OrdinalIgnoreCase);
|
||||
_isHttpWarning = uri.Scheme == "http" && !isLocalhost;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex flex-col lg:flex-row justify-between items-center">
|
||||
<p class="text-sm text-center text-gray-500 mb-4 lg:mb-0">
|
||||
© 2024 <span>@AppInfo.ApplicationName v@(AppInfo.GetFullVersion())</span>. @Localizer["CopyrightText"]
|
||||
© @(DateTime.Now.Year) <span>@AppInfo.ApplicationName v@(AppInfo.GetFullVersion())</span>. @Localizer["CopyrightText"]
|
||||
</p>
|
||||
<div class="hidden lg:block text-center text-gray-400 text-sm">@_randomQuote</div>
|
||||
</div>
|
||||
|
||||
@@ -74,4 +74,12 @@
|
||||
<value>Log in with existing account</value>
|
||||
<comment>Button text for logging in with existing account</comment>
|
||||
</data>
|
||||
<data name="HttpsWarningTitle" xml:space="preserve">
|
||||
<value>HTTPS Required</value>
|
||||
<comment>Title for HTTPS warning banner</comment>
|
||||
</data>
|
||||
<data name="HttpsWarningMessage" xml:space="preserve">
|
||||
<value>Browsers only allow secure crypto operations via HTTPS, except for localhost. Login/registration won't work over HTTP with the current hostname. Please switch to HTTPS.</value>
|
||||
<comment>Message explaining why HTTPS is required</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1525,6 +1525,11 @@ video {
|
||||
border-color: rgb(254 215 170 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-orange-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(249 115 22 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-primary-100 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(253 222 133 / var(--tw-border-opacity));
|
||||
@@ -1665,6 +1670,11 @@ video {
|
||||
background-color: rgb(238 242 255 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-orange-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 237 213 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-orange-50 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 247 237 / var(--tw-bg-opacity));
|
||||
@@ -1771,6 +1781,10 @@ video {
|
||||
--tw-gradient-to: #d68338 var(--tw-gradient-to-position);
|
||||
}
|
||||
|
||||
.fill-current {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.fill-primary-600 {
|
||||
fill: #d68338;
|
||||
}
|
||||
@@ -2146,6 +2160,16 @@ video {
|
||||
color: rgb(67 56 202 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-orange-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(249 115 22 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-orange-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(194 65 12 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-orange-800 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(154 52 18 / var(--tw-text-opacity));
|
||||
@@ -3443,6 +3467,10 @@ video {
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:fixed {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.lg\:relative {
|
||||
position: relative;
|
||||
}
|
||||
@@ -3503,6 +3531,10 @@ video {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lg\:min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.lg\:w-1\/2 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,34 @@
|
||||
/**
|
||||
* Custom error class for crypto availability issues
|
||||
*/
|
||||
class CryptoNotAvailableError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'CryptoNotAvailableError';
|
||||
// Prevent stack trace from being captured
|
||||
this.stack = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if crypto API is available and throw user-friendly error if not.
|
||||
*/
|
||||
function checkCryptoAvailable() {
|
||||
if (!window.crypto || !window.crypto.subtle) {
|
||||
const error = new CryptoNotAvailableError("Cryptographic operations are not available. Please ensure you are accessing AliasVault over HTTPS, as this is required for security features to work properly.");
|
||||
console.error(error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AES (symmetric) encryption and decryption functions.
|
||||
* @type {{encrypt: (function(*, *): Promise<string>), decrypt: (function(*, *): Promise<string>), decryptBytes: (function(*, *): Promise<Uint8Array>)}}
|
||||
*/
|
||||
window.cryptoInterop = {
|
||||
encrypt: async function (plaintext, base64Key) {
|
||||
checkCryptoAvailable();
|
||||
|
||||
const key = await window.crypto.subtle.importKey(
|
||||
"raw",
|
||||
Uint8Array.from(atob(base64Key), c => c.charCodeAt(0)),
|
||||
@@ -36,6 +61,8 @@ window.cryptoInterop = {
|
||||
);
|
||||
},
|
||||
decrypt: async function (base64Ciphertext, base64Key) {
|
||||
checkCryptoAvailable();
|
||||
|
||||
const key = await window.crypto.subtle.importKey(
|
||||
"raw",
|
||||
Uint8Array.from(atob(base64Key), c => c.charCodeAt(0)),
|
||||
@@ -61,6 +88,8 @@ window.cryptoInterop = {
|
||||
return decoder.decode(decrypted);
|
||||
},
|
||||
decryptBytes: async function (base64Ciphertext, base64Key) {
|
||||
checkCryptoAvailable();
|
||||
|
||||
const key = await window.crypto.subtle.importKey(
|
||||
"raw",
|
||||
Uint8Array.from(atob(base64Key), c => c.charCodeAt(0)),
|
||||
@@ -96,6 +125,8 @@ window.rsaInterop = {
|
||||
* @returns {Promise<{publicKey: string, privateKey: string}>} A promise that resolves to an object containing the public and private keys as JWK strings.
|
||||
*/
|
||||
generateRsaKeyPair : async function() {
|
||||
checkCryptoAvailable();
|
||||
|
||||
const keyPair = await window.crypto.subtle.generateKey(
|
||||
{
|
||||
name: "RSA-OAEP",
|
||||
@@ -122,6 +153,8 @@ window.rsaInterop = {
|
||||
* @returns {Promise<string>} A promise that resolves to the encrypted data as a base64-encoded string.
|
||||
*/
|
||||
encryptWithPublicKey : async function(plaintext, publicKey) {
|
||||
checkCryptoAvailable();
|
||||
|
||||
const publicKeyObj = await window.crypto.subtle.importKey(
|
||||
"jwk",
|
||||
JSON.parse(publicKey),
|
||||
@@ -151,6 +184,8 @@ window.rsaInterop = {
|
||||
* @returns {Promise<Uint8Array>} A promise that resolves to the decrypted data as a Uint8Array.
|
||||
*/
|
||||
decryptWithPrivateKey: async function(ciphertext, privateKey) {
|
||||
checkCryptoAvailable();
|
||||
|
||||
try {
|
||||
// Parse the private key
|
||||
let parsedPrivateKey = JSON.parse(privateKey);
|
||||
|
||||
@@ -10,8 +10,8 @@ LABEL org.opencontainers.image.description="Nginx reverse proxy for AliasVault.
|
||||
# Install OpenSSL and inotify-tools for certificate watching
|
||||
RUN apk add --no-cache openssl inotify-tools
|
||||
|
||||
# Copy configuration and entrypoint script
|
||||
COPY apps/server/nginx.conf /etc/nginx/nginx.conf
|
||||
# Copy all nginx configurations and entrypoint script
|
||||
COPY apps/server/nginx*.conf /etc/nginx/
|
||||
COPY apps/server/status.html /usr/share/nginx/html/status.html
|
||||
COPY apps/server/entrypoint.sh /docker-entrypoint.sh
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
@inherits ComponentBase
|
||||
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
<div class="bg-orange-100 border-l-4 border-orange-500 text-orange-700 p-4 mb-6" role="alert">
|
||||
<div class="flex">
|
||||
<div class="py-1">
|
||||
<svg class="fill-current h-6 w-6 text-orange-500 mr-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
@if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
<p class="font-bold">@Title</p>
|
||||
}
|
||||
<div class="text-sm">@ChildContent</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
/// <summary>
|
||||
/// Gets or sets the title to display.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the child content to display.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
}
|
||||
@@ -3,17 +3,67 @@
|
||||
# Create SSL directory if it doesn't exist
|
||||
mkdir -p /etc/nginx/ssl
|
||||
|
||||
# Generate self-signed SSL certificate if not exists
|
||||
if [ ! -f /etc/nginx/ssl/cert.pem ] || [ ! -f /etc/nginx/ssl/key.pem ]; then
|
||||
# Select the appropriate nginx configuration based on FORCE_HTTPS_REDIRECT
|
||||
# Default to true (nginx-443.conf) for backward compatibility
|
||||
# Only disable redirect if explicitly set to "false"
|
||||
if [ "${FORCE_HTTPS_REDIRECT:-true}" = "false" ]; then
|
||||
echo "Using nginx-80-443.conf (HTTP and HTTPS without redirect)"
|
||||
cp /etc/nginx/nginx-80-443.conf /etc/nginx/nginx.conf
|
||||
else
|
||||
echo "Using nginx-443.conf (HTTP to HTTPS redirect enabled - default)"
|
||||
cp /etc/nginx/nginx-443.conf /etc/nginx/nginx.conf
|
||||
fi
|
||||
|
||||
# Function to check if certificate needs regeneration
|
||||
needs_cert_regeneration() {
|
||||
# If cert doesn't exist, need to generate
|
||||
if [ ! -f /etc/nginx/ssl/cert.pem ] || [ ! -f /etc/nginx/ssl/key.pem ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if we have a hostname marker file
|
||||
if [ -f /etc/nginx/ssl/.hostname_marker ]; then
|
||||
STORED_HOSTNAME=$(cat /etc/nginx/ssl/.hostname_marker)
|
||||
if [ "$STORED_HOSTNAME" != "${HOSTNAME:-localhost}" ]; then
|
||||
echo "Hostname changed from '$STORED_HOSTNAME' to '${HOSTNAME:-localhost}', regenerating certificate..."
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
# No marker file, regenerate to be safe
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Generate self-signed SSL certificate if not exists or hostname changed
|
||||
if needs_cert_regeneration; then
|
||||
echo "Generating new SSL certificate (10 years validity)..."
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /etc/nginx/ssl/key.pem \
|
||||
-out /etc/nginx/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
|
||||
|
||||
HOSTNAME_VALUE="${HOSTNAME:-localhost}"
|
||||
|
||||
if [ "$HOSTNAME_VALUE" = "localhost" ] || [ -z "$HOSTNAME_VALUE" ]; then
|
||||
# Default localhost-only configuration
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /etc/nginx/ssl/key.pem \
|
||||
-out /etc/nginx/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
|
||||
else
|
||||
# Generate certificate with the hostname and include localhost as SAN
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /etc/nginx/ssl/key.pem \
|
||||
-out /etc/nginx/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${HOSTNAME_VALUE}" \
|
||||
-addext "subjectAltName=DNS:${HOSTNAME_VALUE},DNS:localhost,IP:127.0.0.1"
|
||||
fi
|
||||
|
||||
# Set proper permissions
|
||||
chmod 644 /etc/nginx/ssl/cert.pem
|
||||
chmod 600 /etc/nginx/ssl/key.pem
|
||||
|
||||
# Store current hostname for change detection
|
||||
echo "${HOSTNAME:-localhost}" > /etc/nginx/ssl/.hostname_marker
|
||||
chmod 644 /etc/nginx/ssl/.hostname_marker
|
||||
fi
|
||||
|
||||
# Create the appropriate SSL configuration based on LETSENCRYPT_ENABLED
|
||||
|
||||
143
apps/server/nginx-443.conf
Normal file
143
apps/server/nginx-443.conf
Normal file
@@ -0,0 +1,143 @@
|
||||
# This is the Nginx configuration file for the AliasVault reverse-proxy container.
|
||||
# which exposes all AliasVault services via 443 (HTTPS) with a self-signed or Let's Encrypt certificate.
|
||||
# It also redirects all non-ACME challenge requests from HTTP to HTTPS.
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
client_max_body_size 25M;
|
||||
|
||||
upstream client {
|
||||
server client:3000 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream api {
|
||||
server api:3001 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream admin {
|
||||
server admin:3002 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
# Preserve any existing X-Forwarded-* headers, this is relevant if AliasVault
|
||||
# is running behind another reverse proxy.
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Enable gzip compression, which reduces the amount of data that needs to be transferred
|
||||
# to speed up WASM load times.
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
# Handle ACME challenge for Let's Encrypt certificate validation
|
||||
location /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /var/www/certbot;
|
||||
try_files $uri =404;
|
||||
default_type "text/plain";
|
||||
add_header Cache-Control "no-cache";
|
||||
break;
|
||||
}
|
||||
|
||||
# Redirect all other HTTP traffic to HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
# Include the appropriate SSL certificate configuration generated
|
||||
# by the entrypoint script.
|
||||
include /etc/nginx/ssl.conf;
|
||||
|
||||
# Security headers
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'" always;
|
||||
|
||||
# Root for static files
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
# Error page handler location (internal use only)
|
||||
location = /status.html {
|
||||
internal;
|
||||
try_files /status.html =404;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# Admin interface
|
||||
location /admin {
|
||||
proxy_pass http://admin;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Prefix /admin/;
|
||||
|
||||
# Rewrite HTTP redirects to HTTPS
|
||||
proxy_redirect http:// https://;
|
||||
|
||||
# Add WebSocket support for Blazor server
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
|
||||
# Show status page if admin is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# API endpoints
|
||||
location /api {
|
||||
proxy_pass http://api;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if api is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# Client app (root path)
|
||||
location / {
|
||||
proxy_pass http://client;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Rewrite HTTP redirects to HTTPS
|
||||
proxy_redirect http:// https://;
|
||||
|
||||
# Show status page if client is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
128
apps/server/nginx-80-443.conf
Normal file
128
apps/server/nginx-80-443.conf
Normal file
@@ -0,0 +1,128 @@
|
||||
# This is the main Nginx configuration file for the AliasVault reverse-proxy container.
|
||||
# which exposes all AliasVault services via both 80 (HTTP)
|
||||
# and 443 (HTTPS) with either a self-signed or Let's Encrypt certificate.
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
client_max_body_size 25M;
|
||||
|
||||
upstream client {
|
||||
server client:3000 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream api {
|
||||
server api:3001 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream admin {
|
||||
server admin:3002 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
# Preserve any existing X-Forwarded-* headers, this is relevant if AliasVault
|
||||
# is running behind another reverse proxy.
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Enable gzip compression, which reduces the amount of data that needs to be transferred
|
||||
# to speed up WASM load times.
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
# Include the appropriate SSL certificate configuration generated
|
||||
# by the entrypoint script (only applies to 443).
|
||||
include /etc/nginx/ssl.conf;
|
||||
|
||||
# Security headers
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'" always;
|
||||
|
||||
# Root for static files
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
# Handle ACME challenge for Let's Encrypt certificate validation
|
||||
location /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /var/www/certbot;
|
||||
try_files $uri =404;
|
||||
default_type "text/plain";
|
||||
add_header Cache-Control "no-cache";
|
||||
break;
|
||||
}
|
||||
|
||||
# Error page handler location (internal use only)
|
||||
location = /status.html {
|
||||
internal;
|
||||
try_files /status.html =404;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# Admin interface
|
||||
location /admin {
|
||||
proxy_pass http://admin;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Prefix /admin/;
|
||||
|
||||
# Add WebSocket support for Blazor server
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
|
||||
# Show status page if admin is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# API endpoints
|
||||
location /api {
|
||||
proxy_pass http://api;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if api is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# Client app (root path)
|
||||
location / {
|
||||
proxy_pass http://client;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if client is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,24 +18,39 @@ COPY shared/ ./shared/
|
||||
|
||||
# Install required .NET workloads and restore packages once for the entire solution
|
||||
WORKDIR /src/apps/server
|
||||
|
||||
# Install workloads and restore packages once for the entire solution
|
||||
RUN dotnet workload install wasm-tools && \
|
||||
dotnet restore aliasvault.sln
|
||||
|
||||
# Build all applications
|
||||
# Build each application in separate layers to avoid lock contention
|
||||
|
||||
# Build API
|
||||
RUN dotnet publish AliasVault.Api/AliasVault.Api.csproj \
|
||||
-c Release -o /app/api --no-restore && \
|
||||
dotnet publish AliasVault.Client/AliasVault.Client.csproj \
|
||||
-c Release -o /app/client --no-restore && \
|
||||
dotnet publish AliasVault.Admin/AliasVault.Admin.csproj \
|
||||
-c Release -o /app/admin --no-restore && \
|
||||
dotnet publish Services/AliasVault.SmtpService/AliasVault.SmtpService.csproj \
|
||||
-c Release -o /app/smtp --no-restore && \
|
||||
dotnet publish Services/AliasVault.TaskRunner/AliasVault.TaskRunner.csproj \
|
||||
-c Release -o /app/taskrunner --no-restore && \
|
||||
dotnet publish Utilities/AliasVault.InstallCli/AliasVault.InstallCli.csproj \
|
||||
-c Release -o /app/installcli --no-restore && \
|
||||
# Clean up .NET debug files and unnecessary files
|
||||
find /app -name "*.pdb" -delete && \
|
||||
-c Release -o /app/api --no-restore
|
||||
|
||||
# Build Client (contains WASM which can be slow)
|
||||
RUN dotnet publish AliasVault.Client/AliasVault.Client.csproj \
|
||||
-c Release -o /app/client --no-restore
|
||||
|
||||
# Build Admin
|
||||
RUN dotnet publish AliasVault.Admin/AliasVault.Admin.csproj \
|
||||
-c Release -o /app/admin --no-restore
|
||||
|
||||
# Build SMTP Service
|
||||
RUN dotnet publish Services/AliasVault.SmtpService/AliasVault.SmtpService.csproj \
|
||||
-c Release -o /app/smtp --no-restore
|
||||
|
||||
# Build Task Runner
|
||||
RUN dotnet publish Services/AliasVault.TaskRunner/AliasVault.TaskRunner.csproj \
|
||||
-c Release -o /app/taskrunner --no-restore
|
||||
|
||||
# Build Install CLI
|
||||
RUN dotnet publish Utilities/AliasVault.InstallCli/AliasVault.InstallCli.csproj \
|
||||
-c Release -o /app/installcli --no-restore
|
||||
|
||||
# Clean up .NET debug files and unnecessary files
|
||||
RUN find /app -name "*.pdb" -delete && \
|
||||
find /app -name "*.xml" -not -name "*.deps.json" -delete && \
|
||||
find /app -name "*.Development.json" -delete && \
|
||||
find /app -name "web.config" -delete
|
||||
@@ -109,31 +124,33 @@ RUN apt-get update && \
|
||||
/app/taskrunner \
|
||||
/app/installcli \
|
||||
/database \
|
||||
/certificates/ssl \
|
||||
/logs/postgres \
|
||||
/etc/nginx/ssl \
|
||||
/var/run/postgresql \
|
||||
/var/www/certbot \
|
||||
/etc/s6-overlay/s6-rc.d/user/contents.d
|
||||
|
||||
# Copy built applications and all configuration files from builder stage
|
||||
COPY --from=dotnet-builder /app /app
|
||||
|
||||
# Copy configuration files and scripts directly to their destinations
|
||||
COPY dockerfiles/all-in-one/reset-admin-password.sh /usr/local/bin/reset-admin-password.sh
|
||||
# Copy all scripts from scripts directory to /usr/local/bin
|
||||
COPY dockerfiles/all-in-one/scripts/ /usr/local/bin/
|
||||
COPY apps/server/AliasVault.Client/nginx.conf /app/client/nginx.conf
|
||||
COPY apps/server/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY dockerfiles/all-in-one/config/nginx-80-443.conf /etc/nginx/nginx-80-443.conf
|
||||
COPY dockerfiles/all-in-one/config/nginx-443.conf /etc/nginx/nginx-443.conf
|
||||
COPY apps/server/status.html /usr/share/nginx/html/status.html
|
||||
COPY dockerfiles/all-in-one/s6-scripts /etc/s6-overlay/s6-rc.d/
|
||||
|
||||
# Copy InstallCLI to /usr/local/bin and configure everything
|
||||
RUN cp -r /app/installcli /usr/local/bin/aliasvault-cli && \
|
||||
chmod +x /usr/local/bin/aliasvault-cli/AliasVault.InstallCli \
|
||||
/usr/local/bin/reset-admin-password.sh && \
|
||||
chmod +x /usr/local/bin/aliasvault-cli/AliasVault.InstallCli && \
|
||||
ln -s /usr/local/bin/aliasvault-cli/AliasVault.InstallCli /usr/local/bin/aliasvault-cli.sh && \
|
||||
sed -i 's/server client:3000/server localhost:3000/g; \
|
||||
s/server api:3001/server localhost:3001/g; \
|
||||
s/server admin:3002/server localhost:3002/g' /etc/nginx/nginx.conf && \
|
||||
# Make all scripts executable and create symlinks without .sh extension
|
||||
for script in /usr/local/bin/*.sh; do \
|
||||
if [ -f "$script" ]; then \
|
||||
chmod +x "$script" && \
|
||||
basename="$(basename "$script" .sh)" && \
|
||||
ln -sf "$script" "/usr/local/bin/$basename"; \
|
||||
fi; \
|
||||
done && \
|
||||
find /etc/s6-overlay/s6-rc.d -type f \( -name "run" -o -name "up" -o -name "script" \) -exec chmod +x {} \; && \
|
||||
cd /etc/s6-overlay/s6-rc.d/user/contents.d && \
|
||||
touch init postgres api client admin smtp taskrunner nginx notification && \
|
||||
@@ -146,15 +163,17 @@ ENV ALIASVAULT_VERBOSITY=0 \
|
||||
IP_LOGGING_ENABLED=true \
|
||||
SUPPORT_EMAIL="" \
|
||||
PRIVATE_EMAIL_DOMAINS="" \
|
||||
HOSTNAME=localhost \
|
||||
POSTGRES_HOST=localhost \
|
||||
POSTGRES_PORT=5432 \
|
||||
POSTGRES_USER=aliasvault \
|
||||
POSTGRES_DATABASE=aliasvault \
|
||||
FORCE_HTTPS_REDIRECT=false \
|
||||
S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
|
||||
S6_VERBOSITY=0
|
||||
|
||||
EXPOSE 80 443 25 587
|
||||
VOLUME ["/database", "/certificates", "/logs", "/secrets"]
|
||||
VOLUME ["/database", "/logs", "/secrets"]
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
|
||||
CMD curl -f -k https://localhost/api || exit 1
|
||||
CMD curl -f http://localhost/api || exit 1
|
||||
ENTRYPOINT ["/init"]
|
||||
@@ -18,9 +18,7 @@ docker build -f dockerfiles/all-in-one/Dockerfile -t aliasvault-allinone:local .
|
||||
docker run -d \
|
||||
--name aliasvault \
|
||||
-p 80:80 \
|
||||
-p 443:443 \
|
||||
-v ./database:/database \
|
||||
-v ./certificates:/certificates \
|
||||
-v ./logs:/logs \
|
||||
-v ./secrets:/secrets \
|
||||
aliasvault-allinone:local
|
||||
|
||||
126
dockerfiles/all-in-one/config/nginx-443.conf
Normal file
126
dockerfiles/all-in-one/config/nginx-443.conf
Normal file
@@ -0,0 +1,126 @@
|
||||
# Nginx configuration for AliasVault all-in-one container with forced HTTP to HTTPS redirect
|
||||
# and uses a self-signed cert.
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
client_max_body_size 25M;
|
||||
|
||||
upstream client {
|
||||
server localhost:3000 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream api {
|
||||
server localhost:3001 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream admin {
|
||||
server localhost:3002 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
# Preserve any existing X-Forwarded-* headers, this is relevant if AliasVault
|
||||
# is running behind another reverse proxy.
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Enable gzip compression, which reduces the amount of data that needs to be transferred
|
||||
# to speed up WASM load times.
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
# HTTP server - redirects all traffic to HTTPS
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
# Redirect all HTTP traffic to HTTPS
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
# HTTPS server
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
# Include the appropriate SSL certificate configuration generated
|
||||
# by the entrypoint script.
|
||||
include /etc/nginx/ssl.conf;
|
||||
|
||||
# Security headers
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'" always;
|
||||
|
||||
# Root for static files
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
# Error page handler location (internal use only)
|
||||
location = /status.html {
|
||||
internal;
|
||||
try_files /status.html =404;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# Admin interface
|
||||
location /admin {
|
||||
proxy_pass http://admin;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Prefix /admin/;
|
||||
|
||||
# Add WebSocket support for Blazor server
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
|
||||
# Show status page if admin is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# API endpoints
|
||||
location /api {
|
||||
proxy_pass http://api;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if api is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# Client app (root path)
|
||||
location / {
|
||||
proxy_pass http://client;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if client is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
188
dockerfiles/all-in-one/config/nginx-80-443.conf
Normal file
188
dockerfiles/all-in-one/config/nginx-80-443.conf
Normal file
@@ -0,0 +1,188 @@
|
||||
# This is the main Nginx configuration file for the AliasVault all-in-one container.
|
||||
# which exposes all AliasVault services via both 80 (HTTP)
|
||||
# and optionally 443 (HTTPS) with self-signed cert.
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
client_max_body_size 25M;
|
||||
|
||||
upstream client {
|
||||
server localhost:3000 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream api {
|
||||
server localhost:3001 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
upstream admin {
|
||||
server localhost:3002 max_fails=1 fail_timeout=5s;
|
||||
}
|
||||
|
||||
# Preserve any existing X-Forwarded-* headers, this is relevant if AliasVault
|
||||
# is running behind another reverse proxy.
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Enable gzip compression, which reduces the amount of data that needs to be transferred
|
||||
# to speed up WASM load times.
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
# Security headers
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'" always;
|
||||
|
||||
# Root for static files
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
# Error page handler location (internal use only)
|
||||
location = /status.html {
|
||||
internal;
|
||||
try_files /status.html =404;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# Admin interface
|
||||
location /admin {
|
||||
proxy_pass http://admin;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Prefix /admin/;
|
||||
|
||||
# Add WebSocket support for Blazor server
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
|
||||
# Show status page if admin is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# API endpoints
|
||||
location /api {
|
||||
proxy_pass http://api;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if api is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# Client app (root path)
|
||||
location / {
|
||||
proxy_pass http://client;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if client is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTPS server
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
# Include the appropriate SSL certificate configuration generated
|
||||
# by the entrypoint script.
|
||||
include /etc/nginx/ssl.conf;
|
||||
|
||||
# Security headers
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'" always;
|
||||
|
||||
# Root for static files
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
# Error page handler location (internal use only)
|
||||
location = /status.html {
|
||||
internal;
|
||||
try_files /status.html =404;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# Admin interface
|
||||
location /admin {
|
||||
proxy_pass http://admin;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Prefix /admin/;
|
||||
|
||||
# Add WebSocket support for Blazor server
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
|
||||
# Show status page if admin is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# API endpoints
|
||||
location /api {
|
||||
proxy_pass http://api;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if api is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
|
||||
# Client app (root path)
|
||||
location / {
|
||||
proxy_pass http://client;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Show status page if client is down
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 =503 /status.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh -e
|
||||
#!/command/with-contenv sh
|
||||
|
||||
# AliasVault Container Initialization Script
|
||||
# This script runs once at container startup and handles all initialization tasks
|
||||
@@ -154,37 +154,81 @@ else
|
||||
chmod 700 /database/postgres
|
||||
fi
|
||||
|
||||
# Future: Database migrations could go here
|
||||
# log 1 "[init] Checking for database migrations..."
|
||||
# if [ -f /app/migrations/pending ]; then
|
||||
# log 1 "[init] → Running database migrations..."
|
||||
# # Run migration logic here
|
||||
# fi
|
||||
# Function to check if certificate needs regeneration
|
||||
needs_cert_regeneration() {
|
||||
# If cert doesn't exist, need to generate
|
||||
if [ ! -f /certificates/ssl/cert.pem ] || [ ! -f /certificates/ssl/key.pem ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Generate SSL certificates if needed
|
||||
if [ ! -f /certificates/ssl/cert.pem ] || [ ! -f /certificates/ssl/key.pem ]; then
|
||||
# Check if we have a hostname marker file
|
||||
if [ -f /certificates/ssl/.hostname_marker ]; then
|
||||
STORED_HOSTNAME=$(cat /certificates/ssl/.hostname_marker)
|
||||
if [ "$STORED_HOSTNAME" != "${HOSTNAME:-localhost}" ]; then
|
||||
log 0 "[init] Hostname changed from '$STORED_HOSTNAME' to '${HOSTNAME:-localhost}', regenerating certificate..."
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
# No marker file, regenerate to be safe
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Generate SSL certificates if needed or hostname changed
|
||||
if needs_cert_regeneration; then
|
||||
log 0 ""
|
||||
log 0 "[init] Generating SSL certificates..."
|
||||
mkdir -p /certificates/ssl
|
||||
if [ "$VERBOSITY" -ge 2 ]; then
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /certificates/ssl/key.pem \
|
||||
-out /certificates/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${HOSTNAME:-localhost}"
|
||||
|
||||
HOSTNAME_VALUE="${HOSTNAME:-localhost}"
|
||||
|
||||
if [ "$HOSTNAME_VALUE" = "localhost" ] || [ -z "$HOSTNAME_VALUE" ]; then
|
||||
# Default localhost-only configuration
|
||||
if [ "$VERBOSITY" -ge 2 ]; then
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /certificates/ssl/key.pem \
|
||||
-out /certificates/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=localhost"
|
||||
else
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /certificates/ssl/key.pem \
|
||||
-out /certificates/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=localhost" \
|
||||
>/dev/null 2>&1
|
||||
fi
|
||||
else
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /certificates/ssl/key.pem \
|
||||
-out /certificates/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${HOSTNAME:-localhost}" \
|
||||
>/dev/null 2>&1
|
||||
# Generate certificate with the hostname and include localhost as SAN
|
||||
if [ "$VERBOSITY" -ge 2 ]; then
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /certificates/ssl/key.pem \
|
||||
-out /certificates/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${HOSTNAME_VALUE}" \
|
||||
-addext "subjectAltName=DNS:${HOSTNAME_VALUE},DNS:localhost,IP:127.0.0.1"
|
||||
else
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /certificates/ssl/key.pem \
|
||||
-out /certificates/ssl/cert.pem \
|
||||
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${HOSTNAME_VALUE}" \
|
||||
-addext "subjectAltName=DNS:${HOSTNAME_VALUE},DNS:localhost,IP:127.0.0.1" \
|
||||
>/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
chmod 600 /certificates/ssl/key.pem
|
||||
chmod 644 /certificates/ssl/cert.pem
|
||||
|
||||
# Store current hostname for change detection
|
||||
echo "${HOSTNAME:-localhost}" > /certificates/ssl/.hostname_marker
|
||||
chmod 644 /certificates/ssl/.hostname_marker
|
||||
|
||||
log 0 "[init] Self-signed SSL certificates generated"
|
||||
else
|
||||
log 0 "[init] ✅ Self-signed SSL certificates already exist"
|
||||
fi
|
||||
|
||||
|
||||
echo ""
|
||||
echo "[init] Waiting for all services to be ready... this can take a short while..."
|
||||
echo ""
|
||||
|
||||
@@ -19,6 +19,16 @@ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDS
|
||||
ssl_prefer_server_ciphers off;
|
||||
SSLEOF
|
||||
|
||||
# Configure nginx based on FORCE_HTTPS_REDIRECT environment variable
|
||||
FORCE_HTTPS_REDIRECT=${FORCE_HTTPS_REDIRECT:-false}
|
||||
if [[ "${FORCE_HTTPS_REDIRECT}" == "true" ]]; then
|
||||
echo "Configuring nginx with HTTPS-only (443) - redirects HTTP to HTTPS"
|
||||
cp /etc/nginx/nginx-443.conf /etc/nginx/nginx.conf
|
||||
else
|
||||
echo "Configuring nginx with HTTP and HTTPS support (80+443)"
|
||||
cp /etc/nginx/nginx-80-443.conf /etc/nginx/nginx.conf
|
||||
fi
|
||||
|
||||
echo "Starting Nginx reverse proxy..."
|
||||
|
||||
# Set nginx error log level based on verbosity
|
||||
|
||||
@@ -37,16 +37,16 @@ if [ "$VERBOSITY" -le 1 ]; then
|
||||
# Admin password hash exists - show the legacy warning
|
||||
echo "🔑 Admin Login:"
|
||||
echo " • Username: admin"
|
||||
echo " • Password: (previously set - to reset the admin password, login to this container via \`docker exec -it [container-name] /bin/bash\` and run: reset-admin-password.sh)"
|
||||
echo " • Password: (previously set - to reset the admin password, login to this container via \`docker exec -it aliasvault /bin/bash\` and run: aliasvault reset-admin-password)"
|
||||
echo ""
|
||||
else
|
||||
# No admin password hash file - show setup instructions
|
||||
echo "🔑 Admin Setup:"
|
||||
echo " • Admin user is not configured by default"
|
||||
echo " • To configure admin access:"
|
||||
echo " 1. docker exec -it [container-name] /bin/bash"
|
||||
echo " 2. reset-admin-password.sh"
|
||||
echo " 3. Restart the container"
|
||||
echo " 1. $ docker exec -it aliasvault /bin/bash"
|
||||
echo " 2. $ aliasvault reset-admin-password"
|
||||
echo " 3. $ docker compose restart"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
|
||||
35
dockerfiles/all-in-one/scripts/aliasvault.sh
Normal file
35
dockerfiles/all-in-one/scripts/aliasvault.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Simple AliasVault command dispatcher wrapper which allows
|
||||
# running AliasVault commands from the Docker container CLI
|
||||
# like `aliasvault reset-admin-password`.
|
||||
|
||||
case "$1" in
|
||||
reset-admin-password)
|
||||
shift
|
||||
exec /usr/local/bin/reset-admin-password.sh "$@"
|
||||
;;
|
||||
hash-password)
|
||||
shift
|
||||
exec /usr/local/bin/aliasvault-cli/AliasVault.InstallCli hash-password "$@"
|
||||
;;
|
||||
help|--help|-h|"")
|
||||
echo "AliasVault Commands"
|
||||
echo ""
|
||||
echo "Usage: aliasvault <command> [options]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " reset-admin-password Reset admin password"
|
||||
echo " hash-password Hash a password"
|
||||
echo " help Show this help"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " aliasvault reset-admin-password -y"
|
||||
echo " aliasvault hash-password 'mypassword'"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command: $1"
|
||||
echo "Run 'aliasvault help' for usage"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
36
dockerfiles/docker-compose.all-in-one.nas.yml
Normal file
36
dockerfiles/docker-compose.all-in-one.nas.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
# Docker Compose file for the AliasVault all-in-one container
|
||||
#
|
||||
# Specific for NAS devices:
|
||||
# - Uses custom HTTP ports by default to avoid conflicts
|
||||
# - Uses named bind mounts for the database, logs and secrets to ensure they are persisted
|
||||
#
|
||||
version: "3"
|
||||
services:
|
||||
aliasvault:
|
||||
image: ghcr.io/aliasvault/aliasvault:latest
|
||||
container_name: aliasvault
|
||||
restart: unless-stopped
|
||||
|
||||
ports:
|
||||
- "1080:80"
|
||||
- "1443:443"
|
||||
- "25:25"
|
||||
- "587:587"
|
||||
|
||||
volumes:
|
||||
- avdata:/database
|
||||
- avlogs:/logs
|
||||
- avsecrets:/secrets
|
||||
|
||||
environment:
|
||||
HOSTNAME: "localhost"
|
||||
PUBLIC_REGISTRATION_ENABLED: "true"
|
||||
IP_LOGGING_ENABLED: "true"
|
||||
FORCE_HTTPS_REDIRECT: "false"
|
||||
SUPPORT_EMAIL: ""
|
||||
PRIVATE_EMAIL_DOMAINS: ""
|
||||
|
||||
volumes:
|
||||
avdata:
|
||||
avlogs:
|
||||
avsecrets:
|
||||
@@ -1,5 +1,8 @@
|
||||
version: "3"
|
||||
|
||||
# Docker Compose file for the AliasVault all-in-one container
|
||||
#
|
||||
# This is the general purpose template which uses local folder bind mounts for the database, logs and secrets.
|
||||
# - For NAS devices, its safer to use the docker-compose.all-in-one.nas.yml template instead.
|
||||
#
|
||||
services:
|
||||
aliasvault:
|
||||
image: ghcr.io/aliasvault/aliasvault:latest
|
||||
@@ -14,12 +17,13 @@ services:
|
||||
|
||||
volumes:
|
||||
- ./database:/database
|
||||
- ./certificates:/certificates
|
||||
- ./logs:/logs
|
||||
- ./secrets:/secrets
|
||||
|
||||
environment:
|
||||
HOSTNAME: "localhost"
|
||||
PUBLIC_REGISTRATION_ENABLED: "true"
|
||||
IP_LOGGING_ENABLED: "true"
|
||||
FORCE_HTTPS_REDIRECT: "false"
|
||||
SUPPORT_EMAIL: ""
|
||||
PRIVATE_EMAIL_DOMAINS: ""
|
||||
|
||||
68
docs/404.html
Normal file
68
docs/404.html
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
layout: default
|
||||
title: 404 - Page not found
|
||||
permalink: /404.html
|
||||
nav_exclude: true
|
||||
search_exclude: true
|
||||
---
|
||||
|
||||
<style>
|
||||
.error-404 {
|
||||
text-align: center;
|
||||
padding: 4rem 2rem;
|
||||
}
|
||||
.error-404 h1 {
|
||||
font-size: 6rem;
|
||||
color: #f49541;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.error-404 h2 {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #f8f9fa;
|
||||
}
|
||||
.error-404 p {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 2rem;
|
||||
color: #d1d5db;
|
||||
}
|
||||
.error-404 .btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
background-color: #d68338;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
.error-404 .btn:hover {
|
||||
background-color: #f49541;
|
||||
}
|
||||
.error-404 .links {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
.error-404 .links a {
|
||||
margin: 0 1rem;
|
||||
color: #f49541;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.error-404 .links a:hover {
|
||||
color: #ffd5a8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="error-404">
|
||||
<h1>404</h1>
|
||||
<h2>Page Not Found</h2>
|
||||
<p>The page you're looking for doesn't exist or may have been moved.</p>
|
||||
<p>This could happen if the documentation structure has been reorganized or the page has been renamed.</p>
|
||||
|
||||
<a href="{{ '/' | relative_url }}" class="btn">Go to Home</a>
|
||||
|
||||
<div class="links">
|
||||
<p>Or try these helpful links:</p>
|
||||
<a href="{{ '/installation/' | relative_url }}">Installation Guide</a>
|
||||
<a href="{{ '/browser-extension/' | relative_url }}">Browser Extension</a>
|
||||
<a href="{{ '/mobile-app/' | relative_url }}">Mobile App</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -6,3 +6,7 @@ gem "just-the-docs"
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
gem "github-pages", group: :jekyll_plugins
|
||||
|
||||
group :jekyll_plugins do
|
||||
gem "jekyll-sitemap"
|
||||
end
|
||||
|
||||
@@ -284,6 +284,7 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
github-pages
|
||||
jekyll-sitemap
|
||||
just-the-docs
|
||||
|
||||
BUNDLED WITH
|
||||
|
||||
@@ -38,3 +38,19 @@ callouts:
|
||||
note:
|
||||
title: Note
|
||||
color: purple
|
||||
important:
|
||||
title: Important
|
||||
color: yellow
|
||||
|
||||
# 404 page
|
||||
defaults:
|
||||
- scope:
|
||||
path: "404.html"
|
||||
values:
|
||||
sitemap: false
|
||||
|
||||
# Sitemap settings
|
||||
url: "https://docs.aliasvault.net"
|
||||
plugins:
|
||||
- jekyll-sitemap
|
||||
- jekyll-redirect-from
|
||||
|
||||
44
docs/_plugins/404_server.rb
Normal file
44
docs/_plugins/404_server.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
require 'webrick'
|
||||
|
||||
module Jekyll
|
||||
class FourOhFourPage < StaticFile
|
||||
def write(dest)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class FourOhFourGenerator < Generator
|
||||
priority :low
|
||||
|
||||
def generate(site)
|
||||
site.static_files << FourOhFourPage.new(site, site.dest, '/', '404.html')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Override WEBrick to serve 404.html for missing files
|
||||
if defined?(WEBrick)
|
||||
module WEBrick
|
||||
class HTTPServlet::FileHandler
|
||||
alias_method :do_GET_original, :do_GET
|
||||
|
||||
def do_GET(req, res)
|
||||
do_GET_original(req, res)
|
||||
rescue HTTPStatus::NotFound => ex
|
||||
return_404_page(req, res)
|
||||
rescue => ex
|
||||
raise ex
|
||||
end
|
||||
|
||||
def return_404_page(req, res)
|
||||
path = File.join(@config[:DocumentRoot], '404.html')
|
||||
if File.exist?(path)
|
||||
res.body = File.read(path)
|
||||
res['content-type'] = 'text/html'
|
||||
else
|
||||
raise HTTPStatus::NotFound
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -38,5 +38,11 @@ $purple-100: #ffd5a8;
|
||||
$purple-200: #f49541;
|
||||
$purple-300: #d68338;
|
||||
|
||||
// Orange Colors
|
||||
$orange-000: #f8b963;
|
||||
$orange-100: #ffd5a8;
|
||||
$orange-200: #f49541;
|
||||
$orange-300: #d68338;
|
||||
|
||||
// Navigation additional
|
||||
$nav-button-color: #f49541;
|
||||
|
||||
@@ -9,11 +9,11 @@ permalink: /
|
||||
# AliasVault Documentation
|
||||
{: .fs-9 }
|
||||
|
||||
A self-hostable, end-to-end encrypted password manager with a built-in alias generator and email server.
|
||||
A privacy-first password manager with built-in email aliasing. Fully encrypted and self-hostable.
|
||||
|
||||
{: .fs-6 .fw-300 }
|
||||
|
||||
[Server Installation](./installation/install){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
||||
[Self-host Install](./installation){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
||||
[View on GitHub](https://github.com/aliasvault/aliasvault){: .btn .fs-5 .mb-4 .mb-md-0 }
|
||||
|
||||
---
|
||||
@@ -37,7 +37,7 @@ All data is end-to-end encrypted on the client. Your master password never leave
|
||||
Generate virtual email addresses for each identity. Emails sent to these addresses are instantly visible in the AliasVault app.
|
||||
|
||||
### Virtual Identities
|
||||
Create separate identities for different purposes, each with its own email aliases and credentials.
|
||||
Create separate identities for different purposes, each with its own email aliases.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Database Backup
|
||||
parent: Advanced
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Database Backup
|
||||
|
||||
In order to backup the database, you can use the `install.sh` script. This script will stop all services, export the database to a file, and then restart the services.
|
||||
|
||||
```bash
|
||||
./install.sh db-backup > backup.sql.gz
|
||||
```
|
||||
|
||||
# Database Restore
|
||||
|
||||
To restore the database, you can use the `install.sh` script. This script will stop all services, drop the database, import the database from a file, and then restart the services.
|
||||
|
||||
```bash
|
||||
./install.sh db-restore < backup.sql.gz
|
||||
```
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Advanced
|
||||
parent: Server Installation
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Advanced Installation
|
||||
The following guides provide more advanced installation options for AliasVault. These options are not required for the basic installation, but may be useful for advanced users.
|
||||
|
||||
- [Manual Setup](manual-setup.md) - Step-by-step manual installation without the install script
|
||||
- [Reverse Proxy Configuration](reverse-proxy-configuration.md) - Configure AliasVault with your existing reverse proxy
|
||||
- [Build from Source](build-from-source.md) - Build AliasVault from source code
|
||||
- [Database Configuration](database.md) - Advanced database configuration options
|
||||
@@ -1,139 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Manual Setup
|
||||
parent: Advanced
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Manual Setup
|
||||
|
||||
If you prefer to manually set up AliasVault instead of using the `install.sh` script, this README provides step-by-step instructions.
|
||||
|
||||
**Prerequisities:**
|
||||
- Docker (20.10+) and Docker Compose (2.0+) installed on your system
|
||||
- See instructions: [https://docs.docker.com/engine/install/](https://docs.docker.com/engine/install/)
|
||||
- Knowledge of working with direct Docker commands
|
||||
- Knowledge of .env files
|
||||
- OpenSSL for generating random passwords
|
||||
|
||||
---
|
||||
|
||||
{: .toc }
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Steps
|
||||
Follow these steps to manually install AliasVault on your own server.
|
||||
|
||||
1. **Clone the git repository**
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/aliasvault/aliasvault.git
|
||||
|
||||
# Navigate to the AliasVault directory
|
||||
cd aliasvault
|
||||
```
|
||||
|
||||
2. **Create required directories**
|
||||
|
||||
Create the following directories in your project root:
|
||||
```bash
|
||||
# Create required directories
|
||||
mkdir -p certificates/ssl database/postgres
|
||||
```
|
||||
|
||||
3. **Create .env file**
|
||||
|
||||
```bash
|
||||
# Copy the .env.example file to create a new .env file
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
4. **Set all required settings in .env**
|
||||
|
||||
Open the .env file in your favorite text editor and fill in all required variables
|
||||
by following the instructions inside the file.
|
||||
|
||||
```bash
|
||||
# Open the .env file with your favorite editor, e.g. nano.
|
||||
nano .env
|
||||
```
|
||||
|
||||
5. **Start the docker containers**
|
||||
|
||||
After you are done configuring your .env file, you can start the Docker Compose stack:
|
||||
```bash
|
||||
# Start the docker compose stack
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
6. **Access AliasVault**
|
||||
|
||||
AliasVault should now be running. You can access it at:
|
||||
|
||||
- Admin Panel: https://localhost/admin
|
||||
- Username: admin
|
||||
- Password: [Use the password you set in the .env file]
|
||||
|
||||
- Client Website: https://localhost/
|
||||
- Create your own account from here
|
||||
|
||||
> Note: if you changed the default ports from 80/443 to something else in the .env file, use those ports to access AliasVault here.
|
||||
|
||||
7. **Configuring private email domains**
|
||||
|
||||
By default, the AliasVault private email domains feature is disabled. If you wish to enable this to use your own private domains to create email aliases with, please read the `Email Server Setup` section in the main installation guide [Basic Install](../install.md#3-email-server-setup).
|
||||
|
||||
For more information, read the article explaining the differences between AliasVault's [private and public domains](../../misc/private-vs-public-email.md).
|
||||
|
||||
|
||||
## Important Notes
|
||||
|
||||
- Make sure to save both the admin password and PostgreSQL password in a secure location.
|
||||
- Always keep your .env file secure and do not share it, as it contains sensitive information.
|
||||
- The PostgreSQL data is persisted in the `database/postgres` directory.
|
||||
- The docker-compose.yml file uses the `:latest` tag for containers by default. This means it always uses the latest available AliasVault version. In order to update AliasVault to a newer version at a later time, you can pull new containers when they are available with this command:
|
||||
```
|
||||
docker compose pull && docker compose down && docker compose up -d
|
||||
```
|
||||
|
||||
## Using a Custom Reverse Proxy (e.g. Cloudflare Tunnel)
|
||||
|
||||
AliasVault includes its own internal reverse proxy (nginx) container that routes traffic to other containers. By default, the built-in nginx container (`reverse-proxy`) makes AliasVault's services available at:
|
||||
|
||||
- **Client**: `http://localhost/`
|
||||
- **API**: `http://localhost/api`
|
||||
- **Admin**: `http://localhost/admin`
|
||||
|
||||
If you want to use your own reverse proxy setup (e.g. with a Cloudflare Tunnel), you **must** ensure the following:
|
||||
|
||||
- Your custom proxy/tunnel **points to the AliasVault `reverse-proxy` container**, **not** directly to the client, API, or admin containers.
|
||||
- The forwarding protocol must be **HTTPS**, since the `reverse-proxy` container listens on port `443` for secure connections.
|
||||
|
||||
> ⚠️ Failing to route through the reverse-proxy container correctly will break the app. Errors such as HTTP 502 often indicate a misconfigured reverse proxy.
|
||||
|
||||
If you're using **Cloudflare Tunnel**, you will likely encounter TLS verification issues. In that case, go to the Cloudflare dashboard and enable the **"No TLS Verify"** option for your tunnel configuration. This tells Cloudflare to skip certificate validation when connecting to the internal reverse-proxy over HTTPS.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
If you encounter any miscellaneous issues during the setup:
|
||||
|
||||
1. Check the Docker logs:
|
||||
```bash
|
||||
docker compose logs
|
||||
```
|
||||
2. Ensure all required ports (80, 443, 25, 587 and 5432) are available and not being used by other services.
|
||||
3. Verify that all variables in the .env file are set correctly.
|
||||
4. Check PostgreSQL container logs specifically:
|
||||
```bash
|
||||
docker compose logs postgres
|
||||
```
|
||||
|
||||
For more detailed troubleshooting information, please refer to the full [troubleshooting guide](../troubleshooting.md).
|
||||
|
||||
## FAQ
|
||||
### Why does AliasVault use its own reverse proxy?
|
||||
AliasVault requires precise routing between its client, API, and admin interfaces. These are structured under `/`, `/api`, and `/admin`. A unified nginx reverse proxy ensures that all AliasVault's containers are accessible under the same hostname and path structure. If you use your own reverse proxy, you must replicate this logic exactly. See the [nginx.conf](https://raw.githubusercontent.com/aliasvault/aliasvault/refs/heads/main/apps/server/nginx.conf) configuration that's used by the official container for reference.
|
||||
@@ -1,141 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Reverse Proxy Configuration
|
||||
parent: Advanced
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Reverse Proxy Configuration
|
||||
This guide is intended for users who already have a self-hosted reverse proxy setup (such as nginx, Apache, or Cloudflare Tunnel) and want to expose AliasVault through it. In this case, the recommended approach is to forward a single hostname (e.g., `aliasvault.example.com`) to the internal reverse proxy container that AliasVault provides.
|
||||
|
||||
If you do **not** already have an existing reverse proxy, you can simply rely on the built-in reverse proxy that comes with AliasVault, as it's fully capable of handling all routing, SSL termination, and WebSocket support out of the box.
|
||||
|
||||
|
||||
## Overview
|
||||
AliasVault includes its own internal reverse proxy (nginx) that handles routing between its three core services:
|
||||
- **Client Application** (`/`) – The main user interface
|
||||
- **API Server** (`/api`) – REST API endpoints
|
||||
- **Admin Panel** (`/admin`) – Administrative interface
|
||||
|
||||
When using an external reverse proxy, you **must** forward requests to the `reverse-proxy` container. Do **not** route traffic directly to the individual services.
|
||||
|
||||
## Why AliasVault Uses Its Own Reverse Proxy
|
||||
AliasVault’s internal reverse proxy ensures proper routing and configuration of all services under one domain:
|
||||
|
||||
1. **Unified Hostname** – All services operate under the same domain (e.g., `aliasvault.example.com`)
|
||||
2. **Path-Based Routing** – Correct dispatch of `/`, `/api`, and `/admin` requests
|
||||
3. **Security Headers** – Consistent headers across services
|
||||
4. **SSL Termination** – Central SSL/TLS handling
|
||||
5. **WebSocket Support** – Required for the Blazor-based admin interface
|
||||
|
||||
## Internal Nginx Configuration Structure
|
||||
AliasVault's reverse proxy follows a path-based routing configuration like this:
|
||||
|
||||
```nginx
|
||||
# Upstream services
|
||||
upstream client {
|
||||
server client:3000;
|
||||
}
|
||||
upstream api {
|
||||
server api:3001;
|
||||
}
|
||||
upstream admin {
|
||||
server admin:3002;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
location /admin {
|
||||
proxy_pass http://admin;
|
||||
# WebSocket support and headers
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://api;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://client;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Simplest Setup (Recommended)
|
||||
Forward all traffic from your external reverse proxy to the AliasVault internal reverse proxy container. This avoids manual path-based routing.
|
||||
|
||||
### Example: External Nginx Reverse Proxy
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name aliasvault.example.com;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name aliasvault.example.com;
|
||||
|
||||
ssl_certificate /path/to/your/certificate.crt;
|
||||
ssl_certificate_key /path/to/your/private.key;
|
||||
|
||||
location / {
|
||||
proxy_pass https://aliasvault-internal:443;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Port Configuration
|
||||
AliasVault’s internal reverse proxy defaults to port `443`. If this port is already in use, you can change it in the `.env` file inside your AliasVault folder:
|
||||
|
||||
```
|
||||
HTTP_PORT=80
|
||||
HTTPS_PORT=443
|
||||
```
|
||||
|
||||
Make sure your external proxy points to the correct port.
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### HTTP 502 Bad Gateway
|
||||
|
||||
**Cause**: External proxy routing to wrong container.
|
||||
**Fix**: Ensure it routes to `reverse-proxy` container, not `client`, `api`, or `admin`.
|
||||
|
||||
### WebSocket Errors
|
||||
|
||||
**Cause**: WebSocket headers not forwarded.
|
||||
**Fix**: Make sure `Upgrade` and `Connection` headers are preserved.
|
||||
|
||||
### SSL/TLS Verification (e.g., Cloudflare Tunnel)
|
||||
|
||||
**Cause**: TLS verification fails.
|
||||
**Fix**: Enable “No TLS Verify” in your Cloudflare Tunnel configuration.
|
||||
|
||||
### Partial Routing Failures
|
||||
|
||||
**Cause**: External proxy modifies paths.
|
||||
**Fix**: Do not strip or rewrite paths. Proxy should pass `/`, `/api`, `/admin` as-is.
|
||||
|
||||
## Testing
|
||||
After setup, verify:
|
||||
|
||||
- `https://your-domain.com/` loads the client app
|
||||
- `https://your-domain.com/api` returns OK
|
||||
- `https://your-domain.com/admin` loads the admin interface
|
||||
|
||||
All services must be available under the **same** hostname.
|
||||
|
||||
## Security Considerations
|
||||
- Always use HTTPS in production
|
||||
- Preserve headers like `X-Real-IP`, `X-Forwarded-For`
|
||||
- Consider adding rate limiting or IP restrictions on your external proxy
|
||||
- Keep certificates and secrets secure
|
||||
|
||||
For advanced scenarios or troubleshooting, refer to the main [troubleshooting guide](../troubleshooting.md).
|
||||
32
docs/installation/docker-compose/advanced/database.md
Normal file
32
docs/installation/docker-compose/advanced/database.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
layout: default
|
||||
title: Database Operations
|
||||
parent: Advanced
|
||||
grand_parent: Docker Compose
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Database Operations
|
||||
This page explains how to import/export on the AliasVault server database via Docker commands.
|
||||
|
||||
## Database Export
|
||||
In order to backup the AliasVault server database (which includes all encrypted user vaults as well), you can use the following command. Run this command from the directory where your AliasVault `docker-compose.yml` is located.
|
||||
|
||||
```bash
|
||||
$ docker compose exec aliasvault pg_dump -U aliasvault aliasvault > backup.sql
|
||||
```
|
||||
|
||||
## Database Import
|
||||
|
||||
To restore a previously exported database, you can use the following snippet. Run these commands from the directory where your AliasVault `docker-compose.yml` is located.
|
||||
|
||||
```bash
|
||||
# Drop database first (warning: this can't be undone!)
|
||||
docker compose exec -T aliasvault psql -U postgres -d postgres -c "DROP DATABASE IF EXISTS aliasvault WITH (FORCE);"
|
||||
|
||||
# Create new empty database
|
||||
docker compose exec -T aliasvault psql -U postgres -d postgres -c "CREATE DATABASE aliasvault OWNER aliasvault;"
|
||||
|
||||
# Import backup
|
||||
docker compose exec -T aliasvault psql -U aliasvault aliasvault < backup.sql
|
||||
```
|
||||
9
docs/installation/docker-compose/advanced/index.md
Normal file
9
docs/installation/docker-compose/advanced/index.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
layout: default
|
||||
title: Advanced
|
||||
parent: Docker Compose
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Advanced Installation
|
||||
The following guides provide more advanced installation options for AliasVault. These options are not required for the basic installation, but may be useful for advanced users.
|
||||
30
docs/installation/docker-compose/advanced/lifecycle.md
Normal file
30
docs/installation/docker-compose/advanced/lifecycle.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
layout: default
|
||||
title: Stop/start
|
||||
parent: Advanced
|
||||
grand_parent: Docker Compose
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Stopping and starting AliasVault
|
||||
You can stop and start AliasVault via the default docker compose commands. Run these commands from the directory where your AliasVault `docker-compose.yml` is located.
|
||||
|
||||
## Stop
|
||||
To stop AliasVault:
|
||||
```bash
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Start
|
||||
To start AliasVault:
|
||||
|
||||
```bash
|
||||
$ docker compose up -d
|
||||
```
|
||||
|
||||
## Restart
|
||||
To restart AliasVault (note: when making changes to the `docker-compose.yml`, you'll need to manually stop and start to make the new changes be applied)
|
||||
|
||||
```bash
|
||||
$ docker compose restart
|
||||
```
|
||||
20
docs/installation/docker-compose/advanced/uninstall.md
Normal file
20
docs/installation/docker-compose/advanced/uninstall.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
layout: default
|
||||
title: Uninstall
|
||||
parent: Advanced
|
||||
grand_parent: Docker Compose
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Uninstall
|
||||
|
||||
To uninstall AliasVault, run the following command. This will stop and remove the AliasVault containers and remove the Docker images.
|
||||
|
||||
{: .note }
|
||||
This will not delete any data stored in the database. If you wish to delete all data, you should manually delete the `database` directory and the other directories created by AliasVault.
|
||||
|
||||
### Steps
|
||||
1. Run docker compose down and remove any local Docker images related to AliasVault.
|
||||
```bash
|
||||
$ docker compose down --rmi all
|
||||
```
|
||||
186
docs/installation/docker-compose/index.md
Normal file
186
docs/installation/docker-compose/index.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
layout: default
|
||||
title: Docker Compose
|
||||
parent: Self-host Install
|
||||
redirect_from:
|
||||
- /installation/advanced/manual-setup
|
||||
- /installation/advanced/manual-setup.html
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Self-host using Docker Compose (single container)
|
||||
The following guide will walk you through the steps to install AliasVault via the All-In-One Docker container. This container uses `s6-overlay` to combine all AliasVault's services into one image for convenience. The only downside compared to the `install.sh` installer is that this version does NOT come with SSL/TLS support, so you'll have to make the container available through your own SSL/TLS proxy.
|
||||
|
||||
{: .important-title }
|
||||
> Requirements:
|
||||
> - Docker (20.10+) and Docker Compose (2.0+) installed on your system
|
||||
> - See instructions: [https://docs.docker.com/engine/install/](https://docs.docker.com/engine/install/)
|
||||
> - You have existing SSL/TLS proxy infrastructure (Traefik, Nginx, HAProxy, Cloudflare Tunnel)
|
||||
> - Knowledge of working with direct Docker commands
|
||||
> - Knowledge of .yml and .env files
|
||||
|
||||
## 1. Basic installation
|
||||
1. Create a new folder where you want to store AliasVault's data and configuration folders.
|
||||
```bash
|
||||
mkdir aliasvault
|
||||
cd aliasvault
|
||||
```
|
||||
2. Create a new `docker-compose.yml` file with the following contents. Note: the directories specified in `volumes:` will be auto-created in the current folder on container first start.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
aliasvault:
|
||||
image: ghcr.io/aliasvault/aliasvault:latest
|
||||
container_name: aliasvault
|
||||
restart: unless-stopped
|
||||
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "25:25"
|
||||
- "587:587"
|
||||
|
||||
volumes:
|
||||
- ./database:/database
|
||||
- ./logs:/logs
|
||||
- ./secrets:/secrets
|
||||
|
||||
environment:
|
||||
HOSTNAME: "localhost"
|
||||
PUBLIC_REGISTRATION_ENABLED: "true"
|
||||
IP_LOGGING_ENABLED: "true"
|
||||
FORCE_HTTPS_REDIRECT: "false"
|
||||
SUPPORT_EMAIL: ""
|
||||
PRIVATE_EMAIL_DOMAINS: ""
|
||||
```
|
||||
3. Run `docker-compose up -d` to start the container.
|
||||
4. After the container has started, AliasVault should now be running. You can access it at:
|
||||
|
||||
- Admin Panel: http://localhost/admin
|
||||
- **Username:** admin
|
||||
- **Password:** [*Read instructions on page*]
|
||||
|
||||
- Client Website: http://localhost/
|
||||
- Create your own account from here
|
||||
|
||||
- API: http://localhost/api
|
||||
- Used for configuring the browser extension and mobile app to connect to your server
|
||||
|
||||
---
|
||||
|
||||
## 2. SSL/TLS configuration
|
||||
To use AliasVault securely, HTTPS is required in the following situations:
|
||||
- When accessing the web app from any address other than `localhost` (due to browser security restrictions)
|
||||
- When using the mobile apps, which require the API URL to have a valid TLS certificate; otherwise, the app will not connect
|
||||
|
||||
You must set up and configure your own TLS/SSL infrastructure (such as Traefik, Nginx, HAProxy, or Cloudflare Tunnel) to make the AliasVault container accessible over HTTPS with a valid SSL/TLS certificate. For example: `https://aliasvault.yourdomain.com`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Email Server Setup
|
||||
|
||||
AliasVault includes a built-in email server that allows you to generate email aliases on-the-fly for every website you use, and receive the emails straight in AliasVault.
|
||||
|
||||
{: .note }
|
||||
If you skip this step, AliasVault will default to use public email domains offered by SpamOK. While this still works for creating aliases, it has privacy limitations. For complete privacy and control, we recommend setting up your own domain.
|
||||
[Learn more about the differences between private and public email domains](../misc/private-vs-public-email.md).
|
||||
|
||||
---
|
||||
|
||||
### Requirements
|
||||
- A **public IPv4 address** with ports 25 and 587 forwarded to your AliasVault server
|
||||
- Open ports **25** and **587** on your server firewall for email SMTP traffic (*NOTE: some residential IP's block this, check with your ISP*).
|
||||
|
||||
#### Verifying Port Access
|
||||
|
||||
While the AliasVault docker containers are running, use `telnet` to confirm your public IP allows access to the ports:
|
||||
|
||||
```bash
|
||||
# Test standard SMTP port
|
||||
telnet <your-server-public-ip> 25
|
||||
|
||||
# Test secure SMTP port
|
||||
telnet <your-server-public-ip> 587
|
||||
```
|
||||
|
||||
### Choose your configuration: primary domain vs subdomain
|
||||
|
||||
AliasVault can be configured under:
|
||||
|
||||
- **A primary (top-level) domain**
|
||||
Example: `your-aliasvault.net`. This allows you to receive email on `%alias%@your-aliasvault.net`.
|
||||
|
||||
- **A subdomain of your existing domain**
|
||||
Example: `aliasvault.example.net`. This allows you to receive email on `%alias%@aliasvault.example.net`. Email sent to your main domain remains unaffected and will continue arriving in your usual inbox.
|
||||
|
||||
---
|
||||
|
||||
#### a) Setup using a primary domain
|
||||
|
||||
##### DNS Configuration
|
||||
|
||||
Configure the following DNS records **on your primary domain** (e.g. `your-aliasvault.net`):
|
||||
|
||||
| Name | Type | Priority | Content | TTL |
|
||||
|------|------|----------|---------------------------|-----|
|
||||
| mail | A | | `<your-server-public-ip>` | 3600 |
|
||||
| @ | MX | 10 | `mail.your-aliasvault.net`| 3600 |
|
||||
|
||||
> Replace `<your-server-public-ip>` with your actual server IP.
|
||||
|
||||
##### Example
|
||||
|
||||
- `mail.your-aliasvault.net` points to your server IP.
|
||||
- Email to `@your-aliasvault.net` will be handled by your AliasVault server.
|
||||
|
||||
---
|
||||
|
||||
#### b) Setup using a subdomain
|
||||
|
||||
##### DNS Configuration
|
||||
|
||||
Configure the following DNS records **on your subdomain setup** (for example, `aliasvault.example.com`):
|
||||
|
||||
| Name | Type | Priority | Content | TTL |
|
||||
|---------------------------|------|----------|-------------------------------|-----|
|
||||
| mail.aliasvault | A | | `<your-server-public-ip>` | 3600 |
|
||||
| aliasvault | MX | 10 | `mail.aliasvault.example.com` | 3600 |
|
||||
|
||||
> 🔹 Explanation:
|
||||
> - `mail.aliasvault` creates a DNS A record for `mail.aliasvault.example.com` pointing to your server IP.
|
||||
> - The MX record on `aliasvault.example` tells senders to send their mail addressed to `%@aliasvault.example.com` to `mail.aliasvault.example.com`.
|
||||
|
||||
> Replace `<your-server-public-ip>` with your actual server’s IP address.
|
||||
|
||||
##### Example
|
||||
|
||||
- `mail.aliasvault.example.com` points to your server IP.
|
||||
- Emails to `user@aliasvault.example.com` will be handled by your AliasVault server.
|
||||
|
||||
This keeps the email configuration of your primary domain (`example.com`) completely separate, so you can keep receiving email on your normal email addresses and have unique AliasVault addresses too.
|
||||
|
||||
---
|
||||
|
||||
### Configuring AliasVault
|
||||
After setting up your DNS, you have to configure AliasVault to let it know which email domains it should support. Update the `docker-compose.yml` file:
|
||||
|
||||
```bash
|
||||
# ...
|
||||
environment:
|
||||
PRIVATE_EMAIL_DOMAINS: "yourdomain1.com,yourdomain2.com"
|
||||
# ...
|
||||
```
|
||||
|
||||
After updating the docker-compose.yml file, restart the Docker Compose stack:
|
||||
```bash
|
||||
# To apply new environment variables, containers must be recreated.
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Afterwards, when you login to the AliasVault web app, you should now be able to create an alias with your configured private domain and be able to receive email on it.
|
||||
|
||||
{: .note }
|
||||
Important: DNS propagation can take up to 24-48 hours. During this time, email delivery might be inconsistent.
|
||||
|
||||
If you encounter any issues, feel free to join the [Discord chat](https://discord.gg/DsaXMTEtpF) to get help from other users and maintainers.
|
||||
82
docs/installation/docker-compose/troubleshooting.md
Normal file
82
docs/installation/docker-compose/troubleshooting.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
layout: default
|
||||
title: Troubleshooting
|
||||
parent: Docker Compose
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
This guide covers common issues and troubleshooting steps for AliasVault encountered during installation, updates or general maintenance.
|
||||
|
||||
{: .toc }
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
---
|
||||
|
||||
## Check Docker Container Status
|
||||
For any issues you might encounter, the first step is to check the Docker containers health. This will give you a quick insight into the status of the individual containers which will help you identify the root cause of the issue.
|
||||
|
||||
1. Check the Docker container running status:
|
||||
```bash
|
||||
$ docker compose ps
|
||||
```
|
||||
|
||||
2. Check the Docker container logs
|
||||
```bash
|
||||
$ docker compose logs
|
||||
```
|
||||
|
||||
3. Try restarting the Docker container
|
||||
```bash
|
||||
$ docker compose restart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Check AliasVault Text Logs
|
||||
All AliasVault services log information and errors to text files. These files are located in the `logs` directory. You can check the logs of a specific service by running the following command:
|
||||
|
||||
```bash
|
||||
$ cat logs/[service-name].txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Issues
|
||||
Below are some common issues you might encounter and how to troubleshoot them.
|
||||
|
||||
### 1. No emails being received
|
||||
If you are not receiving emails on your aliases, check the following:
|
||||
- Verify DNS records are correctly configured
|
||||
- Ensure ports 25 and 587 are accessible
|
||||
- Check your server's firewall settings
|
||||
- Verify that your ISP/hosting provider allows SMTP traffic and does not block port 25
|
||||
|
||||
Refer to the [installation guide](./#3-email-server-setup) for more information on how to configure your DNS records and ports.
|
||||
|
||||
|
||||
### 2. Forgot AliasVault Admin Password
|
||||
If you have lost your admin password, you can reset it by running the `aliasvault reset-admin-password` option. This will generate a new random password and update the secret. After that it will restart the AliasVault containers to apply the changes.
|
||||
|
||||
1. SSH into the aliasvault container:
|
||||
```bash
|
||||
$ docker compose exec -it aliasvault /bin/bash
|
||||
```
|
||||
2. Run the reset-admin-password.sh script:
|
||||
```bash
|
||||
$ aliasvault reset-admin-password
|
||||
```
|
||||
3. Remember the password outputted by the step above. Then quit out of the SSH session (ctrl+C) and then restart the container:
|
||||
```bash
|
||||
$ docker compose restart
|
||||
```
|
||||
4. You can now login to the admin panel (/admin) with the new password.
|
||||
|
||||
---
|
||||
|
||||
## Other Issues
|
||||
If you encounter any other issues not mentioned here and need help, please join our Discord server or create an issue on the GitHub repository and we will be happy to help you out.
|
||||
|
||||
Find all contact information on the contact page of our website: [https://www.aliasvault.net/contact](https://www.aliasvault.net/contact)
|
||||
66
docs/installation/docker-compose/update/index.md
Normal file
66
docs/installation/docker-compose/update/index.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
layout: default
|
||||
title: Update
|
||||
parent: Docker Compose
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Updating AliasVault
|
||||
{: .no_toc }
|
||||
|
||||
<details open markdown="block">
|
||||
<summary>
|
||||
Table of contents
|
||||
</summary>
|
||||
{: .text-delta }
|
||||
1. TOC
|
||||
{:toc}
|
||||
</details>
|
||||
|
||||
## Before You Begin
|
||||
You can see the latest available version of AliasVault on [GitHub](https://github.com/aliasvault/aliasvault/releases).
|
||||
|
||||
{: .warning }
|
||||
Before updating, it's recommended to backup your database and other important data. You can do this by making
|
||||
a copy of the `database` and `certificates` directories.
|
||||
|
||||
## Standard Update Process
|
||||
For most version updates, you can use the standard update process. The container will automatically handle database migrations on startup:
|
||||
|
||||
1. Navigate to your AliasVault directory:
|
||||
```bash
|
||||
cd /path/to/your/aliasvault
|
||||
```
|
||||
|
||||
2. Pull the latest Docker image:
|
||||
```bash
|
||||
docker compose pull
|
||||
```
|
||||
|
||||
3. Restart the container with the new image:
|
||||
```bash
|
||||
docker compose down && docker compose up -d
|
||||
```
|
||||
|
||||
## Version-Specific Upgrade Guides
|
||||
While database migrations are automated, some releases may require manual file/config migration steps. Always check this page before updating to ensure you don't miss any required manual steps.
|
||||
|
||||
> Currently there are no version-specific manual migration steps required for the single container setup. Check back here when updating to ensure you haven't missed any new requirements.
|
||||
|
||||
## Additional Update Options
|
||||
|
||||
### Installing a Specific Version
|
||||
If you need to install a specific version instead of the latest, you can do the following. Note: downgrading to a previous version is not officially supported and may lead to unexpected issues, as database schema changes may prevent older versions from working correctly.
|
||||
|
||||
1. Edit your `docker-compose.yml` file
|
||||
2. Change the image tag from `:latest` to a specific version:
|
||||
```yaml
|
||||
# ...
|
||||
image: ghcr.io/aliasvault/aliasvault:0.23.0 # Replace with desired version
|
||||
# ... rest of configuration
|
||||
```
|
||||
3. Pull and restart:
|
||||
```bash
|
||||
docker compose pull
|
||||
docker compose down && docker compose up -d
|
||||
```
|
||||
@@ -1,8 +1,121 @@
|
||||
---
|
||||
layout: default
|
||||
title: Server Installation
|
||||
title: Self-host Install
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Server Installation
|
||||
The following guide will walk you through the steps to install AliasVault on your own server. Minimum experience with Docker and Linux is required.
|
||||
# Self-host Install
|
||||
|
||||
AliasVault can be self-hosted on your own servers using two different installation methods. Both use Docker, but they differ in how much is automated versus how much you manage yourself.
|
||||
|
||||
## Which Installation Method to Choose?
|
||||
|
||||
### 🚀 **Option 1: Install Script**
|
||||
The installer script is a **fully managed solution** that handles everything for you. Simply run it on a clean VM/LXC with Docker installed, and it will set up all required containers, configure SSL certificates and provide CLI helpers for easy updates and maintenance.
|
||||
|
||||
### 🛠️ **Option 2: Docker Compose**
|
||||
If you prefer manual setup and **have existing SSL infrastructure**, use the all-in-one Docker image via Docker Compose. It works with your existing SSL proxy (Traefik, HAProxy, Caddy, etc.) and gives you full control over the configuration. Note: because this install method does not include a CLI, future updates may require some manual migrations.
|
||||
|
||||
| | **Option 1: Install Script (multi-container)** | **Option 2: Docker Compose (single container)** |
|
||||
|--------------------------|---------------------------------------------------|-----------------------------------------------|
|
||||
| **Best for** | ☁️ VPS/VM/Proxmox, cloud hosts, DigitalOcean, AWS/Azure | 🏠 NAS/Synology/Unraid, Raspberry Pi, home servers |
|
||||
| **Internet accessible** | Direct internet access with ports 80/443 | Behind existing infrastructure |
|
||||
| **TLS/SSL** | Built-in reverse proxy + Let's Encrypt (automatic) | Bring your own (Traefik, Nginx, HAProxy, Caddy) |
|
||||
| **Containers** | Multiple containers (client, api, postgres, task runner, smtp, admin, reverse proxy) | Single bundled container (all-in-one) |
|
||||
| **Configuration** | Automatic docker-compose.yml setup | Standard Docker commands |
|
||||
| **Updates** | `install.sh` assisted updates & migrations | `docker pull` (manual); occasional manual migrations |
|
||||
| **Admin actions** | `install.sh` helpers for admin password reset | SSH into container for certain tasks (e.g. password reset) |
|
||||
| **Setup style** | Managed, opinionated, production-ready defaults | Fits into existing homelab/stack tools (Portainer compatible) |
|
||||
| **Build from source** | Supported | Pre-built container only |
|
||||
| **Choose if…** | You want auto SSL and a managed stack | You already have TLS and prefer manual control |
|
||||
| | [**Self-host via Install Script →**](./script){: .btn .btn-primary } | [**Self-host via Docker →**](./docker-compose){: .btn .btn-primary } |
|
||||
|
||||
### Quick Decision Guide
|
||||
|
||||
**Go with the Install Script if:**
|
||||
- ✅ You have a fresh VM or VPS dedicated to AliasVault
|
||||
- ✅ You want automatic SSL setup without hassle
|
||||
- ✅ You prefer managed updates and maintenance
|
||||
- ✅ You're new to Docker or want the simplest setup
|
||||
|
||||
**Go with Docker Compose if:**
|
||||
- ✅ You're already running other Docker containers on this host
|
||||
- ✅ You have existing SSL infrastructure (reverse proxy)
|
||||
- ✅ You want to integrate with your homelab tools (Portainer, etc.)
|
||||
- ✅ You prefer manual control over the configuration
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
<details style="margin-bottom: 10px;">
|
||||
<summary style="background-color: #4a5568; color: #ffffff; padding: 10px; border-radius: 5px; cursor: pointer;">What's the difference between multi-container and single container?</summary>
|
||||
<div style="background-color: #2d3748; color: #ffffff; padding: 15px; border-left: 3px solid #4299e1;" markdown="1">
|
||||
|
||||
| **Multi-container (Installer Script)** | **Single container (Manual Setup)** |
|
||||
|----------------------------------------|-------------------------------------|
|
||||
| Separates services into individual containers | All services bundled in one container |
|
||||
| Easier to scale individual components | Simpler to manage with Docker commands |
|
||||
| Uses docker-compose for orchestration | Lower resource overhead |
|
||||
| Better for production deployments | Better for home labs and personal use |
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details style="margin-bottom: 10px;">
|
||||
<summary style="background-color: #4a5568; color: #ffffff; padding: 10px; border-radius: 5px; cursor: pointer;">Do I need to handle SSL/TLS certificates myself?</summary>
|
||||
<div style="background-color: #2d3748; color: #ffffff; padding: 15px; border-left: 3px solid #4299e1;" markdown="1">
|
||||
|
||||
- **Installer Script**: No, it includes automatic Let's Encrypt certificates
|
||||
- **Manual Setup**: Yes, you need your own reverse proxy for HTTPS
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details style="margin-bottom: 10px;">
|
||||
<summary style="background-color: #4a5568; color: #ffffff; padding: 10px; border-radius: 5px; cursor: pointer;">How do updates work?</summary>
|
||||
<div style="background-color: #2d3748; color: #ffffff; padding: 15px; border-left: 3px solid #4299e1;" markdown="1">
|
||||
|
||||
| Method | Update Process |
|
||||
|--------|---------------|
|
||||
| **Installer Script** | Run `./install.sh update` for automated updates and migrations |
|
||||
| **Manual Setup** | Use `docker pull` to get the latest image; manual migrations may be required |
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details style="margin-bottom: 10px;">
|
||||
<summary style="background-color: #4a5568; color: #ffffff; padding: 10px; border-radius: 5px; cursor: pointer;">Can I migrate between installation methods?</summary>
|
||||
<div style="background-color: #2d3748; color: #ffffff; padding: 15px; border-left: 3px solid #4299e1;" markdown="1">
|
||||
|
||||
Yes! Both methods use the same bind mount directories (`/database`, `/certificates`, `/logs`, `/secrets`), making migration straightforward. Simply stop/uninstall via one method and follow the installation steps for the other - your data will be preserved.
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details style="margin-bottom: 10px;">
|
||||
<summary style="background-color: #4a5568; color: #ffffff; padding: 10px; border-radius: 5px; cursor: pointer;">What are the system requirements?</summary>
|
||||
<div style="background-color: #2d3748; color: #ffffff; padding: 15px; border-left: 3px solid #4299e1;" markdown="1">
|
||||
|
||||
**Minimum requirements:**
|
||||
- 64-bit Linux OS (Ubuntu or RHEL-based recommended)
|
||||
- 1 vCPU, 1GB RAM, 16GB disk
|
||||
- Docker CE (≥ 20.10) and Docker Compose (≥ 2.0)
|
||||
|
||||
**Network requirements:**
|
||||
- Ports 80 and 443 available
|
||||
- Optional: Ports 25 and 587 for private email domains
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details style="margin-bottom: 10px;">
|
||||
<summary style="background-color: #4a5568; color: #ffffff; padding: 10px; border-radius: 5px; cursor: pointer;">Can I build from source?</summary>
|
||||
<div style="background-color: #2d3748; color: #ffffff; padding: 15px; border-left: 3px solid #4299e1;" markdown="1">
|
||||
|
||||
- **Installer Script**: Yes, optional build from source is supported
|
||||
- **Manual Setup**: No, uses pre-built container images only
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
layout: default
|
||||
title: Build from Source
|
||||
parent: Advanced
|
||||
grand_parent: Install Script
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
@@ -18,13 +19,13 @@ Building from source requires more resources:
|
||||
## Steps
|
||||
1. Clone the repository
|
||||
```bash
|
||||
git clone https://github.com/aliasvault/aliasvault.git
|
||||
cd aliasvault
|
||||
$ git clone https://github.com/aliasvault/aliasvault.git
|
||||
$ cd aliasvault
|
||||
```
|
||||
2. Make the build script executable and run it. This will create the .env file, build the Docker images locally from source, and start the AliasVault containers. Follow the on-screen prompts to configure AliasVault.
|
||||
```bash
|
||||
chmod +x install.sh
|
||||
./install.sh build
|
||||
$ chmod +x install.sh
|
||||
$ ./install.sh build
|
||||
```
|
||||
> **Note:** The complete build process can take a while depending on your hardware (5-15 minutes).
|
||||
|
||||
25
docs/installation/script/advanced/database.md
Normal file
25
docs/installation/script/advanced/database.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
layout: default
|
||||
title: Database Operations
|
||||
parent: Advanced
|
||||
grand_parent: Install Script
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Database Operations
|
||||
This page explains how to import/export on the AliasVault server database via the `./install.sh` script.
|
||||
|
||||
## Database Export
|
||||
In order to backup the AliasVault server database (which includes all encrypted user vaults as well), you can use the `install.sh` script. This script will stop all services, export the database to a file, and then restart the services.
|
||||
|
||||
```bash
|
||||
$ ./install.sh db-export > backup.sql.gz
|
||||
```
|
||||
|
||||
## Database Import
|
||||
|
||||
To restore a previously exported database, you can use the `install.sh` script. This script will stop all services, drop the database, import the database from a file, and then restart the services.
|
||||
|
||||
```bash
|
||||
$ ./install.sh db-import < backup.sql.gz
|
||||
```
|
||||
9
docs/installation/script/advanced/index.md
Normal file
9
docs/installation/script/advanced/index.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
layout: default
|
||||
title: Advanced
|
||||
parent: Install Script
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Advanced Installation
|
||||
The following guides provide more advanced installation options for AliasVault. These options are not required for the basic installation, but may be useful for advanced users.
|
||||
@@ -1,30 +1,31 @@
|
||||
---
|
||||
layout: default
|
||||
title: Start/stop
|
||||
parent: Server Installation
|
||||
title: Stop/start
|
||||
parent: Advanced
|
||||
grand_parent: Install Script
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Starting and stopping AliasVault
|
||||
You can start and stop AliasVault easily by using the install script.
|
||||
# Stopping and starting AliasVault
|
||||
You can stop and start AliasVault easily by using the install script.
|
||||
|
||||
## Stop
|
||||
To stop AliasVault, run the install script with the `stop` option. This will stop all running AliasVault containers.
|
||||
|
||||
```bash
|
||||
./install.sh stop
|
||||
$ ./install.sh stop
|
||||
```
|
||||
|
||||
## Start
|
||||
To start AliasVault, run the install script with the `start` option. This will start all AliasVault containers.
|
||||
|
||||
```bash
|
||||
./install.sh start
|
||||
$ ./install.sh start
|
||||
```
|
||||
|
||||
## Restart
|
||||
To restart AliasVault, run the install script with the `restart` option. This will restart all AliasVault containers.
|
||||
|
||||
```bash
|
||||
./install.sh restart
|
||||
$ ./install.sh restart
|
||||
```
|
||||
@@ -1,13 +1,14 @@
|
||||
---
|
||||
layout: default
|
||||
title: Uninstall
|
||||
parent: Server Installation
|
||||
parent: Advanced
|
||||
grand_parent: Install Script
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Uninstall
|
||||
|
||||
To uninstall AliasVault, run the install script with the `uninstall` option. This will stop and remove the AliasVault containers, remove the Docker images, and delete the .env file.
|
||||
To uninstall AliasVault, run the install script with the `uninstall` option. This will stop and remove the AliasVault containers and remove any local AliasVault Docker images.
|
||||
|
||||
{: .note }
|
||||
This will not delete any data stored in the database. If you wish to delete all data, you should manually delete the `database` directory and the other directories created by AliasVault.
|
||||
@@ -15,5 +16,5 @@ This will not delete any data stored in the database. If you wish to delete all
|
||||
### Steps
|
||||
1. Run the install script with the `uninstall` option
|
||||
```bash
|
||||
./install.sh uninstall
|
||||
$ ./install.sh uninstall
|
||||
```
|
||||
73
docs/installation/script/index-bak.md
Normal file
73
docs/installation/script/index-bak.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
layout: default
|
||||
title: Installer Script (multi-container)
|
||||
parent: Self-host Installs
|
||||
nav_order: 1
|
||||
has_children: true
|
||||
---
|
||||
|
||||
# Installer Script (multi-container)
|
||||
|
||||
The installer script provides a managed, production-ready deployment of AliasVault using multiple Docker containers. This method includes automatic SSL certificates, built-in reverse proxy, and CLI-based management tools.
|
||||
|
||||
{: .important }
|
||||
> **Best for:** VPS, cloud hosting (AWS, Azure, DigitalOcean), dedicated servers with direct internet access
|
||||
|
||||
1. **New Installation?** Start with the [Installation Guide](./installation)
|
||||
2. **Upgrading?** Check the [Update Guide](./update/)
|
||||
3. **Need Help?** Visit [Troubleshooting](./troubleshooting) or join our [Discord](https://discord.gg/DsaXMTEtpF)
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; margin: 20px 0;">
|
||||
|
||||
<div style="background: #4a5568; border: 1px solid #d1d5da; border-radius: 8px; padding: 20px;">
|
||||
<h3 style="margin-top: 0;">🚀 Getting Started</h3>
|
||||
<p>Initial installation and configuration</p>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li>📖 <a href="./installation">Installation Guide</a></li>
|
||||
<li>🔒 <a href="./installation#tls-ssl-configuration">SSL/TLS Setup</a></li>
|
||||
<li>📧 <a href="./installation#email-server-setup">Email Configuration</a></li>
|
||||
<li>👤 <a href="./installation#configure-account-registration">Registration Settings</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background: #4a5568; border: 1px solid #d1d5da; border-radius: 8px; padding: 20px;">
|
||||
<h3 style="margin-top: 0;">🔄 Updates & Maintenance</h3>
|
||||
<p>Keep your instance up-to-date</p>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li>📖 <a href="./update/">Update Guide</a></li>
|
||||
<li>💾 <a href="./advanced/database">Database Backup</a></li>
|
||||
<li>🗑️ <a href="./advanced/uninstall">Uninstall Guide</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background: #4a5568; border: 1px solid #d1d5da; border-radius: 8px; padding: 20px;">
|
||||
<h3 style="margin-top: 0;">❓ Help & Support</h3>
|
||||
<p>Troubleshooting and assistance</p>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<li>🐛 <a href="./troubleshooting">Troubleshooting Guide</a></li>
|
||||
<li>💬 <a href="https://discord.gg/DsaXMTEtpF">Discord Community</a></li>
|
||||
<li>📝 <a href="https://github.com/aliasvault/aliasvault/issues">Report Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The installer script deploys AliasVault as a multi-container application:
|
||||
|
||||
| Container | Purpose |
|
||||
|-----------|---------|
|
||||
| **reverse-proxy** | Nginx reverse proxy with SSL termination |
|
||||
| **client** | Web interface (Blazor WebAssembly) |
|
||||
| **api** | REST API backend |
|
||||
| **admin** | Admin portal |
|
||||
| **postgres** | PostgreSQL database |
|
||||
| **smtp** | Email server for aliases |
|
||||
| **task-runner** | Background jobs and maintenance |
|
||||
|
||||
All containers are managed via `./install.sh` (which uses `docker compose` in the background) and configured through a centralized `.env` file.
|
||||
@@ -1,29 +1,27 @@
|
||||
---
|
||||
layout: default
|
||||
title: Basic Install
|
||||
parent: Server Installation
|
||||
title: Install Script
|
||||
parent: Self-host Install
|
||||
redirect_from:
|
||||
- /installation/install
|
||||
- /installation/install.html
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Basic Install
|
||||
The following guide will walk you through the steps to install AliasVault on your own server. Minimum experience with Docker and Linux is required.
|
||||
# Self-host using Install Script (multi-container)
|
||||
The following guide will walk you through the steps to install AliasVault on your own server using the AliasVault installer script: `install.sh`. This script will pull pre-built Docker Images and do all the configuration for you while using `docker compose` in the background.
|
||||
|
||||
{: .toc }
|
||||
* TOC
|
||||
{:toc}
|
||||
{: .important-title }
|
||||
> Requirements:
|
||||
> - 64-bit Linux VM with root access (Ubuntu or RHEL-based recommended)
|
||||
> - Minimum: 1 vCPU, 1GB RAM, 16GB disk
|
||||
> - Docker (CE ≥ 20.10) and Docker Compose (≥ 2.0)
|
||||
> → Installation guide: [Docker Docs](https://docs.docker.com/engine/install/)
|
||||
> - Able to forward ports 80, 443 (with optional 25/587 for private email domains)
|
||||
|
||||
---
|
||||
|
||||
## 1. Basic Installation
|
||||
To get AliasVault up and running quickly, run the install script to pull pre-built Docker images. The install script will also configure the .env file and start the AliasVault containers. You can get up and running in less than 5 minutes.
|
||||
|
||||
### Hardware requirements
|
||||
- 64-bit Linux VM with root access (Ubuntu or RHEL-based recommended)
|
||||
- Minimum: 1 vCPU, 1GB RAM, 16GB disk
|
||||
- Docker (CE ≥ 20.10) and Docker Compose (≥ 2.0)
|
||||
→ Installation guide: [Docker Docs](https://docs.docker.com/engine/install/)
|
||||
|
||||
### Installation steps
|
||||
1. Download the install script to a directory of your choice. All AliasVault files and directories will be created in this directory.
|
||||
```bash
|
||||
# Download the install script
|
||||
@@ -45,14 +43,14 @@ chmod +x install.sh
|
||||
- Client: `https://localhost`
|
||||
- Admin: `https://localhost/admin`
|
||||
|
||||
> Note: if you do not wish to run the `install.sh` wizard but want to use Docker commands directly, follow the [manual setup guide](advanced/manual-setup.md). We do however encourage the use of `install.sh` as it will guide you through all configuration steps and allow you to easily update your AliasVault server later.
|
||||
> Note: if you do not wish to run the `install.sh` wizard but prefer to use Docker commands directly, follow the [manual setup guide](../manual) instead.
|
||||
|
||||
---
|
||||
|
||||
## 2. SSL configuration
|
||||
The default installation will create a self-signed SSL certificate and configure Nginx to use it.
|
||||
## 2. TLS/SSL configuration
|
||||
The default installation will create a self-signed TLS/SSL certificate and configure Nginx to use it. This is sufficient for local deployments using only the web-app, however the mobile apps (iOS and Android) require a valid (external) SSL certificate to be able to connect.
|
||||
|
||||
You can however also use Let's Encrypt to generate valid SSL certificates and configure Nginx to use it. In order to make this work you will need the following:
|
||||
To generate a valid external TLS/SSL certificate for AliasVault, you can use Let's Encrypt via a built-in helper tool. In order to make this work you will need the following:
|
||||
|
||||
- A public IPv4 address assigned to your server
|
||||
- Port 80 and 443 on your server must be open and accessible from the internet
|
||||
@@ -66,29 +64,28 @@ You can however also use Let's Encrypt to generate valid SSL certificates and co
|
||||
```
|
||||
2. Follow the prompts to configure Let's Encrypt.
|
||||
|
||||
### Reverting to self-signed SSL
|
||||
If at any point you would like to revert to the self-signed SSL certificate, run the install script again with the `configure-ssl` option
|
||||
### Reverting to self-signed TLS/SSL
|
||||
If at any point you would like to revert to the self-signed TLS/SSL certificate, run the install script again with the `configure-ssl` option
|
||||
and then in the prompt choose option 2.
|
||||
|
||||
---
|
||||
|
||||
## 3. Email Server Setup
|
||||
|
||||
AliasVault includes a built-in email server that allows you to generate email aliases on-the-fly for every website you use, and receive the and read the emails straight in AliasVault.
|
||||
AliasVault includes a built-in email server that allows you to generate email aliases on-the-fly for every website you use, and receive + read the emails straight in AliasVault.
|
||||
|
||||
> **Note:**
|
||||
> If you skip this step, AliasVault will default to use public email domains offered by SpamOK. While this still works for creating aliases, it has privacy limitations. For complete privacy and control, we recommend setting up your own domain.
|
||||
> [Learn more about the differences between private and public email domains](../misc/private-vs-public-email.md).
|
||||
{: .note }
|
||||
If you skip this step, AliasVault will default to use public email domains offered by SpamOK. While this still works for creating aliases, it has privacy limitations. For complete privacy and control, we recommend setting up your own domain. [Learn more about the differences between private and public email domains](../misc/private-vs-public-email.md).
|
||||
|
||||
---
|
||||
|
||||
### Requirements
|
||||
- A **public IPv4 address** with ports 25 and 587 pointing to your AliasVault server
|
||||
- Open ports **25** and **587** on your server firewall for email SMTP traffic.
|
||||
- A **public IPv4 address** with ports 25 and 587 forwarded to your AliasVault server
|
||||
- Open ports **25** and **587** on your server firewall for email SMTP traffic (*NOTE: some residential IP's block this, check with your ISP*).
|
||||
|
||||
#### Verifying Port Access
|
||||
|
||||
While the AliasVault docker containers are running, use `telnet` to confirm your public IP allows access to the ports:
|
||||
While the AliasVault docker container is running, use `telnet` to confirm your public IP allows access to the ports:
|
||||
|
||||
```bash
|
||||
# Test standard SMTP port
|
||||
@@ -1,7 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
title: Troubleshooting
|
||||
parent: Server Installation
|
||||
parent: Install Script
|
||||
redirect_from:
|
||||
- /installation/troubleshooting
|
||||
- /installation/troubleshooting.html
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
@@ -42,10 +45,10 @@ docker compose restart [container-name-here]
|
||||
---
|
||||
|
||||
## Check AliasVault Text Logs
|
||||
All AliasVault services log information and errors to text files. These files are located in the `logs` directory. You can check the logs of a specific container by running the following command:
|
||||
All AliasVault services log information and errors to text files. These files are located in the `logs` directory. You can check the logs of a specific service by running the following command:
|
||||
|
||||
```bash
|
||||
cat logs/[container-name-here].log
|
||||
cat logs/[service-name-here].txt
|
||||
```
|
||||
|
||||
---
|
||||
@@ -70,13 +73,13 @@ docker compose ps
|
||||
docker compose logs postgres
|
||||
```
|
||||
|
||||
### 2. SSL Certificate Issues
|
||||
### 2. TLS/SSL Certificate Issues
|
||||
|
||||
**Symptoms:**
|
||||
- Browser shows SSL errors
|
||||
- Browser shows TLS/SSL errors
|
||||
|
||||
**Steps:**
|
||||
1. Check the certbot container logs if SSL certificates are being correctly renewed:
|
||||
1. Check the certbot container logs if TLS/SSL certificates are being correctly renewed:
|
||||
```bash
|
||||
docker compose logs certbot
|
||||
```
|
||||
@@ -86,7 +89,7 @@ docker compose logs certbot
|
||||
docker compose logs reverse-proxy
|
||||
```
|
||||
|
||||
3. In case the SSL certificates are being correctly renewed, but the browser still shows SSL errors, try to restart AliasVault manually in order to force the NGINX container to reload the SSL certificates:
|
||||
3. In case the SSL certificates are being correctly renewed, but the browser still shows TLS/SSL errors, try to restart AliasVault manually in order to force the NGINX container to reload the TLS/SSL certificates:
|
||||
```bash
|
||||
./install.sh restart
|
||||
```
|
||||
@@ -98,7 +101,7 @@ If you are not receiving emails on your aliases, check the following:
|
||||
- Check your server's firewall settings
|
||||
- Verify that your ISP/hosting provider allows SMTP traffic
|
||||
|
||||
Refer to the [installation guide](./install.md) for more information on how to configure your DNS records and ports.
|
||||
Refer to the [installation guide](./#3-email-server-setup) for more information on how to configure your DNS records and ports.
|
||||
|
||||
|
||||
### 4. Forgot AliasVault Admin Password
|
||||
@@ -113,4 +116,4 @@ If you have lost your admin password, you can reset it by running the install sc
|
||||
## Other Issues
|
||||
If you encounter any other issues not mentioned here and need help, please join our Discord server or create an issue on the GitHub repository and we will be happy to help you out.
|
||||
|
||||
Find all contact information on the contact page of our website: [https://aliasvault.net/contact](https://aliasvault.net/contact)
|
||||
Find all contact information on the contact page of our website: [https://www.aliasvault.net/contact](https://www.aliasvault.net/contact)
|
||||
@@ -1,7 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
title: Update
|
||||
parent: Server Installation
|
||||
parent: Install Script
|
||||
redirect_from:
|
||||
- /installation/update
|
||||
- /installation/update.html
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
@@ -36,6 +39,7 @@ For most version updates, you can use the standard update process:
|
||||
## Version-Specific Upgrade Guides
|
||||
Upgrading from certain earlier versions require additional steps during upgrade. If you are upgrading from an older version, please check the relevant articles below if it applies to your server:
|
||||
|
||||
- [Updating to 0.23.0](v0.23.0.html) - Update Docker Image locations due to new AliasVault GitHub organization
|
||||
- [Updating to 0.22.0](v0.22.0.html) - Move secrets from .env to file based secrets
|
||||
|
||||
## Additional Update Options
|
||||
@@ -56,5 +60,5 @@ To install a specific version and skip the automatic version checks, run the ins
|
||||
./install.sh install <version>
|
||||
|
||||
# Example:
|
||||
./install.sh install 0.7.0
|
||||
./install.sh install 0.22.0
|
||||
```
|
||||
@@ -2,8 +2,11 @@
|
||||
layout: default
|
||||
title: Update to v0.22.0
|
||||
parent: Update
|
||||
grand_parent: Server Installation
|
||||
nav_order: 1
|
||||
grand_parent: Install Script
|
||||
redirect_from:
|
||||
- /installation/update/v0.22.0
|
||||
- /installation/update/v0.22.0.html
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Updating to v0.22.0
|
||||
107
docs/installation/script/update/v0.23.0.md
Normal file
107
docs/installation/script/update/v0.23.0.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
layout: default
|
||||
title: Update to v0.23.0
|
||||
parent: Update
|
||||
grand_parent: Install Script
|
||||
redirect_from:
|
||||
- /installation/update/v0.23.0
|
||||
- /installation/update/v0.23.0.html
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Updating to v0.23.0
|
||||
{: .no_toc }
|
||||
|
||||
Since v0.23.0, AliasVault has moved from `lanedirt/aliasvault` to the new `aliasvault/aliasvault` GitHub organization, and Docker image names have been simplified.
|
||||
|
||||
## Update Methods
|
||||
|
||||
### 1. Installed via install.sh
|
||||
|
||||
If you have installed AliasVault using the official `install.sh` method, you don't need to do anything. Running the built-in `install.sh update` command will take care of all necessary changes for you.
|
||||
|
||||
```bash
|
||||
./install.sh update
|
||||
```
|
||||
|
||||
### 2. Manually installed
|
||||
|
||||
If you have manually installed AliasVault via a custom `docker-compose.yml` file or other Docker management interface such as Portainer, you need to update your Docker image references.
|
||||
|
||||
#### Docker Image Name Changes
|
||||
|
||||
Update all Docker image references in your `docker-compose.yml` file according to this mapping:
|
||||
|
||||
| Old Image Name | New Image Name |
|
||||
|----------------|----------------|
|
||||
| ghcr.io/lanedirt/aliasvault-postgres | ghcr.io/aliasvault/postgres |
|
||||
| ghcr.io/lanedirt/aliasvault-reverse-proxy | ghcr.io/aliasvault/reverse-proxy |
|
||||
| ghcr.io/lanedirt/aliasvault-api | ghcr.io/aliasvault/api |
|
||||
| ghcr.io/lanedirt/aliasvault-client | ghcr.io/aliasvault/client |
|
||||
| ghcr.io/lanedirt/aliasvault-admin | ghcr.io/aliasvault/admin |
|
||||
| ghcr.io/lanedirt/aliasvault-smtp | ghcr.io/aliasvault/smtp |
|
||||
| ghcr.io/lanedirt/aliasvault-task-runner | ghcr.io/aliasvault/task-runner |
|
||||
|
||||
#### Example docker-compose.yml Update
|
||||
|
||||
**Before (v0.22.0 and earlier):**
|
||||
```yaml
|
||||
services:
|
||||
postgres:
|
||||
image: ghcr.io/lanedirt/aliasvault-postgres:0.22.0
|
||||
|
||||
reverse-proxy:
|
||||
image: ghcr.io/lanedirt/aliasvault-reverse-proxy:0.22.0
|
||||
|
||||
api:
|
||||
image: ghcr.io/lanedirt/aliasvault-api:0.22.0
|
||||
|
||||
client:
|
||||
image: ghcr.io/lanedirt/aliasvault-client:0.22.0
|
||||
|
||||
admin:
|
||||
image: ghcr.io/lanedirt/aliasvault-admin:0.22.0
|
||||
|
||||
smtp:
|
||||
image: ghcr.io/lanedirt/aliasvault-smtp:0.22.0
|
||||
|
||||
task-runner:
|
||||
image: ghcr.io/lanedirt/aliasvault-task-runner:0.22.0
|
||||
```
|
||||
|
||||
**After (v0.23.0 and later):**
|
||||
```yaml
|
||||
services:
|
||||
postgres:
|
||||
image: ghcr.io/aliasvault/postgres:0.23.0
|
||||
|
||||
reverse-proxy:
|
||||
image: ghcr.io/aliasvault/reverse-proxy:0.23.0
|
||||
|
||||
api:
|
||||
image: ghcr.io/aliasvault/api:0.23.0
|
||||
|
||||
client:
|
||||
image: ghcr.io/aliasvault/client:0.23.0
|
||||
|
||||
admin:
|
||||
image: ghcr.io/aliasvault/admin:0.23.0
|
||||
|
||||
smtp:
|
||||
image: ghcr.io/aliasvault/smtp:0.23.0
|
||||
|
||||
task-runner:
|
||||
image: ghcr.io/aliasvault/task-runner:0.23.0
|
||||
```
|
||||
|
||||
#### Update and restart
|
||||
|
||||
After updating your `docker-compose.yml`, pull the latest images and restart your containers:
|
||||
|
||||
```bash
|
||||
docker-compose pull
|
||||
docker-compose down
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
If you encounter any issues during the upgrade, please join the AliasVault Discord, create an issue on GitHub or contact us by email.
|
||||
@@ -58,8 +58,7 @@ gunzip < aliasvault.sql.gz | docker compose exec -iT postgres psql -U aliasvault
|
||||
```
|
||||
|
||||
### Change master password
|
||||
By default during initial installation the PostgreSQL master password is set to a random string that is
|
||||
stored in the `.env` file with the `POSTGRES_PASSWORD` variable.
|
||||
By default during initial installation the PostgreSQL master password is set to a random string that is stored in the `./secrets/postgres_password` secret file.
|
||||
|
||||
If you wish to change the master password, you can do so by running the following command:
|
||||
|
||||
@@ -74,7 +73,7 @@ If you wish to change the master password, you can do so by running the followin
|
||||
```
|
||||
4. Press Enter to confirm the changes.
|
||||
5. Exit the PostgreSQL shell by running `\q`.
|
||||
6. Manually update the `.env` file variable `POSTGRES_PASSWORD` with the new password.
|
||||
6. Manually update the `./secrets/postgres_password` secret file contents with the new password.
|
||||
7. Restart the AliasVault containers by running the following command:
|
||||
```bash
|
||||
docker compose restart
|
||||
|
||||
65
docs/mobile-apps/android/ssl-setup.md
Normal file
65
docs/mobile-apps/android/ssl-setup.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
layout: page
|
||||
title: Self-Signed SSL Setup
|
||||
parent: Android App
|
||||
grand_parent: Mobile Apps
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# Self-Signed SSL Certificate Setup for Android
|
||||
|
||||
By default, the AliasVault Android app only supports connecting to servers with a valid SSL certificate from a trusted external authority. If you want to use your own self-signed certificate, you must manually install and trust the certificate on your Android device by following these steps.
|
||||
|
||||
## Server Setup
|
||||
|
||||
### Standard Installation
|
||||
Configure your hostname and restart AliasVault:
|
||||
```bash
|
||||
./install.sh configure-hostname
|
||||
./install.sh restart
|
||||
```
|
||||
|
||||
### All-in-One Docker
|
||||
Update your `docker-compose.yml`:
|
||||
```yaml
|
||||
environment:
|
||||
HOSTNAME: "192.168.3.2" # Your server IP/hostname
|
||||
```
|
||||
Then restart: `docker compose down && docker compose up -d`
|
||||
|
||||
## Step 1: Get the Certificate
|
||||
|
||||
### Option A: From Browser
|
||||
1. Open Chrome, go to your AliasVault instance (e.g., `https://192.168.3.2`)
|
||||
2. Click the padlock icon → inspect certificate
|
||||
3. Export the certificate and send it to your phone
|
||||
|
||||
### Option B: From Server
|
||||
Copy from your AliasVault installation directory:
|
||||
```bash
|
||||
cp [aliasvault-install-dir]/certificates/ssl/cert.pem ~/aliasvault.crt
|
||||
```
|
||||
Transfer to your Android device.
|
||||
|
||||
## Step 2: Install Certificate (Android 10+)
|
||||
|
||||
1. **Open Settings** → search for "Certificate"
|
||||
2. **Tap "Install a certificate"** → **"CA certificate"**
|
||||
3. **Browse to Downloads** → select your certificate file
|
||||
4. **Enter your PIN/password** when prompted
|
||||
5. **Name it "AliasVault"** and tap **OK**
|
||||
|
||||
## Step 3: Configure AliasVault App
|
||||
|
||||
1. **Open the AliasVault app**
|
||||
2. **Go to Settings** → **Server Configuration**
|
||||
3. **Enter your server URL**: `https://192.168.3.2/api` (use your configured hostname)
|
||||
4. **Test connection** - should work without SSL errors
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Certificate not trusted**: Verify it's installed under Settings → Security → Trusted credentials → User tab
|
||||
|
||||
**App can't connect**: Ensure the hostname in the app matches your server configuration exactly
|
||||
|
||||
**Installation fails**: Make sure you have a screen lock set up on your device
|
||||
71
docs/mobile-apps/ios/ssl-setup.md
Normal file
71
docs/mobile-apps/ios/ssl-setup.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
layout: page
|
||||
title: Self-Signed SSL Setup
|
||||
parent: iOS App
|
||||
grand_parent: Mobile Apps
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# Self-Signed SSL Certificate Setup for iOS
|
||||
|
||||
By default, the AliasVault iOS app only supports connecting to servers with a valid SSL certificate from a trusted external authority. If you want to use your own self-signed certificate, you must manually install and trust the certificate on your iOS device by following these steps.
|
||||
|
||||
## Server Setup
|
||||
|
||||
### Standard Installation
|
||||
Configure your hostname and restart AliasVault:
|
||||
```bash
|
||||
./install.sh configure-hostname
|
||||
./install.sh restart
|
||||
```
|
||||
|
||||
### All-in-One Docker
|
||||
Update your `docker-compose.yml`:
|
||||
```yaml
|
||||
environment:
|
||||
HOSTNAME: "192.168.3.2" # Your server IP/hostname
|
||||
```
|
||||
Then restart: `docker compose down && docker compose up -d`
|
||||
|
||||
## Step 1: Get the Certificate
|
||||
|
||||
### Option A: From Browser
|
||||
1. Open Chrome on your computer, go to your AliasVault instance (e.g., `https://192.168.3.2`)
|
||||
2. Click the padlock icon → inspect certificate
|
||||
3. Export the certificate and send it to your device (e.g. via email)
|
||||
|
||||
### Option B: From Server
|
||||
Copy from your AliasVault installation directory:
|
||||
```bash
|
||||
cp [aliasvault-install-dir]/certificates/ssl/cert.pem ~/aliasvault.crt
|
||||
```
|
||||
|
||||
## Step 2: Install Certificate Profile
|
||||
|
||||
1. Open the certificate on your iOS device
|
||||
1. **Tap "Install"** in the top right corner
|
||||
2. **Enter your passcode** when prompted
|
||||
3. **Tap "Install"** again to confirm the warning
|
||||
4. **Tap "Done"** when complete
|
||||
|
||||
## Step 3: Enable Certificate Trust (Critical!)
|
||||
|
||||
1. **Settings** → **General** → **About** → **Certificate Trust Settings**
|
||||
2. **Find your certificate** (listed by hostname like "192.168.3.2")
|
||||
3. **Toggle the switch to ON**
|
||||
4. **Tap "Continue"** in the warning
|
||||
|
||||
## Step 4: Configure AliasVault App
|
||||
|
||||
1. **Open the AliasVault app**
|
||||
2. **Go to Settings** → **Server Configuration**
|
||||
3. **Enter your server URL**: `https://192.168.3.2/api` (use your configured hostname)
|
||||
4. **Test connection** - should work without SSL errors
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**SSL errors**: Ensure you completed Step 3 (Certificate Trust) - this is the most commonly missed step
|
||||
|
||||
**Certificate Trust Settings not visible**: You must install a certificate profile first
|
||||
|
||||
**App can't connect**: Verify the hostname in the app matches your server configuration exactly
|
||||
133
install.sh
133
install.sh
@@ -871,9 +871,9 @@ main() {
|
||||
if [ $? -eq 0 ]; then
|
||||
printf "${CYAN}> Restarting admin container...${NC}\n"
|
||||
if [ "$VERBOSE" = true ]; then
|
||||
$(get_docker_compose_command) up -d --force-recreate admin
|
||||
eval "$(get_docker_compose_command) up -d --force-recreate admin"
|
||||
else
|
||||
$(get_docker_compose_command) up -d --force-recreate admin > /dev/null 2>&1
|
||||
eval "$(get_docker_compose_command) up -d --force-recreate admin" > /dev/null 2>&1
|
||||
fi
|
||||
print_password_reset_message
|
||||
fi
|
||||
@@ -1142,7 +1142,7 @@ create_env_file() {
|
||||
populate_hostname() {
|
||||
if ! grep -q "^HOSTNAME=" "$ENV_FILE" || [ -z "$(grep "^HOSTNAME=" "$ENV_FILE" | cut -d '=' -f2)" ]; then
|
||||
while true; do
|
||||
read -p "Enter the (public) hostname where this AliasVault server can be accessed from (e.g. aliasvault.net): " USER_HOSTNAME
|
||||
read -p "Enter the hostname where this AliasVault server can be accessed (e.g. aliasvault.example.com): " USER_HOSTNAME
|
||||
if [ -n "$USER_HOSTNAME" ]; then
|
||||
HOSTNAME="$USER_HOSTNAME"
|
||||
break
|
||||
@@ -1583,13 +1583,13 @@ recreate_docker_containers() {
|
||||
if [ "$VERBOSE" = true ]; then
|
||||
printf "${CYAN}ℹ (Re)creating Docker containers...${NC}\n"
|
||||
printf "\b${NC}\n"
|
||||
if ! $(get_docker_compose_command) up -d --force-recreate; then
|
||||
if ! eval "$(get_docker_compose_command) up -d --force-recreate"; then
|
||||
log_error "Failed to recreate Docker containers"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
(
|
||||
$(get_docker_compose_command) up -d --force-recreate > /tmp/docker_recreate.log 2>&1 &
|
||||
eval "$(get_docker_compose_command) up -d --force-recreate" > /tmp/docker_recreate.log 2>&1 &
|
||||
RECREATE_PID=$!
|
||||
show_spinner $RECREATE_PID "Recreating Docker containers "
|
||||
wait $RECREATE_PID
|
||||
@@ -1793,13 +1793,13 @@ handle_build() {
|
||||
if [ "$VERBOSE" = true ]; then
|
||||
printf "${CYAN}ℹ Building Docker Compose stack...${NC}\n"
|
||||
printf "\b${NC}\n"
|
||||
if ! $(get_docker_compose_command) build; then
|
||||
if ! eval "$(get_docker_compose_command) build"; then
|
||||
log_error "Failed to build Docker Compose stack"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
(
|
||||
$(get_docker_compose_command) build > install_compose_build_output.log 2>&1 &
|
||||
eval "$(get_docker_compose_command) build" > install_compose_build_output.log 2>&1 &
|
||||
BUILD_PID=$!
|
||||
show_spinner $BUILD_PID "Building Docker Compose stack "
|
||||
wait $BUILD_PID
|
||||
@@ -1936,7 +1936,7 @@ handle_ssl_configuration() {
|
||||
printf "Hostname: ${CYAN}${CURRENT_HOSTNAME}${NC} (change via: ./install.sh configure-hostname)\n"
|
||||
printf "\n"
|
||||
printf "Choose an option:\n"
|
||||
printf "1) Use Let's Encrypt certificate (recommended)\n"
|
||||
printf "1) Use Let's Encrypt certificate (recommended for public domains)\n"
|
||||
printf "2) Use self-signed certificate\n"
|
||||
printf "3) Cancel\n"
|
||||
printf "\n"
|
||||
@@ -2192,11 +2192,11 @@ configure_letsencrypt() {
|
||||
|
||||
# Restart only the reverse proxy with new configuration so it loads the new certificate
|
||||
printf "${CYAN}> Restarting reverse proxy with Let's Encrypt configuration...${NC}\n"
|
||||
$(get_docker_compose_command) up -d reverse-proxy --force-recreate
|
||||
eval "$(get_docker_compose_command) up -d reverse-proxy --force-recreate"
|
||||
|
||||
# Starting certbot container to renew certificates automatically
|
||||
printf "${CYAN}> Starting new certbot container to renew certificates automatically...${NC}\n"
|
||||
$(get_docker_compose_command) up -d certbot
|
||||
eval "$(get_docker_compose_command) up -d certbot"
|
||||
|
||||
# Print success message
|
||||
printf "\n"
|
||||
@@ -2210,17 +2210,27 @@ generate_self_signed_cert() {
|
||||
# Disable Let's Encrypt
|
||||
update_env_var "LETSENCRYPT_ENABLED" "false"
|
||||
|
||||
# Get current hostname from .env
|
||||
HOSTNAME_VALUE=$(grep "^HOSTNAME=" "$ENV_FILE" | cut -d '=' -f2)
|
||||
|
||||
if [ -n "$HOSTNAME_VALUE" ] && [ "$HOSTNAME_VALUE" != "localhost" ]; then
|
||||
printf "${CYAN}> Using configured hostname: ${HOSTNAME_VALUE}${NC}\n"
|
||||
printf "${CYAN}> The certificate will include:${NC}\n"
|
||||
printf " ${GREEN}Primary CN:${NC} ${HOSTNAME_VALUE}\n"
|
||||
printf " ${GREEN}Alternative Names:${NC} localhost, 127.0.0.1\n\n"
|
||||
fi
|
||||
|
||||
# Stop existing containers
|
||||
printf "${CYAN}> Stopping existing containers...${NC}\n"
|
||||
docker compose down
|
||||
|
||||
# Remove existing certificates
|
||||
rm -f ./certificates/ssl/cert.pem ./certificates/ssl/key.pem
|
||||
# Remove existing certificates and hostname marker
|
||||
rm -f ./certificates/ssl/cert.pem ./certificates/ssl/key.pem ./certificates/ssl/.hostname_marker
|
||||
|
||||
# Remove Let's Encrypt directories
|
||||
rm -rf ./certificates/letsencrypt
|
||||
|
||||
# Start containers (which will generate new self-signed certs)
|
||||
# Start containers (which will generate new self-signed cert with hostname)
|
||||
printf "${CYAN}> Restarting services...${NC}\n"
|
||||
docker compose up -d
|
||||
|
||||
@@ -2232,7 +2242,7 @@ generate_self_signed_cert() {
|
||||
# New functions to handle container lifecycle:
|
||||
handle_start() {
|
||||
printf "${CYAN}> Starting AliasVault containers...${NC}\n"
|
||||
$(get_docker_compose_command) up -d
|
||||
eval "$(get_docker_compose_command) up -d"
|
||||
printf "${GREEN}> AliasVault containers started successfully.${NC}\n"
|
||||
}
|
||||
|
||||
@@ -2243,14 +2253,14 @@ handle_stop() {
|
||||
exit 0
|
||||
fi
|
||||
|
||||
$(get_docker_compose_command) down
|
||||
eval "$(get_docker_compose_command) down"
|
||||
printf "${GREEN}> AliasVault containers stopped successfully.${NC}\n"
|
||||
}
|
||||
|
||||
handle_restart() {
|
||||
printf "\n${CYAN}> Restarting AliasVault containers...${NC}\n"
|
||||
$(get_docker_compose_command) down
|
||||
$(get_docker_compose_command) up -d
|
||||
eval "$(get_docker_compose_command) down"
|
||||
eval "$(get_docker_compose_command) up -d"
|
||||
printf "${GREEN}> AliasVault containers restarted successfully.${NC}\n"
|
||||
}
|
||||
|
||||
@@ -2727,9 +2737,10 @@ handle_db_export() {
|
||||
printf "Options:\n" >&2
|
||||
printf " --dev Export from development database\n" >&2
|
||||
printf "\n" >&2
|
||||
printf "Example:\n" >&2
|
||||
printf "Examples:\n" >&2
|
||||
printf " ./install.sh db-export > my_backup_$(date +%Y%m%d).sql.gz\n" >&2
|
||||
printf " ./install.sh db-export --dev > my_dev_backup_$(date +%Y%m%d).sql.gz\n" >&2
|
||||
printf "\n" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -2791,7 +2802,15 @@ handle_db_import() {
|
||||
|
||||
# Check if we're getting input from a pipe
|
||||
if [ -t 0 ]; then
|
||||
printf "Usage: ./install.sh db-import [--dev] < backup.sql.gz\n"
|
||||
printf "Usage: ./install.sh db-import [--dev] < backup_file\n"
|
||||
printf "\n"
|
||||
printf "Options:\n"
|
||||
printf " --dev Import to development database\n"
|
||||
printf "\n"
|
||||
printf "Examples:\n"
|
||||
printf " ./install.sh db-import < backup.sql.gz # Import gzipped backup\n"
|
||||
printf " ./install.sh db-import < backup.sql # Import plain SQL backup\n"
|
||||
printf " ./install.sh db-import --dev < backup.sql # Import to dev database\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -2840,15 +2859,25 @@ handle_db_import() {
|
||||
fi
|
||||
printf "database...${NC}\n"
|
||||
|
||||
# Create a temporary file to verify the gzip input
|
||||
# Create a temporary file to store the input
|
||||
temp_file=$(mktemp)
|
||||
cat <&3 > "$temp_file" # Read from fd 3 instead of stdin
|
||||
exec 3<&- # Close fd 3
|
||||
|
||||
if ! gzip -t "$temp_file" 2>/dev/null; then
|
||||
printf "${RED}Error: Input is not a valid gzip file${NC}\n"
|
||||
rm "$temp_file"
|
||||
exit 1
|
||||
# Detect if the file is gzipped or plain SQL
|
||||
is_gzipped=false
|
||||
if gzip -t "$temp_file" 2>/dev/null; then
|
||||
is_gzipped=true
|
||||
printf "${CYAN}> Detected gzipped SQL backup${NC}\n"
|
||||
else
|
||||
# Check if it looks like SQL (basic validation)
|
||||
if head -n 10 "$temp_file" | grep -qE '(^--|^CREATE |^INSERT |^ALTER |^DROP |^\\\\connect|^SET |^COMMENT |^GRANT |^REVOKE )'; then
|
||||
printf "${CYAN}> Detected plain SQL backup${NC}\n"
|
||||
else
|
||||
printf "${RED}Error: Input is neither a valid gzip file nor a SQL file${NC}\n"
|
||||
rm "$temp_file"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DEV_DB" = true ]; then
|
||||
@@ -2856,24 +2885,40 @@ handle_db_import() {
|
||||
docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'aliasvault' AND pid <> pg_backend_pid();" && \
|
||||
docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault postgres -c "DROP DATABASE IF EXISTS aliasvault;" && \
|
||||
docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault postgres -c "CREATE DATABASE aliasvault OWNER aliasvault;" && \
|
||||
gunzip -c "$temp_file" | docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault aliasvault
|
||||
if [ "$is_gzipped" = true ]; then
|
||||
gunzip -c "$temp_file" | docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault aliasvault
|
||||
else
|
||||
cat "$temp_file" | docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault aliasvault
|
||||
fi
|
||||
else
|
||||
docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'aliasvault' AND pid <> pg_backend_pid();" > /dev/null 2>&1 && \
|
||||
docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault postgres -c "DROP DATABASE IF EXISTS aliasvault;" > /dev/null 2>&1 && \
|
||||
docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault postgres -c "CREATE DATABASE aliasvault OWNER aliasvault;" > /dev/null 2>&1 && \
|
||||
gunzip -c "$temp_file" | docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault aliasvault > /dev/null 2>&1
|
||||
if [ "$is_gzipped" = true ]; then
|
||||
gunzip -c "$temp_file" | docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault aliasvault > /dev/null 2>&1
|
||||
else
|
||||
cat "$temp_file" | docker compose -f dockerfiles/docker-compose.dev.yml -p aliasvault-dev exec -T postgres-dev psql -U aliasvault aliasvault > /dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ "$VERBOSE" = true ]; then
|
||||
docker compose exec -T postgres psql -U aliasvault postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'aliasvault' AND pid <> pg_backend_pid();" && \
|
||||
docker compose exec -T postgres psql -U aliasvault postgres -c "DROP DATABASE IF EXISTS aliasvault;" && \
|
||||
docker compose exec -T postgres psql -U aliasvault postgres -c "CREATE DATABASE aliasvault OWNER aliasvault;" && \
|
||||
gunzip -c "$temp_file" | docker compose exec -T postgres psql -U aliasvault aliasvault
|
||||
if [ "$is_gzipped" = true ]; then
|
||||
gunzip -c "$temp_file" | docker compose exec -T postgres psql -U aliasvault aliasvault
|
||||
else
|
||||
cat "$temp_file" | docker compose exec -T postgres psql -U aliasvault aliasvault
|
||||
fi
|
||||
else
|
||||
docker compose exec -T postgres psql -U aliasvault postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'aliasvault' AND pid <> pg_backend_pid();" > /dev/null 2>&1 && \
|
||||
docker compose exec -T postgres psql -U aliasvault postgres -c "DROP DATABASE IF EXISTS aliasvault;" > /dev/null 2>&1 && \
|
||||
docker compose exec -T postgres psql -U aliasvault postgres -c "CREATE DATABASE aliasvault OWNER aliasvault;" > /dev/null 2>&1 && \
|
||||
gunzip -c "$temp_file" | docker compose exec -T postgres psql -U aliasvault aliasvault > /dev/null 2>&1
|
||||
if [ "$is_gzipped" = true ]; then
|
||||
gunzip -c "$temp_file" | docker compose exec -T postgres psql -U aliasvault aliasvault > /dev/null 2>&1
|
||||
else
|
||||
cat "$temp_file" | docker compose exec -T postgres psql -U aliasvault aliasvault > /dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -2908,8 +2953,7 @@ handle_hostname_configuration() {
|
||||
fi
|
||||
|
||||
printf "The hostname is the domain name where your AliasVault server will be accessible.\n"
|
||||
printf "A valid hostname is required for Let's Encrypt SSL certificate generation.\n"
|
||||
printf "The hostname must be a real domain that points to this server (not localhost).\n"
|
||||
printf "This hostname will be used for both Let's Encrypt and self-signed certificates.\n"
|
||||
printf "\n"
|
||||
|
||||
# Get current hostname
|
||||
@@ -2919,7 +2963,7 @@ handle_hostname_configuration() {
|
||||
|
||||
# Ask for new hostname
|
||||
while true; do
|
||||
read -p "Enter new hostname (e.g. aliasvault.net): " NEW_HOSTNAME
|
||||
read -p "Enter new hostname (e.g. aliasvault.example.com): " NEW_HOSTNAME
|
||||
if [ -n "$NEW_HOSTNAME" ]; then
|
||||
break
|
||||
else
|
||||
@@ -2927,9 +2971,36 @@ handle_hostname_configuration() {
|
||||
fi
|
||||
done
|
||||
|
||||
# Check if hostname changed
|
||||
HOSTNAME_CHANGED=false
|
||||
if [ "$CURRENT_HOSTNAME" != "$NEW_HOSTNAME" ]; then
|
||||
HOSTNAME_CHANGED=true
|
||||
fi
|
||||
|
||||
# Update the hostname
|
||||
update_env_var "HOSTNAME" "$NEW_HOSTNAME"
|
||||
|
||||
# If using self-signed cert and hostname changed, offer to regenerate
|
||||
if [ "$HOSTNAME_CHANGED" = true ]; then
|
||||
LETSENCRYPT_ENABLED=$(grep "^LETSENCRYPT_ENABLED=" "$ENV_FILE" | cut -d '=' -f2)
|
||||
if [ "$LETSENCRYPT_ENABLED" != "true" ]; then
|
||||
printf "\n${YELLOW}Hostname changed. The self-signed certificate needs to be regenerated.${NC}\n"
|
||||
read -p "Regenerate certificate now? (y/n): " REGEN_CERT
|
||||
if [ "$REGEN_CERT" = "y" ] || [ "$REGEN_CERT" = "Y" ]; then
|
||||
# Remove the hostname marker to force regeneration
|
||||
rm -f ./certificates/ssl/.hostname_marker
|
||||
|
||||
printf "\n${YELLOW}Restarting services to regenerate certificate...${NC}\n"
|
||||
handle_restart
|
||||
else
|
||||
printf "${YELLOW}Please restart services manually to apply the new certificate.${NC}\n"
|
||||
fi
|
||||
else
|
||||
printf "\n${YELLOW}Note: You're using Let's Encrypt. Make sure the new hostname has proper DNS records.${NC}\n"
|
||||
printf "${YELLOW}You may need to reconfigure Let's Encrypt for the new hostname.${NC}\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "\n"
|
||||
print_success_box "Hostname updated successfully to ${NEW_HOSTNAME}!"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user